From 123fa87f68c42b4f121ad315623a9fb5a39ab30c Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 14 Apr 2023 23:33:11 +0300 Subject: all LogStreamInEvents implementations unified, old memory allocation schema dropped --- plugins/Scriver/src/globals.h | 2 +- plugins/Scriver/src/msglog.cpp | 256 ++++++++++++------------------------ plugins/Scriver/src/msgoptions.cpp | 6 +- plugins/TabSRMM/src/globals.cpp | 7 +- plugins/TabSRMM/src/msgdlgother.cpp | 4 +- plugins/TabSRMM/src/msglog.cpp | 231 ++++++++++---------------------- plugins/TabSRMM/src/msgoptions.cpp | 10 +- plugins/TabSRMM/src/msgs.h | 7 +- plugins/TabSRMM/src/sendqueue.cpp | 11 +- 9 files changed, 179 insertions(+), 355 deletions(-) (limited to 'plugins') diff --git a/plugins/Scriver/src/globals.h b/plugins/Scriver/src/globals.h index 995d823ebb..69758366a4 100644 --- a/plugins/Scriver/src/globals.h +++ b/plugins/Scriver/src/globals.h @@ -135,6 +135,6 @@ int ImageList_AddIcon_Ex2(HIMAGELIST hIml, HICON hIcon); int ImageList_ReplaceIcon_Ex(HIMAGELIST hIml, int nIndex, int id); int ImageList_AddIcon_ProtoEx(HIMAGELIST hIml, const char *szProto, int status); -void StreamInTestEvents(HWND hEditWnd, GlobalMessageData *gdat); +void StreamInTestEvents(CDlgBase *pDlg, GlobalMessageData *gdat); #endif diff --git a/plugins/Scriver/src/msglog.cpp b/plugins/Scriver/src/msglog.cpp index 6b3e777bca..9371504a9d 100644 --- a/plugins/Scriver/src/msglog.cpp +++ b/plugins/Scriver/src/msglog.cpp @@ -31,27 +31,11 @@ static int logPixelSY; static char* pLogIconBmpBits[3]; static HIMAGELIST g_hImageList; -#define STREAMSTAGE_HEADER 0 -#define STREAMSTAGE_EVENTS 1 -#define STREAMSTAGE_TAIL 2 -#define STREAMSTAGE_STOP 3 - -struct LogStreamData +struct RtfLogStreamData : public RtfLogStreamBase { - int stage; - MCONTACT hContact; - MEVENT hDbEvent, hDbEventLast; - char *buffer; - size_t bufferOffset, bufferLen; - int eventsToInsert; - int isFirst; - class CLogWindow *pLog; GlobalMessageData *gdat; - DB::EventInfo *dbei; }; -static DWORD CALLBACK LogStreamInEvents(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb); - bool DbEventIsMessageOrCustom(const DB::EventInfo &dbei) { return dbei.eventType == EVENTTYPE_MESSAGE || dbei.eventType == EVENTTYPE_FILE || dbei.isSrmm(); @@ -108,51 +92,6 @@ static void AppendUnicodeToBuffer(CMStringA &buf, const wchar_t *line) buf.AppendChar('}'); } -// mir_free() the return value -static char* CreateRTFHeader() -{ - HDC hdc = GetDC(nullptr); - logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY); - ReleaseDC(nullptr, hdc); - - CMStringA buf; - - buf.Append("{\\rtf1\\ansi\\deff0{\\fonttbl"); - for (int i = 0; i < fontOptionsListSize; i++) { - LOGFONT lf; - LoadMsgDlgFont(i, &lf, nullptr); - buf.AppendFormat("{\\f%u\\fnil\\fcharset%u %S;}", i, lf.lfCharSet, lf.lfFaceName); - } - buf.Append("}{\\colortbl "); - - COLORREF colour; - for (int i = 0; i < fontOptionsListSize; i++) { - LoadMsgDlgFont(i, nullptr, &colour); - buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - } - if (GetSysColorBrush(COLOR_HOTLIGHT) == nullptr) - colour = RGB(0, 0, 255); - else - colour = GetSysColor(COLOR_HOTLIGHT); - buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - colour = g_plugin.getDword(SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR); - buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - colour = g_plugin.getDword(SRMSGSET_INCOMINGBKGCOLOUR, SRMSGDEFSET_INCOMINGBKGCOLOUR); - buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - colour = g_plugin.getDword(SRMSGSET_OUTGOINGBKGCOLOUR, SRMSGDEFSET_OUTGOINGBKGCOLOUR); - buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - colour = g_plugin.getDword(SRMSGSET_LINECOLOUR, SRMSGDEFSET_LINECOLOUR); - buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - buf.Append("}"); - return buf.Detach(); -} - -// mir_free() the return value -static char* CreateRTFTail() -{ - return mir_strdup("}"); -} - // return value is static static char* SetToStyle(int style) { @@ -222,7 +161,7 @@ int isSameDate(time_t time1, time_t time2) return 0; } -static void AppendWithCustomLinks(DBEVENTINFO &dbei, int style, CMStringA &buf) +static void AppendWithCustomLinks(const DB::EventInfo &dbei, int style, CMStringA &buf) { if (dbei.pBlob == nullptr) return; @@ -322,6 +261,13 @@ void FreeMsgLogIcons(void) ///////////////////////////////////////////////////////////////////////////////////////// // CLogWindow - built-in log window +const char *szBuiltinEvents[] = { + "O Lord, bless this Thy hand grenade that with it Thou mayest blow Thine enemies", + "to tiny bits, in Thy mercy", + "Lorem ipsum dolor sit amet,", + "consectetur adipisicing elit", +}; + class CLogWindow : public CRtfLogWindow { typedef CRtfLogWindow CSuper; @@ -372,12 +318,63 @@ public: m_rtf.SendMsg(EM_AUTOURLDETECT, TRUE, 0); } - char* CreateRTFFromEvent(DB::EventInfo &dbei, LogStreamData *streamData) + void CreateRtfHeader(RtfLogStreamData *streamData) override + { + HDC hdc = GetDC(nullptr); + logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(nullptr, hdc); + + auto &buf = streamData->buf; + + buf.Append("{\\rtf1\\ansi\\deff0{\\fonttbl"); + for (int i = 0; i < fontOptionsListSize; i++) { + LOGFONT lf; + LoadMsgDlgFont(i, &lf, nullptr); + buf.AppendFormat("{\\f%u\\fnil\\fcharset%u %S;}", i, lf.lfCharSet, lf.lfFaceName); + } + buf.Append("}{\\colortbl "); + + COLORREF colour; + for (int i = 0; i < fontOptionsListSize; i++) { + LoadMsgDlgFont(i, nullptr, &colour); + buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + } + if (GetSysColorBrush(COLOR_HOTLIGHT) == nullptr) + colour = RGB(0, 0, 255); + else + colour = GetSysColor(COLOR_HOTLIGHT); + buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + colour = g_plugin.getDword(SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR); + buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + colour = g_plugin.getDword(SRMSGSET_INCOMINGBKGCOLOUR, SRMSGDEFSET_INCOMINGBKGCOLOUR); + buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + colour = g_plugin.getDword(SRMSGSET_OUTGOINGBKGCOLOUR, SRMSGDEFSET_OUTGOINGBKGCOLOUR); + buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + colour = g_plugin.getDword(SRMSGSET_LINECOLOUR, SRMSGDEFSET_LINECOLOUR); + buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + buf.Append("}"); + } + + bool CreateRtfEvent(RtfLogStreamData *streamData, DB::EventInfo &dbei) override { + if (!DbEventIsShown(dbei)) + return false; + + if (streamData->dbei) { + if (streamData->eventsToInsert == _countof(szBuiltinEvents)) + return false; + + dbei.flags = DBEF_UTF | ((streamData->eventsToInsert < 2) ? DBEF_SENT : 0); + dbei.pBlob = (uint8_t *)TranslateU(szBuiltinEvents[streamData->eventsToInsert]); + dbei.cbBlob = (int)mir_strlen((char *)dbei.pBlob); + } + int style, showColon = 0; int isGroupBreak = TRUE; int highlight = 0; + auto *gdat = streamData->gdat; + auto &buf = streamData->buf; if ((gdat->flags.bGroupMessages) && dbei.flags == LOWORD(m_lastEventType) && dbei.eventType == EVENTTYPE_MESSAGE && HIWORD(m_lastEventType) == EVENTTYPE_MESSAGE && @@ -385,21 +382,21 @@ public: isGroupBreak = FALSE; } + bool bIsRtl = (dbei.flags & DBEF_RTL) != 0; ptrW wszText(DbEvent_GetTextW(&dbei, CP_UTF8)), wszNick; // test contact - if (m_pDlg.m_hContact != 0) { + if (streamData->dbei == 0) { if (dbei.flags & DBEF_SENT) wszNick = Contact::GetInfo(CNF_DISPLAY, 0, m_pDlg.m_szProto); else wszNick = mir_wstrdup(Clist_GetContactDisplayName(m_pDlg.m_hContact)); + + if (!m_pDlg.m_bUseRtl && Utils_IsRtl(wszText)) + bIsRtl = true; } else wszNick = mir_wstrdup((dbei.flags & DBEF_SENT) ? TranslateT("Me") : TranslateT("My contact")); - if (!m_pDlg.m_bUseRtl && Utils_IsRtl(wszText)) - dbei.flags |= DBEF_RTL; - - CMStringA buf; if (!streamData->isFirst && !m_isMixed) { if (isGroupBreak || gdat->flags.bMarkFollowups) buf.Append("\\par"); @@ -407,13 +404,13 @@ public: buf.Append("\\line"); } - if (dbei.flags & DBEF_RTL) + if (bIsRtl) m_isMixed = 1; if (!streamData->isFirst && isGroupBreak && (gdat->flags.bDrawLines)) buf.AppendFormat("\\sl-1\\slmult0\\highlight%d\\cf%d\\fs1 \\par\\sl0", fontOptionsListSize + 4, fontOptionsListSize + 4); - buf.Append((dbei.flags & DBEF_RTL) ? "\\rtlpar" : "\\ltrpar"); + buf.Append(bIsRtl ? "\\rtlpar" : "\\ltrpar"); if (dbei.eventType == EVENTTYPE_MESSAGE) highlight = fontOptionsListSize + 2 + ((dbei.flags & DBEF_SENT) ? 1 : 0); @@ -429,7 +426,7 @@ public: } streamData->isFirst = FALSE; if (m_isMixed) { - if (dbei.flags & DBEF_RTL) + if (bIsRtl) buf.Append("\\ltrch\\rtlch"); else buf.Append("\\rtlch\\ltrch"); @@ -505,7 +502,7 @@ public: showColon = 1; } if (showColon && dbei.eventType == EVENTTYPE_MESSAGE) { - if (dbei.flags & DBEF_RTL) + if (bIsRtl) buf.AppendFormat("\\~%s: ", SetToStyle(dbei.flags & DBEF_SENT ? MSGFONTID_MYCOLON : MSGFONTID_YOURCOLON)); else buf.AppendFormat("%s: ", SetToStyle(dbei.flags & DBEF_SENT ? MSGFONTID_MYCOLON : MSGFONTID_YOURCOLON)); @@ -549,7 +546,7 @@ public: m_lastEventTime = dbei.timestamp; m_lastEventType = MAKELONG(dbei.flags, dbei.eventType); - return buf.Detach(); + return true; } void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) override @@ -561,7 +558,7 @@ public: m_rtf.SetDraw(false); m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldSel); - LogStreamData streamData = {}; + RtfLogStreamData streamData = {}; streamData.hContact = m_pDlg.m_hContact; streamData.hDbEvent = hDbEventFirst; streamData.hDbEventLast = m_pDlg.m_hDbEventLast; @@ -570,9 +567,6 @@ public: streamData.isFirst = bAppend ? m_rtf.GetRichTextLength() == 0 : 1; streamData.gdat = &g_dat; - EDITSTREAM stream = {}; - stream.pfnCallback = LogStreamInEvents; - stream.dwCookie = (DWORD_PTR)&streamData; sel.cpMin = 0; POINT scrollPos; @@ -606,7 +600,8 @@ public: m_isMixed = 0; } - m_rtf.SendMsg(EM_STREAMIN, bAppend ? SFF_SELECTION | SF_RTF : SFF_SELECTION | SF_RTF, (LPARAM)&stream); + StreamRtfEvents(&streamData, bAppend); + if (bottomScroll) { sel.cpMin = sel.cpMax = -1; m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); @@ -814,91 +809,7 @@ public: ///////////////////////////////////////////////////////////////////////////////////////// -const char *szBuiltinEvents[] = { - "O Lord, bless this Thy hand grenade that with it Thou mayest blow Thine enemies", - "to tiny bits, in Thy mercy", - "Lorem ipsum dolor sit amet,", - "consectetur adipisicing elit", -}; - -static DWORD CALLBACK LogStreamInEvents(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) -{ - LogStreamData *dat = (LogStreamData *)dwCookie; - - if (dat->buffer == nullptr) { - dat->bufferOffset = 0; - switch (dat->stage) { - case STREAMSTAGE_HEADER: - dat->buffer = CreateRTFHeader(); - dat->stage = STREAMSTAGE_EVENTS; - break; - - case STREAMSTAGE_EVENTS: - // predefined text event - if (dat->dbei != nullptr) { - dat->dbei->flags = DBEF_UTF | ((dat->eventsToInsert < 2) ? DBEF_SENT : 0); - dat->dbei->pBlob = (uint8_t *)TranslateU(szBuiltinEvents[dat->eventsToInsert++]); - dat->dbei->cbBlob = (int)mir_strlen((char *)dat->dbei->pBlob); - dat->buffer = dat->pLog->CreateRTFFromEvent(*dat->dbei, dat); - if (dat->eventsToInsert == _countof(szBuiltinEvents)) { - dat->dbei->pBlob = nullptr; - dat->dbei = nullptr; - } - } - // usual database event - else if (dat->eventsToInsert) { - do { - dat->buffer = nullptr; - - DB::EventInfo dbei(dat->hDbEvent); - if (dbei && DbEventIsShown(dbei)) { - dat->buffer = dat->pLog->CreateRTFFromEvent(dbei, dat); - - if (!(dbei.flags & DBEF_SENT) && (dbei.eventType == EVENTTYPE_MESSAGE || dbei.isSrmm())) { - db_event_markRead(dat->hContact, dat->hDbEvent); - g_clistApi.pfnRemoveEvent(dat->hContact, dat->hDbEvent); - } - else if (dbei.eventType == EVENTTYPE_JABBER_CHATSTATES || dbei.eventType == EVENTTYPE_JABBER_PRESENCE) - db_event_markRead(dat->hContact, dat->hDbEvent); - } - - if (dat->buffer) - dat->hDbEventLast = dat->hDbEvent; - dat->hDbEvent = db_event_next(dat->hContact, dat->hDbEvent); - if (--dat->eventsToInsert == 0) - break; - } while (dat->buffer == nullptr && dat->hDbEvent); - } - if (dat->buffer) - break; - - dat->stage = STREAMSTAGE_TAIL; - __fallthrough; - - case STREAMSTAGE_TAIL: - dat->buffer = CreateRTFTail(); - dat->stage = STREAMSTAGE_STOP; - break; - - case STREAMSTAGE_STOP: - *pcb = 0; - return 0; - } - dat->bufferLen = mir_strlen(dat->buffer); - } - *pcb = min(cb, LONG(dat->bufferLen - dat->bufferOffset)); - memcpy(pbBuff, dat->buffer + dat->bufferOffset, *pcb); - dat->bufferOffset += *pcb; - if (dat->bufferOffset == dat->bufferLen) { - mir_free(dat->buffer); - dat->buffer = nullptr; - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void StreamInTestEvents(HWND hEditWnd, GlobalMessageData *gdat) +void StreamInTestEvents(CDlgBase *pDlg, GlobalMessageData *gdat) { DB::EventInfo dbei; dbei.flags = DBEF_UTF; @@ -906,22 +817,19 @@ void StreamInTestEvents(HWND hEditWnd, GlobalMessageData *gdat) dbei.timestamp = time(0); dbei.szModule = SRMM_MODULE; - CMsgDialog *dat = new CMsgDialog(0, false); + auto *pLog = new CLogWindow(*(CMsgDialog*)pDlg); - LogStreamData streamData = {}; + RtfLogStreamData streamData = {}; streamData.isFirst = TRUE; streamData.dbei = &dbei; - streamData.pLog = new CLogWindow(*dat); + streamData.pLog = pLog; streamData.gdat = gdat; + pLog->StreamRtfEvents(&streamData, false); - EDITSTREAM stream = { 0 }; - stream.pfnCallback = LogStreamInEvents; - stream.dwCookie = (DWORD_PTR)&streamData; - SendMessage(hEditWnd, EM_STREAMIN, SF_RTF, (LPARAM)&stream); - SendMessage(hEditWnd, EM_HIDESELECTION, FALSE, 0); + SendDlgItemMessage(pDlg->GetHwnd(), IDC_SRMM_LOG, EM_HIDESELECTION, FALSE, 0); - delete streamData.pLog; - delete dat; + dbei.pBlob = nullptr; + delete pLog; } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/Scriver/src/msgoptions.cpp b/plugins/Scriver/src/msgoptions.cpp index 226307dcd2..3ffb686ae7 100644 --- a/plugins/Scriver/src/msgoptions.cpp +++ b/plugins/Scriver/src/msgoptions.cpp @@ -296,12 +296,12 @@ public: void onChange_Cascade(CCtrlCheck *pCheck) { - chkSavePerContact.SetState(!pCheck->GetState()); + chkSavePerContact.SetState(!pCheck->IsChecked()); } void onChange_SavePerContact(CCtrlCheck *pCheck) { - chkCascade.SetState(!pCheck->GetState()); + chkCascade.SetState(!pCheck->IsChecked()); } }; @@ -528,7 +528,7 @@ class CLogOptionsDlg : public CBaseOptionDlg pf2.dxOffset = (gdat.flags.bIndentText) ? gdat.indentSize * 1440 / g_dat.logPixelSX : 0; m_rtf.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); - StreamInTestEvents(m_rtf.GetHwnd(), &gdat); + StreamInTestEvents(this, &gdat); } public: diff --git a/plugins/TabSRMM/src/globals.cpp b/plugins/TabSRMM/src/globals.cpp index 7c7a649412..997bd3780c 100644 --- a/plugins/TabSRMM/src/globals.cpp +++ b/plugins/TabSRMM/src/globals.cpp @@ -494,10 +494,9 @@ void CGlobals::logStatusChange(WPARAM wParam, const CContactCache *c) else text.Format(TranslateT("changed status from %s to %s."), szOldStatus, szNewStatus); - T2Utf szMsg(text); - DBEVENTINFO dbei = {}; - dbei.pBlob = (uint8_t*)(char*)szMsg; - dbei.cbBlob = (int)mir_strlen(szMsg) + 1; + DB::EventInfo dbei; + dbei.pBlob = (uint8_t*)T2Utf(text).detach(); + dbei.cbBlob = (int)mir_strlen((char*)dbei.pBlob); dbei.flags = DBEF_UTF | DBEF_READ; dbei.eventType = EVENTTYPE_STATUSCHANGE; dbei.timestamp = time(0); diff --git a/plugins/TabSRMM/src/msgdlgother.cpp b/plugins/TabSRMM/src/msgdlgother.cpp index 2360894d31..68b97ba962 100644 --- a/plugins/TabSRMM/src/msgdlgother.cpp +++ b/plugins/TabSRMM/src/msgdlgother.cpp @@ -1413,7 +1413,7 @@ void CMsgDialog::LoadSplitter() ///////////////////////////////////////////////////////////////////////////////////////// -void CMsgDialog::LogEvent(DBEVENTINFO &dbei) +void CMsgDialog::LogEvent(DB::EventInfo &dbei) { if (m_iLogMode != WANT_BUILTIN_LOG) { dbei.flags |= DBEF_TEMPORARY; @@ -1424,7 +1424,7 @@ void CMsgDialog::LogEvent(DBEVENTINFO &dbei) db_event_delete(hDbEvent); } } - else LOG()->LogEvents(0, 1, true, &dbei); + else LOG()->LogEvents(0, 0, true, &dbei); } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/TabSRMM/src/msglog.cpp b/plugins/TabSRMM/src/msglog.cpp index 59b68b9bc5..c48d5d1d4d 100644 --- a/plugins/TabSRMM/src/msglog.cpp +++ b/plugins/TabSRMM/src/msglog.cpp @@ -80,22 +80,9 @@ COLORREF fontcolors[MSGDLGFONTCOUNT + 2]; static HICON Logicons[NR_LOGICONS]; -#define STREAMSTAGE_HEADER 0 -#define STREAMSTAGE_EVENTS 1 -#define STREAMSTAGE_TAIL 2 -#define STREAMSTAGE_STOP 3 -struct LogStreamData +struct RtfLogStreamData : public RtfLogStreamBase { - int stage; - MCONTACT hContact; - MEVENT hDbEvent, hDbEventLast; - char *buffer; - int bufferOffset, bufferLen; - int eventsToInsert; - int isEmpty; int isAppend; - class CLogWindow *pLog; - DBEVENTINFO *dbei; }; __forceinline char* GetRTFFont(uint32_t dwIndex) @@ -303,68 +290,6 @@ static void AppendUnicodeToBuffer(CMStringA &str, const wchar_t *line, int mode) str.AppendChar('}'); } -///////////////////////////////////////////////////////////////////////////////////////// -// mir_free() the return value - -static char* CreateRTFHeader(CLogWindow *pLog) -{ - int i; - CMStringA str; - auto &dat = pLog->GetDialog(); - TLogTheme *theme = &dat.m_pContainer->m_theme; - LOGFONTW *logFonts = theme->logFonts; - COLORREF *fontColors = theme->fontColors; - - str.Append("{\\rtf1\\ansi\\deff0{\\fonttbl"); - - for (i = 0; i < MSGDLGFONTCOUNT; i++) - str.AppendFormat("{\\f%u\\fnil\\fcharset%u %S;}", i, logFonts[i].lfCharSet, logFonts[i].lfFaceName); - str.AppendFormat("{\\f%u\\fnil\\fcharset%u %s;}", MSGDLGFONTCOUNT, logFonts[i].lfCharSet, "Arial"); - - str.Append("}{\\colortbl "); - for (i = 0; i < MSGDLGFONTCOUNT; i++) - str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(fontColors[i]), GetGValue(fontColors[i]), GetBValue(fontColors[i])); - - COLORREF colour = (GetSysColorBrush(COLOR_HOTLIGHT) == nullptr) ? RGB(0, 0, 255) : GetSysColor(COLOR_HOTLIGHT); - str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - - // OnO: Create incoming and outcoming colours - colour = theme->inbg; - str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - colour = theme->outbg; - str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - colour = theme->bg; - str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - colour = theme->hgrid; - str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - colour = theme->oldinbg; - str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - colour = theme->oldoutbg; - str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - colour = theme->statbg; - str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - - // custom template colors... - for (i = 1; i <= 5; i++) { - colour = theme->custom_colors[i - 1]; - if (colour == 0) - colour = RGB(1, 1, 1); - str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); - } - - // bbcode colors... - for (auto &p : Utils::rtf_clrs) - str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(p->clr), GetGValue(p->clr), GetBValue(p->clr)); - - // paragraph header - str.AppendFormat("}"); - - // indent - if (!(dat.m_dwFlags & MWF_LOG_INDENT)) - str.AppendFormat("\\li%u\\ri%u\\fi%u\\tx%u", 2 * 15, 2 * 15, 0, 70 * 15); - return str.Detach(); -} - static void AppendTimeStamp(wchar_t *szFinalTimestamp, int isSent, CMStringA &str, int skipFont, CMsgDialog *dat, int iFontIDOffset) { if (!skipFont) { @@ -399,12 +324,6 @@ static wchar_t* Template_MakeRelativeDate(HANDLE hTimeZone, time_t check, wchar_ return szResult; } -// mir_free() the return value -static char *CreateRTFTail() -{ - return mir_strdup("}"); -} - bool DbEventIsShown(const DB::EventInfo &dbei) { if (!IsCustomEvent(dbei.eventType) || dbei.isSrmm()) @@ -413,57 +332,6 @@ bool DbEventIsShown(const DB::EventInfo &dbei) return IsStatusEvent(dbei.eventType); } -static DWORD CALLBACK LogStreamInEvents(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) -{ - LogStreamData *dat = (LogStreamData*)dwCookie; - - if (dat->buffer == nullptr) { - dat->bufferOffset = 0; - switch (dat->stage) { - case STREAMSTAGE_HEADER: - mir_free(dat->buffer); - dat->buffer = CreateRTFHeader(dat->pLog); - dat->stage = STREAMSTAGE_EVENTS; - break; - - case STREAMSTAGE_EVENTS: - if (dat->eventsToInsert) { - do { - mir_free(dat->buffer); - dat->buffer = dat->pLog->CreateRTFFromDbEvent(dat); - if (dat->buffer) - dat->hDbEventLast = dat->hDbEvent; - dat->hDbEvent = db_event_next(dat->hContact, dat->hDbEvent); - if (--dat->eventsToInsert == 0) - break; - } while (dat->buffer == nullptr && dat->hDbEvent); - - if (dat->buffer) - break; - } - dat->stage = STREAMSTAGE_TAIL; - __fallthrough; - - case STREAMSTAGE_TAIL: - mir_free(dat->buffer); - dat->buffer = CreateRTFTail(); - dat->stage = STREAMSTAGE_STOP; - break; - - case STREAMSTAGE_STOP: - *pcb = 0; - return 0; - } - dat->bufferLen = (int)mir_strlen(dat->buffer); - } - *pcb = min(cb, dat->bufferLen - dat->bufferOffset); - memcpy(pbBuff, dat->buffer + dat->bufferOffset, *pcb); - dat->bufferOffset += *pcb; - if (dat->bufferOffset == dat->bufferLen) - replaceStr(dat->buffer, nullptr); - return 0; -} - ///////////////////////////////////////////////////////////////////////////////////////// INT_PTR CLogWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam) @@ -618,23 +486,79 @@ void CLogWindow::Attach() ///////////////////////////////////////////////////////////////////////////////////////// -char* CLogWindow::CreateRTFFromDbEvent(LogStreamData *streamData) +void CLogWindow::CreateRtfHeader(RtfLogStreamData *streamData) { + int i; + auto &str = streamData->buf; + auto &dat = m_pDlg; + TLogTheme *theme = &dat.m_pContainer->m_theme; + LOGFONTW *logFonts = theme->logFonts; + COLORREF *fontColors = theme->fontColors; + + str.Append("{\\rtf1\\ansi\\deff0{\\fonttbl"); + + for (i = 0; i < MSGDLGFONTCOUNT; i++) + str.AppendFormat("{\\f%u\\fnil\\fcharset%u %S;}", i, logFonts[i].lfCharSet, logFonts[i].lfFaceName); + str.AppendFormat("{\\f%u\\fnil\\fcharset%u %s;}", MSGDLGFONTCOUNT, logFonts[i].lfCharSet, "Arial"); + + str.Append("}{\\colortbl "); + for (i = 0; i < MSGDLGFONTCOUNT; i++) + str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(fontColors[i]), GetGValue(fontColors[i]), GetBValue(fontColors[i])); + + COLORREF colour = (GetSysColorBrush(COLOR_HOTLIGHT) == nullptr) ? RGB(0, 0, 255) : GetSysColor(COLOR_HOTLIGHT); + str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + + // OnO: Create incoming and outcoming colours + colour = theme->inbg; + str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + colour = theme->outbg; + str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + colour = theme->bg; + str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + colour = theme->hgrid; + str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + colour = theme->oldinbg; + str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + colour = theme->oldoutbg; + str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + colour = theme->statbg; + str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + + // custom template colors... + for (i = 1; i <= 5; i++) { + colour = theme->custom_colors[i - 1]; + if (colour == 0) + colour = RGB(1, 1, 1); + str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour)); + } + + // bbcode colors... + for (auto &p : Utils::rtf_clrs) + str.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(p->clr), GetGValue(p->clr), GetBValue(p->clr)); + + // paragraph header + str.AppendFormat("}"); + + // indent + if (!(dat.m_dwFlags & MWF_LOG_INDENT)) + str.AppendFormat("\\li%u\\ri%u\\fi%u\\tx%u", 2 * 15, 2 * 15, 0, 70 * 15); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +bool CLogWindow::CreateRtfEvent(RtfLogStreamData *streamData, DB::EventInfo &dbei) +{ + if (!DbEventIsShown(dbei)) + return false; + + if (streamData->dbei && streamData->eventsToInsert > 0) + return false; + HANDLE hTimeZone = nullptr; struct tm event_time = { 0 }; bool skipToNext = false, skipFont = false; bool isBold = false, isItalic = false, isUnderline = false; - DB::EventInfo dbei; - if (streamData->dbei != nullptr) - memcpy(&dbei, streamData->dbei, sizeof(DBEVENTINFO)); - else { - dbei.cbBlob = -1; - db_event_get(streamData->hDbEvent, &dbei); - if (!DbEventIsShown(dbei)) - return nullptr; - } - auto *dat = &m_pDlg; if (dbei.eventType == EVENTTYPE_MESSAGE && !dbei.markedRead()) dat->m_cache->updateStats(TSessionStats::SET_LAST_RCV, mir_strlen((char *)dbei.pBlob)); @@ -653,7 +577,7 @@ char* CLogWindow::CreateRTFFromDbEvent(LogStreamData *streamData) msg.TrimRight(); dat->FormatRaw(msg, 1, FALSE); - CMStringA str; + auto &str = streamData->buf; // means: last \\par was deleted to avoid new line at end of log if (dat->m_bLastParaDeleted) { @@ -1184,9 +1108,6 @@ skip: str.Append("\\par"); - if (streamData->dbei != nullptr) - dbei.pBlob = 0; - dat->m_iLastEventType = MAKELONG((dbei.flags & (DBEF_SENT | DBEF_READ | DBEF_RTL)), dbei.eventType); dat->m_lastEventTime = dbei.timestamp; return str.Detach(); @@ -1199,7 +1120,7 @@ void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool fAppend) LogEvents(hDbEventFirst, count, fAppend, nullptr); } -void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool fAppend, DBEVENTINFO *dbei_s) +void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool fAppend, DB::EventInfo *dbei_s) { CHARRANGE oldSel, sel; @@ -1228,7 +1149,7 @@ void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool fAppend, DBEVEN m_rtf.SendMsg(EM_HIDESELECTION, TRUE, 0); m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldSel); - LogStreamData streamData = { 0 }; + RtfLogStreamData streamData = { 0 }; streamData.hContact = m_pDlg.m_hContact; streamData.hDbEvent = hDbEventFirst; streamData.pLog = this; @@ -1237,10 +1158,6 @@ void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool fAppend, DBEVEN streamData.dbei = dbei_s; streamData.isAppend = fAppend; - EDITSTREAM stream = { 0 }; - stream.pfnCallback = LogStreamInEvents; - stream.dwCookie = (DWORD_PTR)&streamData; - LONG startAt; if (fAppend) { GETTEXTLENGTHEX gtxl = { 0 }; @@ -1262,7 +1179,7 @@ void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool fAppend, DBEVEN // begin to draw m_rtf.SetDraw(false); - m_rtf.SendMsg(EM_STREAMIN, fAppend ? SFF_SELECTION | SF_RTF : SFF_SELECTION | SF_RTF, (LPARAM)&stream); + StreamRtfEvents(&streamData, true); m_pDlg.m_hDbEventLast = streamData.hDbEventLast; @@ -1287,8 +1204,7 @@ void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool fAppend, DBEVEN if (streamData.dbei != nullptr) isSent = (streamData.dbei->flags & DBEF_SENT) != 0; else { - DBEVENTINFO dbei = {}; - db_event_get(hDbEventFirst, &dbei); + DB::EventInfo dbei(hDbEventFirst, false); isSent = (dbei.flags & DBEF_SENT) != 0; } @@ -1306,7 +1222,6 @@ void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool fAppend, DBEVEN m_rtf.SetDraw(true); InvalidateRect(m_rtf.GetHwnd(), nullptr, FALSE); EnableWindow(GetDlgItem(m_pDlg.m_hwnd, IDC_QUOTE), m_pDlg.m_hDbEventLast != 0); - mir_free(streamData.buffer); } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/TabSRMM/src/msgoptions.cpp b/plugins/TabSRMM/src/msgoptions.cpp index db48cbabdf..d94ecf0eb8 100644 --- a/plugins/TabSRMM/src/msgoptions.cpp +++ b/plugins/TabSRMM/src/msgoptions.cpp @@ -622,15 +622,15 @@ public: T2Utf szText((iIndex == 6) ? TranslateT("is now offline (was online)") : TranslateT("The quick brown fox jumps over the lazy dog.")); - DBEVENTINFO dbei = {}; + DB::EventInfo dbei; dbei.szModule = m_szProto; dbei.timestamp = time(0); dbei.eventType = (iIndex == 6) ? EVENTTYPE_STATUSCHANGE : EVENTTYPE_MESSAGE; dbei.eventType = (iIndex == 7) ? EVENTTYPE_ERRMSG : dbei.eventType; if (dbei.eventType == EVENTTYPE_ERRMSG) dbei.szModule = (char *)TranslateT("Sample error message"); - dbei.pBlob = (uint8_t *)szText.get(); - dbei.cbBlob = (int)mir_strlen((char *)dbei.pBlob) + 1; + dbei.pBlob = (uint8_t *)szText.detach(); + dbei.cbBlob = (int)mir_strlen((char *)dbei.pBlob); dbei.flags = (iIndex == 1 || iIndex == 3 || iIndex == 5) ? DBEF_SENT : 0; dbei.flags |= (m_bRtl ? DBEF_RTL : 0); m_lastEventTime = (iIndex == 4 || iIndex == 5) ? time(0) - 1 : 0; @@ -639,10 +639,10 @@ public: m_dwFlags = (m_bRtl ? m_dwFlags | MWF_LOG_RTL : m_dwFlags & ~MWF_LOG_RTL); m_dwFlags = (iIndex == 0 || iIndex == 1) ? m_dwFlags & ~MWF_LOG_GROUPMODE : m_dwFlags | MWF_LOG_GROUPMODE; mir_snwprintf(m_wszMyNickname, TranslateT("My Nickname")); - LOG()->LogEvents(0, 1, false, &dbei); + LOG()->LogEvents(0, 0, false, &dbei); if (m_bFirstUse) { if (m_bRtl) - LOG()->LogEvents(0, 1, false, &dbei); + LOG()->LogEvents(0, 0, false, &dbei); m_bFirstUse = false; } if (m_bChanged) diff --git a/plugins/TabSRMM/src/msgs.h b/plugins/TabSRMM/src/msgs.h index ba0af19cfd..e92ab942e1 100644 --- a/plugins/TabSRMM/src/msgs.h +++ b/plugins/TabSRMM/src/msgs.h @@ -631,7 +631,7 @@ public: return ((CLogWindow *)m_pLog); } - void LogEvent(DBEVENTINFO &dbei); + void LogEvent(DB::EventInfo &dbei); void DM_OptionsApplied(bool bRemakeLog = true); void DM_RecalcPictureSize(void); @@ -687,7 +687,8 @@ public: CSuper(pDlg) {} - char *CreateRTFFromDbEvent(struct LogStreamData *streamData); + void CreateRtfHeader(RtfLogStreamData *streamData) override; + bool CreateRtfEvent(RtfLogStreamData *streamData, DB::EventInfo &dbei) override; void AppendUnicodeString(CMStringA &str, const wchar_t *pwszBuf) override; void Attach() override; @@ -706,7 +707,7 @@ public: return m_rtf.GetRichTextRtf(bText, bSelection); } - void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend, DBEVENTINFO *dbei); + void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend, DB::EventInfo *dbei); void ReplaceIcons(LONG startAt, int fAppend, BOOL isSent); void ScrollToBottom(bool, bool); diff --git a/plugins/TabSRMM/src/sendqueue.cpp b/plugins/TabSRMM/src/sendqueue.cpp index 9b4e11b583..4f6c35a3cd 100644 --- a/plugins/TabSRMM/src/sendqueue.cpp +++ b/plugins/TabSRMM/src/sendqueue.cpp @@ -340,7 +340,7 @@ void SendQueue::logError(CMsgDialog *dat, int iSendJobIndex, const wchar_t *szEr return; size_t iMsgLen; - DBEVENTINFO dbei = {}; + DB::EventInfo dbei; dbei.eventType = EVENTTYPE_ERRMSG; if (iSendJobIndex >= 0) { dbei.pBlob = (uint8_t *)m_jobs[iSendJobIndex].szSendBuffer; @@ -356,6 +356,8 @@ void SendQueue::logError(CMsgDialog *dat, int iSendJobIndex, const wchar_t *szEr dbei.timestamp = time(0); dbei.szModule = (char *)szErrMsg; dat->LogEvent(dbei); + + dbei.pBlob = nullptr; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -539,14 +541,13 @@ int SendQueue::doSendLater(int iJobIndex, CMsgDialog *dat, MCONTACT hContact, bo else szNote = TranslateT("The send later feature is not available on this protocol."); - T2Utf utfText(szNote); - DBEVENTINFO dbei = {}; + DB::EventInfo dbei; dbei.eventType = EVENTTYPE_MESSAGE; dbei.flags = DBEF_SENT | DBEF_UTF; dbei.szModule = Proto_GetBaseAccountName(dat->m_hContact); dbei.timestamp = time(0); - dbei.cbBlob = (int)mir_strlen(utfText) + 1; - dbei.pBlob = (uint8_t*)(char*)utfText; + dbei.pBlob = (uint8_t*)mir_utf8encodeW(szNote); + dbei.cbBlob = (int)mir_strlen((char*)dbei.pBlob); dat->LogEvent(dbei); if (dat->m_hDbEventFirst == 0) -- cgit v1.2.3