summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2023-04-15 20:37:26 +0300
committerGeorge Hazan <ghazan@miranda.im>2023-04-15 20:37:26 +0300
commit0f09bc6a33604e79996caaf6ff021226e96e53fd (patch)
treef603883af17f3b72fd5adbf11b8846ef191e8208 /src
parent123fa87f68c42b4f121ad315623a9fb5a39ab30c (diff)
fixes #3458 (tabSRMM: двоятся сообщения)
Diffstat (limited to 'src')
-rw-r--r--src/core/stdmsg/src/msglog.cpp12
-rw-r--r--src/mir_app/src/chat.h1
-rw-r--r--src/mir_app/src/chat_log.cpp62
-rw-r--r--src/mir_app/src/chat_manager.cpp103
-rw-r--r--src/mir_app/src/chat_svc.cpp22
-rw-r--r--src/mir_app/src/chat_tools.cpp22
-rw-r--r--src/mir_app/src/srmm_base.cpp32
-rw-r--r--src/mir_app/src/srmm_log_hpp.cpp20
-rw-r--r--src/mir_app/src/srmm_log_rtf.cpp27
9 files changed, 142 insertions, 159 deletions
diff --git a/src/core/stdmsg/src/msglog.cpp b/src/core/stdmsg/src/msglog.cpp
index 92fac27943..d70f1dedee 100644
--- a/src/core/stdmsg/src/msglog.cpp
+++ b/src/core/stdmsg/src/msglog.cpp
@@ -471,20 +471,20 @@ public:
/////////////////////////////////////////////////////////////////////////////////////////
- void LogEvents(struct LOGINFO *lin, bool bRedraw) override
+ void LogEvents(SESSION_INFO *si, int iStart, bool bRedraw) override
{
- auto *si = m_pDlg.m_si;
- if (lin == nullptr || si == nullptr)
+ if (si == nullptr)
return;
- if (!bRedraw && si->iType == GCW_CHATROOM && (m_pDlg.m_iLogFilterFlags & lin->iType) == 0)
+ auto &lin = si->arEvents[iStart];
+ if (!bRedraw && si->iType == GCW_CHATROOM && (m_pDlg.m_iLogFilterFlags & lin.iType) == 0)
return;
LOGSTREAMDATA streamData;
memset(&streamData, 0, sizeof(streamData));
streamData.hwnd = m_rtf.GetHwnd();
streamData.si = si;
- streamData.lin = lin;
+ streamData.iStartEvent = iStart;
streamData.bStripFormat = FALSE;
bool bFlag = false;
@@ -533,7 +533,7 @@ public:
m_rtf.SendMsg(EM_STREAMIN, wp, (LPARAM)&stream);
// do smileys
- if (g_plugin.bSmileyInstalled && (bRedraw || (lin->ptszText && lin->iType != GC_EVENT_JOIN && lin->iType != GC_EVENT_NICK && lin->iType != GC_EVENT_ADDSTATUS && lin->iType != GC_EVENT_REMOVESTATUS))) {
+ if (g_plugin.bSmileyInstalled && (bRedraw || (lin.ptszText && lin.iType != GC_EVENT_JOIN && lin.iType != GC_EVENT_NICK && lin.iType != GC_EVENT_ADDSTATUS && lin.iType != GC_EVENT_REMOVESTATUS))) {
CHARRANGE newsel;
newsel.cpMax = -1;
newsel.cpMin = sel.cpMin;
diff --git a/src/mir_app/src/chat.h b/src/mir_app/src/chat.h
index 04fa195b9c..df5141f2e1 100644
--- a/src/mir_app/src/chat.h
+++ b/src/mir_app/src/chat.h
@@ -129,6 +129,7 @@ int ShowPopup(MCONTACT hContact, SESSION_INFO *si, HICON hIcon, char*
CSrmmLogWindow *Srmm_GetLogWindow(CMsgDialog *pDlg);
+void Chat_EventToGC(SESSION_INFO *si, MEVENT hDbEvent);
void Chat_RemoveContact(MCONTACT hContact);
CMStringW Chat_GetFolderName(SESSION_INFO *si = nullptr);
diff --git a/src/mir_app/src/chat_log.cpp b/src/mir_app/src/chat_log.cpp
index 151662ab5d..5f82bace10 100644
--- a/src/mir_app/src/chat_log.cpp
+++ b/src/mir_app/src/chat_log.cpp
@@ -30,11 +30,11 @@ char *pLogIconBmpBits[14];
#define RTFCACHELINESIZE 128
static char CHAT_rtfFontsGlobal[OPTIONS_FONTCOUNT][RTFCACHELINESIZE];
-static int EventToIndex(LOGINFO *lin)
+static int EventToIndex(const LOGINFO &lin)
{
- switch (lin->iType) {
+ switch (lin.iType) {
case GC_EVENT_MESSAGE:
- if (lin->bIsMe)
+ if (lin.bIsMe)
return 10;
else
return 9;
@@ -54,11 +54,11 @@ static int EventToIndex(LOGINFO *lin)
return 0;
}
-static int EventToIcon(LOGINFO *lin)
+static int EventToIcon(const LOGINFO &lin)
{
- switch (lin->iType) {
+ switch (lin.iType) {
case GC_EVENT_MESSAGE:
- if (lin->bIsMe)
+ if (lin.bIsMe)
return ICON_MESSAGEOUT;
else
return ICON_MESSAGE;
@@ -89,6 +89,7 @@ char* Log_SetStyle(int style)
static int Log_AppendRTF(LOGSTREAMDATA *streamData, bool simpleMode, CMStringA &buf, const wchar_t *line)
{
int textCharsCount = 0;
+ auto &lin = streamData->si->arEvents[streamData->iStartEvent];
for (; *line; line++, textCharsCount++) {
if (*line == '\r' && line[1] == '\n') {
@@ -129,7 +130,7 @@ static int Log_AppendRTF(LOGSTREAMDATA *streamData, bool simpleMode, CMStringA &
case 'C':
case 'F':
if (!g_Settings->bStripFormat && !streamData->bStripFormat) {
- int j = streamData->lin->bIsHighlighted ? 16 : EventToIndex(streamData->lin);
+ int j = lin.bIsHighlighted ? 16 : EventToIndex(lin);
if (*line == 'C')
mir_snprintf(szTemp, "\\cf%u ", j + 1);
else
@@ -154,7 +155,7 @@ static int Log_AppendRTF(LOGSTREAMDATA *streamData, bool simpleMode, CMStringA &
case 'r':
if (!streamData->bStripFormat) {
- int index = EventToIndex(streamData->lin);
+ int index = EventToIndex(lin);
mir_snprintf(szTemp, "%s ", Log_SetStyle(index));
}
break;
@@ -252,16 +253,16 @@ MIR_APP_DLL(bool) Chat_GetDefaultEventDescr(const SESSION_INFO *si, const LOGINF
return false;
}
-static void AddEventToBuffer(CMStringA &buf, LOGSTREAMDATA *streamData)
+static void AddEventToBuffer(CMStringA &buf, LOGSTREAMDATA *streamData, const LOGINFO &lin)
{
CMStringW wszCaption;
- bool bTextUsed = Chat_GetDefaultEventDescr(streamData->si, streamData->lin, wszCaption);
+ bool bTextUsed = Chat_GetDefaultEventDescr(streamData->si, &lin, wszCaption);
if (!wszCaption.IsEmpty())
Log_AppendRTF(streamData, !bTextUsed, buf, wszCaption);
- if (!bTextUsed && streamData->lin->ptszText) {
+ if (!bTextUsed && lin.ptszText) {
if (!wszCaption.IsEmpty())
Log_AppendRTF(streamData, false, buf, L" ");
- Log_AppendRTF(streamData, false, buf, streamData->lin->ptszText);
+ Log_AppendRTF(streamData, false, buf, lin.ptszText);
}
}
@@ -287,20 +288,22 @@ char* Log_CreateRTF(LOGSTREAMDATA *streamData)
buf.Append(header);
// ### RTF BODY (one iteration per event that should be streamed in)
- for (LOGINFO *lin = streamData->lin; lin; lin = lin->prev) {
+ for (int i = 0; i < si->arEvents.getCount(); i++) {
+ auto &lin = si->arEvents[i];
+
// filter
if (si->iType == GCW_CHATROOM || si->iType == GCW_PRIVMESS)
- if (!(si->pDlg->m_iLogFilterFlags & lin->iType))
+ if (!(si->pDlg->m_iLogFilterFlags & lin.iType))
continue;
// create new line, and set font and color
- if (lin->next != nullptr)
+ if (i != 0)
buf.Append("\\par ");
buf.AppendFormat("%s ", Log_SetStyle(0));
// Insert icon
- if ((lin->iType & g_Settings->dwIconFlags) || lin->bIsHighlighted && (g_Settings->dwIconFlags & GC_EVENT_HIGHLIGHT)) {
- int iIndex = (lin->bIsHighlighted && (g_Settings->dwIconFlags & GC_EVENT_HIGHLIGHT)) ? ICON_HIGHLIGHT : EventToIcon(lin);
+ if ((lin.iType & g_Settings->dwIconFlags) || lin.bIsHighlighted && (g_Settings->dwIconFlags & GC_EVENT_HIGHLIGHT)) {
+ int iIndex = (lin.bIsHighlighted && (g_Settings->dwIconFlags & GC_EVENT_HIGHLIGHT)) ? ICON_HIGHLIGHT : EventToIcon(lin);
buf.Append("\\f0\\fs14");
buf.Append(pLogIconBmpBits[iIndex]);
}
@@ -309,12 +312,12 @@ char* Log_CreateRTF(LOGSTREAMDATA *streamData)
LOGFONT &lf = g_chatApi.aFonts[0].lf;
// colored timestamps
- if (lin->ptszNick && lin->iType == GC_EVENT_MESSAGE) {
- int iii = lin->bIsHighlighted ? 16 : (lin->bIsMe ? 2 : 1);
+ if (lin.ptszNick && lin.iType == GC_EVENT_MESSAGE) {
+ int iii = lin.bIsHighlighted ? 16 : (lin.bIsMe ? 2 : 1);
buf.AppendFormat("\\f0\\cf%u\\ul0\\highlight0\\b%d\\i%d\\fs%u", iii + 1, lf.lfWeight >= FW_BOLD ? 1 : 0, lf.lfItalic, 2 * abs(lf.lfHeight) * 74 / g_chatApi.logPixelSY);
}
else {
- int iii = lin->bIsHighlighted ? 16 : EventToIndex(lin);
+ int iii = lin.bIsHighlighted ? 16 : EventToIndex(lin);
buf.AppendFormat("\\f0\\cf%u\\ul0\\highlight0\\b%d\\i%d\\fs%u", iii + 1, lf.lfWeight >= FW_BOLD ? 1 : 0, lf.lfItalic, 2 * abs(lf.lfHeight) * 74 / g_chatApi.logPixelSY);
}
}
@@ -323,33 +326,32 @@ char* Log_CreateRTF(LOGSTREAMDATA *streamData)
if (g_Settings->dwIconFlags)
buf.Append("\\tab ");
- //insert timestamp
+ // insert timestamp
if (g_Settings->bShowTime) {
wchar_t szTimeStamp[100], szOldTimeStamp[100];
- wcsncpy_s(szTimeStamp, MakeTimeStamp(g_Settings->pszTimeStamp, lin->time), _TRUNCATE);
+ wcsncpy_s(szTimeStamp, MakeTimeStamp(g_Settings->pszTimeStamp, lin.time), _TRUNCATE);
wcsncpy_s(szOldTimeStamp, MakeTimeStamp(g_Settings->pszTimeStamp, si->LastTime), _TRUNCATE);
if (!g_Settings->bShowTimeIfChanged || si->LastTime == 0 || mir_wstrcmp(szTimeStamp, szOldTimeStamp)) {
- si->LastTime = lin->time;
+ si->LastTime = lin.time;
Log_AppendRTF(streamData, true, buf, szTimeStamp);
}
buf.Append("\\tab ");
}
// Insert the nick
- if (lin->ptszNick && lin->iType == GC_EVENT_MESSAGE) {
- buf.AppendFormat("%s ", Log_SetStyle(lin->bIsMe ? 2 : 1));
+ if (lin.ptszNick && lin.iType == GC_EVENT_MESSAGE) {
+ buf.AppendFormat("%s ", Log_SetStyle(lin.bIsMe ? 2 : 1));
- CMStringW tmp((lin->bIsMe) ? g_Settings->pszOutgoingNick : g_Settings->pszIncomingNick);
- tmp.Replace(L"%n", lin->ptszNick);
+ CMStringW tmp((lin.bIsMe) ? g_Settings->pszOutgoingNick : g_Settings->pszIncomingNick);
+ tmp.Replace(L"%n", lin.ptszNick);
Log_AppendRTF(streamData, TRUE, buf, tmp);
buf.AppendChar(' ');
}
// Insert the message
- buf.AppendFormat("%s ", Log_SetStyle(lin->bIsHighlighted ? 16 : EventToIndex(lin)));
- streamData->lin = lin;
- AddEventToBuffer(buf, streamData);
+ buf.AppendFormat("%s ", Log_SetStyle(lin.bIsHighlighted ? 16 : EventToIndex(lin)));
+ AddEventToBuffer(buf, streamData, lin);
}
// ### RTF END
diff --git a/src/mir_app/src/chat_manager.cpp b/src/mir_app/src/chat_manager.cpp
index 23984f3601..3917e19801 100644
--- a/src/mir_app/src/chat_manager.cpp
+++ b/src/mir_app/src/chat_manager.cpp
@@ -56,76 +56,24 @@ static int compareModules(const MODULEINFO *p1, const MODULEINFO *p2)
static LIST<MODULEINFO> g_arModules(5, compareModules);
/////////////////////////////////////////////////////////////////////////////////////////
-// Log manager functions
-// Necessary to keep track of events in a window log
-
-static LOGINFO* LM_AddEvent(LOGINFO **ppLogListStart, LOGINFO **ppLogListEnd)
-{
- if (!ppLogListStart || !ppLogListEnd)
- return nullptr;
-
- LOGINFO *node = (LOGINFO *)mir_calloc(sizeof(LOGINFO));
- if (*ppLogListStart == nullptr) { // list is empty
- *ppLogListStart = node;
- *ppLogListEnd = node;
- node->next = nullptr;
- node->prev = nullptr;
- }
- else {
- ppLogListStart[0]->prev = node;
- node->next = *ppLogListStart;
- *ppLogListStart = node;
- ppLogListStart[0]->prev = nullptr;
- }
-
- return node;
-}
+// Session Manager functions
+// Keeps track of all sessions and its windows
-static BOOL LM_TrimLog(LOGINFO **ppLogListStart, LOGINFO **ppLogListEnd, int iCount)
+static int CompareEvents(const LOGINFO *p1, const LOGINFO *p2)
{
- LOGINFO *pTemp = *ppLogListEnd;
- while (pTemp != nullptr && iCount > 0) {
- *ppLogListEnd = pTemp->prev;
- if (*ppLogListEnd == nullptr)
- *ppLogListStart = nullptr;
+ if (p1->time != p2->time)
+ return (p1->time < p2->time) ? -1 : 1;
- mir_free(pTemp->ptszNick);
- mir_free(pTemp->ptszUserInfo);
- mir_free(pTemp->ptszText);
- mir_free(pTemp->ptszStatus);
- mir_free(pTemp);
- pTemp = *ppLogListEnd;
- iCount--;
- }
- ppLogListEnd[0]->next = nullptr;
-
- return TRUE;
-}
-
-static BOOL LM_RemoveAll(LOGINFO **ppLogListStart, LOGINFO **ppLogListEnd)
-{
- while (*ppLogListStart != nullptr) {
- LOGINFO *pLast = ppLogListStart[0]->next;
- mir_free(ppLogListStart[0]->ptszText);
- mir_free(ppLogListStart[0]->ptszNick);
- mir_free(ppLogListStart[0]->ptszStatus);
- mir_free(ppLogListStart[0]->ptszUserInfo);
- mir_free(*ppLogListStart);
- *ppLogListStart = pLast;
- }
- *ppLogListStart = nullptr;
- *ppLogListEnd = nullptr;
- return TRUE;
+ return (int)p1->hEvent - (int)p2->hEvent;
}
-/////////////////////////////////////////////////////////////////////////////////////////
-// Session Manager functions
-// Keeps track of all sessions and its windows
-
SESSION_INFO::SESSION_INFO() :
arKeys(10, CompareKeys),
- arUsers(10, CompareUser)
-{}
+ arUsers(10, CompareUser),
+ arEvents(10, CompareEvents)
+{
+ iLastEvent = MAXINT/2;
+}
SESSION_INFO::~SESSION_INFO()
{}
@@ -186,8 +134,8 @@ void SM_FreeSession(SESSION_INFO *si)
UM_RemoveAll(si);
g_chatApi.TM_RemoveAll(&si->pStatuses);
- g_chatApi.LM_RemoveAll(&si->pLog, &si->pLogEnd);
+ si->arEvents.destroy();
si->iStatusCount = 0;
mir_free(si->pszModule);
@@ -251,23 +199,32 @@ BOOL SM_AddEvent(SESSION_INFO *si, GCEVENT *gce, bool bIsHighlighted)
if (si == nullptr)
return TRUE;
- LOGINFO *li = LM_AddEvent(&si->pLog, &si->pLogEnd);
- si->iEventCount++;
+ LOGINFO *li = new LOGINFO();
+ li->time = gce->time;
+ li->bIsHighlighted = bIsHighlighted;
+ if (si->pMI->bDatabase && gce->hEvent) {
+ li->hEvent = gce->hEvent;
+ if (si->arEvents.find(li)) {
+ delete li;
+ return TRUE;
+ }
+ }
+ else li->hEvent = si->iLastEvent++;
li->iType = gce->iType;
li->ptszNick = mir_wstrdup(gce->pszNick.w);
li->ptszText = mir_wstrdup(gce->pszText.w);
li->ptszStatus = mir_wstrdup(gce->pszStatus.w);
li->ptszUserInfo = mir_wstrdup(gce->pszUserInfo.w);
-
li->bIsMe = gce->bIsMe;
- li->time = gce->time;
- li->bIsHighlighted = bIsHighlighted;
+
+ si->arEvents.insert(li);
+
+ if (g_Settings->iEventLimit > 0 && si->arEvents.getCount() > g_Settings->iEventLimit + 20) {
+ for (int i = si->arEvents.getCount() - g_Settings->iEventLimit; i >= 0; i--)
+ si->arEvents.remove(0);
- if (g_Settings->iEventLimit > 0 && si->iEventCount > g_Settings->iEventLimit + 20) {
- LM_TrimLog(&si->pLog, &si->pLogEnd, si->iEventCount - g_Settings->iEventLimit);
si->bTrimmed = true;
- si->iEventCount = g_Settings->iEventLimit;
return FALSE;
}
return TRUE;
@@ -881,8 +838,6 @@ static void ResetApi()
g_chatApi.UM_FindUserAutoComplete = ::UM_FindUserAutoComplete;
g_chatApi.UM_RemoveUser = ::UM_RemoveUser;
- g_chatApi.LM_RemoveAll = ::LM_RemoveAll;
-
g_chatApi.SetOffline = ::SetOffline;
g_chatApi.SetAllOffline = ::SetAllOffline;
g_chatApi.DoRtfToTags = ::DoRtfToTags;
diff --git a/src/mir_app/src/chat_svc.cpp b/src/mir_app/src/chat_svc.cpp
index 0e590cdeb3..cc573729c6 100644
--- a/src/mir_app/src/chat_svc.cpp
+++ b/src/mir_app/src/chat_svc.cpp
@@ -329,8 +329,7 @@ static int RoomControlHandler(int iCommand, SESSION_INFO *si)
break;
case WINDOW_CLEARLOG:
- g_chatApi.LM_RemoveAll(&si->pLog, &si->pLogEnd);
- si->iEventCount = 0;
+ si->arEvents.destroy();
si->LastTime = 0;
if (si->pDlg)
si->pDlg->ClearLog();
@@ -821,23 +820,8 @@ static int OnEventAdded(WPARAM hContact, LPARAM hDbEvent)
return 0;
if (Contact::IsGroupChat(hContact)) {
- if (auto *si = SM_FindSessionByContact(hContact)) {
- DB::EventInfo dbei(hDbEvent);
- if (dbei) {
- auto *szProto = Proto_GetBaseAccountName(si->hContact);
- if (si && !mir_strcmp(szProto, dbei.szModule) && dbei.eventType == EVENTTYPE_MESSAGE && dbei.szUserId) {
- CMStringA szText((char *)dbei.pBlob);
- szText.Replace("%", "%%");
-
- GCEVENT gce = { si, GC_EVENT_MESSAGE };
- gce.dwFlags = GCEF_ADDTOLOG | GCEF_UTF8;
- gce.pszUID.a = dbei.szUserId;
- gce.pszText.a = szText;
- gce.time = dbei.timestamp;
- Chat_Event(&gce);
- }
- }
- }
+ if (auto *si = SM_FindSessionByContact(hContact))
+ Chat_EventToGC(si, hDbEvent);
}
else {
g_clistApi.pfnRemoveEvent(hContact, 1);
diff --git a/src/mir_app/src/chat_tools.cpp b/src/mir_app/src/chat_tools.cpp
index 938db7b19c..48f5271745 100644
--- a/src/mir_app/src/chat_tools.cpp
+++ b/src/mir_app/src/chat_tools.cpp
@@ -737,6 +737,28 @@ wchar_t* GetChatLogsFilename(SESSION_INFO *si, time_t tTime)
return si->pszLogFileName;
}
+void Chat_EventToGC(SESSION_INFO *si, MEVENT hDbEvent)
+{
+ DB::EventInfo dbei(hDbEvent);
+ if (!dbei)
+ return;
+
+ auto *szProto = Proto_GetBaseAccountName(si->hContact);
+ if (mir_strcmp(szProto, dbei.szModule) || dbei.eventType != EVENTTYPE_MESSAGE || !dbei.szUserId)
+ return;
+
+ CMStringA szText((char *)dbei.pBlob);
+ szText.Replace("%", "%%");
+
+ GCEVENT gce = { si, GC_EVENT_MESSAGE };
+ gce.dwFlags = GCEF_ADDTOLOG | GCEF_UTF8;
+ gce.pszUID.a = dbei.szUserId;
+ gce.pszText.a = szText;
+ gce.time = dbei.timestamp;
+ gce.hEvent = hDbEvent;
+ Chat_Event(&gce);
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
MIR_APP_DLL(wchar_t*) Chat_GetGroup()
diff --git a/src/mir_app/src/srmm_base.cpp b/src/mir_app/src/srmm_base.cpp
index 6e567643d6..8c7b9b69df 100644
--- a/src/mir_app/src/srmm_base.cpp
+++ b/src/mir_app/src/srmm_base.cpp
@@ -74,7 +74,7 @@ CSrmmBaseDialog::CSrmmBaseDialog(CMPluginBase &pPlugin, int idDialog, SESSION_IN
m_bBGSet = true;
}
- m_bFilterEnabled = m_bFilterEnabled = db_get_b(m_hContact, CHAT_MODULE, "FilterEnabled", Chat::bFilterEnabled) != 0;
+ m_bFilterEnabled = db_get_b(m_hContact, CHAT_MODULE, "FilterEnabled", Chat::bFilterEnabled) != 0;
m_iLogFilterFlags = Chat::iFilterFlags;
m_bNicklistEnabled = Chat::bShowNicklist;
}
@@ -581,8 +581,9 @@ INT_PTR CSrmmBaseDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
void CSrmmBaseDialog::AddLog()
{
- if (m_si->pLogEnd)
- m_pLog->LogEvents(m_si->pLog, false);
+ int iEventCount = m_si->arEvents.getCount();
+ if (iEventCount)
+ m_pLog->LogEvents(m_si, iEventCount-1, false);
else
m_pLog->Clear();
}
@@ -617,8 +618,10 @@ void CSrmmBaseDialog::UpdateOptions()
void RedrawLog2(SESSION_INFO *si)
{
si->LastTime = 0;
- if (si->pLog)
- si->pDlg->log()->LogEvents(si->pLogEnd, TRUE);
+
+ int iEventCount = si->arEvents.getCount();
+ if (iEventCount)
+ si->pDlg->log()->LogEvents(si, 0, TRUE);
}
static void __cdecl phase2(SESSION_INFO *si)
@@ -631,22 +634,23 @@ static void __cdecl phase2(SESSION_INFO *si)
void CSrmmBaseDialog::RedrawLog()
{
m_si->LastTime = 0;
- if (m_si->pLog) {
- LOGINFO *pLog = m_si->pLog;
- if (m_si->iEventCount > 60) {
+
+ int iEventCount = m_si->arEvents.getCount();
+ if (iEventCount) {
+ if (iEventCount > 60) {
int index = 0;
while (index < 59) {
- if (pLog->next == nullptr)
+ if (iEventCount == 0)
break;
- pLog = pLog->next;
- if (m_si->iType != GCW_CHATROOM || !m_bFilterEnabled || (m_iLogFilterFlags & pLog->iType) != 0)
+ iEventCount--;
+ if (m_si->iType != GCW_CHATROOM || (m_iLogFilterFlags & m_si->arEvents[iEventCount].iType) != 0)
index++;
}
- m_pLog->LogEvents(pLog, true);
+ m_pLog->LogEvents(m_si, iEventCount, true);
mir_forkThread<SESSION_INFO>(phase2, m_si);
}
- else m_pLog->LogEvents(m_si->pLogEnd, true);
+ else m_pLog->LogEvents(m_si, 0, true);
}
else ClearLog();
}
@@ -684,7 +688,7 @@ void CSrmmBaseDialog::UpdateChatLog()
}
m_si->bHistoryInit = true;
- m_pLog->LogEvents(m_si->pLogEnd, false);
+ m_pLog->LogEvents(m_si, 0, false);
}
void CSrmmBaseDialog::UpdateFilterButton()
diff --git a/src/mir_app/src/srmm_log_hpp.cpp b/src/mir_app/src/srmm_log_hpp.cpp
index 584ed539f9..cfdca891d0 100644
--- a/src/mir_app/src/srmm_log_hpp.cpp
+++ b/src/mir_app/src/srmm_log_hpp.cpp
@@ -109,7 +109,7 @@ public:
CallService(MS_HPP_EG_EVENT, 0, (LPARAM)&event);
}
- void CHppLogWindow::LogEvents(LOGINFO *pLog, bool)
+ void CHppLogWindow::LogEvents(SESSION_INFO *si, int iStart, bool) override
{
IEVIEWEVENTDATA ied = {};
ied.dwFlags = IEEDF_UNICODE_NICK | IEEDF_UNICODE_TEXT;
@@ -122,14 +122,16 @@ public:
event.eventData = &ied;
event.count = 1;
- while (pLog) {
- if (pLog->ptszText) {
- ied.szNick.w = pLog->ptszNick;
- ied.szText.w = pLog->ptszText;
- ied.time = pLog->time;
- ied.bIsMe = pLog->bIsMe;
+ for (int i=iStart; i < si->arEvents.getCount(); i++) {
+ auto &pLog = si->arEvents[i];
+
+ if (pLog.ptszText) {
+ ied.szNick.w = pLog.ptszNick;
+ ied.szText.w = pLog.ptszText;
+ ied.time = pLog.time;
+ ied.bIsMe = pLog.bIsMe;
- switch (pLog->iType) {
+ switch (pLog.iType) {
case GC_EVENT_MESSAGE:
ied.iType = IEED_GC_EVENT_MESSAGE;
ied.dwData = IEEDD_GC_SHOW_NICK;
@@ -173,8 +175,6 @@ public:
ied.dwFlags = IEEDF_UNICODE_TEXT | IEEDF_UNICODE_NICK;
CallService(MS_HPP_EG_EVENT, 0, (LPARAM) & event);
}
-
- pLog = pLog->prev;
}
}
diff --git a/src/mir_app/src/srmm_log_rtf.cpp b/src/mir_app/src/srmm_log_rtf.cpp
index 88a8466f93..b38eb0f4eb 100644
--- a/src/mir_app/src/srmm_log_rtf.cpp
+++ b/src/mir_app/src/srmm_log_rtf.cpp
@@ -359,10 +359,26 @@ static DWORD CALLBACK LogStreamInEvents(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG
void CRtfLogWindow::StreamRtfEvents(RtfLogStreamData *dat, bool bAppend)
{
- EDITSTREAM stream = {};
- stream.pfnCallback = LogStreamInEvents;
- stream.dwCookie = (DWORD_PTR)dat;
- m_rtf.SendMsg(EM_STREAMIN, bAppend ? SFF_SELECTION | SF_RTF : SF_RTF, (LPARAM)&stream);
+ if (Contact::IsGroupChat(dat->hContact)) {
+ if (auto *si = SM_FindSessionByContact(dat->hContact)) {
+ bool bDone = false;
+
+ for (MEVENT hDbEvent = dat->hDbEvent; hDbEvent && dat->eventsToInsert; dat->eventsToInsert--) {
+ Chat_EventToGC(si, dat->hDbEvent);
+ dat->hDbEvent = db_event_next(dat->hContact, dat->hDbEvent);
+ bDone = true;
+ }
+
+ if (bDone && si->pDlg)
+ si->pDlg->RedrawLog();
+ }
+ }
+ else {
+ EDITSTREAM stream = {};
+ stream.pfnCallback = LogStreamInEvents;
+ stream.dwCookie = (DWORD_PTR)dat;
+ m_rtf.SendMsg(EM_STREAMIN, bAppend ? SFF_SELECTION | SF_RTF : SF_RTF, (LPARAM)&stream);
+ }
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -505,8 +521,7 @@ INT_PTR CRtfLogWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam)
case IDM_CLEAR:
m_rtf.SetText(L"");
if (auto *si = m_pDlg.m_si) {
- g_chatApi.LM_RemoveAll(&si->pLog, &si->pLogEnd);
- si->iEventCount = 0;
+ si->arEvents.destroy();
si->LastTime = 0;
}
PostMessage(m_pDlg.m_hwnd, WM_MOUSEACTIVATE, 0, 0);