summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/m_chat.h1
-rw-r--r--include/m_chat_int.h27
-rw-r--r--include/m_srmm_int.h2
-rw-r--r--plugins/IEView/src/ieview_logger.cpp18
-rw-r--r--plugins/NewStory/src/history_log.cpp8
-rw-r--r--plugins/Scriver/src/msglog.cpp12
-rw-r--r--plugins/TabSRMM/src/chat_log.cpp86
-rw-r--r--plugins/TabSRMM/src/msgdlgother.cpp3
-rw-r--r--plugins/TabSRMM/src/msglog.cpp14
-rw-r--r--plugins/TabSRMM/src/msgs.h2
-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
19 files changed, 225 insertions, 249 deletions
diff --git a/include/m_chat.h b/include/m_chat.h
index 92e4e6329b..bd5967dc9f 100644
--- a/include/m_chat.h
+++ b/include/m_chat.h
@@ -381,6 +381,7 @@ struct GCEVENT
INT_PTR dwItemData; // User specified data.
uint32_t time; // Timestamp of the event
+ MEVENT hEvent; // Database event
};
MIR_APP_DLL(int) Chat_Event(GCEVENT*);
diff --git a/include/m_chat_int.h b/include/m_chat_int.h
index cf0e1b5778..807845380b 100644
--- a/include/m_chat_int.h
+++ b/include/m_chat_int.h
@@ -111,17 +111,17 @@ struct FONTINFO
struct LOGINFO
{
- wchar_t *ptszText;
- wchar_t *ptszNick;
- wchar_t *ptszUID;
- wchar_t *ptszStatus;
- wchar_t *ptszUserInfo;
+ ptrW ptszText;
+ ptrW ptszNick;
+ ptrW ptszUID;
+ ptrW ptszStatus;
+ ptrW ptszUserInfo;
bool bIsMe;
bool bIsHighlighted;
bool bSimple;
time_t time;
+ MEVENT hEvent;
int iType;
- LOGINFO *next, *prev;
};
struct STATUSINFO
@@ -153,9 +153,9 @@ struct MIR_APP_EXPORT SESSION_INFO : public MZeroedObject, public MNonCopyable
wchar_t* ptszTopic;
int iType;
- int iEventCount;
- int iStatusCount;
+ int iStatusCount, iLastEvent;
int iTrayFlags, iPopupFlags;
+ int currentHovered;
uint16_t wStatus;
uint16_t wState;
@@ -163,10 +163,7 @@ struct MIR_APP_EXPORT SESSION_INFO : public MZeroedObject, public MNonCopyable
void* pItemData;
time_t LastTime;
- int currentHovered;
-
CMsgDialog *pDlg;
- LOGINFO *pLog, *pLogEnd;
USERINFO *pMe;
STATUSINFO *pStatuses;
MODULEINFO *pMI;
@@ -174,6 +171,7 @@ struct MIR_APP_EXPORT SESSION_INFO : public MZeroedObject, public MNonCopyable
LIST<USERINFO> arKeys;
OBJLIST<USERINFO> arUsers;
+ OBJLIST<LOGINFO> arEvents;
wchar_t pszLogFileName[MAX_PATH];
@@ -196,10 +194,9 @@ struct GCLogStreamDataBase
{
char* buffer;
int bufferOffset, bufferLen;
+ int iStartEvent;
+ bool bStripFormat, bRedraw;
HWND hwnd;
- LOGINFO* lin;
- BOOL bStripFormat;
- BOOL bRedraw;
SESSION_INFO *si;
};
@@ -301,8 +298,6 @@ struct CHAT_MANAGER
wchar_t* (*UM_FindUserAutoComplete)(SESSION_INFO *si, const wchar_t* pszOriginal, const wchar_t* pszCurrent);
BOOL (*UM_RemoveUser)(SESSION_INFO *si, const wchar_t *pszUID);
- BOOL (*LM_RemoveAll)(LOGINFO **ppLogListStart, LOGINFO **ppLogListEnd);
-
BOOL (*SetOffline)(MCONTACT hContact, BOOL bHide);
BOOL (*SetAllOffline)(BOOL bHide, const char *pszModule);
diff --git a/include/m_srmm_int.h b/include/m_srmm_int.h
index 817558e664..9163536e5c 100644
--- a/include/m_srmm_int.h
+++ b/include/m_srmm_int.h
@@ -128,7 +128,7 @@ public:
virtual HWND GetHwnd() = 0;
virtual wchar_t* GetSelection() = 0;
virtual void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) = 0;
- virtual void LogEvents(struct LOGINFO *, bool) = 0;
+ virtual void LogEvents(struct SESSION_INFO *si, int iStart, bool bAppend) = 0;
virtual void Resize() = 0;
virtual void ScrollToBottom() = 0;
virtual void UpdateOptions() {};
diff --git a/plugins/IEView/src/ieview_logger.cpp b/plugins/IEView/src/ieview_logger.cpp
index 9da4150847..6f613882c2 100644
--- a/plugins/IEView/src/ieview_logger.cpp
+++ b/plugins/IEView/src/ieview_logger.cpp
@@ -103,7 +103,7 @@ public:
HandleIEEvent(0, LPARAM(&event));
}
- void LogEvents(LOGINFO *pLog, bool bRedraw) override
+ void LogEvents(SESSION_INFO *si, int iStart, bool bRedraw) override
{
IEVIEWEVENTDATA ied = {};
ied.dwFlags = IEEDF_UNICODE_NICK;
@@ -116,13 +116,15 @@ public:
event.eventData = &ied;
event.count = 1;
- while (pLog) {
- 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 &lin = si->arEvents[i];
- switch (pLog->iType) {
+ ied.szNick.w = lin.ptszNick;
+ ied.szText.w = lin.ptszText;
+ ied.time = lin.time;
+ ied.bIsMe = lin.bIsMe;
+
+ switch (lin.iType) {
case GC_EVENT_MESSAGE:
ied.iType = IEED_GC_EVENT_MESSAGE;
ied.dwData = IEEDD_GC_SHOW_NICK;
@@ -165,8 +167,6 @@ public:
ied.dwData |= IEEDD_GC_SHOW_TIME | IEEDD_GC_SHOW_ICON;
ied.dwFlags = IEEDF_UNICODE_TEXT | IEEDF_UNICODE_NICK;
HandleIEEvent(0, LPARAM(&event));
-
- pLog = pLog->prev;
}
if (bRedraw)
diff --git a/plugins/NewStory/src/history_log.cpp b/plugins/NewStory/src/history_log.cpp
index 05b53ca28a..87b0b7fc9d 100644
--- a/plugins/NewStory/src/history_log.cpp
+++ b/plugins/NewStory/src/history_log.cpp
@@ -60,12 +60,10 @@ public:
SendMessage(m_hwnd, NSM_ADDEVENTS, (LPARAM)&tmp, 0);
}
- void LogEvents(LOGINFO *pLog, bool) override
+ void LogEvents(SESSION_INFO *si, int iStart, bool) override
{
- while (pLog) {
- SendMessage(m_hwnd, NSM_ADDCHATEVENT, (WPARAM)m_pDlg.getChat(), (LPARAM)pLog);
- pLog = pLog->prev;
- }
+ for (int i=iStart; i < si->arEvents.getCount(); i++)
+ SendMessage(m_hwnd, NSM_ADDCHATEVENT, (WPARAM)m_pDlg.getChat(), (LPARAM)&si->arEvents[i]);
}
void Resize() override
diff --git a/plugins/Scriver/src/msglog.cpp b/plugins/Scriver/src/msglog.cpp
index 9371504a9d..8a16ebd013 100644
--- a/plugins/Scriver/src/msglog.cpp
+++ b/plugins/Scriver/src/msglog.cpp
@@ -643,20 +643,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 (m_rtf.GetHwnd() == nullptr || lin == nullptr || si == nullptr)
+ if (m_rtf.GetHwnd() == nullptr || si == nullptr || si == nullptr)
return;
- if (!bRedraw && (si->iType == GCW_CHATROOM || si->iType == GCW_PRIVMESS) && !(m_pDlg.m_iLogFilterFlags & lin->iType))
+ auto &lin = si->arEvents[iStart];
+ if (!bRedraw && (si->iType == GCW_CHATROOM || si->iType == GCW_PRIVMESS) && !(m_pDlg.m_iLogFilterFlags & lin.iType))
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;
streamData.isFirst = bRedraw ? 1 : m_rtf.GetRichTextLength() == 0;
@@ -702,7 +702,7 @@ public:
m_rtf.SendMsg(EM_STREAMIN, wp, (LPARAM)&stream);
// do smileys
- if (g_dat.smileyAddInstalled && (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_dat.smileyAddInstalled && (bRedraw || (lin.ptszText && lin.iType != GC_EVENT_JOIN && lin.iType != GC_EVENT_NICK && lin.iType != GC_EVENT_ADDSTATUS && lin.iType != GC_EVENT_REMOVESTATUS))) {
newsel.cpMax = -1;
newsel.cpMin = sel.cpMin;
if (newsel.cpMin < 0)
diff --git a/plugins/TabSRMM/src/chat_log.cpp b/plugins/TabSRMM/src/chat_log.cpp
index 950fe19d77..624384a362 100644
--- a/plugins/TabSRMM/src/chat_log.cpp
+++ b/plugins/TabSRMM/src/chat_log.cpp
@@ -34,11 +34,11 @@
* the srmm module and then modified to fit the chat module.
*/
-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;
@@ -69,11 +69,11 @@ static int EventToIndex(LOGINFO *lin)
return 0;
}
-static uint8_t EventToSymbol(LOGINFO *lin)
+static uint8_t EventToSymbol(const LOGINFO &lin)
{
- switch (lin->iType) {
+ switch (lin.iType) {
case GC_EVENT_MESSAGE:
- return (lin->bIsMe) ? 0x37 : 0x38;
+ return (lin.bIsMe) ? 0x37 : 0x38;
case GC_EVENT_JOIN:
return 0x34;
case GC_EVENT_PART:
@@ -98,11 +98,11 @@ static uint8_t EventToSymbol(LOGINFO *lin)
return 0x73;
}
-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;
@@ -133,7 +133,7 @@ static int EventToIcon(LOGINFO *lin)
return 0;
}
-static void Log_AppendRTF(LOGSTREAMDATA *streamData, bool simpleMode, CMStringA &str, const wchar_t *line)
+static void Log_AppendRTF(LOGSTREAMDATA *streamData, const LOGINFO &lin, bool simpleMode, CMStringA &str, const wchar_t *line)
{
int textCharsCount = 0;
@@ -175,7 +175,7 @@ static void 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')
res.AppendFormat("\\cf%u ", j + 1);
else
@@ -198,7 +198,7 @@ static void Log_AppendRTF(LOGSTREAMDATA *streamData, bool simpleMode, CMStringA
case 'r':
if (!streamData->bStripFormat) {
- int index = EventToIndex(streamData->lin);
+ int index = EventToIndex(lin);
res.AppendFormat("%s ", g_chatApi.Log_SetStyle(index));
}
break;
@@ -220,19 +220,19 @@ static void Log_AppendRTF(LOGSTREAMDATA *streamData, bool simpleMode, CMStringA
str += res;
}
-static void AddEventToBuffer(CMStringA &str, LOGSTREAMDATA *streamData)
+static void AddEventToBuffer(CMStringA &str, LOGSTREAMDATA *streamData, const LOGINFO &lin)
{
- if (streamData == nullptr || streamData->lin == nullptr)
+ if (streamData == nullptr)
return;
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, str, wszCaption);
- if (!bTextUsed && streamData->lin->ptszText) {
+ Log_AppendRTF(streamData, lin, !bTextUsed, str, wszCaption);
+ if (!bTextUsed && lin.ptszText) {
if (!wszCaption.IsEmpty())
- Log_AppendRTF(streamData, false, str, L" ");
- Log_AppendRTF(streamData, false, str, streamData->lin->ptszText);
+ Log_AppendRTF(streamData, lin, false, str, L" ");
+ Log_AppendRTF(streamData, lin, false, str, lin.ptszText);
}
}
@@ -304,7 +304,6 @@ char* Log_CreateRtfHeader(void)
char* Log_CreateRTF(LOGSTREAMDATA *streamData)
{
- LOGINFO *lin = streamData->lin;
SESSION_INFO *si = streamData->si;
MODULEINFO *mi = si->pMI;
@@ -321,10 +320,13 @@ char* Log_CreateRTF(LOGSTREAMDATA *streamData)
str.Append(header);
// ### RTF BODY (one iteration per event that should be streamed in)
- while (lin) {
+ int iEventCount = si->arEvents.getCount();
+ for (int i = streamData->iStartEvent; i < iEventCount; i++) {
+ auto &lin = si->arEvents[i];
+
// filter
- if ((si->iType != GCW_CHATROOM && si->iType != GCW_PRIVMESS) || (si->pDlg->m_iLogFilterFlags & lin->iType) != 0) {
- if (lin->next != nullptr)
+ if ((si->iType != GCW_CHATROOM && si->iType != GCW_PRIVMESS) || (si->pDlg->m_iLogFilterFlags & lin.iType) != 0) {
+ if (i != 0)
str.Append("\\par ");
if (streamData->dat->m_bDividerWanted) {
@@ -332,19 +334,19 @@ char* Log_CreateRTF(LOGSTREAMDATA *streamData)
if (szStyle_div[0] == 0)
mir_snprintf(szStyle_div, "\\f%u\\cf%u\\ul0\\b%d\\i%d\\fs%u", 17, 18, 0, 0, 5);
- if (lin->prev || !streamData->bRedraw)
+ if (i != iEventCount - 1 || !streamData->bRedraw)
str.AppendFormat("\\qc\\sl-1\\highlight%d %s ---------------------------------------------------------------------------------------\\par ", 18, szStyle_div);
streamData->dat->m_bDividerWanted = false;
}
// create new line, and set font and color
str.AppendFormat("\\ql\\sl0%s ", g_chatApi.Log_SetStyle(0));
- str.AppendFormat("\\v~-+%p+-~\\v0 ", lin);
+ str.AppendFormat("\\v~-+%p+-~\\v0 ", &lin);
// Insert icon
if (g_Settings.bLogSymbols) // use symbols
str.AppendFormat("%s %c", g_chatApi.Log_SetStyle(17), EventToSymbol(lin));
else if (g_Settings.dwIconFlags) {
- int iIndex = lin->bIsHighlighted ? ICON_HIGHLIGHT : EventToIcon(lin);
+ int iIndex = lin.bIsHighlighted ? ICON_HIGHLIGHT : EventToIcon(lin);
str.Append("\\f0\\fs14");
str.Append(g_chatApi.pLogIconBmpBits[iIndex]);
}
@@ -354,14 +356,14 @@ char* Log_CreateRTF(LOGSTREAMDATA *streamData)
static char szStyle[256];
LOGFONT &F = g_chatApi.aFonts[0].lf;
int iii;
- if (lin->ptszNick && lin->iType == GC_EVENT_MESSAGE) {
- iii = lin->bIsHighlighted ? 16 : (lin->bIsMe ? 2 : 1);
+ if (lin.ptszNick && lin.iType == GC_EVENT_MESSAGE) {
+ iii = lin.bIsHighlighted ? 16 : (lin.bIsMe ? 2 : 1);
mir_snprintf(szStyle, "\\f0\\cf%u\\ul0\\highlight0\\b%d\\i%d\\ul%d\\fs%u",
iii + 1, F.lfWeight >= FW_BOLD ? 1 : 0, F.lfItalic, F.lfUnderline, 2 * abs(F.lfHeight) * 74 / g_chatApi.logPixelSY);
str.Append(szStyle);
}
else {
- iii = lin->bIsHighlighted ? 16 : EventToIndex(lin);
+ iii = lin.bIsHighlighted ? 16 : EventToIndex(lin);
mir_snprintf(szStyle, "\\f0\\cf%u\\ul0\\highlight0\\b%d\\i%d\\ul%d\\fs%u",
iii + 1, F.lfWeight >= FW_BOLD ? 1 : 0, F.lfItalic, F.lfUnderline, 2 * abs(F.lfHeight) * 74 / g_chatApi.logPixelSY);
str.Append(szStyle);
@@ -378,54 +380,52 @@ char* Log_CreateRTF(LOGSTREAMDATA *streamData)
if (g_Settings.bShowTime) {
wchar_t szTimeStamp[30], szOldTimeStamp[30];
- wcsncpy_s(szTimeStamp, g_chatApi.MakeTimeStamp(g_Settings.pszTimeStamp, lin->time), _TRUNCATE);
+ wcsncpy_s(szTimeStamp, g_chatApi.MakeTimeStamp(g_Settings.pszTimeStamp, lin.time), _TRUNCATE);
wcsncpy_s(szOldTimeStamp, g_chatApi.MakeTimeStamp(g_Settings.pszTimeStamp, si->LastTime), _TRUNCATE);
if (!g_Settings.bShowTimeIfChanged || si->LastTime == 0 || mir_wstrcmp(szTimeStamp, szOldTimeStamp)) {
- si->LastTime = lin->time;
- Log_AppendRTF(streamData, TRUE, str, szTimeStamp);
+ si->LastTime = lin.time;
+ Log_AppendRTF(streamData, lin, TRUE, str, szTimeStamp);
}
str.Append("\\tab ");
}
// Insert the nick
- if (lin->ptszNick && lin->iType == GC_EVENT_MESSAGE) {
+ if (lin.ptszNick && lin.iType == GC_EVENT_MESSAGE) {
char pszIndicator[3] = "\0\0";
int crNickIndex = 0;
if (g_Settings.bLogClassicIndicators || g_Settings.bColorizeNicksInLog)
- pszIndicator[0] = GetIndicator(si, lin->ptszNick, &crNickIndex);
+ pszIndicator[0] = GetIndicator(si, lin.ptszNick, &crNickIndex);
- str.Append(g_chatApi.Log_SetStyle(lin->bIsMe ? 2 : 1));
+ str.Append(g_chatApi.Log_SetStyle(lin.bIsMe ? 2 : 1));
str.AppendChar(' ');
if (g_Settings.bLogClassicIndicators)
str.Append(pszIndicator);
- CMStringW pszTemp(lin->bIsMe ? g_Settings.pszOutgoingNick : g_Settings.pszIncomingNick);
- if (!lin->bIsMe) {
+ CMStringW pszTemp(lin.bIsMe ? g_Settings.pszOutgoingNick : g_Settings.pszIncomingNick);
+ if (!lin.bIsMe) {
if (g_Settings.bClickableNicks)
pszTemp.Replace(L"%n", CLICKNICK_BEGIN L"%n" CLICKNICK_END);
if (g_Settings.bColorizeNicksInLog && pszIndicator[0])
str.AppendFormat("\\cf%u ", OPTIONS_FONTCOUNT + Utils::rtf_clrs.getCount() + streamData->crCount + crNickIndex);
}
- pszTemp.Replace(L"%n", lin->ptszNick);
+ pszTemp.Replace(L"%n", lin.ptszNick);
if (g_Settings.bNewLineAfterNames)
pszTemp.AppendChar('\n');
- Log_AppendRTF(streamData, TRUE, str, pszTemp);
+ Log_AppendRTF(streamData, lin, TRUE, str, pszTemp);
str.AppendChar(' ');
}
// Insert the message
- str.Append(g_chatApi.Log_SetStyle(lin->bIsHighlighted ? 16 : EventToIndex(lin)));
+ str.Append(g_chatApi.Log_SetStyle(lin.bIsHighlighted ? 16 : EventToIndex(lin)));
str.AppendChar(' ');
- streamData->lin = lin;
- AddEventToBuffer(str, streamData);
+ AddEventToBuffer(str, streamData, lin);
}
- lin = lin->prev;
}
// ### RTF END
diff --git a/plugins/TabSRMM/src/msgdlgother.cpp b/plugins/TabSRMM/src/msgdlgother.cpp
index 68b97ba962..1b3003ee04 100644
--- a/plugins/TabSRMM/src/msgdlgother.cpp
+++ b/plugins/TabSRMM/src/msgdlgother.cpp
@@ -2498,8 +2498,7 @@ LBL_SkipEnd:
void CMsgDialog::tabClearLog()
{
if (isChat()) {
- g_chatApi.LM_RemoveAll(&m_si->pLog, &m_si->pLogEnd);
- m_si->iEventCount = 0;
+ m_si->arEvents.destroy();
m_si->LastTime = 0;
PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0);
}
diff --git a/plugins/TabSRMM/src/msglog.cpp b/plugins/TabSRMM/src/msglog.cpp
index c48d5d1d4d..709b44a3d0 100644
--- a/plugins/TabSRMM/src/msglog.cpp
+++ b/plugins/TabSRMM/src/msglog.cpp
@@ -1226,13 +1226,13 @@ void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool fAppend, DB::Ev
/////////////////////////////////////////////////////////////////////////////////////////
-void CLogWindow::LogEvents(LOGINFO *lin, bool bRedraw)
+void CLogWindow::LogEvents(SESSION_INFO *si, int iStart, bool bRedraw)
{
- auto *si = m_pDlg.m_si;
- if (m_rtf.GetHwnd() == nullptr || lin == nullptr || si == nullptr)
+ if (m_rtf.GetHwnd() == nullptr || si == nullptr)
return;
- if (!bRedraw && m_pDlg.AllowTyping() && !(m_pDlg.m_iLogFilterFlags & lin->iType))
+ auto &lin = si->arEvents[iStart];
+ if (!bRedraw && m_pDlg.AllowTyping() && !(m_pDlg.m_iLogFilterFlags & lin.iType))
return;
bool bFlag = false, bDoReplace, bAtBottom = AtBottom();
@@ -1241,7 +1241,7 @@ void CLogWindow::LogEvents(LOGINFO *lin, bool bRedraw)
memset(&streamData, 0, sizeof(streamData));
streamData.hwnd = m_rtf.GetHwnd();
streamData.si = si;
- streamData.lin = lin;
+ streamData.iStartEvent = iStart;
streamData.bStripFormat = FALSE;
streamData.dat = &m_pDlg;
@@ -1285,7 +1285,7 @@ void CLogWindow::LogEvents(LOGINFO *lin, bool bRedraw)
// for new added events, only replace in message or action events.
// no need to replace smileys or math formulas elsewhere
- bDoReplace = (bRedraw || (lin->ptszText && (lin->iType == GC_EVENT_MESSAGE || lin->iType == GC_EVENT_ACTION)));
+ bDoReplace = (bRedraw || (lin.ptszText && (lin.iType == GC_EVENT_MESSAGE || lin.iType == GC_EVENT_ACTION)));
// replace marked nicknames with hyperlinks to make the nicks clickable
if (g_Settings.bClickableNicks) {
@@ -1344,7 +1344,7 @@ void CLogWindow::LogEvents(LOGINFO *lin, bool bRedraw)
// this uses hidden marks in the rich text to find the events which should be deleted
if (si->bTrimmed) {
wchar_t szPattern[50];
- mir_snwprintf(szPattern, L"~-+%p+-~", si->pLogEnd);
+ mir_snwprintf(szPattern, L"~-+%p+-~", &lin);
FINDTEXTEX fi;
fi.lpstrText = szPattern;
diff --git a/plugins/TabSRMM/src/msgs.h b/plugins/TabSRMM/src/msgs.h
index e92ab942e1..79032e37b0 100644
--- a/plugins/TabSRMM/src/msgs.h
+++ b/plugins/TabSRMM/src/msgs.h
@@ -693,7 +693,7 @@ public:
void AppendUnicodeString(CMStringA &str, const wchar_t *pwszBuf) override;
void Attach() override;
void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) override;
- void LogEvents(struct LOGINFO *, bool) override;
+ void LogEvents(SESSION_INFO *si, int iStart, bool) override;
void ScrollToBottom() override;
void UpdateOptions() override;
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);