From 7a948f1ef804ecd9971b0869e0591c22944fa6da Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 2 Oct 2019 20:42:44 +0300 Subject: merge with SrmmLogContainer --- include/m_gui.h | 3 + include/m_srmm_int.h | 80 +++- libs/win32/mir_app.lib | Bin 194782 -> 200090 bytes libs/win32/mir_core.lib | Bin 461050 -> 461402 bytes libs/win64/mir_app.lib | Bin 190380 -> 195768 bytes libs/win64/mir_core.lib | Bin 465828 -> 466190 bytes plugins/HistoryPlusPlus/historypp.dpr | 8 +- plugins/HistoryPlusPlus/historypp.dproj | 32 +- plugins/HistoryPlusPlus/hpp_global.pas | 3 + plugins/IEView/src/Options.h | 2 +- plugins/IEView/src/ieview_logger.cpp | 245 ++++++++++ plugins/IEView/src/ieview_main.cpp | 3 + plugins/IEView/src/ieview_services.h | 8 +- plugins/IEView/src/stdafx.h | 6 + plugins/Scriver/res/resource.rc | 123 +++-- plugins/Scriver/src/chat_log.cpp | 123 ----- plugins/Scriver/src/globals.cpp | 1 - plugins/Scriver/src/globals.h | 2 - plugins/Scriver/src/input.cpp | 4 +- plugins/Scriver/src/msgdialog.cpp | 149 +----- plugins/Scriver/src/msglog.cpp | 381 +++++++++++----- plugins/Scriver/src/msgoptions.cpp | 29 +- plugins/Scriver/src/msgs.cpp | 1 - plugins/Scriver/src/msgs.h | 49 +- plugins/Scriver/src/msgutils.cpp | 44 +- plugins/Scriver/src/resource.h | 1 - plugins/Scriver/src/srmm.cpp | 13 +- plugins/Scriver/src/stdafx.h | 6 +- plugins/Scriver/src/tabs.cpp | 2 +- plugins/TabSRMM/res/resource.rc | 58 ++- plugins/TabSRMM/src/chat.h | 3 + plugins/TabSRMM/src/chat_log.cpp | 526 ++-------------------- plugins/TabSRMM/src/container.cpp | 5 - plugins/TabSRMM/src/generic_msghandlers.cpp | 89 +--- plugins/TabSRMM/src/globals.cpp | 13 +- plugins/TabSRMM/src/globals.h | 2 +- plugins/TabSRMM/src/mim.cpp | 18 + plugins/TabSRMM/src/msgdialog.cpp | 277 ++---------- plugins/TabSRMM/src/msgdlgother.cpp | 141 ++---- plugins/TabSRMM/src/msgdlgutils.cpp | 27 -- plugins/TabSRMM/src/msgdlgutils.h | 1 - plugins/TabSRMM/src/msglog.cpp | 674 ++++++++++++++++++++-------- plugins/TabSRMM/src/msgoptions.cpp | 64 +-- plugins/TabSRMM/src/msgs.h | 64 ++- plugins/TabSRMM/src/resource.h | 18 +- plugins/TabSRMM/src/sendqueue.cpp | 5 +- plugins/TabSRMM/src/srmm.cpp | 3 + plugins/TabSRMM/src/stdafx.h | 2 + plugins/TabSRMM/src/taskbar.cpp | 15 +- plugins/TabSRMM/src/templates.cpp | 11 +- plugins/TabSRMM/src/themes.cpp | 4 +- plugins/TabSRMM/src/userprefs.cpp | 74 +-- protocols/JabberG/src/jabber_chat.cpp | 2 +- protocols/JabberG/src/jabber_disco.cpp | 2 +- protocols/JabberG/src/jabber_menu.cpp | 2 +- src/core/stdmsg/src/chat_window.cpp | 51 +-- src/core/stdmsg/src/msgdialog.cpp | 170 +------ src/core/stdmsg/src/msglog.cpp | 253 ++++++++--- src/core/stdmsg/src/msgs.h | 34 +- src/core/stdmsg/src/srmm.cpp | 3 + src/core/stdmsg/src/stdafx.h | 3 + src/core/stdmsg/src/tabs.cpp | 2 +- src/mir_app/mir_app.vcxproj | 2 +- src/mir_app/res/resource.rc | 27 +- src/mir_app/src/chat.h | 6 + src/mir_app/src/mir_app.def | 26 +- src/mir_app/src/mir_app64.def | 26 +- src/mir_app/src/resource.h | 2 + src/mir_app/src/srmm_base.cpp | 277 +----------- src/mir_app/src/srmm_log.cpp | 141 ++++++ src/mir_app/src/srmm_log_hpp.cpp | 259 +++++++++++ src/mir_app/src/srmm_log_rtf.cpp | 375 ++++++++++++++++ src/mir_app/src/srmm_toolbar.cpp | 4 + src/mir_app/src/stdafx.h | 2 + src/mir_core/src/CDlgBase.cpp | 5 + src/mir_core/src/mir_core.def | 1 + src/mir_core/src/mir_core64.def | 1 + 77 files changed, 2730 insertions(+), 2358 deletions(-) create mode 100644 plugins/IEView/src/ieview_logger.cpp delete mode 100644 plugins/Scriver/src/chat_log.cpp create mode 100644 src/mir_app/src/srmm_log.cpp create mode 100644 src/mir_app/src/srmm_log_hpp.cpp create mode 100644 src/mir_app/src/srmm_log_rtf.cpp diff --git a/include/m_gui.h b/include/m_gui.h index 2636ccd0aa..ce489d7520 100644 --- a/include/m_gui.h +++ b/include/m_gui.h @@ -444,6 +444,9 @@ protected: // register controls void AddControl(CCtrlBase *ctrl); + void RemoveControl(CCtrlBase *ctrl); + + // timers void AddTimer(CTimer *timer); // options support diff --git a/include/m_srmm_int.h b/include/m_srmm_int.h index 54fa90f6f3..b2d36f2a5d 100644 --- a/include/m_srmm_int.h +++ b/include/m_srmm_int.h @@ -99,6 +99,78 @@ EXTERN_C MIR_APP_DLL(void) Srmm_ClickToolbarIcon(MCONTACT hContact, int idFrom, // lParam = 0 (ignored) #define WM_CBD_RECREATE (WM_CBD_FIRST+4) +///////////////////////////////////////////////////////////////////////////////////////// +// SRMM log window container + +class CMsgDialog; + +class MIR_APP_EXPORT CSrmmLogWindow +{ + CSrmmLogWindow(const CSrmmLogWindow &) = delete; + CSrmmLogWindow &operator=(const CSrmmLogWindow &) = delete; + +protected: + CMsgDialog &m_pDlg; + + CSrmmLogWindow(CMsgDialog &pDlg) : + m_pDlg(pDlg) + {} + +public: + virtual ~CSrmmLogWindow() {} + + virtual void Attach() = 0; + virtual void Detach() = 0; + + virtual bool AtBottom() = 0; + virtual void Clear() = 0; + virtual int GetType() = 0; + virtual HWND GetHwnd() = 0; + virtual wchar_t* GetSelection() = 0; + virtual void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) = 0; + virtual void LogEvents(DBEVENTINFO *dbei, bool bAppend) = 0; + virtual void LogEvents(struct LOGINFO *, bool) = 0; + virtual void Resize() = 0; + virtual void ScrollToBottom() = 0; + virtual void UpdateOptions() {}; + + virtual INT_PTR Notify(WPARAM, LPARAM) { return 0; } +}; + +typedef CSrmmLogWindow *(__cdecl *pfnSrmmLogCreator)(CMsgDialog &pDlg); + +EXTERN_C MIR_APP_DLL(HANDLE) RegisterSrmmLog(const char *pszShortName, const wchar_t *pwszScreenName, pfnSrmmLogCreator fnBuilder); +EXTERN_C MIR_APP_DLL(void) UnregisterSrmmLog(HANDLE); + +///////////////////////////////////////////////////////////////////////////////////////// +// Standard built-in RTF logger class + +class MIR_APP_EXPORT CRtfLogWindow : public CSrmmLogWindow +{ +protected: + CCtrlRichEdit &m_rtf; + +public: + CRtfLogWindow(CMsgDialog &pDlg); + ~CRtfLogWindow() override; + + virtual INT_PTR WndProc(UINT msg, WPARAM wParam, LPARAM lParam); + + //////////////////////////////////////////////////////////////////////////////////////// + void Attach() override; + void Detach() override; + + bool AtBottom() override; + void Clear() override; + HWND GetHwnd() override; + wchar_t* GetSelection() override; + int GetType() override; + void Resize() override; + void ScrollToBottom() override; + + INT_PTR Notify(WPARAM, LPARAM) override; +}; + ///////////////////////////////////////////////////////////////////////////////////////// // Basic SRMM window dialog @@ -111,6 +183,8 @@ EXTERN_C MIR_APP_DLL(LRESULT) CALLBACK stubNicklistProc(HWND hwnd, UINT msg, WPA class MIR_APP_EXPORT CSrmmBaseDialog : public CDlgBase { + friend class CRtfLogWindow; + CSrmmBaseDialog(const CSrmmBaseDialog &) = delete; CSrmmBaseDialog &operator=(const CSrmmBaseDialog &) = delete; @@ -128,7 +202,8 @@ protected: void RunUserMenu(HWND hwndOwner, struct USERINFO *ui, const POINT &pt); protected: - CCtrlRichEdit m_message, m_log; + CSrmmLogWindow *m_pLog = nullptr; + CCtrlRichEdit m_message; SESSION_INFO *m_si; COLORREF m_clrInputBG, m_clrInputFG; time_t m_iLastEnterTime; @@ -163,16 +238,13 @@ public: virtual void CloseTab() {} virtual bool IsActive() const PURE; virtual void LoadSettings() PURE; - virtual void ScrollToBottom() {} virtual void SetStatusText(const wchar_t *, HICON) {} virtual void ShowFilterMenu() {} - virtual void StreamInEvents(struct LOGINFO *, bool) {} virtual void UpdateNickList() {} virtual void UpdateOptions(); virtual void UpdateStatusBar() {} virtual void UpdateTitle() PURE; - virtual LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam); virtual LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam); virtual LRESULT WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam); diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib index 7ff2cd557f..e9812df22f 100644 Binary files a/libs/win32/mir_app.lib and b/libs/win32/mir_app.lib differ diff --git a/libs/win32/mir_core.lib b/libs/win32/mir_core.lib index ef441c8454..6c799c8aa7 100644 Binary files a/libs/win32/mir_core.lib and b/libs/win32/mir_core.lib differ diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib index 107ab240c3..98e34cf6da 100644 Binary files a/libs/win64/mir_app.lib and b/libs/win64/mir_app.lib differ diff --git a/libs/win64/mir_core.lib b/libs/win64/mir_core.lib index 3665f61eba..73f13f4b78 100644 Binary files a/libs/win64/mir_core.lib and b/libs/win64/mir_core.lib differ diff --git a/plugins/HistoryPlusPlus/historypp.dpr b/plugins/HistoryPlusPlus/historypp.dpr index a9843a5d2a..71841fb8bf 100644 --- a/plugins/HistoryPlusPlus/historypp.dpr +++ b/plugins/HistoryPlusPlus/historypp.dpr @@ -23,8 +23,6 @@ {.$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])} library historypp; -{$IMAGEBASE $02630000} - {$R 'hpp_resource.res' 'hpp_resource.rc'} {$R 'version.res'} {$R 'hpp_opt_dialog.res' 'hpp_opt_dialog.rc'} @@ -112,6 +110,9 @@ var HookMetaDefaultChanged, HookPreshutdown: THandle; +procedure RegisterHppLogger; stdcall; external AppDll; +procedure UnregisterHppLogger; stdcall; external AppDll; + function OnModulesLoad(awParam:WPARAM; alParam:LPARAM):int; cdecl; forward; function OnSettingsChanged(wParam: WPARAM; lParam: LPARAM): Integer; cdecl; forward; function OnSmAddSettingsChanged(wParam: WPARAM; lParam: LPARAM): Integer; cdecl; forward; @@ -499,6 +500,7 @@ function OnPreshutdown(wParam: WPARAM; lParam: LPARAM): Integer; cdecl; begin Result := 0; NotifyAllForms(HM_MIEV_PRESHUTDOWN,0,0); + UnregisterHppLogger; end; exports @@ -509,6 +511,8 @@ exports begin DisableThreadLibraryCalls(hInstance); + RegisterHppLogger; + PluginInfo.cbSize:= SizeOf(TPLUGININFOEX); PluginInfo.shortName:= hppShortNameV; PluginInfo.version:= hppVersion; diff --git a/plugins/HistoryPlusPlus/historypp.dproj b/plugins/HistoryPlusPlus/historypp.dproj index fe85622dc8..4387bf178e 100644 --- a/plugins/HistoryPlusPlus/historypp.dproj +++ b/plugins/HistoryPlusPlus/historypp.dproj @@ -114,31 +114,31 @@ true ..\..\include\delphi;..\..\plugins\ExternalAPI\delphi;$(DCC_UnitSearchPath) true - ..\..\bin15\Debug\Plugins\ + ..\..\bin16\Debug\Plugins\ ..\..\bin15\temp\res\ - ..\..\bin15\Debug\Plugins\ + ..\..\bin16\Debug\Plugins\ 1033 - ..\..\bin15\Debug\Obj\hpp\ + ..\..\bin16\Debug\Obj\hpp\ None - ..\..\bin15\Debug\Obj\hpp\ + ..\..\bin16\Debug\Obj\hpp\ - D:\Myranda\bin15\Debug64 + D:\Myranda\bin16\Debug64 true - D:\Myranda\bin15\Debug64\Miranda64.exe + D:\Myranda\bin16\Debug64\Miranda64.exe ..\..\bin15\temp\res\ - ..\..\bin15\Debug64\Plugins\ - ..\..\bin15\Debug64\Plugins\ - ..\..\bin15\Debug64\Obj\hpp\ - ..\..\bin15\Debug64\Obj\hpp\ + ..\..\bin16\Debug64\Plugins\ + ..\..\bin16\Debug64\Plugins\ + ..\..\bin16\Debug64\Obj\hpp\ + ..\..\bin16\Debug64\Obj\hpp\ - ..\..\bin15\Debug\Plugins\ - ..\..\bin15\Debug\Plugins\ - ..\..\bin15\Debug\Obj\hpp\ - ..\..\bin15\Debug\Obj\hpp\ - W:\miranda-ng\bin15\Debug - W:\miranda-ng\bin15\Debug\Miranda32.exe + ..\..\bin16\Debug\Plugins\ + ..\..\bin16\Debug\Plugins\ + ..\..\bin16\Debug\Obj\hpp\ + ..\..\bin16\Debug\Obj\hpp\ + W:\miranda-ng\bin16\Debug + W:\miranda-ng\bin16\Debug\Miranda32.exe true diff --git a/plugins/HistoryPlusPlus/hpp_global.pas b/plugins/HistoryPlusPlus/hpp_global.pas index 38ae093051..9bae1efa3c 100644 --- a/plugins/HistoryPlusPlus/hpp_global.pas +++ b/plugins/HistoryPlusPlus/hpp_global.pas @@ -580,6 +580,9 @@ var begin WSize := (Length(WideStr)+1)*SizeOf(WideChar); if WSize = SizeOf(WideChar) then exit; + if CodePage = 1200 then + CodePage := CP_ACP; + AnsiStr := WideToAnsiString(WideStr,CodePage); ASize := Length(AnsiStr)+1; OpenClipboard(Handle); diff --git a/plugins/IEView/src/Options.h b/plugins/IEView/src/Options.h index f791aa553f..fb5a534453 100644 --- a/plugins/IEView/src/Options.h +++ b/plugins/IEView/src/Options.h @@ -45,7 +45,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define DBS_HISTORY_CSS "HistoryCSSFile" #define DBS_HISTORY_TEMPLATE "HistoryTemplateFile" -extern int IEViewOptInit(WPARAM wParam, LPARAM lParam); +int IEViewOptInit(WPARAM wParam, LPARAM lParam); class ProtocolSettings { diff --git a/plugins/IEView/src/ieview_logger.cpp b/plugins/IEView/src/ieview_logger.cpp new file mode 100644 index 0000000000..b9a8490011 --- /dev/null +++ b/plugins/IEView/src/ieview_logger.cpp @@ -0,0 +1,245 @@ +/* + +IEView Plugin for Miranda IM +Copyright (C) 2005-2010 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "stdafx.h" + +#define EVENTTYPE_STATUSCHANGE 25368 +#define EVENTTYPE_ERRMSG 25366 + +class CMsgDialog : public CSrmmBaseDialog {}; + +///////////////////////////////////////////////////////////////////////////////////////// +// CIeviewLogWindow class + +class CIeviewLogWindow : public CSrmmLogWindow +{ + HWND m_hwnd = nullptr; + +public: + CIeviewLogWindow(CMsgDialog &pDlg) : + CSrmmLogWindow(pDlg) + { + } + + void Attach() override + { + IEVIEWWINDOW ieWindow = {}; + ieWindow.iType = IEW_CREATE; + ieWindow.dwMode = IEWM_TABSRMM; + ieWindow.parent = m_pDlg.GetHwnd(); + ieWindow.cx = 200; + ieWindow.cy = 200; + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); + m_hwnd = ieWindow.hwnd; + } + + void Detach() override + { + IEVIEWWINDOW ieWindow = {}; + ieWindow.iType = IEW_DESTROY; + ieWindow.hwnd = m_hwnd; + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + bool AtBottom() override + { + return false; + } + + void Clear() override + { + IEVIEWEVENT event = {}; + event.iType = IEE_CLEAR_LOG; + event.hwnd = m_hwnd; + CallService(MS_IEVIEW_EVENT, 0, (LPARAM) & event); + } + + HWND GetHwnd() override + { + return m_hwnd; + } + + wchar_t *GetSelection() override + { + IEVIEWEVENT event = {}; + event.hwnd = m_hwnd; + event.iType = IEE_GET_SELECTION; + event.hContact = m_pDlg.m_hContact; + return (wchar_t *)CallService(MS_IEVIEW_EVENT, 0, (LPARAM) & event); + } + + int GetType() override + { + return 1; + } + + void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) override + { + if (!bAppend) + Clear(); + + IEVIEWEVENT event = {}; + event.iType = IEE_LOG_DB_EVENTS; + event.hwnd = m_hwnd; + event.hDbEventFirst = hDbEventFirst; + event.hContact = m_pDlg.m_hContact; + event.count = count; + CallService(MS_IEVIEW_EVENT, 0, (LPARAM) & event); + } + + void CIeviewLogWindow::LogEvents(DBEVENTINFO *dbei_s, bool bAppend) + { + if (dbei_s == nullptr) + return; + + if (!bAppend) + Clear(); + + IEVIEWEVENT event = {}; + event.hwnd = m_hwnd; + event.iType = IEE_LOG_MEM_EVENTS; + event.count = 1; + + IEVIEWEVENTDATA evData = {}; + if (dbei_s->flags & DBEF_SENT) { + evData.dwFlags = IEEDF_SENT; + evData.bIsMe = true; + } + else { + evData.dwFlags = IEEDF_UNICODE_NICK; + evData.szNick.w = Clist_GetContactDisplayName(m_pDlg.m_hContact); + } + switch (dbei_s->eventType) { + case EVENTTYPE_STATUSCHANGE: evData.iType = IEED_EVENT_STATUSCHANGE; break; + case EVENTTYPE_FILE: evData.iType = IEED_EVENT_FILE; break; + case EVENTTYPE_ERRMSG: evData.iType = IEED_EVENT_ERRMSG; break; + default: evData.iType = IEED_EVENT_MESSAGE; break; + } + evData.szText.a = (char *)dbei_s->pBlob; + evData.time = dbei_s->timestamp; + event.eventData = &evData; + event.codepage = CP_UTF8; + CallService(MS_IEVIEW_EVENT, 0, (LPARAM) & event); + } + + void LogEvents(LOGINFO *pLog, bool) override + { + IEVIEWEVENTDATA ied = {}; + ied.dwFlags = IEEDF_UNICODE_NICK; + + IEVIEWEVENT event = {}; + event.hwnd = m_hwnd; + event.hContact = m_pDlg.m_hContact; + event.codepage = CP_UTF8; + event.iType = IEE_LOG_MEM_EVENTS; + event.eventData = &ied; + event.count = 1; + + while (pLog) { + T2Utf szText(pLog->ptszText); + ied.szNick.w = pLog->ptszNick; + ied.szText.a = szText; + ied.time = pLog->time; + ied.bIsMe = pLog->bIsMe; + + switch (pLog->iType) { + case GC_EVENT_MESSAGE: + ied.iType = IEED_GC_EVENT_MESSAGE; + ied.dwData = IEEDD_GC_SHOW_NICK; + break; + case GC_EVENT_ACTION: + ied.iType = IEED_GC_EVENT_ACTION; + break; + case GC_EVENT_JOIN: + ied.iType = IEED_GC_EVENT_JOIN; + break; + case GC_EVENT_PART: + ied.iType = IEED_GC_EVENT_PART; + break; + case GC_EVENT_QUIT: + ied.iType = IEED_GC_EVENT_QUIT; + break; + case GC_EVENT_NICK: + ied.iType = IEED_GC_EVENT_NICK; + break; + case GC_EVENT_KICK: + ied.iType = IEED_GC_EVENT_KICK; + break; + case GC_EVENT_NOTICE: + ied.iType = IEED_GC_EVENT_NOTICE; + break; + case GC_EVENT_TOPIC: + ied.iType = IEED_GC_EVENT_TOPIC; + break; + case GC_EVENT_INFORMATION: + ied.iType = IEED_GC_EVENT_INFORMATION; + break; + case GC_EVENT_ADDSTATUS: + ied.iType = IEED_GC_EVENT_ADDSTATUS; + break; + case GC_EVENT_REMOVESTATUS: + ied.iType = IEED_GC_EVENT_REMOVESTATUS; + break; + } + + ied.dwData |= IEEDD_GC_SHOW_TIME | IEEDD_GC_SHOW_ICON; + ied.dwFlags = IEEDF_UNICODE_TEXT | IEEDF_UNICODE_NICK | IEEDF_UNICODE_TEXT2; + CallService(MS_IEVIEW_EVENT, 0, (LPARAM) & event); + + pLog = pLog->prev; + } + } + + void Resize() override + { + RECT rcRichEdit; + GetWindowRect(GetDlgItem(m_pDlg.GetHwnd(), IDC_SRMM_LOG), &rcRichEdit); + + POINT pt = { rcRichEdit.left, rcRichEdit.top }; + ScreenToClient(GetParent(m_hwnd), &pt); + + IEVIEWWINDOW ieWindow = { sizeof(ieWindow) }; + ieWindow.iType = IEW_SETPOS; + ieWindow.parent = m_hwnd; + ieWindow.hwnd = m_hwnd; + ieWindow.x = pt.x; + ieWindow.y = pt.y; + ieWindow.cx = rcRichEdit.right - rcRichEdit.left; + ieWindow.cy = rcRichEdit.bottom - rcRichEdit.top; + if (ieWindow.cx != 0 && ieWindow.cy != 0) + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); + } + + void ScrollToBottom() override + { + IEVIEWWINDOW iew = { sizeof(iew) }; + iew.iType = IEW_SCROLLBOTTOM; + iew.hwnd = m_hwnd; + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&iew); + } +}; + +CSrmmLogWindow *logBuilder(CMsgDialog &pDlg) +{ + return new CIeviewLogWindow(pDlg); +} diff --git a/plugins/IEView/src/ieview_main.cpp b/plugins/IEView/src/ieview_main.cpp index 7da866604a..e8d59998bc 100644 --- a/plugins/IEView/src/ieview_main.cpp +++ b/plugins/IEView/src/ieview_main.cpp @@ -67,6 +67,8 @@ int CMPlugin::Load() workingDirUtf8 = mir_utf8encodeW(workingDir); delete[] workingDir; + hLogger = RegisterSrmmLog("ieview", L"IEView log", &logBuilder); + HookEvent(ME_OPT_INITIALISE, IEViewOptInit); HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); @@ -83,6 +85,7 @@ int CMPlugin::Load() int CMPlugin::Unload() { + UnregisterSrmmLog(hLogger); Options::uninit(); DestroyHookableEvent(hHookOptionsChanged); IEView::release(); diff --git a/plugins/IEView/src/ieview_services.h b/plugins/IEView/src/ieview_services.h index fe3f42bd4a..ccb378b76e 100644 --- a/plugins/IEView/src/ieview_services.h +++ b/plugins/IEView/src/ieview_services.h @@ -23,10 +23,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "stdafx.h" -extern INT_PTR HandleIEWindow(WPARAM wParam, LPARAM lParam); -extern INT_PTR HandleIEEvent(WPARAM wParam, LPARAM lParam); -extern INT_PTR HandleIENavigate(WPARAM wParam, LPARAM lParam); -extern INT_PTR ReloadOptions(WPARAM, LPARAM); +INT_PTR HandleIEWindow(WPARAM wParam, LPARAM lParam); +INT_PTR HandleIEEvent(WPARAM wParam, LPARAM lParam); +INT_PTR HandleIENavigate(WPARAM wParam, LPARAM lParam); +INT_PTR ReloadOptions(WPARAM, LPARAM); #endif diff --git a/plugins/IEView/src/stdafx.h b/plugins/IEView/src/stdafx.h index f7da077d89..a6c9a689f1 100644 --- a/plugins/IEView/src/stdafx.h +++ b/plugins/IEView/src/stdafx.h @@ -37,6 +37,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#include #include #include #include @@ -49,6 +50,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include +#include #include #include #include @@ -77,10 +79,14 @@ struct CMPlugin : public PLUGIN { CMPlugin(); + HANDLE hLogger; + int Load() override; int Unload() override; }; +CSrmmLogWindow *logBuilder(CMsgDialog &pDlg); + extern IEView *debugView; extern char *workingDirUtf8; extern HANDLE hHookOptionsChanged; diff --git a/plugins/Scriver/res/resource.rc b/plugins/Scriver/res/resource.rc index 89db29772e..0b48c827f2 100644 --- a/plugins/Scriver/res/resource.rc +++ b/plugins/Scriver/res/resource.rc @@ -1,7 +1,8 @@ // Microsoft Visual C++ generated resource script. // +#pragma code_page(65001) + #include "..\src\resource.h" -#include "..\..\include\chat_resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// @@ -18,7 +19,6 @@ #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(1250) ///////////////////////////////////////////////////////////////////////////// // @@ -58,7 +58,8 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN GROUPBOX "Tabs",IDC_STATIC,0,0,304,118 CONTROL "Enable tabs",IDC_USETABS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,12,260,10 - CONTROL "Only show tab bar when it's needed",IDC_HIDEONETAB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,23,252,10 + CONTROL "Only show tab bar when it's needed",IDC_HIDEONETAB, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,23,252,10 CONTROL "Tabs at the bottom",IDC_TABSATBOTTOM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,34,252,10 CONTROL "Limit names on tabs to",IDC_LIMITNAMES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,45,126,10 EDITTEXT IDC_LIMITNAMESLEN,212,44,30,12,ES_RIGHT | ES_NUMBER @@ -106,41 +107,40 @@ BEGIN LTEXT "You can use embedded variables here: %name% for contact's name, %status% for its status, %statusmsg% for its status message and %account% for its account's name",IDC_STATIC,17,38,279,25 END -IDD_OPT_MSGLOG DIALOGEX 2, 0, 304, 232 +IDD_OPT_MSGLOG DIALOGEX 2, 0, 304, 221 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - GROUPBOX "Message window event log",IDC_STMSGLOGGROUP,0,0,304,181 - CONTROL "Enable IEView",IDC_USEIEVIEW,"Button",BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,8,12,140,10 - CONTROL "Show icons",IDC_SHOWLOGICONS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,25,140,10 - CONTROL "Show time",IDC_SHOWTIMES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,36,140,10 - CONTROL "Show seconds",IDC_SHOWSECONDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,47,132,10 - CONTROL "Show date",IDC_SHOWDATES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,58,132,10 - CONTROL "Long date format",IDC_USELONGDATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,69,123,10 - CONTROL "Relative date",IDC_USERELATIVEDATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,80,123,10 - CONTROL "Hide names",IDC_HIDENAMES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,160,25,140,10 - CONTROL "Enable message grouping",IDC_GROUPMESSAGES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,160,36,140,10 + GROUPBOX "Message window event log",IDC_STMSGLOGGROUP,0,0,304,166 + CONTROL "Show icons",IDC_SHOWLOGICONS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,12,140,10 + CONTROL "Show time",IDC_SHOWTIMES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,23,140,10 + CONTROL "Show seconds",IDC_SHOWSECONDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,34,132,10 + CONTROL "Show date",IDC_SHOWDATES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,45,132,10 + CONTROL "Long date format",IDC_USELONGDATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,27,56,123,10 + CONTROL "Relative date",IDC_USERELATIVEDATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,27,67,123,10 + CONTROL "Hide names",IDC_HIDENAMES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,156,12,140,10 + CONTROL "Enable message grouping",IDC_GROUPMESSAGES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,156,23,140,10 CONTROL "Mark follow-up messages with timestamp",IDC_MARKFOLLOWUPS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,168,47,132,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,164,34,132,10 CONTROL "Start message text on a new line",IDC_MESSAGEONNEWLINE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,160,58,140,10 - CONTROL "Show lines between messages",IDC_DRAWLINES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,160,69,120,10 - CONTROL "Indent text",IDC_INDENTTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,160,80,102,10 - EDITTEXT IDC_INDENTSIZE,262,79,33,12,ES_RIGHT | ES_NUMBER | WS_DISABLED + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,156,45,140,10 + CONTROL "Show lines between messages",IDC_DRAWLINES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,156,56,120,10 + CONTROL "Indent text",IDC_INDENTTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,156,67,102,10 + EDITTEXT IDC_INDENTSIZE,262,66,33,12,ES_RIGHT | ES_NUMBER | WS_DISABLED CONTROL "Spin1",IDC_INDENTSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK | WS_DISABLED,290,79,10,12 - CONTROL "Customize fonts and colors",IDC_FONTSCOLORS,"Hyperlink",0x0,8,91,200,8 - CONTROL "",IDC_SRMM_LOG,"RichEdit50W",WS_VSCROLL | WS_TABSTOP | 0x844,8,105,288,68,WS_EX_STATICEDGE - GROUPBOX "Preload",IDC_STATIC,0,181,304,50 - CONTROL "Unread events only",IDC_LOADUNREAD,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,192,138,10 - CONTROL "Last",IDC_LOADCOUNT,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,204,138,10 - CONTROL "Events in the last",IDC_LOADTIME,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,216,138,10 - EDITTEXT IDC_LOADCOUNTN,148,202,33,12,ES_RIGHT | ES_NUMBER | WS_DISABLED - CONTROL "Spin1",IDC_LOADCOUNTSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK | WS_DISABLED,170,201,10,14 - LTEXT "events",IDC_LOADCOUNTTEXT2,185,202,90,8,WS_DISABLED - EDITTEXT IDC_LOADTIMEN,148,215,33,12,ES_RIGHT | ES_NUMBER | WS_DISABLED - CONTROL "Spin1",IDC_LOADTIMESPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK | WS_DISABLED,170,214,10,14 - LTEXT "minutes",IDC_STMINSOLD,185,216,90,8,WS_DISABLED + CONTROL "Customize fonts and colors",IDC_FONTSCOLORS,"Hyperlink",0x0,8,78,200,8 + CONTROL "",IDC_SRMM_LOG,"RichEdit50W",WS_VSCROLL | WS_TABSTOP | 0x844,8,92,288,68,WS_EX_STATICEDGE + GROUPBOX "Preload",IDC_STATIC,0,166,304,50 + CONTROL "Unread events only",IDC_LOADUNREAD,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,177,138,10 + CONTROL "Last",IDC_LOADCOUNT,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,189,138,10 + CONTROL "Events in the last",IDC_LOADTIME,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,201,138,10 + EDITTEXT IDC_LOADCOUNTN,150,187,33,12,ES_RIGHT | ES_NUMBER | WS_DISABLED + CONTROL "Spin1",IDC_LOADCOUNTSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK | WS_DISABLED,173,188,10,14 + LTEXT "events",IDC_LOADCOUNTTEXT2,185,187,90,8,WS_DISABLED + EDITTEXT IDC_LOADTIMEN,150,200,33,12,ES_RIGHT | ES_NUMBER | WS_DISABLED + CONTROL "Spin1",IDC_LOADTIMESPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK | WS_DISABLED,175,200,11,14 + LTEXT "minutes",IDC_STMINSOLD,185,201,90,8,WS_DISABLED END IDD_OPT_MSGTYPE DIALOGEX 0, 0, 283, 252 @@ -344,11 +344,11 @@ BEGIN VERTGUIDE, 10 VERTGUIDE, 19 VERTGUIDE, 28 - VERTGUIDE, 148 + VERTGUIDE, 150 VERTGUIDE, 156 VERTGUIDE, 169 VERTGUIDE, 300 - BOTTOMMARGIN, 229 + BOTTOMMARGIN, 218 HORZGUIDE, 199 END @@ -434,64 +434,116 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_ADDCONTACT ICON "addcontact.ico" + IDI_USERDETAILS ICON "details.ico" + IDI_HISTORY ICON "history.ico" + IDI_SEND ICON "send.ico" + IDI_SMILEY ICON "smiley.ico" + IDI_TYPING ICON "typing.ico" + IDI_TYPINGOFF ICON "typingoff.ico" + IDI_TIMESTAMP ICON "clock.ico" + IDI_QUOTE ICON "quote.ico" + IDI_INCOMING ICON "message.ico" + IDI_OUTGOING ICON "messageout.ico" + IDI_NOTICE ICON "highlight.ico" + IDI_CLOSEX ICON "closex.ico" + IDI_BUNDERLINE ICON "chat/underline.ico" + IDI_BBOLD ICON "chat/bold.ico" + IDI_BITALICS ICON "chat/italic.ico" + IDI_JOIN ICON "chat/join.ico" + IDI_TOPIC ICON "chat/topic.ico" + IDI_ADDSTATUS ICON "chat/addmode.ico" + IDI_INFO ICON "chat/info.ico" + IDI_KICK ICON "chat/kick.ico" + IDI_NICK ICON "chat/nick.ico" + IDI_CHAT_NOTICE ICON "chat/notice.ico" + IDI_PART ICON "chat/part.ico" + IDI_QUIT ICON "chat/quit.ico" + IDI_REMSTATUS ICON "chat/removestatus.ico" + IDI_ACTION ICON "chat/action.ico" + IDI_TOPICBUT ICON "chat/topicbut.ico" + IDI_BKGCOLOR ICON "chat/bkgcolor.ico" + IDI_CHANMGR ICON "chat/window.ico" + IDI_COLOR ICON "chat/color.ico" + IDI_FILTER ICON "chat/filter.ico" + IDI_NICKLIST ICON "chat/nicklist.ico" + IDI_STATUS3 ICON "chat/4.ico" + IDI_STATUS2 ICON "chat/3.ico" + IDI_STATUS4 ICON "chat/5.ico" + IDI_STATUS1 ICON "chat/2.ico" + IDI_STATUS0 ICON "chat/1.ico" + IDI_STATUS5 ICON "chat/6.ico" + IDI_OVERLAY ICON "chat/overlay.ico" + IDI_NICKLIST2 ICON "chat/nicklist2.ico" + IDI_FILTER2 ICON "chat/filter2.ico" + IDI_GOOGLE ICON "google.ico" + IDI_BING ICON "bing.ico" + IDI_YANDEX ICON "yandex.ico" + IDI_WIKIPEDIA ICON "wikipedia.ico" + IDI_GOOGLE_MAPS ICON "gmaps.ico" + IDI_GOOGLE_TRANSLATE ICON "gtranslate.ico" + IDI_YAHOO ICON "yahoo.ico" + IDI_FOODNETWORK ICON "foodnetwork.ico" + ///////////////////////////////////////////////////////////////////////////// // // Cursor // IDC_HYPERLINKHAND CURSOR "hyperlin.cur" + IDC_DRAGCURSOR CURSOR "dragcopy.cur" + ///////////////////////////////////////////////////////////////////////////// // // Menu @@ -532,6 +584,11 @@ BEGIN 0 END +IDD_OPT_MSGLOG AFX_DIALOG_LAYOUT +BEGIN + 0 +END + #endif // Neutral resources ///////////////////////////////////////////////////////////////////////////// diff --git a/plugins/Scriver/src/chat_log.cpp b/plugins/Scriver/src/chat_log.cpp deleted file mode 100644 index acc786eb4b..0000000000 --- a/plugins/Scriver/src/chat_log.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* -Chat module plugin for Miranda IM - -Copyright (C) 2003 Jörgen Persson -Copyright 2003-2009 Miranda ICQ/IM project, - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "stdafx.h" - -#ifndef EM_GETSCROLLPOS -#define EM_GETSCROLLPOS (WM_USER+221) -#endif - -void CMsgDialog::StreamInEvents(LOGINFO *lin, bool bRedraw) -{ - if (m_hwnd == nullptr || lin == nullptr || m_si == nullptr) - return; - - if (!bRedraw && (m_si->iType == GCW_CHATROOM || m_si->iType == GCW_PRIVMESS) && m_bFilterEnabled && !(m_iLogFilterFlags & lin->iType)) - return; - - LOGSTREAMDATA streamData; - memset(&streamData, 0, sizeof(streamData)); - streamData.hwnd = m_log.GetHwnd(); - streamData.si = m_si; - streamData.lin = lin; - streamData.bStripFormat = FALSE; - streamData.isFirst = bRedraw ? 1 : m_log.GetRichTextLength() == 0; - - EDITSTREAM stream = { 0 }; - stream.pfnCallback = Srmm_LogStreamCallback; - stream.dwCookie = (DWORD_PTR)&streamData; - - SCROLLINFO scroll; - scroll.cbSize = sizeof(SCROLLINFO); - scroll.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; - GetScrollInfo(m_log.GetHwnd(), SB_VERT, &scroll); - - POINT point = { 0 }; - m_log.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&point); - - // do not scroll to bottom if there is a selection - CHARRANGE oldsel, sel, newsel; - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldsel); - if (oldsel.cpMax != oldsel.cpMin) - m_log.SendMsg(WM_SETREDRAW, FALSE, 0); - - // set the insertion point at the bottom - sel.cpMin = sel.cpMax = m_log.GetRichTextLength(); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); - - // fix for the indent... must be a M$ bug - if (sel.cpMax == 0) - bRedraw = TRUE; - - // should the event(s) be appended to the current log - WPARAM wp = bRedraw ? SF_RTF : SFF_SELECTION | SF_RTF; - - // get the number of pixels per logical inch - bool bFlag = false; - if (bRedraw) { - m_log.SendMsg(WM_SETREDRAW, FALSE, 0); - bFlag = true; - } - - // stream in the event(s) - streamData.lin = lin; - streamData.bRedraw = bRedraw; - m_log.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))) { - newsel.cpMax = -1; - newsel.cpMin = sel.cpMin; - if (newsel.cpMin < 0) - newsel.cpMin = 0; - - SMADD_RICHEDIT3 sm = { sizeof(sm) }; - sm.hwndRichEditControl = m_log.GetHwnd(); - sm.Protocolname = m_si->pszModule; - sm.rangeToReplace = bRedraw ? nullptr : &newsel; - sm.flags = 0; - sm.disableRedraw = TRUE; - sm.hContact = m_hContact; - CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&sm); - } - - // scroll log to bottom if the log was previously scrolled to bottom, else restore old position - if (bRedraw || (UINT)scroll.nPos >= (UINT)scroll.nMax - scroll.nPage - 5 || scroll.nMax - scroll.nMin - scroll.nPage < 50) - ScrollToBottom(); - else - m_log.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&point); - - // do we need to restore the selection - if (oldsel.cpMax != oldsel.cpMin) { - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldsel); - m_log.SendMsg(WM_SETREDRAW, TRUE, 0); - InvalidateRect(m_log.GetHwnd(), nullptr, TRUE); - } - - // need to invalidate the window - if (bFlag) { - sel.cpMin = sel.cpMax = m_log.GetRichTextLength(); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - m_log.SendMsg(WM_SETREDRAW, TRUE, 0); - InvalidateRect(m_log.GetHwnd(), nullptr, TRUE); - } -} diff --git a/plugins/Scriver/src/globals.cpp b/plugins/Scriver/src/globals.cpp index cc69569287..34b64b6081 100644 --- a/plugins/Scriver/src/globals.cpp +++ b/plugins/Scriver/src/globals.cpp @@ -352,7 +352,6 @@ void ReloadGlobals() g_dat.flags.bStayMinimized = g_plugin.bStayMinimized; g_dat.flags.bSaveDrafts = g_plugin.bSaveDrafts; g_dat.flags.bDelTemp = g_plugin.bDelTemp; - g_dat.flags.bUseIeview = g_plugin.bUseIeview; g_dat.sendMode = (SendMode)g_plugin.getByte(SRMSGSET_SENDMODE, SRMSGDEFSET_SENDMODE); g_dat.openFlags = g_plugin.iPopFlags; diff --git a/plugins/Scriver/src/globals.h b/plugins/Scriver/src/globals.h index 1701681025..19b61bdcb9 100644 --- a/plugins/Scriver/src/globals.h +++ b/plugins/Scriver/src/globals.h @@ -48,7 +48,6 @@ struct WindowFlags bool bShowProgress : 1; bool bShowAvatar : 1; bool bRtl : 1; - bool bUseIeview : 1; bool bShowIcons : 1; bool bHideNames : 1; bool bShowTime : 1; @@ -107,7 +106,6 @@ struct GlobalMessageData SendMode sendMode; int tabIconListUsageSize; int smileyAddInstalled; - int ieviewInstalled; int limitTabsNum; int limitChatsTabsNum; int indentSize; diff --git a/plugins/Scriver/src/input.cpp b/plugins/Scriver/src/input.cpp index db9ba52e01..518bdbc224 100644 --- a/plugins/Scriver/src/input.cpp +++ b/plugins/Scriver/src/input.cpp @@ -134,8 +134,8 @@ bool CMsgDialog::CheckSend() if (m_iLastEnterTime + 1000 < GetTickCount()) m_iLastEnterTime = GetTickCount(); else { - m_log.SendMsg(WM_KEYDOWN, VK_BACK, 0); - m_log.SendMsg(WM_KEYUP, VK_BACK, 0); + LOG()->WndProc(WM_KEYDOWN, VK_BACK, 0); + LOG()->WndProc(WM_KEYUP, VK_BACK, 0); PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); return true; } diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp index 82a13c15ba..75a58a7717 100644 --- a/plugins/Scriver/src/msgdialog.cpp +++ b/plugins/Scriver/src/msgdialog.cpp @@ -230,7 +230,6 @@ bool CMsgDialog::OnInitDialog() m_startTime = time(0); m_bUseRtl = g_plugin.getByte(m_hContact, "UseRTL", 0) != 0; - m_bUseIEView = (g_dat.ieviewInstalled) ? g_dat.flags.bUseIeview && !m_si : false; PARAFORMAT2 pf2; memset(&pf2, 0, sizeof(pf2)); @@ -246,22 +245,6 @@ bool CMsgDialog::OnInitDialog() } m_message.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); - // Workaround to make Richedit display RTL messages correctly - memset(&pf2, 0, sizeof(pf2)); - pf2.cbSize = sizeof(pf2); - pf2.dwMask = PFM_RTLPARA | PFM_OFFSETINDENT | PFM_RIGHTINDENT; - pf2.wEffects = PFE_RTLPARA; - pf2.dxStartIndent = 30; - pf2.dxRightIndent = 30; - m_log.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); - - pf2.dwMask = PFM_RTLPARA; - pf2.wEffects = 0; - m_log.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); - - DWORD dwExStyle = GetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE); - SetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE, (m_bUseRtl) ? dwExStyle | WS_EX_LEFTSCROLLBAR :dwExStyle & ~WS_EX_LEFTSCROLLBAR); - RECT rc; GetWindowRect(m_message.GetHwnd(), &rc); m_minLogBoxHeight = m_minEditBoxHeight = rc.bottom - rc.top; @@ -290,14 +273,6 @@ bool CMsgDialog::OnInitDialog() SendMessage(m_hwnd, DM_CHANGEICONS, 0, 0); - m_log.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK | ENM_KEYEVENTS); - m_log.SendMsg(EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, SES_EXTENDBACKCOLOR); - m_log.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_log.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~(IMF_AUTOKEYBOARD | IMF_AUTOFONTSIZEADJUST)); - m_log.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0, 0)); - m_log.SendMsg(EM_LIMITTEXT, sizeof(wchar_t) * 0x7FFFFFFF, 0); - m_log.SendMsg(EM_HIDESELECTION, TRUE, 0); - m_log.SendMsg(EM_AUTOURLDETECT, TRUE, 0); - m_message.SetReadOnly(false); m_message.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_message.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD); m_message.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_CHANGE | ENM_REQUESTRESIZE); @@ -308,23 +283,9 @@ bool CMsgDialog::OnInitDialog() } // get around a lame bug in the Windows template resource code where richedits are limited to 0x7FFF - m_log.SendMsg(EM_LIMITTEXT, sizeof(wchar_t) * 0x7FFFFFFF, 0); ::DragAcceptFiles(m_message.GetHwnd(), TRUE); CreateInfobar(); - if (m_bUseIEView) { - IEVIEWWINDOW ieWindow = { sizeof(IEVIEWWINDOW) }; - ieWindow.iType = IEW_CREATE; - ieWindow.dwMode = IEWM_SCRIVER; - ieWindow.parent = m_hwnd; - ieWindow.cx = 200; - ieWindow.cy = 300; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - m_hwndIeview = ieWindow.hwnd; - if (m_hwndIeview == nullptr) - m_bUseIEView = false; - } - if (isChat()) { UpdateOptions(); UpdateStatusBar(); @@ -478,12 +439,7 @@ void CMsgDialog::OnDestroy() m_si->pDlg = nullptr; m_pParent->RemoveChild(m_hwnd); - if (m_hwndIeview != nullptr) { - IEVIEWWINDOW ieWindow = { sizeof(ieWindow) }; - ieWindow.iType = IEW_DESTROY; - ieWindow.hwnd = m_hwndIeview; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - } + NotifyEvent(MSG_WINDOW_EVT_CLOSE); mir_free(m_wszSearchQuery); @@ -591,16 +547,7 @@ void CMsgDialog::onClick_Quote(CCtrlButton*) st.flags = ST_SELECTION; st.codepage = 1200; - wchar_t *buffer = nullptr; - if (m_hwndIeview != nullptr) { - IEVIEWEVENT evt = { sizeof(evt) }; - evt.hwnd = m_hwndIeview; - evt.hContact = m_hContact; - evt.iType = IEE_GET_SELECTION; - buffer = mir_wstrdup((wchar_t*)CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&evt)); - } - else buffer = GetRichEditSelection(m_log.GetHwnd()); - + wchar_t *buffer = m_pLog->GetSelection(); if (buffer != nullptr) { wchar_t *quotedBuffer = GetQuotedTextW(buffer); m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&st, (LPARAM)quotedBuffer); @@ -674,7 +621,7 @@ void CMsgDialog::onClick_ShowList(CCtrlButton *pButton) m_bNicklistEnabled = !m_bNicklistEnabled; pButton->SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(m_bNicklistEnabled ? IDI_NICKLIST : IDI_NICKLIST2)); - ScrollToBottom(); + m_pLog->ScrollToBottom(); Resize(); } @@ -754,7 +701,7 @@ void CMsgDialog::MessageDialogResize(int w, int h) logH -= toolbarHeight; HDWP hdwp = BeginDeferWindowPos(5); - hdwp = DeferWindowPos(hdwp, m_log.GetHwnd(), nullptr, 1, 0, bNick ? w - pdat->iSplitterX - 1 : w - 2, logH, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, m_pLog->GetHwnd(), nullptr, 1, 0, bNick ? w - pdat->iSplitterX - 1 : w - 2, logH, SWP_NOZORDER); hdwp = DeferWindowPos(hdwp, m_nickList.GetHwnd(), nullptr, w - pdat->iSplitterX + 2, 0, pdat->iSplitterX - 3, logH, SWP_NOZORDER); hdwp = DeferWindowPos(hdwp, m_splitterX.GetHwnd(), nullptr, w - pdat->iSplitterX, 1, 2, logH, SWP_NOZORDER); hdwp = DeferWindowPos(hdwp, m_splitterY.GetHwnd(), nullptr, 0, h - pdat->iSplitterY, w, SPLITTER_HEIGHT, SWP_NOZORDER); @@ -821,7 +768,7 @@ void CMsgDialog::MessageDialogResize(int w, int h) HDWP hdwp = BeginDeferWindowPos(5); hdwp = DeferWindowPos(hdwp, m_hwndInfo, nullptr, 1, 0, w - 2, infobarInnerHeight - 2, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, m_log.GetHwnd(), nullptr, 1, logY, w - 2, logH, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, m_pLog->GetHwnd(), nullptr, 1, logY, w - 2, logH, SWP_NOZORDER); hdwp = DeferWindowPos(hdwp, m_message.GetHwnd(), nullptr, 1, h - hSplitterPos - 1, messageEditWidth, hSplitterPos, SWP_NOZORDER); hdwp = DeferWindowPos(hdwp, GetDlgItem(m_hwnd, IDC_AVATAR), nullptr, w - avatarWidth - 1, h - (avatarHeight + avatarWidth) / 2 - 1, avatarWidth, avatarWidth, SWP_NOZORDER); hdwp = DeferWindowPos(hdwp, m_splitterY.GetHwnd(), nullptr, 0, h - hSplitterPos - SPLITTER_HEIGHT - 1, toolbarWidth, SPLITTER_HEIGHT, SWP_NOZORDER); @@ -833,19 +780,6 @@ void CMsgDialog::MessageDialogResize(int w, int h) SetButtonsPos(m_hwnd, m_hContact, bToolbar); - if (m_hwndIeview != nullptr) { - IEVIEWWINDOW ieWindow = { sizeof(ieWindow) }; - ieWindow.iType = IEW_SETPOS; - ieWindow.parent = m_hwnd; - ieWindow.hwnd = m_hwndIeview; - ieWindow.x = 0; - ieWindow.y = logY; - ieWindow.cx = w; - ieWindow.cy = logH; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - } - else RedrawWindow(m_log.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); - RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); } @@ -923,9 +857,9 @@ INT_PTR CALLBACK CMsgDialog::FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wPara ///////////////////////////////////////////////////////////////////////////////////////// -LRESULT CMsgDialog::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) +INT_PTR CLogWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam) { - int result = InputAreaShortcuts(m_log.GetHwnd(), msg, wParam, lParam); + int result = m_pDlg.InputAreaShortcuts(m_rtf.GetHwnd(), msg, wParam, lParam); if (result != -1) return result; @@ -938,20 +872,20 @@ LRESULT CMsgDialog::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) return DrawMenuItem(wParam, lParam); case WM_LBUTTONUP: - if (isChat()) { + if (m_pDlg.isChat()) { CHARRANGE sel; - SendMessage(m_log.GetHwnd(), EM_EXGETSEL, 0, (LPARAM)&sel); + SendMessage(m_rtf.GetHwnd(), EM_EXGETSEL, 0, (LPARAM)&sel); if (sel.cpMin != sel.cpMax) { - SendMessage(m_log.GetHwnd(), WM_COPY, 0, 0); + SendMessage(m_rtf.GetHwnd(), WM_COPY, 0, 0); sel.cpMin = sel.cpMax; - SendMessage(m_log.GetHwnd(), EM_EXSETSEL, 0, (LPARAM)&sel); + SendMessage(m_rtf.GetHwnd(), EM_EXSETSEL, 0, (LPARAM)&sel); } - SetFocus(m_message.GetHwnd()); + SetFocus(m_pDlg.m_message.GetHwnd()); } break; } - return CSuper::WndProc_Log(msg, wParam, lParam); + return CSuper::WndProc(msg, wParam, lParam); } LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) @@ -1017,7 +951,7 @@ LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) } if (wParam == VK_NEXT || wParam == VK_PRIOR) { - m_log.SendMsg(msg, wParam, lParam); + LOG()->WndProc(msg, wParam, lParam); return TRUE; } } @@ -1029,7 +963,7 @@ LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) case WM_MOUSEWHEEL: if ((GetWindowLongPtr(m_message.GetHwnd(), GWL_STYLE) & WS_VSCROLL) == 0) - m_log.SendMsg(WM_MOUSEWHEEL, wParam, lParam); + LOG()->WndProc(WM_MOUSEWHEEL, wParam, lParam); m_iLastEnterTime = 0; break; @@ -1184,7 +1118,7 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) case WM_LBUTTONDBLCLK: if (LOWORD(lParam) < 30) - ScrollToBottom(); + m_pLog->ScrollToBottom(); else SendMessage(m_hwndParent, WM_SYSCOMMAND, SC_MINIMIZE, 0); break; @@ -1237,33 +1171,12 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) break; case DM_OPTIONSAPPLIED: - m_bUseIEView = (g_dat.ieviewInstalled) ? g_dat.flags.bUseIeview && !m_si : false; - if (m_bUseIEView && m_hwndIeview == nullptr) { - IEVIEWWINDOW ieWindow = { sizeof(ieWindow) }; - ieWindow.iType = IEW_CREATE; - ieWindow.dwMode = IEWM_SCRIVER; - ieWindow.parent = m_hwnd; - ieWindow.cx = 200; - ieWindow.cy = 300; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - m_hwndIeview = ieWindow.hwnd; - if (m_hwndIeview == nullptr) - m_bUseIEView = false; - } - else if (!m_bUseIEView && m_hwndIeview != nullptr) { - IEVIEWWINDOW ieWindow = { sizeof(ieWindow) }; - ieWindow.iType = IEW_DESTROY; - ieWindow.hwnd = m_hwndIeview; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - m_hwndIeview = nullptr; - } - GetAvatar(); SetDialogToType(); { - COLORREF colour = g_plugin.getDword(SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR); - m_log.SendMsg(EM_SETBKGNDCOLOR, 0, colour); - colour = g_plugin.getDword(SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR); + m_pLog->UpdateOptions(); + + COLORREF colour = g_plugin.getDword(SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR); m_message.SendMsg(EM_SETBKGNDCOLOR, 0, colour); InvalidateRect(m_message.GetHwnd(), nullptr, FALSE); @@ -1285,15 +1198,6 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) m_message.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_message.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD); } - PARAFORMAT2 pf2; - memset(&pf2, 0, sizeof(pf2)); - pf2.cbSize = sizeof(pf2); - pf2.dwMask = PFM_OFFSET; - pf2.dxOffset = (g_dat.flags.bIndentText) ? g_dat.indentSize * 1440 / g_dat.logPixelSX : 0; - m_log.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); - m_log.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_log.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~(IMF_AUTOKEYBOARD | IMF_AUTOFONTSIZEADJUST)); - m_log.SetTextA(""); - SendMessage(m_hwnd, DM_REMAKELOG, 0, 0); UpdateTitle(); UpdateTabControl(); @@ -1371,16 +1275,11 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) case DM_SETFOCUS: if (lParam == WM_MOUSEACTIVATE) { - HWND hLog; POINT pt; GetCursorPos(&pt); - if (m_hwndIeview != nullptr) - hLog = m_hwndIeview; - else - hLog = m_log.GetHwnd(); RECT rc; - GetWindowRect(hLog, &rc); + GetWindowRect(m_pLog->GetHwnd(), &rc); if (pt.x >= rc.left && pt.x <= rc.right && pt.y >= rc.top && pt.y <= rc.bottom) return TRUE; } @@ -1405,7 +1304,7 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) case WM_SIZE: if (wParam == SIZE_MAXIMIZED) - ScrollToBottom(); + m_pLog->ScrollToBottom(); if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED) { RECT rc; @@ -1418,9 +1317,9 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) case DM_REMAKELOG: m_lastEventType = -1; if (wParam == 0 || wParam == m_hContact) - StreamInEvents(m_hDbEventFirst, -1, 0); + m_pLog->LogEvents(m_hDbEventFirst, -1, 0); - InvalidateRect(m_log.GetHwnd(), nullptr, FALSE); + InvalidateRect(m_pLog->GetHwnd(), nullptr, FALSE); break; case HM_DBEVENTADDED: @@ -1449,7 +1348,7 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) } if (hDbEvent != m_hDbEventFirst && db_event_next(m_hContact, hDbEvent) == 0) - StreamInEvents(hDbEvent, 1, 1); + m_pLog->LogEvents(hDbEvent, 1, 1); else SendMessage(m_hwnd, DM_REMAKELOG, 0, 0); diff --git a/plugins/Scriver/src/msglog.cpp b/plugins/Scriver/src/msglog.cpp index 087a78859a..d01d2a9bab 100644 --- a/plugins/Scriver/src/msglog.cpp +++ b/plugins/Scriver/src/msglog.cpp @@ -626,122 +626,6 @@ void StreamInTestEvents(HWND hEditWnd, GlobalMessageData *gdat) delete dat; } -void CMsgDialog::StreamInEvents(MEVENT hDbEventFirst, int count, int bAppend) -{ - // IEVIew MOD Begin - if (m_hwndIeview != nullptr) { - IEVIEWEVENT evt; - evt.dwFlags = (m_bUseRtl) ? IEEF_RTL : 0; - evt.hwnd = m_hwndIeview; - evt.hContact = m_hContact; - evt.pszProto = m_szProto; - if (!bAppend) { - evt.iType = IEE_CLEAR_LOG; - CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&evt); - } - evt.iType = IEE_LOG_DB_EVENTS; - evt.hDbEventFirst = hDbEventFirst; - evt.count = count; - CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&evt); - m_hDbEventLast = evt.hDbEventFirst != 0 ? evt.hDbEventFirst : m_hDbEventLast; - - IEVIEWWINDOW ieWindow = {}; - ieWindow.iType = IEW_SCROLLBOTTOM; - ieWindow.hwnd = m_hwndIeview; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - return; - } - // IEVIew MOD End - - CHARRANGE oldSel, sel; - m_log.SendMsg(WM_SETREDRAW, FALSE, 0); - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldSel); - - LogStreamData streamData = {}; - streamData.hContact = m_hContact; - streamData.hDbEvent = hDbEventFirst; - streamData.hDbEventLast = m_hDbEventLast; - streamData.dlgDat = this; - streamData.eventsToInsert = count; - streamData.isFirst = bAppend ? m_log.GetRichTextLength() == 0 : 1; - streamData.gdat = &g_dat; - - EDITSTREAM stream = {}; - stream.pfnCallback = LogStreamInEvents; - stream.dwCookie = (DWORD_PTR)& streamData; - sel.cpMin = 0; - - POINT scrollPos; - bool bottomScroll = (GetFocus() != m_log.GetHwnd()); - if (bottomScroll && (GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL)) { - SCROLLINFO si = {}; - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; - GetScrollInfo(m_log.GetHwnd(), SB_VERT, &si); - bottomScroll = (si.nPos + (int)si.nPage) >= si.nMax; - } - if (!bottomScroll) - m_log.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&scrollPos); - - FINDTEXTEXA fi; - if (bAppend) { - GETTEXTLENGTHEX gtxl = { 0 }; - gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMCHARS; - gtxl.codepage = 1200; - fi.chrg.cpMin = m_log.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0); - sel.cpMin = sel.cpMax = m_log.GetRichTextLength(); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - } - else { - m_log.SendMsg(WM_SETREDRAW, FALSE, 0); - m_log.SetTextA(""); - sel.cpMin = 0; - sel.cpMax = m_log.GetRichTextLength(); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - fi.chrg.cpMin = 0; - m_isMixed = 0; - } - - m_log.SendMsg(EM_STREAMIN, bAppend ? SFF_SELECTION | SF_RTF : SFF_SELECTION | SF_RTF, (LPARAM)&stream); - if (bottomScroll) { - sel.cpMin = sel.cpMax = -1; - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - } - else { - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldSel); - m_log.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&scrollPos); - } - - if (g_dat.smileyAddInstalled) { - SMADD_RICHEDIT3 smre; - smre.cbSize = sizeof(SMADD_RICHEDIT3); - smre.hwndRichEditControl = m_log.GetHwnd(); - - MCONTACT hContact = db_mc_getSrmmSub(m_hContact); - smre.Protocolname = (hContact != 0) ? GetContactProto(hContact) : m_szProto; - - if (fi.chrg.cpMin > 0) { - sel.cpMin = fi.chrg.cpMin; - sel.cpMax = -1; - smre.rangeToReplace = &sel; - } - else smre.rangeToReplace = nullptr; - - smre.disableRedraw = TRUE; - smre.hContact = m_hContact; - smre.flags = 0; - CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&smre); - } - - m_log.SendMsg(WM_SETREDRAW, TRUE, 0); - if (bottomScroll) { - ScrollToBottom(); - RedrawWindow(m_log.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW); - } - - m_hDbEventLast = streamData.hDbEventLast; -} - #define RTFPICTHEADERMAXSIZE 78 void LoadMsgLogIcons(void) @@ -820,3 +704,268 @@ void FreeMsgLogIcons(void) ImageList_RemoveAll(g_hImageList); ImageList_Destroy(g_hImageList); } + +///////////////////////////////////////////////////////////////////////////////////////// + +void CLogWindow::Attach() +{ + CSuper::Attach(); + + DWORD dwExStyle = GetWindowLongPtr(m_rtf.GetHwnd(), GWL_EXSTYLE); + SetWindowLongPtr(m_rtf.GetHwnd(), GWL_EXSTYLE, (m_pDlg.m_bUseRtl) ? dwExStyle | WS_EX_LEFTSCROLLBAR : dwExStyle & ~WS_EX_LEFTSCROLLBAR); + + // Workaround to make Richedit display RTL messages correctly + PARAFORMAT2 pf2; + memset(&pf2, 0, sizeof(pf2)); + pf2.cbSize = sizeof(pf2); + pf2.dwMask = PFM_RTLPARA | PFM_OFFSETINDENT | PFM_RIGHTINDENT; + pf2.wEffects = PFE_RTLPARA; + pf2.dxStartIndent = 30; + pf2.dxRightIndent = 30; + m_rtf.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); + + pf2.dwMask = PFM_RTLPARA; + pf2.wEffects = 0; + m_rtf.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); + + m_rtf.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK | ENM_KEYEVENTS); + m_rtf.SendMsg(EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, SES_EXTENDBACKCOLOR); + m_rtf.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_rtf.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~(IMF_AUTOKEYBOARD | IMF_AUTOFONTSIZEADJUST)); + m_rtf.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0, 0)); + m_rtf.SendMsg(EM_LIMITTEXT, 0x7FFFFFFF, 0); + m_rtf.SendMsg(EM_HIDESELECTION, TRUE, 0); + m_rtf.SendMsg(EM_AUTOURLDETECT, TRUE, 0); +} + +void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) +{ + CHARRANGE oldSel, sel; + m_rtf.SendMsg(WM_SETREDRAW, FALSE, 0); + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldSel); + + LogStreamData streamData = {}; + streamData.hContact = m_pDlg.m_hContact; + streamData.hDbEvent = hDbEventFirst; + streamData.hDbEventLast = m_pDlg.m_hDbEventLast; + streamData.dlgDat = &m_pDlg; + streamData.eventsToInsert = count; + 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; + bool bottomScroll = (GetFocus() != m_rtf.GetHwnd()); + if (bottomScroll && (GetWindowLongPtr(m_rtf.GetHwnd(), GWL_STYLE) & WS_VSCROLL)) { + SCROLLINFO si = {}; + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; + GetScrollInfo(m_rtf.GetHwnd(), SB_VERT, &si); + bottomScroll = (si.nPos + (int)si.nPage) >= si.nMax; + } + if (!bottomScroll) + m_rtf.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&scrollPos); + + FINDTEXTEXA fi; + if (bAppend) { + GETTEXTLENGTHEX gtxl = { 0 }; + gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMCHARS; + gtxl.codepage = 1200; + fi.chrg.cpMin = m_rtf.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0); + sel.cpMin = sel.cpMax = m_rtf.GetRichTextLength(); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + } + else { + m_rtf.SendMsg(WM_SETREDRAW, FALSE, 0); + m_rtf.SetTextA(""); + sel.cpMin = 0; + sel.cpMax = m_rtf.GetRichTextLength(); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + fi.chrg.cpMin = 0; + m_pDlg.m_isMixed = 0; + } + + m_rtf.SendMsg(EM_STREAMIN, bAppend ? SFF_SELECTION | SF_RTF : SFF_SELECTION | SF_RTF, (LPARAM)&stream); + if (bottomScroll) { + sel.cpMin = sel.cpMax = -1; + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + } + else { + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldSel); + m_rtf.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&scrollPos); + } + + if (g_dat.smileyAddInstalled) { + SMADD_RICHEDIT3 smre; + smre.cbSize = sizeof(SMADD_RICHEDIT3); + smre.hwndRichEditControl = m_rtf.GetHwnd(); + + MCONTACT hContact = db_mc_getSrmmSub(m_pDlg.m_hContact); + smre.Protocolname = (hContact != 0) ? GetContactProto(hContact) : m_pDlg.m_szProto; + + if (fi.chrg.cpMin > 0) { + sel.cpMin = fi.chrg.cpMin; + sel.cpMax = -1; + smre.rangeToReplace = &sel; + } + else smre.rangeToReplace = nullptr; + + smre.disableRedraw = TRUE; + smre.hContact = m_pDlg.m_hContact; + smre.flags = 0; + CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&smre); + } + + m_rtf.SendMsg(WM_SETREDRAW, TRUE, 0); + if (bottomScroll) { + ScrollToBottom(); + RedrawWindow(m_rtf.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW); + } + + m_pDlg.m_hDbEventLast = streamData.hDbEventLast; +} + +void CLogWindow::LogEvents(DBEVENTINFO*, bool) +{ +} + +void CLogWindow::LogEvents(LOGINFO *lin, bool bRedraw) +{ + auto *si = m_pDlg.m_si; + if (m_rtf.GetHwnd() == nullptr || lin == nullptr || si == nullptr) + return; + + if (!bRedraw && (si->iType == GCW_CHATROOM || si->iType == GCW_PRIVMESS) && m_pDlg.m_bFilterEnabled && !(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.bStripFormat = FALSE; + streamData.isFirst = bRedraw ? 1 : m_rtf.GetRichTextLength() == 0; + + EDITSTREAM stream = {}; + stream.pfnCallback = Srmm_LogStreamCallback; + stream.dwCookie = (DWORD_PTR)&streamData; + + SCROLLINFO scroll; + scroll.cbSize = sizeof(SCROLLINFO); + scroll.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; + GetScrollInfo(m_rtf.GetHwnd(), SB_VERT, &scroll); + + POINT point = {}; + m_rtf.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&point); + + // do not scroll to bottom if there is a selection + CHARRANGE oldsel, sel, newsel; + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldsel); + if (oldsel.cpMax != oldsel.cpMin) + m_rtf.SendMsg(WM_SETREDRAW, FALSE, 0); + + // set the insertion point at the bottom + sel.cpMin = sel.cpMax = m_rtf.GetRichTextLength(); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + + // fix for the indent... must be a M$ bug + if (sel.cpMax == 0) + bRedraw = TRUE; + + // should the event(s) be appended to the current log + WPARAM wp = bRedraw ? SF_RTF : SFF_SELECTION | SF_RTF; + + // get the number of pixels per logical inch + bool bFlag = false; + if (bRedraw) { + m_rtf.SendMsg(WM_SETREDRAW, FALSE, 0); + bFlag = true; + } + + // stream in the event(s) + streamData.lin = lin; + streamData.bRedraw = bRedraw; + 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))) { + newsel.cpMax = -1; + newsel.cpMin = sel.cpMin; + if (newsel.cpMin < 0) + newsel.cpMin = 0; + + SMADD_RICHEDIT3 sm = { sizeof(sm) }; + sm.hwndRichEditControl = m_rtf.GetHwnd(); + sm.Protocolname = si->pszModule; + sm.rangeToReplace = bRedraw ? nullptr : &newsel; + sm.flags = 0; + sm.disableRedraw = TRUE; + sm.hContact = m_pDlg.m_hContact; + CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&sm); + } + + // scroll log to bottom if the log was previously scrolled to bottom, else restore old position + if (bRedraw || (UINT)scroll.nPos >= (UINT)scroll.nMax - scroll.nPage - 5 || scroll.nMax - scroll.nMin - scroll.nPage < 50) + ScrollToBottom(); + else + m_rtf.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&point); + + // do we need to restore the selection + if (oldsel.cpMax != oldsel.cpMin) { + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldsel); + m_rtf.SendMsg(WM_SETREDRAW, TRUE, 0); + InvalidateRect(m_rtf.GetHwnd(), nullptr, TRUE); + } + + // need to invalidate the window + if (bFlag) { + sel.cpMin = sel.cpMax = m_rtf.GetRichTextLength(); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + m_rtf.SendMsg(WM_SETREDRAW, TRUE, 0); + InvalidateRect(m_rtf.GetHwnd(), nullptr, TRUE); + } +} + +void CLogWindow::ScrollToBottom() +{ + if (GetWindowLongPtr(m_rtf.GetHwnd(), GWL_STYLE) & WS_VSCROLL) { + SCROLLINFO si = { sizeof(si) }; + si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; + if (GetScrollInfo(m_rtf.GetHwnd(), SB_VERT, &si)) { + if (m_rtf.GetHwnd() != GetFocus()) { + si.fMask = SIF_POS; + si.nPos = si.nMax - si.nPage + 1; + SetScrollInfo(m_rtf.GetHwnd(), SB_VERT, &si, TRUE); + + PostMessage(m_rtf.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0); + } + } + } +} + +void CLogWindow::UpdateOptions() +{ + if (m_pDlg.isChat()) + m_rtf.SendMsg(EM_SETBKGNDCOLOR, 0, g_Settings.crLogBackground); + else + m_rtf.SendMsg(EM_SETBKGNDCOLOR, 0, g_plugin.getDword(SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR)); + + PARAFORMAT2 pf2; + memset(&pf2, 0, sizeof(pf2)); + pf2.cbSize = sizeof(pf2); + pf2.dwMask = PFM_OFFSET; + pf2.dxOffset = (g_dat.flags.bIndentText) ? g_dat.indentSize * 1440 / g_dat.logPixelSX : 0; + m_rtf.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); + m_rtf.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_rtf.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~(IMF_AUTOKEYBOARD | IMF_AUTOFONTSIZEADJUST)); + + Clear(); +} + +CSrmmLogWindow *logBuilder(CMsgDialog &pDlg) +{ + return new CLogWindow(pDlg); +} diff --git a/plugins/Scriver/src/msgoptions.cpp b/plugins/Scriver/src/msgoptions.cpp index 09f89361da..d9f654c03e 100644 --- a/plugins/Scriver/src/msgoptions.cpp +++ b/plugins/Scriver/src/msgoptions.cpp @@ -519,15 +519,15 @@ public: class CLogOptionsDlg : public CBaseOptionDlg { CCtrlSpin spinCount, spinTime, spinIndent; - CCtrlCheck chkLoadUnread, chkLoadCount, chkLoadTime, chkUseIeview; + CCtrlCheck chkLoadUnread, chkLoadCount, chkLoadTime; CCtrlCheck chkShowIcons, chkShowTime, chkShowSecs, chkShowDate, chkLongDate, chkRelativeDate; CCtrlCheck chkGroupMsg, chkIndentText, chkHideNames, chkMarkFollowups, chkMsgOnNewline, chkDrawLines; - CCtrlRichEdit m_log; + CCtrlRichEdit m_rtf; CCtrlHyperlink m_fonts; void OnChange() override { - m_log.SetText(L""); + m_rtf.SetText(L""); struct GlobalMessageData gdat = {}; gdat.flags.bShowIcons = chkShowIcons.GetState(); @@ -548,15 +548,15 @@ class CLogOptionsDlg : public CBaseOptionDlg pf2.cbSize = sizeof(pf2); pf2.dwMask = PFM_OFFSET; pf2.dxOffset = (gdat.flags.bIndentText) ? gdat.indentSize * 1440 / g_dat.logPixelSX : 0; - m_log.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); + m_rtf.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); - StreamInTestEvents(m_log.GetHwnd(), &gdat); + StreamInTestEvents(m_rtf.GetHwnd(), &gdat); } public: CLogOptionsDlg() : CBaseOptionDlg(IDD_OPT_MSGLOG), - m_log(this, IDC_SRMM_LOG), + m_rtf(this, IDC_SRMM_LOG), m_fonts(this, IDC_FONTSCOLORS), chkShowTime(this, IDC_SHOWTIMES), chkShowSecs(this, IDC_SHOWSECONDS), @@ -569,7 +569,6 @@ public: chkShowIcons(this, IDC_SHOWLOGICONS), chkIndentText(this, IDC_INDENTTEXT), chkHideNames(this, IDC_HIDENAMES), - chkUseIeview(this, IDC_USEIEVIEW), chkMsgOnNewline(this, IDC_MESSAGEONNEWLINE), chkLoadTime(this, IDC_LOADTIME), chkLoadCount(this, IDC_LOADCOUNT), @@ -585,7 +584,6 @@ public: CreateLink(chkShowDate, g_plugin.bShowDate); CreateLink(chkLongDate, g_plugin.bLongDate); CreateLink(chkGroupMsg, g_plugin.bGroupMessages); - CreateLink(chkUseIeview, g_plugin.bUseIeview); CreateLink(chkShowIcons, g_plugin.bShowIcons); CreateLink(chkHideNames, g_plugin.bHideNames); CreateLink(chkDrawLines, g_plugin.bDrawLines); @@ -618,11 +616,8 @@ public: CheckDlgButton(m_hwnd, IDC_LOADTIME, BST_CHECKED); break; } - onChange_Time(0); - - if (!g_dat.ieviewInstalled) - EnableWindow(GetDlgItem(m_hwnd, IDC_USEIEVIEW), FALSE); + onChange_Time(0); onChange_Times(0); onChange_Dates(0); onChange_GroupMsg(0); @@ -634,12 +629,12 @@ public: pf2.dwMask = PFM_OFFSETINDENT | PFM_RIGHTINDENT; pf2.dxStartIndent = 30; pf2.dxRightIndent = 30; - m_log.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); + m_rtf.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); - m_log.SendMsg(EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, SES_EXTENDBACKCOLOR); - m_log.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0, 0)); - m_log.SendMsg(EM_AUTOURLDETECT, TRUE, 0); - m_log.SetReadOnly(true); + m_rtf.SendMsg(EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, SES_EXTENDBACKCOLOR); + m_rtf.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0, 0)); + m_rtf.SendMsg(EM_AUTOURLDETECT, TRUE, 0); + m_rtf.SetReadOnly(true); OnChange(); return true; diff --git a/plugins/Scriver/src/msgs.cpp b/plugins/Scriver/src/msgs.cpp index c2124f33f4..a2175f52e5 100644 --- a/plugins/Scriver/src/msgs.cpp +++ b/plugins/Scriver/src/msgs.cpp @@ -464,7 +464,6 @@ int RegisterToolbarIcons(WPARAM, LPARAM) static int ModuleLoad(WPARAM, LPARAM) { g_dat.smileyAddInstalled = ServiceExists(MS_SMILEYADD_SHOWSELECTION) && ServiceExists(MS_SMILEYADD_REPLACESMILEYS); - g_dat.ieviewInstalled = ServiceExists(MS_IEVIEW_WINDOW); return 0; } diff --git a/plugins/Scriver/src/msgs.h b/plugins/Scriver/src/msgs.h index d404942836..57a25aafd6 100644 --- a/plugins/Scriver/src/msgs.h +++ b/plugins/Scriver/src/msgs.h @@ -23,6 +23,31 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef SRMM_MSGS_H #define SRMM_MSGS_H +///////////////////////////////////////////////////////////////////////////////////////// +// CLogWindow - built-in log window + +class CLogWindow : public CRtfLogWindow +{ + typedef CRtfLogWindow CSuper; + +public: + CLogWindow(CMsgDialog &pDlg) : + CSuper(pDlg) + { + } + + void Attach() override; + void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) override; + void LogEvents(DBEVENTINFO *dbei, bool bAppend) override; + void LogEvents(struct LOGINFO *, bool) override; + void ScrollToBottom() override; + void UpdateOptions() override; + + INT_PTR WndProc(UINT msg, WPARAM wParam, LPARAM lParam) override; +}; + +///////////////////////////////////////////////////////////////////////////////////////// + #define MSGERROR_CANCEL 0 #define MSGERROR_RETRY 1 #define MSGERROR_DONE 2 @@ -60,6 +85,7 @@ class CMsgDialog : public CSrmmBaseDialog { typedef CSrmmBaseDialog CSuper; + friend class CLogWindow; friend struct ParentWindowData; friend INT_PTR CALLBACK InfobarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); @@ -75,7 +101,6 @@ class CMsgDialog : public CSrmmBaseDialog void ShowAvatar(void); void SetDialogToType(void); void SetStatusIcon(void); - void StreamInEvents(MEVENT hDbEventFirst, int count, int fAppend); void ToggleRtl(); void UpdateIcon(void); void UpdateReadChars(void); @@ -102,14 +127,13 @@ class CMsgDialog : public CSrmmBaseDialog time_t m_startTime, m_lastEventTime; int m_lastEventType; int m_isMixed; - bool m_bUseRtl, m_bUseIEView; + bool m_bUseRtl; HBITMAP m_hbmpAvatarPic; AVATARCACHEENTRY *m_ace; TCmdList *cmdList, *cmdListCurrent; ParentWindowData *m_pParent; - HWND m_hwndIeview; // info bar support HWND m_hwndInfo; @@ -153,10 +177,8 @@ public: void CloseTab() override; void LoadSettings() override; - void ScrollToBottom() override; void SetStatusText(const wchar_t *, HICON) override; void ShowFilterMenu() override; - void StreamInEvents(LOGINFO *lin, bool bRedraw) override; void UpdateNickList() override; void UpdateOptions() override; void UpdateStatusBar() override; @@ -172,20 +194,23 @@ public: void StopMessageSending(void); void ShowMessageSending(void); - LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override; LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override; LRESULT WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) override; - __forceinline bool IsActive() const - { return GetActiveWindow() == m_hwndParent && GetForegroundWindow() == m_hwndParent && m_pParent->m_hwndActive == m_hwnd; + __forceinline bool IsActive() const { + return GetActiveWindow() == m_hwndParent && GetForegroundWindow() == m_hwndParent && m_pParent->m_hwndActive == m_hwnd; + } + + __forceinline void PopupWindow(bool bIncoming = false) { + m_pParent->PopupWindow(this, bIncoming); } - __forceinline void PopupWindow(bool bIncoming = false) - { m_pParent->PopupWindow(this, bIncoming); + __forceinline void StartFlashing() const { + m_pParent->StartFlashing(); } - __forceinline void StartFlashing() const - { m_pParent->StartFlashing(); + __forceinline CLogWindow *LOG() { + return ((CLogWindow *)m_pLog); } wchar_t *m_wszInitialText; diff --git a/plugins/Scriver/src/msgutils.cpp b/plugins/Scriver/src/msgutils.cpp index 71fea672d6..47dc5e8de8 100644 --- a/plugins/Scriver/src/msgutils.cpp +++ b/plugins/Scriver/src/msgutils.cpp @@ -25,16 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. void CMsgDialog::ClearLog() { - if (m_hwndIeview != nullptr) { - IEVIEWEVENT evt = { sizeof(evt) }; - evt.iType = IEE_CLEAR_LOG; - evt.dwFlags = (m_bUseRtl) ? IEEF_RTL : 0; - evt.hwnd = m_hwndIeview; - evt.hContact = m_hContact; - evt.pszProto = m_szProto; - CallService(MS_IEVIEW_EVENT, 0, (LPARAM)& evt); - } - else CSuper::ClearLog(); + CSuper::ClearLog(); m_hDbEventFirst = 0; m_lastEventType = -1; @@ -218,31 +209,6 @@ void CMsgDialog::Reattach(HWND hwndContainer) ///////////////////////////////////////////////////////////////////////////////////////// -void CMsgDialog::ScrollToBottom() -{ - if (m_hwndIeview != nullptr) { - IEVIEWWINDOW ieWindow = {}; - ieWindow.iType = IEW_SCROLLBOTTOM; - ieWindow.hwnd = m_hwndIeview; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - return; - } - - if (GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL) { - SCROLLINFO si = { sizeof(si) }; - si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; - if (GetScrollInfo(m_log.GetHwnd(), SB_VERT, &si)) { - if (m_log.GetHwnd() != GetFocus()) { - si.fMask = SIF_POS; - si.nPos = si.nMax - si.nPage + 1; - SetScrollInfo(m_log.GetHwnd(), SB_VERT, &si, TRUE); - - PostMessage(m_log.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0); - } - } - } -} - void CMsgDialog::SetDialogToType() { if (!isChat()) { @@ -257,8 +223,6 @@ void CMsgDialog::SetDialogToType() } m_message.Show(); - m_log.Show(m_hwndIeview == nullptr); - m_splitterY.Show(); m_btnOk.Enable(m_message.GetRichTextLength() != 0); Resize(); @@ -439,12 +403,12 @@ void CMsgDialog::ToggleRtl() if (m_bUseRtl) { pf2.wEffects = PFE_RTLPARA; SetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE) | WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR); - SetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE) | WS_EX_LEFTSCROLLBAR); + SetWindowLongPtr(m_pLog->GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_pLog->GetHwnd(), GWL_EXSTYLE) | WS_EX_LEFTSCROLLBAR); } else { pf2.wEffects = 0; SetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE) & ~(WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR)); - SetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE) & ~(WS_EX_LEFTSCROLLBAR)); + SetWindowLongPtr(m_pLog->GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_pLog->GetHwnd(), GWL_EXSTYLE) & ~(WS_EX_LEFTSCROLLBAR)); } m_message.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); SendMessage(m_hwnd, DM_REMAKELOG, 0, 0); @@ -493,7 +457,7 @@ void CMsgDialog::UpdateOptions() UpdateTitle(); FixTabIcons(); - m_log.SendMsg(EM_SETBKGNDCOLOR, 0, g_Settings.crLogBackground); + m_pLog->UpdateOptions(); // messagebox COLORREF crFore; diff --git a/plugins/Scriver/src/resource.h b/plugins/Scriver/src/resource.h index 5c449cdd48..14f62efbaa 100644 --- a/plugins/Scriver/src/resource.h +++ b/plugins/Scriver/src/resource.h @@ -91,7 +91,6 @@ #define IDC_SHOWSECONDS 1023 #define IDC_USELONGDATE 1024 #define IDC_USERELATIVEDATE 1025 -#define IDC_USEIEVIEW 1026 #define IDC_FONTSCOLORS 1027 #define IDC_LOADUNREAD 1031 #define IDC_SHOWLOGICONS 1032 diff --git a/plugins/Scriver/src/srmm.cpp b/plugins/Scriver/src/srmm.cpp index cb054873c2..b687894c75 100644 --- a/plugins/Scriver/src/srmm.cpp +++ b/plugins/Scriver/src/srmm.cpp @@ -54,7 +54,6 @@ CMPlugin::CMPlugin() : bTypingNew(SRMM_MODULE, "DefaultTyping", 1), bAutoClose(SRMM_MODULE, "AutoClose", 0), bAutoPopup(SRMM_MODULE, "AutoPopupMsg", 0), - bUseIeview(SRMM_MODULE, "UseIEView", 1), bSaveDrafts(SRMM_MODULE, "SaveDrafts", 0), bTypingUnknown(SRMM_MODULE, "UnknownTyping", 0), bHideContainer(SRMM_MODULE, "HideContainers", 0), @@ -125,6 +124,17 @@ int CMPlugin::Load() if (IsWinVer7Plus()) CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_ALL, IID_ITaskbarList3, (void**)&pTaskbarInterface); + hLogger = RegisterSrmmLog("built-in", L"Scriver internal log", &logBuilder); + + switch (getByte("UseIEView", -1)) { + case 1: + setString("Logger", "ieview"); + __fallthrough; + + case 0: + delSetting("UseIEView"); + } + return OnLoadModule(); } @@ -132,6 +142,7 @@ int CMPlugin::Load() int CMPlugin::Unload() { + UnregisterSrmmLog(hLogger); if (pTaskbarInterface) pTaskbarInterface->Release(); return OnUnloadModule(); diff --git a/plugins/Scriver/src/stdafx.h b/plugins/Scriver/src/stdafx.h index 45fd0c664f..62c24c9887 100644 --- a/plugins/Scriver/src/stdafx.h +++ b/plugins/Scriver/src/stdafx.h @@ -70,8 +70,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. struct CMPlugin : public PLUGIN { + HANDLE hLogger; + CMOption bSavePerContact, bCascade, bStayMinimized, bAutoMin, bSaveDrafts, bDelTemp, bHideContainer, bAutoPopup; - CMOption bUseIeview, bUseTransparency, bTopmost, bAutoClose, bTypingNew, bTypingUnknown; + CMOption bUseTransparency, bTopmost, bAutoClose, bTypingNew, bTypingUnknown; CMOption bShowTitleBar, bShowStatusBar, bShowToolBar, bShowInfoBar; CMOption bShowAvatar, bShowProgress, bShowIcons, bShowTime, bShowSeconds, bShowDate, bLongDate, bRelativeDate; CMOption bGroupMessages, bMarkFollowups, bMsgOnNewline, bDrawLines, bHideNames, bIndentText; @@ -124,6 +126,8 @@ int OptInitialise(WPARAM wParam, LPARAM lParam); int FontServiceFontsChanged(WPARAM wParam, LPARAM lParam); int StatusIconPressed(WPARAM wParam, LPARAM lParam); +CSrmmLogWindow *logBuilder(CMsgDialog &pDlg); + #include "cmdlist.h" #include "sendqueue.h" #include "globals.h" diff --git a/plugins/Scriver/src/tabs.cpp b/plugins/Scriver/src/tabs.cpp index d8b7ea07dc..d12206e9e4 100644 --- a/plugins/Scriver/src/tabs.cpp +++ b/plugins/Scriver/src/tabs.cpp @@ -196,7 +196,7 @@ void ParentWindowData::ActivateChild(CMsgDialog *pDlg) pDlg->UpdateTitle(); SendMessage(m_hwndActive, WM_SIZE, 0, 0); ShowWindow(m_hwndActive, SW_SHOWNOACTIVATE); - pDlg->ScrollToBottom(); + pDlg->m_pLog->ScrollToBottom(); if (hwndPrev != nullptr) ShowWindow(hwndPrev, SW_HIDE); } diff --git a/plugins/TabSRMM/res/resource.rc b/plugins/TabSRMM/res/resource.rc index 6ac69add5d..18eac86202 100644 --- a/plugins/TabSRMM/res/resource.rc +++ b/plugins/TabSRMM/res/resource.rc @@ -143,31 +143,28 @@ BEGIN CONTROL "",IDC_MSGTABS,"TSTabCtrlClass",0xc048,31,7,5,5 END -IDD_USERPREFS DIALOGEX 0, 0, 316, 265 +IDD_USERPREFS DIALOGEX 0, 0, 316, 148 STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CAPTION CAPTION "Dialog" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - GROUPBOX "Message log view mode (does not affect open windows)",IDC_STATIC,4,5,310,39 - COMBOBOX IDC_IEVIEWMODE,8,25,128,46,CBS_DROPDOWNLIST | WS_VSCROLL | WS_GROUP | WS_TABSTOP - LTEXT "Select how to display the message log. This setting can be ignored when one of the listed plugins is not installed.",IDC_STATIC,143,17,164,24 - GROUPBOX "Send text formatting method",IDC_STATIC,4,45,310,33 - COMBOBOX IDC_TEXTFORMATTING,8,57,128,46,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "You can override the global setting for text formatting here. Use ""Force off"" to never send formatting info for this contact.",IDC_STATIC,143,52,164,24 - GROUPBOX "Other options",IDC_STATIC,4,118,310,142 - LTEXT "Info panel mode",IDC_STATIC,12,128,128,8 - COMBOBOX IDC_INFOPANEL,9,138,130,46,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Show avatar in message window",IDC_STATIC,12,158,127,8 - COMBOBOX IDC_SHOWAVATAR,9,169,130,46,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Send text formatting method",IDC_STATIC,4,0,310,33 + COMBOBOX IDC_TEXTFORMATTING,8,12,128,46,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "You can override the global setting for text formatting here. Use ""Force off"" to never send formatting info for this contact.",IDC_STATIC,143,7,164,24 + GROUPBOX "Other options",IDC_STATIC,4,34,310,112 + LTEXT "Info panel mode",IDC_STATIC,12,44,128,8 + COMBOBOX IDC_INFOPANEL,9,54,130,46,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Show avatar in message window",IDC_STATIC,12,113,127,8 + COMBOBOX IDC_SHOWAVATAR,9,85,130,46,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Use private splitter position",IDC_PRIVATESPLITTER, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,187,296,12 - CONTROL "Contact is a favorite contact",IDC_ISFAVORITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,199,297,12 - CONTROL "Ignore sending timeouts",IDC_IGNORETIMEOUTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,154,164,12 - CONTROL "Load only actual history",IDC_LOADONLYACTUAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,166,164,12 - CONTROL "Always trim message log to",IDC_ALWAYSTRIM2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,214,163,12 - EDITTEXT IDC_TRIM,178,213,33,12,ES_RIGHT | ES_NUMBER | WS_DISABLED - CONTROL "",IDC_TRIMSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK | WS_DISABLED,213,207,10,14 - LTEXT "events",IDC_STATIC,215,215,64,8 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,103,296,12 + CONTROL "Contact is a favorite contact",IDC_ISFAVORITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,115,297,12 + CONTROL "Ignore sending timeouts",IDC_IGNORETIMEOUTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,70,164,12 + CONTROL "Load only actual history",IDC_LOADONLYACTUAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,82,164,12 + CONTROL "Always trim message log to",IDC_ALWAYSTRIM2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,130,163,12 + EDITTEXT IDC_TRIM,178,129,33,12,ES_RIGHT | ES_NUMBER | WS_DISABLED + CONTROL "",IDC_TRIMSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK | WS_DISABLED,207,129,11,14 + LTEXT "events",IDC_STATIC,215,131,64,8 END IDD_CONTAINEROPTIONS DIALOGEX 0, 0, 428, 258 @@ -277,14 +274,14 @@ EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN GROUPBOX "Options",IDC_STATIC,3,0,300,106 - CONTROL "",IDC_LOGOPTIONS,"SysTreeView32",TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,6,9,294,94 - GROUPBOX "Indent values",IDC_STMSGLOGGROUP2,3,107,145,29 - LTEXT "Left/Right",IDC_STATIC,10,119,48,11 - EDITTEXT IDC_INDENTAMOUNT,60,117,29,12,ES_AUTOHSCROLL - CONTROL "",IDC_INDENTSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_HOTTRACK,72,120,10,11 - EDITTEXT IDC_RIGHTINDENT,94,117,29,12,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_RINDENTSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,113,118,10,11 - CTEXT "px",IDC_STATIC,124,119,21,9 + CONTROL "",IDC_LOGOPTIONS,"SysTreeView32",TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | WS_BORDER | WS_HSCROLL | WS_TABSTOP,6,9,294,94 + GROUPBOX "Indent values",IDC_STMSGLOGGROUP2,3,107,300,29 + LTEXT "Left/Right",IDC_STATIC,10,119,83,10 + EDITTEXT IDC_INDENTAMOUNT,95,118,29,12,ES_AUTOHSCROLL + CONTROL "",IDC_INDENTSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_HOTTRACK,124,118,10,11 + EDITTEXT IDC_RIGHTINDENT,146,118,29,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_RINDENTSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,175,118,10,11 + LTEXT "px",IDC_STATIC,193,119,49,9 GROUPBOX "Template sets",IDC_STMSGLOGGROUP,3,138,300,26 PUSHBUTTON "Standard templates...",IDC_MODIFY,27,147,95,14 PUSHBUTTON "RTL templates...",IDC_RTLMODIFY,178,147,95,14 @@ -301,9 +298,6 @@ BEGIN CONTROL "",IDC_TRIMSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK | WS_DISABLED,200,209,10,14 LTEXT "events",IDC_STATIC,210,212,82,8 LTEXT "minutes old",IDC_STMINSOLD,210,200,83,8,WS_DISABLED - GROUPBOX "Global message log display",IDC_STMSGLOGGROUP3,149,107,147,29 - COMBOBOX IDC_MSGLOGDIDSPLAY,155,117,135,46,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Static",IDC_EXPLAINMSGLOGSETTINGS,31,25,240,59 END IDD_OPT_MSGTYPE DIALOGEX 0, 0, 283, 251 @@ -771,8 +765,6 @@ IDR_MENUBAR MENU BEGIN POPUP "&File" BEGIN - MENUITEM "Save message log as...", ID_FILE_SAVEMESSAGELOGAS - MENUITEM SEPARATOR MENUITEM "Close message session\tCtrl+W", ID_FILE_CLOSEMESSAGESESSION MENUITEM "Close container\tAlt+F4", ID_FILE_CLOSE END diff --git a/plugins/TabSRMM/src/chat.h b/plugins/TabSRMM/src/chat.h index 8d9910dfed..928aeb6317 100644 --- a/plugins/TabSRMM/src/chat.h +++ b/plugins/TabSRMM/src/chat.h @@ -29,6 +29,9 @@ //defines +#define CLICKNICK_BEGIN L"~~++#" +#define CLICKNICK_END L"#++~~" + enum TChatStatusEx { CHAT_STATUS_NORMAL, diff --git a/plugins/TabSRMM/src/chat_log.cpp b/plugins/TabSRMM/src/chat_log.cpp index f8e2c4b951..302ff08645 100644 --- a/plugins/TabSRMM/src/chat_log.cpp +++ b/plugins/TabSRMM/src/chat_log.cpp @@ -34,296 +34,7 @@ * the srmm module and then modified to fit the chat module. */ -static char *szDivider = "\\strike----------------------------------------------------------------------------\\strike0"; - -/* - * ieview MUC support - mostly from scriver - */ - -/* - -static char* u2a(const wchar_t* src, int codepage) -{ - int cbLen = WideCharToMultiByte(codepage, 0, src, -1, nullptr, 0, nullptr, nullptr); - char* result = (char*)mir_alloc(cbLen + 1); - if (result == nullptr) - return nullptr; - - WideCharToMultiByte(codepage, 0, src, -1, result, cbLen, nullptr, nullptr); - result[cbLen] = 0; - return result; -} - -static char* t2acp(const wchar_t* src, int codepage) -{ - return u2a(src, codepage); -} - -static wchar_t *a2tcp(const char *text, int cp) -{ - if (text != nullptr) { - int cbLen = MultiByteToWideChar(cp, 0, text, -1, nullptr, 0); - wchar_t* result = (wchar_t*)mir_alloc(sizeof(wchar_t)*(cbLen + 1)); - if (result == nullptr) - return nullptr; - MultiByteToWideChar(cp, 0, text, -1, result, cbLen); - return result; - } - return nullptr; -} - -static int Log_AppendIEView(LOGSTREAMDATA* streamData, BOOL simpleMode, wchar_t **buffer, int *cbBufferEnd, int *cbBufferAlloced, const wchar_t *fmt, ...) -{ - va_list va; - int lineLen, textCharsCount = 0; - wchar_t* line = (wchar_t*)_alloca(8001 * sizeof(wchar_t)); - wchar_t* d; - MODULEINFO *mi = streamData->si->pMI; - - va_start(va, fmt); - lineLen = mir_vsnwprintf(line, 8000, fmt, va); - if (lineLen < 0) - return 0; - line[lineLen] = 0; - va_end(va); - lineLen = lineLen * 9 + 8; - if (*cbBufferEnd + lineLen > *cbBufferAlloced) { - cbBufferAlloced[0] += (lineLen + 1024 - lineLen % 1024); - *buffer = (wchar_t*)mir_realloc(*buffer, *cbBufferAlloced * sizeof(wchar_t)); - } - - d = *buffer + *cbBufferEnd; - - for (; *line; line++, textCharsCount++) { - if (*line == '%' && !simpleMode) { - wchar_t szTemp[200]; - - szTemp[0] = '\0'; - switch (*++line) { - case '\0': - case '%': - *d++ = '%'; - break; - - case 'c': - case 'f': - if (!g_Settings.bStripFormat && !streamData->bStripFormat) { - if (line[1] != '\0' && line[2] != '\0') { - wchar_t szTemp3[3], c = *line; - int col; - szTemp3[0] = line[1]; - szTemp3[1] = line[2]; - szTemp3[2] = '\0'; - col = _wtoi(szTemp3); - mir_snwprintf(szTemp, L"%%%c#%02X%02X%02X", c, GetRValue(mi->crColors[col]), GetGValue(mi->crColors[col]), GetBValue(mi->crColors[col])); - } - } - line += 2; - break; - case 'C': - case 'F': - if (!g_Settings.bStripFormat && !streamData->bStripFormat) { - mir_snwprintf(szTemp, L"%%%c", *line); - } - break; - case 'b': - case 'u': - case 'i': - case 'B': - case 'U': - case 'I': - case 'r': - if (!streamData->bStripFormat) { - mir_snwprintf(szTemp, L"%%%c", *line); - } - break; - } - - if (szTemp[0]) { - size_t iLen = mir_wstrlen(szTemp); - memcpy(d, szTemp, iLen * sizeof(wchar_t)); - d += iLen; - } - } - else if (*line == '%') { - *d++ = '%'; - *d++ = (char)*line; - } - else { - *d++ = (wchar_t)*line; - } - } - *d = '\0'; - *cbBufferEnd = (int)(d - *buffer); - return textCharsCount; -} - -static void AddEventTextToBufferIEView(wchar_t **buffer, int *bufferEnd, int *bufferAlloced, LOGSTREAMDATA *streamData) -{ - if (streamData->lin->ptszText) - Log_AppendIEView(streamData, FALSE, str, L": %s", streamData->lin->ptszText); -} - -static void AddEventToBufferIEView(wchar_t **buffer, int *bufferEnd, int *bufferAlloced, LOGSTREAMDATA *streamData, wchar_t *pszNick) -{ - - if (streamData && streamData->lin) { - switch (streamData->lin->iType) { - case GC_EVENT_MESSAGE: - if (streamData->lin->ptszText) { - wchar_t *ptszTemp = nullptr; - wchar_t *ptszText = streamData->lin->ptszText; - if (streamData->dat->codePage != CP_ACP) { - char *aText = t2acp(streamData->lin->ptszText, CP_ACP); - ptszText = ptszTemp = a2tcp(aText, streamData->dat->codePage); - mir_free(aText); - } - Log_AppendIEView(streamData, FALSE, str, L"%s", ptszText); - mir_free(ptszTemp); - } - break; - case GC_EVENT_ACTION: - if (pszNick && streamData->lin->ptszText) { - Log_AppendIEView(streamData, TRUE, str, L"%s ", streamData->lin->ptszNick); - Log_AppendIEView(streamData, FALSE, str, L"%s", streamData->lin->ptszText); - } - break; - case GC_EVENT_JOIN: - if (pszNick) { - if (!streamData->lin->bIsMe) - Log_AppendIEView(streamData, TRUE, str, TranslateT("%s has joined"), pszNick); - else - Log_AppendIEView(streamData, TRUE, str, TranslateT("You have joined %s"), streamData->si->ptszName); - } - break; - case GC_EVENT_PART: - if (pszNick) - Log_AppendIEView(streamData, TRUE, str, TranslateT("%s has left"), pszNick); - AddEventTextToBufferIEView(str, streamData); - break; - case GC_EVENT_QUIT: - if (pszNick) - Log_AppendIEView(streamData, TRUE, str, TranslateT("%s has disconnected"), pszNick); - AddEventTextToBufferIEView(str, streamData); - break; - case GC_EVENT_NICK: - if (pszNick && streamData->lin->ptszText) { - if (!streamData->lin->bIsMe) - Log_AppendIEView(streamData, TRUE, str, TranslateT("%s is now known as %s"), pszNick, streamData->lin->ptszText); - else - Log_AppendIEView(streamData, TRUE, str, TranslateT("You are now known as %s"), streamData->lin->ptszText); - } - break; - case GC_EVENT_KICK: - if (pszNick && streamData->lin->ptszStatus) - Log_AppendIEView(streamData, TRUE, str, TranslateT("%s kicked %s"), streamData->lin->ptszStatus, streamData->lin->ptszNick); - AddEventTextToBufferIEView(str, streamData); - break; - case GC_EVENT_NOTICE: - if (pszNick && streamData->lin->ptszText) { - Log_AppendIEView(streamData, TRUE, str, TranslateT("Notice from %s"), pszNick); - AddEventTextToBufferIEView(str, streamData); - } - break; - case GC_EVENT_TOPIC: - if (streamData->lin->ptszText) - Log_AppendIEView(streamData, FALSE, str, TranslateT("The topic is '%s%s'"), streamData->lin->ptszText, L"%r"); - if (pszNick) - Log_AppendIEView(streamData, TRUE, str, - streamData->lin->ptszUserInfo ? TranslateT(" (set by %s on %s)") : TranslateT(" (set by %s)"), - pszNick, streamData->lin->ptszUserInfo); - break; - case GC_EVENT_INFORMATION: - if (streamData->lin->ptszText) - Log_AppendIEView(streamData, FALSE, str, (streamData->lin->bIsMe) ? L"--> %s" : L"%s", streamData->lin->ptszText); - break; - case GC_EVENT_ADDSTATUS: - if (pszNick && streamData->lin->ptszText && streamData->lin->ptszStatus) - Log_AppendIEView(streamData, TRUE, str, TranslateT("%s enables '%s' status for %s"), streamData->lin->ptszText, streamData->lin->ptszStatus, streamData->lin->ptszNick); - break; - case GC_EVENT_REMOVESTATUS: - if (pszNick && streamData->lin->ptszText && streamData->lin->ptszStatus) - Log_AppendIEView(streamData, TRUE, str, TranslateT("%s disables '%s' status for %s"), streamData->lin->ptszText, streamData->lin->ptszStatus, streamData->lin->ptszNick); - break; - } - } -} - -static void LogEventIEView(LOGSTREAMDATA *streamData, wchar_t *ptszNick) -{ - wchar_t *buffer = nullptr; - int bufferEnd = 0; - int bufferAlloced = 0; - IEVIEWEVENTDATA ied; - IEVIEWEVENT event; - memset(&event, 0, sizeof(event)); - event.cbSize = sizeof(event); - event.dwFlags = 0; - event.hwnd = streamData->dat->m_hwndIEView ? streamData->dat->m_hwndIEView : streamData->dat->m_hwndHPP; - event.hContact = streamData->dat->m_hContact; - event.codepage = streamData->dat->codePage; - event.pszProto = streamData->si->pszModule; - event.iType = IEE_LOG_MEM_EVENTS; - event.eventData = &ied; - event.count = 1; - - memset(&ied, 0, sizeof(ied)); - AddEventToBufferIEView(str, streamData, ptszNick); - ied.ptszNick = ptszNick; - ied.ptszText = buffer; - ied.time = streamData->lin->time; - ied.bIsMe = streamData->lin->bIsMe; - - switch (streamData->lin->iType) { - case GC_EVENT_MESSAGE: - ied.iType = IEED_GC_EVENT_MESSAGE; - ied.dwData = IEEDD_GC_SHOW_NICK; - break; - case GC_EVENT_ACTION: - ied.iType = IEED_GC_EVENT_ACTION; - break; - case GC_EVENT_JOIN: - ied.iType = IEED_GC_EVENT_JOIN; - break; - case GC_EVENT_PART: - ied.iType = IEED_GC_EVENT_PART; - break; - case GC_EVENT_QUIT: - ied.iType = IEED_GC_EVENT_QUIT; - break; - case GC_EVENT_NICK: - ied.iType = IEED_GC_EVENT_NICK; - break; - case GC_EVENT_KICK: - ied.iType = IEED_GC_EVENT_KICK; - break; - case GC_EVENT_NOTICE: - ied.iType = IEED_GC_EVENT_NOTICE; - break; - case GC_EVENT_TOPIC: - ied.iType = IEED_GC_EVENT_TOPIC; - break; - case GC_EVENT_INFORMATION: - ied.iType = IEED_GC_EVENT_INFORMATION; - break; - case GC_EVENT_ADDSTATUS: - ied.iType = IEED_GC_EVENT_ADDSTATUS; - break; - case GC_EVENT_REMOVESTATUS: - ied.iType = IEED_GC_EVENT_REMOVESTATUS; - break; - } - ied.dwData |= g_Settings.bShowTime ? IEEDD_GC_SHOW_TIME : 0; - ied.dwData |= IEEDD_GC_SHOW_ICON; - ied.dwFlags = IEEDF_UNICODE_TEXT | IEEDF_UNICODE_NICK | IEEDF_UNICODE_TEXT2; - ied.next = nullptr; - CallService(streamData->dat->m_hwndIEView ? MS_IEVIEW_EVENT : MS_HPP_EG_EVENT, 0, (LPARAM)&event); - mir_free(buffer); -} - -*/ - -static int EventToIndex(LOGINFO * lin) +static int EventToIndex(LOGINFO *lin) { switch (lin->iType) { case GC_EVENT_MESSAGE: @@ -387,7 +98,7 @@ static BYTE EventToSymbol(LOGINFO *lin) return 0x73; } -static int EventToIcon(LOGINFO * lin) +static int EventToIcon(LOGINFO *lin) { switch (lin->iType) { case GC_EVENT_MESSAGE: @@ -425,7 +136,7 @@ static int EventToIcon(LOGINFO * lin) static void Log_AppendRTF(LOGSTREAMDATA *streamData, BOOL simpleMode, CMStringA &str, const wchar_t *fmt, ...) { int textCharsCount = 0; - wchar_t *line = (wchar_t*)_alloca(8001 * sizeof(wchar_t)); + wchar_t *line = (wchar_t *)_alloca(8001 * sizeof(wchar_t)); va_list va; va_start(va, fmt); @@ -512,7 +223,7 @@ static void Log_AppendRTF(LOGSTREAMDATA *streamData, BOOL simpleMode, CMStringA else if (*line > 0 && *line < 128) { res.AppendChar((char)*line); } - else res.AppendFormat("\\u%u ?", (WORD)* line); + else res.AppendFormat("\\u%u ?", (WORD)*line); } str += res; @@ -520,32 +231,24 @@ static void Log_AppendRTF(LOGSTREAMDATA *streamData, BOOL simpleMode, CMStringA static void AddEventToBuffer(CMStringA &str, LOGSTREAMDATA *streamData) { - wchar_t szTemp[512], szTemp2[512]; - wchar_t* pszNick = nullptr; - - if (streamData == nullptr) - return; - - if (streamData->lin == nullptr) + if (streamData == nullptr || streamData->lin == nullptr) return; + CMStringW wszNick; if (streamData->lin->ptszNick) { if (g_Settings.bLogLimitNames && mir_wstrlen(streamData->lin->ptszNick) > 20) { - wcsncpy_s(szTemp, 20, streamData->lin->ptszNick, _TRUNCATE); - wcsncpy_s(szTemp + 20, 4, L"...", _TRUNCATE); + wszNick.Append(streamData->lin->ptszNick, 20); + wszNick.Append(L"..."); } - else wcsncpy_s(szTemp, streamData->lin->ptszNick, _TRUNCATE); + else wszNick.Append(streamData->lin->ptszNick); - if (g_Settings.bClickableNicks) - mir_snwprintf(szTemp2, L"~~++#%s#++~~", szTemp); - else - wcsncpy_s(szTemp2, szTemp, _TRUNCATE); + if (g_Settings.bClickableNicks) { + wszNick.Insert(0, CLICKNICK_BEGIN); + wszNick.Append(CLICKNICK_END); + } if (streamData->lin->ptszUserInfo && streamData->lin->iType != GC_EVENT_TOPIC) - mir_snwprintf(szTemp, L"%s (%s)", szTemp2, streamData->lin->ptszUserInfo); - else - wcsncpy_s(szTemp, szTemp2, _TRUNCATE); - pszNick = szTemp; + wszNick.AppendFormat(L" (%s)", streamData->lin->ptszUserInfo); } switch (streamData->lin->iType) { @@ -560,64 +263,64 @@ static void AddEventToBuffer(CMStringA &str, LOGSTREAMDATA *streamData) } break; case GC_EVENT_JOIN: - if (pszNick) { + if (!wszNick.IsEmpty()) { if (!streamData->lin->bIsMe) /* replace nick of a newcomer with a link */ - Log_AppendRTF(streamData, TRUE, str, TranslateT("%s has joined"), pszNick); + Log_AppendRTF(streamData, TRUE, str, TranslateT("%s has joined"), wszNick.c_str()); else Log_AppendRTF(streamData, TRUE, str, TranslateT("You have joined %s"), streamData->si->ptszName); } break; case GC_EVENT_PART: - if (pszNick) - Log_AppendRTF(streamData, TRUE, str, TranslateT("%s has left"), pszNick); + if (!wszNick.IsEmpty()) + Log_AppendRTF(streamData, TRUE, str, TranslateT("%s has left"), wszNick.c_str()); if (streamData->lin->ptszText) Log_AppendRTF(streamData, FALSE, str, L": %s", streamData->lin->ptszText); break; case GC_EVENT_QUIT: - if (pszNick) - Log_AppendRTF(streamData, TRUE, str, TranslateT("%s has disconnected"), pszNick); + if (!wszNick.IsEmpty()) + Log_AppendRTF(streamData, TRUE, str, TranslateT("%s has disconnected"), wszNick.c_str()); if (streamData->lin->ptszText) Log_AppendRTF(streamData, FALSE, str, L": %s", streamData->lin->ptszText); break; case GC_EVENT_NICK: - if (pszNick && streamData->lin->ptszText) { + if (!wszNick.IsEmpty() && streamData->lin->ptszText) { if (!streamData->lin->bIsMe) - Log_AppendRTF(streamData, TRUE, str, TranslateT("%s is now known as %s"), pszNick, streamData->lin->ptszText); + Log_AppendRTF(streamData, TRUE, str, TranslateT("%s is now known as %s"), wszNick.c_str(), streamData->lin->ptszText); else Log_AppendRTF(streamData, TRUE, str, TranslateT("You are now known as %s"), streamData->lin->ptszText); } break; case GC_EVENT_KICK: - if (pszNick && streamData->lin->ptszStatus) - Log_AppendRTF(streamData, TRUE, str, TranslateT("%s kicked %s"), streamData->lin->ptszStatus, pszNick); + if (!wszNick.IsEmpty() && streamData->lin->ptszStatus) + Log_AppendRTF(streamData, TRUE, str, TranslateT("%s kicked %s"), streamData->lin->ptszStatus, wszNick.c_str()); if (streamData->lin->ptszText) Log_AppendRTF(streamData, FALSE, str, L": %s", streamData->lin->ptszText); break; case GC_EVENT_NOTICE: - if (pszNick && streamData->lin->ptszText) { - Log_AppendRTF(streamData, TRUE, str, TranslateT("Notice from %s: "), pszNick); + if (!wszNick.IsEmpty() && streamData->lin->ptszText) { + Log_AppendRTF(streamData, TRUE, str, TranslateT("Notice from %s: "), wszNick.c_str()); Log_AppendRTF(streamData, FALSE, str, L"%s", streamData->lin->ptszText); } break; case GC_EVENT_TOPIC: if (streamData->lin->ptszText) Log_AppendRTF(streamData, FALSE, str, TranslateT("The topic is '%s%s'"), streamData->lin->ptszText, L"%r"); - if (pszNick) - Log_AppendRTF(streamData, TRUE, str, (streamData->lin->ptszUserInfo) ? TranslateT(" (set by %s on %s)") : TranslateT(" (set by %s)"), pszNick, streamData->lin->ptszUserInfo); + if (!wszNick.IsEmpty()) + Log_AppendRTF(streamData, TRUE, str, (streamData->lin->ptszUserInfo) ? TranslateT(" (set by %s on %s)") : TranslateT(" (set by %s)"), wszNick.c_str(), streamData->lin->ptszUserInfo); break; case GC_EVENT_INFORMATION: if (streamData->lin->ptszText) Log_AppendRTF(streamData, FALSE, str, (streamData->lin->bIsMe) ? L"--> %s" : L"%s", streamData->lin->ptszText); break; case GC_EVENT_ADDSTATUS: - if (pszNick && streamData->lin->ptszText && streamData->lin->ptszStatus) - Log_AppendRTF(streamData, TRUE, str, TranslateT("%s enables '%s' status for %s"), streamData->lin->ptszText, streamData->lin->ptszStatus, pszNick); + if (!wszNick.IsEmpty() && streamData->lin->ptszText && streamData->lin->ptszStatus) + Log_AppendRTF(streamData, TRUE, str, TranslateT("%s enables '%s' status for %s"), streamData->lin->ptszText, streamData->lin->ptszStatus, wszNick.c_str()); break; case GC_EVENT_REMOVESTATUS: - if (pszNick && streamData->lin->ptszText && streamData->lin->ptszStatus) - Log_AppendRTF(streamData, TRUE, str, TranslateT("%s disables '%s' status for %s"), streamData->lin->ptszText, streamData->lin->ptszStatus, pszNick); + if (!wszNick.IsEmpty() && streamData->lin->ptszText && streamData->lin->ptszStatus) + Log_AppendRTF(streamData, TRUE, str, TranslateT("%s disables '%s' status for %s"), streamData->lin->ptszText, streamData->lin->ptszStatus, wszNick.c_str()); break; } } @@ -758,7 +461,7 @@ char* Log_CreateRTF(LOGSTREAMDATA *streamData) if (g_Settings.dwIconFlags) str.Append("\\tab "); - //insert timestamp + // insert timestamp if (g_Settings.bShowTime) { wchar_t szTimeStamp[30], szOldTimeStamp[30]; @@ -789,7 +492,7 @@ char* Log_CreateRTF(LOGSTREAMDATA *streamData) pszTemp.Replace(L"%n", L"%s"); if (!lin->bIsMe) { if (g_Settings.bClickableNicks) - pszTemp.Replace(L"%s", L"~~++#%s#++~~"); + pszTemp.Replace(L"%s", CLICKNICK_BEGIN L"%s" CLICKNICK_END); if (g_Settings.bColorizeNicksInLog && pszIndicator[0]) str.AppendFormat("\\cf%u ", OPTIONS_FONTCOUNT + Utils::rtf_clrs.getCount() + streamData->crCount + crNickIndex); @@ -819,164 +522,3 @@ char* Log_CreateRTF(LOGSTREAMDATA *streamData) str.Append("}"); return str.Detach(); } - -void CMsgDialog::StreamInEvents(LOGINFO *lin, bool bRedraw) -{ - if (m_hwnd == nullptr || lin == nullptr || m_si == nullptr) - return; - - LOGSTREAMDATA streamData; - memset(&streamData, 0, sizeof(streamData)); - streamData.hwnd = m_log.GetHwnd(); - streamData.si = m_si; - streamData.lin = lin; - streamData.bStripFormat = FALSE; - streamData.dat = this; - - if (!bRedraw && (m_si->iType == GCW_CHATROOM || m_si->iType == GCW_PRIVMESS) && m_bFilterEnabled && (m_iLogFilterFlags & lin->iType) == 0) - return; - - bool bFlag = false, fDoReplace; - - EDITSTREAM stream = {}; - stream.pfnCallback = Srmm_LogStreamCallback; - stream.dwCookie = (DWORD_PTR)& streamData; - - SCROLLINFO scroll = {}; - scroll.cbSize = sizeof(SCROLLINFO); - scroll.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; - GetScrollInfo(m_log.GetHwnd(), SB_VERT, &scroll); - - POINT point = { 0 }; - m_log.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&point); - - // do not scroll to bottom if there is a selection - CHARRANGE oldsel, sel, newsel; - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldsel); - if (oldsel.cpMax != oldsel.cpMin) - m_log.SendMsg(WM_SETREDRAW, FALSE, 0); - - // set the insertion point at the bottom - sel.cpMin = sel.cpMax = m_log.GetRichTextLength(); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - - // fix for the indent... must be a M$ bug - if (sel.cpMax == 0) - bRedraw = TRUE; - - // should the event(s) be appended to the current log - WPARAM wp = bRedraw ? SF_RTF : SFF_SELECTION | SF_RTF; - - // get the number of pixels per logical inch - if (bRedraw) { - HDC hdc = GetDC(nullptr); - g_chatApi.logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY); - g_chatApi.logPixelSX = GetDeviceCaps(hdc, LOGPIXELSX); - ReleaseDC(nullptr, hdc); - m_log.SendMsg(WM_SETREDRAW, FALSE, 0); - bFlag = true; - } - - // stream in the event(s) - streamData.lin = lin; - streamData.bRedraw = bRedraw; - m_log.SendMsg(EM_STREAMIN, wp, (LPARAM)&stream); - - // for new added events, only replace in message or action events. - // no need to replace smileys or math formulas elsewhere - fDoReplace = (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) { - FINDTEXTEX fi, fi2; - fi.chrg.cpMin = bRedraw ? 0 : sel.cpMin; - fi.chrg.cpMax = -1; - fi.lpstrText = L"~~++#"; - - while (m_log.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) > -1) { - fi2.chrg.cpMin = fi.chrgText.cpMin; - fi2.chrg.cpMax = -1; - fi2.lpstrText = L"#++~~"; - - if (m_log.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi2) > -1) { - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&fi.chrgText); - m_log.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)L""); - - fi2.chrgText.cpMin -= fi.chrgText.cpMax - fi.chrgText.cpMin; - fi2.chrgText.cpMax -= fi.chrgText.cpMax - fi.chrgText.cpMin; - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&fi2.chrgText); - m_log.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)L""); - - fi2.chrgText.cpMax = fi2.chrgText.cpMin; - fi2.chrgText.cpMin = fi.chrgText.cpMin; - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&fi2.chrgText); - - CHARFORMAT2 cf2; - memset(&cf2, 0, sizeof(CHARFORMAT2)); - cf2.cbSize = sizeof(cf2); - cf2.dwMask = CFM_PROTECTED; - cf2.dwEffects = CFE_PROTECTED; - m_log.SendMsg(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); - } - fi.chrg.cpMin = fi.chrgText.cpMax; - } - m_log.SendMsg(EM_SETSEL, -1, -1); - } - - // run smileyadd - if (PluginConfig.g_SmileyAddAvail && fDoReplace) { - newsel.cpMax = -1; - newsel.cpMin = sel.cpMin; - if (newsel.cpMin < 0) - newsel.cpMin = 0; - - SMADD_RICHEDIT3 sm = { sizeof(sm) }; - sm.hwndRichEditControl = m_log.GetHwnd(); - sm.Protocolname = m_si->pszModule; - sm.rangeToReplace = bRedraw ? nullptr : &newsel; - sm.disableRedraw = TRUE; - sm.hContact = m_si->hContact; - CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&sm); - } - - // trim the message log to the number of most recent events - // this uses hidden marks in the rich text to find the events which should be deleted - if (m_si->bTrimmed) { - wchar_t szPattern[50]; - mir_snwprintf(szPattern, L"~-+%p+-~", m_si->pLogEnd); - - FINDTEXTEX fi; - fi.lpstrText = szPattern; - fi.chrg.cpMin = 0; - fi.chrg.cpMax = -1; - if (m_log.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) != 0) { - CHARRANGE rng; - rng.cpMin = 0; - rng.cpMax = 20; - m_log.SendMsg(EM_SETSEL, 0, fi.chrgText.cpMax + 1); - m_log.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)L""); - } - m_si->bTrimmed = false; - } - - // scroll log to bottom if the log was previously scrolled to bottom, else restore old position - if ((bRedraw || (UINT)scroll.nPos >= (UINT)scroll.nMax - scroll.nPage - 5 || scroll.nMax - scroll.nMin - scroll.nPage < 50)) - ScrollToBottom(); - else - m_log.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&point); - - // do we need to restore the selection - if (oldsel.cpMax != oldsel.cpMin) { - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldsel); - m_log.SendMsg(WM_SETREDRAW, TRUE, 0); - InvalidateRect(m_log.GetHwnd(), nullptr, TRUE); - } - - // need to invalidate the window - if (bFlag) { - sel.cpMin = sel.cpMax = m_log.GetRichTextLength(); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - m_log.SendMsg(WM_SETREDRAW, TRUE, 0); - InvalidateRect(m_log.GetHwnd(), nullptr, TRUE); - } -} diff --git a/plugins/TabSRMM/src/container.cpp b/plugins/TabSRMM/src/container.cpp index d7dfa45c66..a0e0c7f5ed 100644 --- a/plugins/TabSRMM/src/container.cpp +++ b/plugins/TabSRMM/src/container.cpp @@ -1200,11 +1200,6 @@ panel_found: SendMessage(pContainer->m_hwndActive, WM_COMMAND, wParam, lParam); // pass the IDOK command to the active child - fixes the "enter not working break; - case ID_FILE_SAVEMESSAGELOGAS: - if (dat) - dat->DM_SaveLogAsRTF(); - break; - case ID_FILE_CLOSEMESSAGESESSION: PostMessage(pContainer->m_hwndActive, WM_CLOSE, 0, 1); break; diff --git a/plugins/TabSRMM/src/generic_msghandlers.cpp b/plugins/TabSRMM/src/generic_msghandlers.cpp index 9e06777e0d..d7087b5911 100644 --- a/plugins/TabSRMM/src/generic_msghandlers.cpp +++ b/plugins/TabSRMM/src/generic_msghandlers.cpp @@ -33,6 +33,7 @@ ///////////////////////////////////////////////////////////////////////////////////////// // Save message log for given session as RTF document +/* void CMsgDialog::DM_SaveLogAsRTF() const { if (m_hwndIEView != nullptr) { @@ -67,10 +68,11 @@ void CMsgDialog::DM_SaveLogAsRTF() const stream.dwCookie = (DWORD_PTR)szFilename; stream.dwError = 0; stream.pfnCallback = Utils::StreamOut; - m_log.SendMsg(EM_STREAMOUT, SF_RTF | SF_USECODEPAGE, (LPARAM)&stream); + m_rtf.SendMsg(EM_STREAMOUT, SF_RTF | SF_USECODEPAGE, (LPARAM)&stream); } } } +*/ ///////////////////////////////////////////////////////////////////////////////////////// // checks if the balloon tooltip can be dismissed (usually called by WM_MOUSEMOVE events) @@ -525,8 +527,6 @@ LRESULT CMsgDialog::DM_MsgWindowCmdHandler(UINT cmd, WPARAM wParam, LPARAM lPara void CMsgDialog::DM_InitRichEdit() { bool fIsChat = isChat(); - - COLORREF colour = fIsChat ? g_Settings.crLogBackground : m_pContainer->m_theme.bg; COLORREF inputcharcolor; char *szStreamOut = nullptr; @@ -534,7 +534,6 @@ void CMsgDialog::DM_InitRichEdit() szStreamOut = m_message.GetRichTextRtf(); SetWindowText(m_message.GetHwnd(), L""); - m_log.SendMsg(EM_SETBKGNDCOLOR, 0, colour); m_message.SendMsg(EM_SETBKGNDCOLOR, 0, m_pContainer->m_theme.inputbg); CHARFORMAT2A cf2; @@ -592,29 +591,12 @@ void CMsgDialog::DM_InitRichEdit() m_message.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); } m_message.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_message.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD); - pf2.wEffects = PFE_RTLPARA; - pf2.dwMask |= PFM_OFFSET; - if (m_dwFlags & MWF_INITMODE) { - pf2.dwMask |= (PFM_RIGHTINDENT | PFM_OFFSETINDENT); - pf2.dxStartIndent = 30; - pf2.dxRightIndent = 30; - } - pf2.dxOffset = m_pContainer->m_theme.left_indent + 30; - - if (!fIsChat) { - ClearLog(); - m_log.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); - m_log.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_log.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD); - // set the scrollbars etc to RTL/LTR (only for manual RTL mode) - if (m_dwFlags & MWF_LOG_RTL) { - SetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE) | WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR); - SetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE) | WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR); - } - else { - SetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE) &~(WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR)); - SetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE) &~(WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR)); - } - } + + if (m_dwFlags & MWF_LOG_RTL) + SetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE) | WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR); + else + SetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE) & ~(WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR)); + if (szStreamOut != nullptr) { SETTEXTEX stx = { ST_DEFAULT, CP_UTF8 }; m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&stx, (LPARAM)szStreamOut); @@ -686,30 +668,10 @@ void CMsgDialog::DM_ScrollToBottom(WPARAM wParam, LPARAM lParam) if (IsIconic(m_pContainer->m_hwnd)) m_dwFlags |= MWF_DEFERREDSCROLL; - if (m_hwndIEView) { - PostMessage(m_hwnd, DM_SCROLLIEVIEW, 0, 0); - return; - } - if (m_hwndHPP) { - SendMessage(m_hwnd, DM_SCROLLIEVIEW, 0, 0); - return; - } - - if (lParam) - SendMessage(m_log.GetHwnd(), WM_SIZE, 0, 0); - - if (wParam == 1 && lParam == 1) { - int len = GetWindowTextLength(m_log.GetHwnd()); - SendMessage(m_log.GetHwnd(), EM_SETSEL, len - 1, len - 1); - } - - if (wParam) - SendMessage(m_log.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0); + if (m_iLogMode == 0) + ((CLogWindow *)m_pLog)->ScrollToBottom(wParam != 0, lParam != 0); else - PostMessage(m_log.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0); - - if (lParam) - InvalidateRect(m_log.GetHwnd(), nullptr, FALSE); + m_pLog->ScrollToBottom(); } void CMsgDialog::DM_RecalcPictureSize() @@ -819,26 +781,18 @@ LRESULT CMsgDialog::DM_MouseWheelHandler(WPARAM wParam, LPARAM lParam) return 0; } } - if (m_hwndIEView) - GetWindowRect(m_hwndIEView, &rc); - else if (m_hwndHPP) - GetWindowRect(m_hwndHPP, &rc); - else - GetWindowRect(m_log.GetHwnd(), &rc); + + GetWindowRect(m_pLog->GetHwnd(), &rc); if (PtInRect(&rc, pt)) { - HWND hwndLog = (m_hwndIEView || m_hwndHPP) ? m_hwndIWebBrowserControl : m_log.GetHwnd(); short wDirection = (short)HIWORD(wParam); - if (hwndLog == nullptr) - hwndLog = WindowFromPoint(pt); - if (LOWORD(wParam) & MK_SHIFT || M.GetByte("fastscroll", 0)) { if (wDirection < 0) - SendMessage(hwndLog, WM_VSCROLL, MAKEWPARAM(SB_PAGEDOWN, 0), 0); + SendMessage(m_pLog->GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_PAGEDOWN, 0), 0); else if (wDirection > 0) - SendMessage(hwndLog, WM_VSCROLL, MAKEWPARAM(SB_PAGEUP, 0), 0); + SendMessage(m_pLog->GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_PAGEUP, 0), 0); } - else SendMessage(hwndLog, WM_MOUSEWHEEL, wParam, lParam); + else SendMessage(m_pLog->GetHwnd(), WM_MOUSEWHEEL, wParam, lParam); return 0; } @@ -874,7 +828,9 @@ void CMsgDialog::DM_ThemeChanged() m_hTheme = OpenThemeData(m_hwnd, L"EDIT"); if (m_hTheme != nullptr || (CSkin::m_skinEnabled && !item_log->IGNORED)) { - SetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE) & ~WS_EX_STATICEDGE); + if (m_iLogMode == 0) + LOG()->DisableStaticEdge(); + if (isChat()) SetWindowLongPtr(m_nickList.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_nickList.GetHwnd(), GWL_EXSTYLE) & ~(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); } @@ -956,7 +912,6 @@ void CMsgDialog::DM_OptionsApplied(WPARAM, LPARAM lParam) m_pPanel.getVisibility(); // small inner margins (padding) for the text areas - m_log.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0, 0)); m_message.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(3, 3)); GetSendFormat(); @@ -1123,7 +1078,7 @@ int CMsgDialog::DM_SplitterGlobalEvent(WPARAM wParam, LPARAM lParam) void CMsgDialog::DM_AddDivider() { if (!(m_dwFlags & MWF_DIVIDERSET) && PluginConfig.m_bUseDividers) { - if (GetWindowTextLength(m_log.GetHwnd()) > 0) + if (GetWindowTextLength(m_pLog->GetHwnd()) > 0) m_dwFlags |= MWF_DIVIDERWANTED | MWF_DIVIDERSET; } } @@ -1181,7 +1136,7 @@ void CMsgDialog::DM_EventAdded(WPARAM hContact, LPARAM lParam) if (hDbEvent != m_hDbEventFirst) { if (!(m_dwFlagsEx & MWF_SHOW_SCROLLINGDISABLED)) - StreamInEvents(hDbEvent, 1, 1, nullptr); + m_pLog->LogEvents(hDbEvent, 1, 1); else { if (m_iNextQueuedEvent >= m_iEventQueueSize) { m_hQueuedEvents = (MEVENT*)mir_realloc(m_hQueuedEvents, (m_iEventQueueSize + 10) * sizeof(MEVENT)); diff --git a/plugins/TabSRMM/src/globals.cpp b/plugins/TabSRMM/src/globals.cpp index 5a6cb1c33d..9df35769e1 100644 --- a/plugins/TabSRMM/src/globals.cpp +++ b/plugins/TabSRMM/src/globals.cpp @@ -97,17 +97,6 @@ void CGlobals::reloadSystemModulesChanged() HookEvent(ME_SMILEYADD_OPTIONSCHANGED, ::SmileyAddOptionsChanged); } - // ieView - BOOL bIEView = ServiceExists(MS_IEVIEW_WINDOW); - if (bIEView) { - BOOL bOldIEView = M.GetByte("ieview_installed", 0); - if (bOldIEView != bIEView) - db_set_b(0, SRMSGMOD_T, "default_ieview", 1); - db_set_b(0, SRMSGMOD_T, "ieview_installed", 1); - HookEvent(ME_IEVIEW_OPTIONSCHANGED, ::IEViewOptionsChanged); - } - else db_set_b(0, SRMSGMOD_T, "ieview_installed", 0); - m_hwndClist = g_clistApi.hwndContactList; CMenuItem mi(&g_plugin); @@ -570,5 +559,5 @@ void CGlobals::logStatusChange(WPARAM wParam, const CContactCache *c) dbei.eventType = EVENTTYPE_STATUSCHANGE; dbei.timestamp = time(0); dbei.szModule = (char*)c->getProto(); - dat->StreamInEvents(0, 1, 1, &dbei); + dat->LogEvent(&dbei); } diff --git a/plugins/TabSRMM/src/globals.h b/plugins/TabSRMM/src/globals.h index 543bed01d0..579a507603 100644 --- a/plugins/TabSRMM/src/globals.h +++ b/plugins/TabSRMM/src/globals.h @@ -68,7 +68,7 @@ public: HICON g_iconOverlayDisabled, g_iconOverlayEnabled, g_iconClock; HCURSOR hCurSplitNS, hCurSplitWE, hCurSplitSW, hCurSplitWSE; HBITMAP g_hbmUnknown; - bool g_SmileyAddAvail, g_WantIEView, g_WantHPP; + bool g_SmileyAddAvail; HIMAGELIST g_hImageList; HICON g_IconMsgEvent, g_IconTypingEvent, g_IconFileEvent, g_IconSend; HICON g_IconMsgEventBig, g_IconTypingEventBig; diff --git a/plugins/TabSRMM/src/mim.cpp b/plugins/TabSRMM/src/mim.cpp index 5b3258ea7d..db31ddb128 100644 --- a/plugins/TabSRMM/src/mim.cpp +++ b/plugins/TabSRMM/src/mim.cpp @@ -193,6 +193,24 @@ void CMimAPI::InitAPI() } } else m_haveBufferedPaint = false; + + switch (GetByte("default_ieview", -1)) { + case 1: + db_set_s(0, "SRMM", "Logger", "ieview"); + __fallthrough; + + case 0: + db_unset(0, SRMSGMOD_T, "default_ieview"); + } + + switch (GetByte("default_hpp", -1)) { + case 1: + db_set_s(0, "SRMM", "Logger", "hpp"); + __fallthrough; + + case 0: + db_unset(0, SRMSGMOD_T, "default_hpp"); + } } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/TabSRMM/src/msgdialog.cpp b/plugins/TabSRMM/src/msgdialog.cpp index dcff6711e9..6a6867b2d4 100644 --- a/plugins/TabSRMM/src/msgdialog.cpp +++ b/plugins/TabSRMM/src/msgdialog.cpp @@ -35,7 +35,6 @@ bool IsStringValidLink(wchar_t *pszText); static int g_cLinesPerPage = 0; static int g_iWheelCarryover = 0; -static const UINT sendControls[] = { IDC_SRMM_MESSAGE, IDC_SRMM_LOG }; static const UINT formatControls[] = { IDC_SRMM_BOLD, IDC_SRMM_ITALICS, IDC_SRMM_UNDERLINE, IDC_FONTSTRIKEOUT }; static const UINT addControls[] = { IDC_ADD, IDC_CANCELADD }; static const UINT btnControls[] = { IDC_RETRY, IDC_CANCELSEND, IDC_MSGSENDLATER, IDC_ADD, IDC_CANCELADD }; @@ -141,12 +140,7 @@ void CMsgDialog::SetDialogToType() Utils::enableDlgControl(m_hwnd, IDC_TIME, true); - if (m_hwndIEView || m_hwndHPP) { - m_log.Hide(); - m_log.Enable(false); - m_message.Show(); - } - else ShowMultipleControls(m_hwnd, sendControls, _countof(sendControls), SW_SHOW); + m_message.Show(); ShowMultipleControls(m_hwnd, errorControls, _countof(errorControls), m_dwFlags & MWF_ERRORSTATE ? SW_SHOW : SW_HIDE); @@ -405,6 +399,8 @@ bool CMsgDialog::OnInitDialog() else m_pWnd = nullptr; + m_iLogMode = m_pLog->GetType(); + // set up Windows themes DM_ThemeChanged(); @@ -504,10 +500,10 @@ bool CMsgDialog::OnInitDialog() LoadLocalFlags(); DM_InitTip(); - m_pPanel.getVisibility(); m_dwFlagsEx |= M.GetByte(m_hContact, "splitoverride", 0) ? MWF_SHOW_SPLITTEROVERRIDE : 0; - SetMessageLog(); + + m_pPanel.getVisibility(); if (m_hContact) m_pPanel.loadHeight(); @@ -565,15 +561,6 @@ bool CMsgDialog::OnInitDialog() SetDlgItemText(m_hwnd, IDC_CANCELSEND, TranslateT("Cancel")); SetDlgItemText(m_hwnd, IDC_MSGSENDLATER, TranslateT("Send later")); - m_log.SendMsg(EM_AUTOURLDETECT, TRUE, 0); - m_log.SendMsg(EM_EXLIMITTEXT, 0, 0x7FFFFFFF); - m_log.SendMsg(EM_SETUNDOLIMIT, 0, 0); - m_log.SendMsg(EM_HIDESELECTION, TRUE, 0); - m_log.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_LINK); - m_log.SendMsg(EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, SES_EXTENDBACKCOLOR); - m_log.SendMsg(EM_SETLANGOPTIONS, 0, m_log.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOFONTSIZEADJUST); - m_log.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(3, 3)); - m_message.SendMsg(EM_SETEVENTMASK, 0, ENM_REQUESTRESIZE | ENM_MOUSEEVENTS | ENM_SCROLL | ENM_KEYEVENTS | ENM_CHANGE); m_message.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(3, 3)); m_message.SetReadOnly(false); @@ -686,8 +673,8 @@ bool CMsgDialog::OnInitDialog() m_dwLastActivity = GetTickCount() - 1000; m_pContainer->m_dwLastActivity = m_dwLastActivity; - if (m_hwndHPP) - mir_subclassWindow(m_hwndHPP, HPPKFSubclassProc); + if (m_iLogMode == WANT_HPP_LOG) + mir_subclassWindow(m_pLog->GetHwnd(), HPPKFSubclassProc); m_dwFlags &= ~MWF_INITMODE; NotifyEvent(MSG_WINDOW_EVT_OPEN); @@ -796,20 +783,6 @@ void CMsgDialog::OnDestroy() NotifyEvent(MSG_WINDOW_EVT_CLOSE); - // clean up IEView and H++ log windows - if (m_hwndIEView != nullptr) { - IEVIEWWINDOW ieWindow = {}; - ieWindow.iType = IEW_DESTROY; - ieWindow.hwnd = m_hwndIEView; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - } - if (m_hwndHPP) { - IEVIEWWINDOW ieWindow = {}; - ieWindow.iType = IEW_DESTROY; - ieWindow.hwnd = m_hwndHPP; - CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow); - } - CSuper::OnDestroy(); } @@ -832,7 +805,7 @@ void CMsgDialog::onClick_Ok(CCtrlButton *) fi.chrg.cpMin = 0; fi.chrg.cpMax = -1; fi.lpstrText = L"{"; - int final_sendformat = m_message.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) == -1 ? m_SendFormat : 0; + final_sendformat = m_message.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) == -1 ? m_SendFormat : 0; fi.lpstrText = L"}"; final_sendformat = m_message.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) == -1 ? final_sendformat : 0; } @@ -959,43 +932,25 @@ void CMsgDialog::onClick_Add(CCtrlButton*) void CMsgDialog::onClick_Quote(CCtrlButton*) { - CHARRANGE sel; SETTEXTEX stx = { ST_SELECTION, 1200 }; - MEVENT hDBEvent = m_hDbEventLast; - if (m_hwndIEView || m_hwndHPP) { // IEView quoting support.. - IEVIEWEVENT event = { sizeof(event) }; - event.hContact = m_hContact; - event.dwFlags = 0; - event.iType = IEE_GET_SELECTION; - - wchar_t *selected; - if (m_hwndIEView) { - event.hwnd = m_hwndIEView; - selected = (wchar_t*)CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&event); - } - else { - event.hwnd = m_hwndHPP; - selected = (wchar_t*)CallService(MS_HPP_EG_EVENT, 0, (LPARAM)&event); - } - - if (selected != nullptr) { - ptrW szQuoted(QuoteText(selected)); - m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&stx, (LPARAM)szQuoted); - return; - } - - hDBEvent = db_event_last(m_hContact); + wchar_t *selected = m_pLog->GetSelection(); + if (selected != nullptr) { + ptrW szQuoted(QuoteText(selected)); + m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&stx, (LPARAM)szQuoted); + return; } + MEVENT hDBEvent = db_event_last(m_hContact); if (hDBEvent == 0) return; - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + CHARRANGE sel; + LOG()->WndProc(EM_EXGETSEL, 0, (LPARAM)&sel); if (sel.cpMin == sel.cpMax) { DBEVENTINFO dbei = {}; dbei.cbBlob = db_event_getBlobSize(hDBEvent); - wchar_t *szText = (wchar_t*)mir_alloc((dbei.cbBlob + 1) * sizeof(wchar_t)); //URLs are made one char bigger for crlf + wchar_t *szText = (wchar_t*)mir_alloc((dbei.cbBlob + 1) * sizeof(wchar_t)); // URLs are made one char bigger for crlf dbei.pBlob = (BYTE*)szText; db_event_get(hDBEvent, &dbei); int iSize = int(mir_strlen((char*)dbei.pBlob)) + 1; @@ -1027,21 +982,20 @@ void CMsgDialog::onClick_Quote(CCtrlButton*) bNeedsFree = true; } - if (szConverted != nullptr) { - ptrW szQuoted(QuoteText(szConverted)); - m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&stx, (LPARAM)szQuoted); - } + if (szConverted != nullptr) + m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&stx, ptrW(QuoteText(szConverted))); + mir_free(szText); if (bNeedsFree) mir_free(szConverted); } else { - ptrA szFromStream(m_log.GetRichTextRtf(true, true)); + ptrA szFromStream(LOG()->GetRichTextRtf(true, true)); ptrW converted(mir_utf8decodeW(szFromStream)); Utils::FilterEventMarkers(converted); - ptrW szQuoted(QuoteText(converted)); - m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&stx, (LPARAM)szQuoted); + m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&stx, ptrW(QuoteText(converted))); } + SetFocus(m_message.GetHwnd()); } @@ -1086,7 +1040,7 @@ void CMsgDialog::onClick_ShowNickList(CCtrlButton *pButton) Resize(); if (CSkin::m_skinEnabled) InvalidateRect(m_hwnd, nullptr, TRUE); - ScrollToBottom(); + m_pLog->ScrollToBottom(); } void CMsgDialog::onDblClick_List(CCtrlListBox *pList) @@ -1160,7 +1114,7 @@ int CMsgDialog::Resizer(UTILRESIZECONTROL *urc) int iSplitterX = m_pContainer->m_pSettings->iSplitterX; RECT rc, rcButton; - GetClientRect(m_log.GetHwnd(), &rc); + GetClientRect(m_pLog->GetHwnd(), &rc); GetClientRect(GetDlgItem(m_hwnd, IDC_PROTOCOL), &rcButton); if (m_bIsAutosizingInput) @@ -1609,7 +1563,7 @@ int CMsgDialog::OnFilter(MSGFILTER *pFilter) return _dlgReturn(m_hwnd, 1); } if (wp == VK_DIVIDE) { - SetFocus(m_log.GetHwnd()); + SetFocus(m_pLog->GetHwnd()); return _dlgReturn(m_hwnd, 1); } if (wp == VK_ADD) { @@ -1653,7 +1607,7 @@ int CMsgDialog::OnFilter(MSGFILTER *pFilter) if (GetSendButtonState(m_hwnd) != PBS_DISABLED && !(m_pContainer->m_dwFlags & CNT_HIDETOOLBAR)) SetFocus(GetDlgItem(m_hwnd, IDOK)); else - SetFocus(m_log.GetHwnd()); + SetFocus(m_pLog->GetHwnd()); return _dlgReturn(m_hwnd, 1); } @@ -1669,14 +1623,14 @@ int CMsgDialog::OnFilter(MSGFILTER *pFilter) POINT pt; GetCursorPos(&pt); RECT rc; - GetWindowRect(m_log.GetHwnd(), &rc); + GetWindowRect(m_pLog->GetHwnd(), &rc); if (PtInRect(&rc, pt)) { short wDirection = (short)HIWORD(wp); if (LOWORD(wp) & MK_SHIFT) { if (wDirection < 0) - m_log.SendMsg(WM_VSCROLL, MAKEWPARAM(SB_PAGEDOWN, 0), 0); + LOG()->WndProc(WM_VSCROLL, MAKEWPARAM(SB_PAGEDOWN, 0), 0); else if (wDirection > 0) - m_log.SendMsg(WM_VSCROLL, MAKEWPARAM(SB_PAGEUP, 0), 0); + LOG()->WndProc(WM_VSCROLL, MAKEWPARAM(SB_PAGEUP, 0), 0); return 0; } return 0; @@ -1750,13 +1704,13 @@ int CMsgDialog::OnFilter(MSGFILTER *pFilter) // holding ctrl-alt does the same, but pastes formatted text if (pFilter->nmhdr.idFrom == IDC_SRMM_LOG && M.GetByte("autocopy", 1)) { CHARRANGE cr; - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&cr); + LOG()->WndProc(EM_EXGETSEL, 0, (LPARAM)&cr); if (cr.cpMax == cr.cpMin) break; cr.cpMin = cr.cpMax; if (isCtrl) { SETTEXTEX stx = { ST_KEEPUNDO | ST_SELECTION, CP_UTF8 }; - ptrA streamOut(m_log.GetRichTextRtf(!isAlt, true)); + ptrA streamOut(LOG()->GetRichTextRtf(!isAlt, true)); if (streamOut) { Utils::FilterEventMarkers(streamOut); m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&stx, (LPARAM)streamOut); @@ -1764,7 +1718,7 @@ int CMsgDialog::OnFilter(MSGFILTER *pFilter) SetFocus(m_message.GetHwnd()); } else if (!isShift) { - m_log.SendMsg(WM_COPY, 0, 0); + LOG()->WndProc(WM_COPY, 0, 0); SetFocus(m_message.GetHwnd()); if (m_pContainer->m_hwndStatus) SendMessage(m_pContainer->m_hwndStatus, SB_SETTEXT, 0, (LPARAM)TranslateT("Selection copied to clipboard")); @@ -1927,135 +1881,6 @@ INT_PTR CALLBACK CMsgDialog::FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wPara ///////////////////////////////////////////////////////////////////////////////////////// -LRESULT CMsgDialog::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) -{ - bool isCtrl, isShift, isAlt; - - switch (msg) { - case WM_KILLFOCUS: - if (wParam != (WPARAM)m_log.GetHwnd() && 0 != wParam) { - CHARRANGE cr; - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&cr); - if (cr.cpMax != cr.cpMin) { - cr.cpMin = cr.cpMax; - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&cr); - } - } - break; - - case WM_CHAR: - KbdState(isShift, isCtrl, isAlt); - if (wParam == 0x03 && isCtrl) // Ctrl+C - return WMCopyHandler(msg, wParam, lParam); - if (wParam == 0x11 && isCtrl) // Ctrl+Q - m_btnQuote.Click(); - break; - - case WM_LBUTTONUP: - if (isChat() && g_Settings.bClickableNicks) { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - CheckCustomLink(m_log.GetHwnd(), &pt, msg, wParam, lParam, TRUE); - } - if (M.GetByte("autocopy", 1)) { - CHARRANGE sel; - SendMessage(m_log.GetHwnd(), EM_EXGETSEL, 0, (LPARAM)& sel); - if (sel.cpMin != sel.cpMax) { - SendMessage(m_log.GetHwnd(), WM_COPY, 0, 0); - sel.cpMin = sel.cpMax; - SendMessage(m_log.GetHwnd(), EM_EXSETSEL, 0, (LPARAM)& sel); - SetFocus(m_message.GetHwnd()); - } - } - break; - - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - case WM_RBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONDBLCLK: - if (isChat() && g_Settings.bClickableNicks) { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - CheckCustomLink(m_log.GetHwnd(), &pt, msg, wParam, lParam, TRUE); - } - break; - - case WM_SETCURSOR: - if (g_Settings.bClickableNicks && isChat() && (LOWORD(lParam) == HTCLIENT)) { - POINT pt; - GetCursorPos(&pt); - ScreenToClient(m_log.GetHwnd(), &pt); - if (CheckCustomLink(m_log.GetHwnd(), &pt, msg, wParam, lParam, FALSE)) - return TRUE; - } - break; - - case WM_SYSKEYUP: - if (wParam == VK_MENU) { - ProcessHotkeysByMsgFilter(m_log, msg, wParam, lParam); - return 0; - } - break; - - case WM_SYSKEYDOWN: - m_bkeyProcessed = false; - if (ProcessHotkeysByMsgFilter(m_log, msg, wParam, lParam)) { - m_bkeyProcessed = true; - return 0; - } - break; - - case WM_SYSCHAR: - if (m_bkeyProcessed) { - m_bkeyProcessed = false; - return 0; - } - break; - - case WM_KEYDOWN: - KbdState(isShift, isCtrl, isAlt); - if (wParam == VK_INSERT && isCtrl) - return WMCopyHandler(msg, wParam, lParam); - - if (wParam == 0x57 && isCtrl) { // ctrl-w (close window) - PostMessage(m_hwnd, WM_CLOSE, 0, 1); - return TRUE; - } - - break; - - case WM_COPY: - return WMCopyHandler(msg, wParam, lParam); - - case WM_NCCALCSIZE: - return CSkin::NcCalcRichEditFrame(m_log.GetHwnd(), this, ID_EXTBKHISTORY, msg, wParam, lParam, stubLogProc); - - case WM_NCPAINT: - return CSkin::DrawRichEditFrame(m_log.GetHwnd(), this, ID_EXTBKHISTORY, msg, wParam, lParam, stubLogProc); - - case WM_CONTEXTMENU: - if (!isChat()) { - POINT pt; - if (lParam == 0xFFFFFFFF) { - CHARRANGE sel; - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)& sel); - m_log.SendMsg(EM_POSFROMCHAR, (WPARAM)& pt, (LPARAM)sel.cpMax); - ClientToScreen(m_log.GetHwnd(), &pt); - } - else { - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - } - - ShowPopupMenu(m_log, pt); - return TRUE; - } - } - - return CSuper::WndProc_Log(msg, wParam, lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// - LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) { bool isCtrl, isShift, isAlt; @@ -2161,7 +1986,7 @@ LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) if ((GetSendButtonState(GetHwnd()) != PBS_DISABLED)) SetFocus(m_btnOk.GetHwnd()); else - SetFocus(m_log.GetHwnd()); + SetFocus(m_pLog->GetHwnd()); } return 0; } @@ -2242,10 +2067,7 @@ LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) else if (wParam == VK_DOWN) wp = MAKEWPARAM(SB_LINEDOWN, 0); - if (m_hwndIEView == nullptr && m_hwndHPP == nullptr) - m_log.SendMsg(WM_VSCROLL, wp, 0); - else - SendMessage(m_hwndIWebBrowserControl, WM_VSCROLL, wp, 0); + LOG()->WndProc(WM_VSCROLL, wp, 0); return 0; } } @@ -2603,7 +2425,7 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_SIZE: if (wParam == SIZE_MAXIMIZED) - ScrollToBottom(); + m_pLog->ScrollToBottom(); if (!IsIconic(m_hwnd)) { if (m_ipFieldHeight == 0) @@ -2684,7 +2506,7 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) if (GetDlgItem(m_hwnd, IDC_CLIST) != nullptr) { RECT rcLog; GetClientRect(m_hwnd, &rcClient); - GetClientRect(m_log.GetHwnd(), &rcLog); + GetClientRect(m_pLog->GetHwnd(), &rcLog); rc.top = 0; rc.right = rcClient.right; rc.left = rcClient.right - m_iMultiSplit; @@ -2694,8 +2516,7 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) MoveWindow(GetDlgItem(m_hwnd, IDC_CLIST), rc.left, rc.top, rc.right - rc.left, rcLog.bottom - rcLog.top, FALSE); } - if (m_hwndIEView || m_hwndHPP) - ResizeIeView(); + m_pLog->Resize(); DetermineMinHeight(); } @@ -2920,22 +2741,7 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) RemakeLog(); } else if (m_hContact == wParam && db_mc_isSub(wParam) && db_event_getContact(lParam) != wParam) - StreamInEvents(lParam, 1, 1, nullptr); - return 0; - - case DM_SCROLLIEVIEW: - { - IEVIEWWINDOW iew = { sizeof(iew) }; - iew.iType = IEW_SCROLLBOTTOM; - if (m_hwndIEView) { - iew.hwnd = m_hwndIEView; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&iew); - } - else if (m_hwndHPP) { - iew.hwnd = m_hwndHPP; - CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&iew); - } - } + m_pLog->LogEvents(lParam, 1, 1); return 0; case HM_DBEVENTADDED: @@ -3019,7 +2825,7 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) Resize(); PostMessage(m_hwnd, DM_UPDATEPICLAYOUT, 0, 0); - if (m_hwndIEView != nullptr) + if (m_iLogMode != WANT_IEVIEW_LOG) SetFocus(m_message.GetHwnd()); if (m_pContainer->m_dwFlags & CNT_SIDEBAR) m_pContainer->m_pSideBar->Layout(); @@ -3263,8 +3069,7 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) break; case DM_IEVIEWOPTIONSCHANGED: - if (m_hwndIEView) - RemakeLog(); + RemakeLog(); break; case DM_SMILEYOPTIONSCHANGED: diff --git a/plugins/TabSRMM/src/msgdlgother.cpp b/plugins/TabSRMM/src/msgdlgother.cpp index 5d9ed3f914..e6ebb9eb48 100644 --- a/plugins/TabSRMM/src/msgdlgother.cpp +++ b/plugins/TabSRMM/src/msgdlgother.cpp @@ -1219,7 +1219,7 @@ void CMsgDialog::RemakeLog() m_szMicroLf[0] = 0; m_lastEventTime = 0; m_iLastEventType = -1; - StreamInEvents(m_hDbEventFirst, -1, 0, nullptr); + m_pLog->LogEvents(m_hDbEventFirst, -1, 0); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -1228,35 +1228,13 @@ void CMsgDialog::ReplayQueue() { for (int i = 0; i < m_iNextQueuedEvent; i++) if (m_hQueuedEvents[i] != 0) - StreamInEvents(m_hQueuedEvents[i], 1, 1, nullptr); + m_pLog->LogEvents(m_hQueuedEvents[i], 1, 1); m_iNextQueuedEvent = 0; SetDlgItemText(m_hwnd, IDC_LOGFROZENTEXT, m_bNotOnList ? TranslateT("Contact not on list. You may add it...") : TranslateT("Auto scrolling is disabled (press F12 to enable it)")); } -///////////////////////////////////////////////////////////////////////////////////////// - -void CMsgDialog::ResizeIeView() -{ - RECT rcRichEdit; - GetWindowRect(m_log.GetHwnd(), &rcRichEdit); - - POINT pt = { rcRichEdit.left, rcRichEdit.top }; - ScreenToClient(m_hwnd, &pt); - - IEVIEWWINDOW ieWindow = { sizeof(ieWindow) }; - ieWindow.iType = IEW_SETPOS; - ieWindow.parent = m_hwnd; - ieWindow.hwnd = m_hwndIEView ? m_hwndIEView : m_hwndHPP; - ieWindow.x = pt.x; - ieWindow.y = pt.y; - ieWindow.cx = rcRichEdit.right - rcRichEdit.left; - ieWindow.cy = rcRichEdit.bottom - rcRichEdit.top; - if (ieWindow.cx != 0 && ieWindow.cy != 0) - CallService(m_hwndIEView ? MS_IEVIEW_WINDOW : MS_HPP_EG_WINDOW, 0, (LPARAM)& ieWindow); -} - ///////////////////////////////////////////////////////////////////////////////////////// // saves a contact picture to disk // takes hbm (bitmap handle) and bool isOwnPic (1 == save the picture as your own avatar) @@ -1346,13 +1324,6 @@ void CMsgDialog::SaveSplitter() } } -///////////////////////////////////////////////////////////////////////////////////////// - -void CMsgDialog::ScrollToBottom() -{ - DM_ScrollToBottom(0, 0); -} - ///////////////////////////////////////////////////////////////////////////////////////// // send a pasted bitmap by file transfer. @@ -1467,41 +1438,6 @@ void TSAPI CleanTempFiles() } } -///////////////////////////////////////////////////////////////////////////////////////// - -void CMsgDialog::SetMessageLog() -{ - if (isChat()) - return; - - unsigned int iLogMode = GetIEViewMode(m_hContact); - - if (iLogMode == WANT_IEVIEW_LOG && m_hwndIEView == nullptr) { - IEVIEWWINDOW ieWindow = {}; - ieWindow.iType = IEW_CREATE; - ieWindow.dwMode = IEWM_TABSRMM; - ieWindow.parent = m_hwnd; - ieWindow.cx = 200; - ieWindow.cy = 200; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)& ieWindow); - m_hwndIEView = ieWindow.hwnd; - m_log.Hide(); - m_log.Enable(false); - } - else if (iLogMode == WANT_HPP_LOG && m_hwndHPP == nullptr) { - IEVIEWWINDOW ieWindow = {}; - ieWindow.iType = IEW_CREATE; - ieWindow.dwMode = IEWM_TABSRMM; - ieWindow.parent = m_hwnd; - ieWindow.cx = 10; - ieWindow.cy = 10; - CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)& ieWindow); - m_hwndHPP = ieWindow.hwnd; - m_log.Hide(); - m_log.Enable(false); - } -} - ///////////////////////////////////////////////////////////////////////////////////////// // Sets a status bar text for a contact @@ -1530,7 +1466,7 @@ void CMsgDialog::ShowFilterMenu() RECT rcFilter, rcLog; GetClientRect(m_hwndFilter, &rcFilter); - GetWindowRect(m_log.GetHwnd(), &rcLog); + GetWindowRect(m_pLog->GetHwnd(), &rcLog); POINT pt; pt.x = rcLog.right; pt.y = rcLog.bottom; @@ -1744,7 +1680,7 @@ void CMsgDialog::SplitterMoved(int coord, HWND hwnd) break; case IDC_PANELSPLITTER: - GetClientRect(m_log.GetHwnd(), &rc); + GetClientRect(m_pLog->GetHwnd(), &rc); POINT pnt = { 0, coord }; ScreenToClient(m_hwnd, &pnt); @@ -1853,37 +1789,14 @@ LBL_SkipEnd: void CMsgDialog::tabClearLog() { if (isChat()) { - SESSION_INFO *s = g_chatApi.SM_FindSession(m_si->ptszID, m_si->pszModule); - if (s) { - ClearLog(); - g_chatApi.LM_RemoveAll(&s->pLog, &s->pLogEnd); - s->iEventCount = 0; - s->LastTime = 0; - m_si->iEventCount = 0; - m_si->LastTime = 0; - m_si->pLog = s->pLog; - m_si->pLogEnd = s->pLogEnd; - PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); - } - } - else { - if (m_hwndIEView || m_hwndHPP) { - IEVIEWEVENT event = {}; - event.iType = IEE_CLEAR_LOG; - event.dwFlags = (m_dwFlags & MWF_LOG_RTL) ? IEEF_RTL : 0; - event.hContact = m_hContact; - if (m_hwndIEView) { - event.hwnd = m_hwndIEView; - CallService(MS_IEVIEW_EVENT, 0, (LPARAM) & event); - } - else { - event.hwnd = m_hwndHPP; - CallService(MS_HPP_EG_EVENT, 0, (LPARAM) & event); - } - } - m_log.SetText(L""); - m_hDbEventFirst = 0; + g_chatApi.LM_RemoveAll(&m_si->pLog, &m_si->pLogEnd); + m_si->iEventCount = 0; + m_si->LastTime = 0; + PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); } + + m_pLog->Clear(); + m_hDbEventFirst = 0; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -1944,7 +1857,7 @@ void CMsgDialog::UpdateNickList() void CMsgDialog::UpdateOptions() { - m_log.SendMsg(EM_SETBKGNDCOLOR, 0, db_get_dw(0, FONTMODULE, SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR)); + m_pLog->UpdateOptions(); DM_InitRichEdit(); m_btnOk.SendMsg(BUTTONSETASNORMAL, TRUE, 0); @@ -2380,28 +2293,28 @@ void CMsgDialog::UpdateWindowState(UINT msg) m_pPanel.Invalidate(); - if (m_dwFlags & MWF_DEFERREDSCROLL && m_hwndIEView == nullptr && m_hwndHPP == nullptr) { + if (m_dwFlags & MWF_DEFERREDSCROLL) { m_dwFlags &= ~MWF_DEFERREDSCROLL; DM_ScrollToBottom(0, 1); } - if (m_hwndIEView) { - RECT rcRTF; - POINT pt; + if (m_iLogMode == WANT_IEVIEW_LOG) { + HWND hwndLog = m_pLog->GetHwnd(); - GetWindowRect(m_log.GetHwnd(), &rcRTF); + RECT rcRTF; + GetWindowRect(hwndLog, &rcRTF); rcRTF.left += 20; rcRTF.top += 20; + + POINT pt; pt.x = rcRTF.left; pt.y = rcRTF.top; - if (m_hwndIEView) { - if (M.GetByte("subclassIEView", 0)) { - mir_subclassWindow(m_hwndIEView, IEViewSubclassProc); - SetWindowPos(m_hwndIEView, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME); - RedrawWindow(m_hwndIEView, nullptr, nullptr, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW); - } + + if (M.GetByte("subclassIEView", 0)) { + mir_subclassWindow(hwndLog, IEViewSubclassProc); + SetWindowPos(hwndLog, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME); + RedrawWindow(hwndLog, nullptr, nullptr, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW); } - m_hwndIWebBrowserControl = WindowFromPoint(pt); } if (m_dwFlagsEx & MWF_EX_AVATARCHANGED) { @@ -2437,14 +2350,14 @@ void CMsgDialog::UpdateWindowState(UINT msg) LRESULT CMsgDialog::WMCopyHandler(UINT msg, WPARAM wParam, LPARAM lParam) { - LRESULT result = mir_callNextSubclass(m_log.GetHwnd(), stubLogProc, msg, wParam, lParam); + LRESULT result = mir_callNextSubclass(m_pLog->GetHwnd(), stubLogProc, msg, wParam, lParam); - ptrA szFromStream(m_log.GetRichTextRtf(true, true)); + ptrA szFromStream(LOG()->GetRichTextRtf(true, true)); if (szFromStream != nullptr) { ptrW converted(mir_utf8decodeW(szFromStream)); if (converted != nullptr) { Utils::FilterEventMarkers(converted); - Utils::CopyToClipBoard(converted, m_log.GetHwnd()); + Utils::CopyToClipBoard(converted, m_pLog->GetHwnd()); } } diff --git a/plugins/TabSRMM/src/msgdlgutils.cpp b/plugins/TabSRMM/src/msgdlgutils.cpp index 147250a16d..65041b78e9 100644 --- a/plugins/TabSRMM/src/msgdlgutils.cpp +++ b/plugins/TabSRMM/src/msgdlgutils.cpp @@ -322,33 +322,6 @@ wchar_t* TSAPI QuoteText(const wchar_t *text) ///////////////////////////////////////////////////////////////////////////////////////// -static int g_IEViewAvail = -1; -static int g_HPPAvail = -1; - -UINT TSAPI GetIEViewMode(MCONTACT hContact) -{ - int iWantIEView = 0, iWantHPP = 0; - - if (g_IEViewAvail == -1) - g_IEViewAvail = ServiceExists(MS_IEVIEW_WINDOW); - - if (g_HPPAvail == -1) - g_HPPAvail = ServiceExists(MS_HPP_GETVERSION); - - PluginConfig.g_WantIEView = g_IEViewAvail && M.GetByte("default_ieview", 0); - PluginConfig.g_WantHPP = g_HPPAvail && M.GetByte("default_hpp", 0); - - iWantIEView = (PluginConfig.g_WantIEView) || (M.GetByte(hContact, "ieview", 0) == 1 && g_IEViewAvail); - iWantIEView = (M.GetByte(hContact, "ieview", 0) == (BYTE)-1) ? 0 : iWantIEView; - - iWantHPP = (PluginConfig.g_WantHPP) || (M.GetByte(hContact, "hpplog", 0) == 1 && g_HPPAvail); - iWantHPP = (M.GetByte(hContact, "hpplog", 0) == (BYTE)-1) ? 0 : iWantHPP; - - return iWantHPP ? WANT_HPP_LOG : (iWantIEView ? WANT_IEVIEW_LOG : 0); -} - -///////////////////////////////////////////////////////////////////////////////////////// - bool IsStringValidLink(wchar_t *pszText) { if (pszText == nullptr) diff --git a/plugins/TabSRMM/src/msgdlgutils.h b/plugins/TabSRMM/src/msgdlgutils.h index e8ff8805b3..d434ee48ad 100644 --- a/plugins/TabSRMM/src/msgdlgutils.h +++ b/plugins/TabSRMM/src/msgdlgutils.h @@ -34,7 +34,6 @@ void TSAPI ProcessAvatarChange(HWND hwnd, LPARAM lParam); BOOL TSAPI CheckCustomLink(HWND hwndRich, POINT *ptClient, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bUrlNeeded); int TSAPI CheckValidSmileyPack(const char *szProto, MCONTACT hContact); wchar_t* TSAPI QuoteText(const wchar_t *text); -UINT TSAPI GetIEViewMode(MCONTACT hContact); int TSAPI CutContactName(const wchar_t *szold, wchar_t *sznew, size_t size); LRESULT TSAPI GetSendButtonState(HWND hwnd); void TSAPI RearrangeTab(HWND hwndDlg, const CMsgDialog *dat, int iMode, BOOL bSavePos); diff --git a/plugins/TabSRMM/src/msglog.cpp b/plugins/TabSRMM/src/msglog.cpp index a709216efd..faf830e942 100644 --- a/plugins/TabSRMM/src/msglog.cpp +++ b/plugins/TabSRMM/src/msglog.cpp @@ -1054,7 +1054,431 @@ static DWORD CALLBACK LogStreamInEvents(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG return 0; } -void CMsgDialog::ReplaceIcons(LONG startAt, int fAppend, BOOL isSent) +///////////////////////////////////////////////////////////////////////////////////////// + +INT_PTR CLogWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam) +{ + bool isCtrl, isShift, isAlt; + + switch (msg) { + case WM_KILLFOCUS: + if (wParam != (WPARAM)m_rtf.GetHwnd() && 0 != wParam) { + CHARRANGE cr; + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&cr); + if (cr.cpMax != cr.cpMin) { + cr.cpMin = cr.cpMax; + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&cr); + } + } + break; + + case WM_CHAR: + m_pDlg.KbdState(isShift, isCtrl, isAlt); + if (wParam == 0x03 && isCtrl) // Ctrl+C + return m_pDlg.WMCopyHandler(msg, wParam, lParam); + if (wParam == 0x11 && isCtrl) // Ctrl+Q + m_pDlg.m_btnQuote.Click(); + break; + + case WM_LBUTTONUP: + if (m_pDlg.isChat() && g_Settings.bClickableNicks) { + POINT pt = { LOWORD(lParam), HIWORD(lParam) }; + CheckCustomLink(m_rtf.GetHwnd(), &pt, msg, wParam, lParam, TRUE); + } + if (M.GetByte("autocopy", 1)) { + CHARRANGE sel; + SendMessage(m_rtf.GetHwnd(), EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin != sel.cpMax) { + SendMessage(m_rtf.GetHwnd(), WM_COPY, 0, 0); + sel.cpMin = sel.cpMax; + SendMessage(m_rtf.GetHwnd(), EM_EXSETSEL, 0, (LPARAM)&sel); + SetFocus(m_pDlg.m_message.GetHwnd()); + } + } + break; + + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_RBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONDBLCLK: + if (m_pDlg.isChat() && g_Settings.bClickableNicks) { + POINT pt = { LOWORD(lParam), HIWORD(lParam) }; + CheckCustomLink(m_rtf.GetHwnd(), &pt, msg, wParam, lParam, TRUE); + } + break; + + case WM_SETCURSOR: + if (g_Settings.bClickableNicks && m_pDlg.isChat() && (LOWORD(lParam) == HTCLIENT)) { + POINT pt; + GetCursorPos(&pt); + ScreenToClient(m_rtf.GetHwnd(), &pt); + if (CheckCustomLink(m_rtf.GetHwnd(), &pt, msg, wParam, lParam, FALSE)) + return TRUE; + } + break; + + case WM_SYSKEYUP: + if (wParam == VK_MENU) { + ProcessHotkeysByMsgFilter(m_rtf, msg, wParam, lParam); + return 0; + } + break; + + case WM_SYSKEYDOWN: + m_pDlg.m_bkeyProcessed = false; + if (ProcessHotkeysByMsgFilter(m_rtf, msg, wParam, lParam)) { + m_pDlg.m_bkeyProcessed = true; + return 0; + } + break; + + case WM_SYSCHAR: + if (m_pDlg.m_bkeyProcessed) { + m_pDlg.m_bkeyProcessed = false; + return 0; + } + break; + + case WM_KEYDOWN: + m_pDlg.KbdState(isShift, isCtrl, isAlt); + if (wParam == VK_INSERT && isCtrl) + return m_pDlg.WMCopyHandler(msg, wParam, lParam); + + if (wParam == 0x57 && isCtrl) { // ctrl-w (close window) + PostMessage(m_pDlg.m_hwnd, WM_CLOSE, 0, 1); + return TRUE; + } + + break; + + case WM_COPY: + return m_pDlg.WMCopyHandler(msg, wParam, lParam); + + case WM_NCCALCSIZE: + return CSkin::NcCalcRichEditFrame(m_rtf.GetHwnd(), &m_pDlg, ID_EXTBKHISTORY, msg, wParam, lParam, stubLogProc); + + case WM_NCPAINT: + return CSkin::DrawRichEditFrame(m_rtf.GetHwnd(), &m_pDlg, ID_EXTBKHISTORY, msg, wParam, lParam, stubLogProc); + + case WM_CONTEXTMENU: + if (!m_pDlg.isChat()) { + POINT pt; + if (lParam == 0xFFFFFFFF) { + CHARRANGE sel; + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + m_rtf.SendMsg(EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)sel.cpMax); + ClientToScreen(m_rtf.GetHwnd(), &pt); + } + else { + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + } + + m_pDlg.ShowPopupMenu(m_rtf, pt); + return TRUE; + } + } + + return CSuper::WndProc(msg, wParam, lParam); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CLogWindow::Attach() +{ + CSuper::Attach(); + + m_rtf.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0, 0)); + m_rtf.SendMsg(EM_AUTOURLDETECT, TRUE, 0); + m_rtf.SendMsg(EM_EXLIMITTEXT, 0, 0x7FFFFFFF); + m_rtf.SendMsg(EM_SETUNDOLIMIT, 0, 0); + m_rtf.SendMsg(EM_HIDESELECTION, TRUE, 0); + m_rtf.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_LINK); + m_rtf.SendMsg(EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, SES_EXTENDBACKCOLOR); + m_rtf.SendMsg(EM_SETLANGOPTIONS, 0, m_rtf.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOFONTSIZEADJUST); + m_rtf.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(3, 3)); +} + +void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool fAppend) +{ + LogEvents(hDbEventFirst, count, fAppend, nullptr); +} + +void CLogWindow::LogEvents(DBEVENTINFO *dbei, bool bAppend) +{ + LogEvents(0, 1, bAppend, dbei); +} + +void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool fAppend, DBEVENTINFO *dbei_s) +{ + CHARRANGE oldSel, sel; + + // calc time limit for grouping + rtfFonts = m_pDlg.m_pContainer->m_theme.rtfFonts ? m_pDlg.m_pContainer->m_theme.rtfFonts : &(rtfFontsGlobal[0][0]); + time_t now = time(0); + + struct tm tm_now = *localtime(&now); + struct tm tm_today = tm_now; + tm_today.tm_hour = tm_today.tm_min = tm_today.tm_sec = 0; + today = mktime(&tm_today); + + m_pDlg.DM_ScrollToBottom(0, 0); + if (fAppend && hDbEventFirst) + m_pDlg.m_hDbEventLast = hDbEventFirst; + else + m_pDlg.m_hDbEventLast = db_event_last(m_pDlg.m_hContact); + + // separator strings used for grid lines, message separation and so on... + m_pDlg.m_bClrAdded = false; + + if (m_pDlg.m_szMicroLf[0] == 0) { + if (m_pDlg.m_hHistoryEvents) + strncpy_s(m_pDlg.m_szMicroLf, "\\v\\cf%d \\ ~-+%d+-~\\v0 ", _TRUNCATE); + else + mir_snprintf(m_pDlg.m_szMicroLf, "%s\\par\\ltrpar\\sl-1%s ", GetRTFFont(MSGDLGFONTCOUNT), GetRTFFont(MSGDLGFONTCOUNT)); + } + + szYourName = const_cast(m_pDlg.m_cache->getNick()); + szMyName = m_pDlg.m_wszMyNickname; + + m_rtf.SendMsg(EM_HIDESELECTION, TRUE, 0); + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldSel); + + LogStreamData streamData = { 0 }; + streamData.hContact = m_pDlg.m_hContact; + streamData.hDbEvent = hDbEventFirst; + streamData.dlgDat = &m_pDlg; + streamData.eventsToInsert = count; + streamData.isEmpty = fAppend ? GetWindowTextLength(m_rtf.GetHwnd()) == 0 : 1; + 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 }; + gtxl.codepage = 1200; + gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMCHARS; + startAt = m_rtf.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0); + sel.cpMin = sel.cpMax = GetWindowTextLength(m_rtf.GetHwnd()); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + } + else { + SetWindowText(m_rtf.GetHwnd(), L""); + sel.cpMin = 0; + sel.cpMax = GetWindowTextLength(m_rtf.GetHwnd()); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + startAt = 0; + m_pDlg.m_isAutoRTL = 0; + } + + // begin to draw + m_rtf.SendMsg(WM_SETREDRAW, FALSE, 0); + + m_rtf.SendMsg(EM_STREAMIN, fAppend ? SFF_SELECTION | SF_RTF : SFF_SELECTION | SF_RTF, (LPARAM)&stream); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldSel); + m_rtf.SendMsg(EM_HIDESELECTION, FALSE, 0); + m_pDlg.m_hDbEventLast = streamData.hDbEventLast; + + if (m_pDlg.m_isAutoRTL & 1) + m_rtf.SendMsg(EM_SETBKGNDCOLOR, 0, (LOWORD(m_pDlg.m_iLastEventType) & DBEF_SENT) + ? (fAppend ? m_pDlg.m_pContainer->m_theme.outbg : m_pDlg.m_pContainer->m_theme.oldoutbg) + : (fAppend ? m_pDlg.m_pContainer->m_theme.inbg : m_pDlg.m_pContainer->m_theme.oldinbg)); + + if (!(m_pDlg.m_isAutoRTL & 1)) { + GETTEXTLENGTHEX gtxl = { 0 }; + gtxl.codepage = 1200; + gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMCHARS; + + sel.cpMax = m_rtf.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0); + sel.cpMin = sel.cpMax - 1; + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + m_rtf.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)L""); + m_pDlg.m_isAutoRTL |= 2; + } + + BOOL isSent; + if (streamData.dbei != nullptr) + isSent = (streamData.dbei->flags & DBEF_SENT) != 0; + else { + DBEVENTINFO dbei = {}; + db_event_get(hDbEventFirst, &dbei); + isSent = (dbei.flags & DBEF_SENT) != 0; + } + + ReplaceIcons(startAt, fAppend, isSent); + m_pDlg.m_bClrAdded = false; + + int len = GetWindowTextLength(m_rtf.GetHwnd())-1; + m_rtf.SendMsg(EM_SETSEL, len, len); + + m_pDlg.DM_ScrollToBottom(0, 0); + + m_rtf.SendMsg(WM_SETREDRAW, TRUE, 0); + InvalidateRect(m_rtf.GetHwnd(), nullptr, FALSE); + EnableWindow(GetDlgItem(m_pDlg.m_hwnd, IDC_QUOTE), m_pDlg.m_hDbEventLast != 0); + mir_free(streamData.buffer); +} + +void CLogWindow::LogEvents(LOGINFO *lin, bool bRedraw) +{ + auto *si = m_pDlg.m_si; + if (m_rtf.GetHwnd() == nullptr || lin == nullptr || si == nullptr) + return; + + if (!bRedraw && (si->iType == GCW_CHATROOM || si->iType == GCW_PRIVMESS) && m_pDlg.m_bFilterEnabled && (m_pDlg.m_iLogFilterFlags & lin->iType) == 0) + return; + + bool bFlag = false, bDoReplace, bAtBottom = AtBottom(); + + LOGSTREAMDATA streamData; + memset(&streamData, 0, sizeof(streamData)); + streamData.hwnd = m_rtf.GetHwnd(); + streamData.si = si; + streamData.lin = lin; + streamData.bStripFormat = FALSE; + streamData.dat = &m_pDlg; + + EDITSTREAM stream = {}; + stream.pfnCallback = Srmm_LogStreamCallback; + stream.dwCookie = (DWORD_PTR)&streamData; + + POINT point = { 0 }; + m_rtf.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&point); + + // do not scroll to bottom if there is a selection + CHARRANGE oldsel, sel, newsel; + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldsel); + if (oldsel.cpMax != oldsel.cpMin) + m_rtf.SendMsg(WM_SETREDRAW, FALSE, 0); + + // set the insertion point at the bottom + sel.cpMin = sel.cpMax = m_rtf.GetRichTextLength(); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + + // fix for the indent... must be a M$ bug + if (sel.cpMax == 0) + bRedraw = TRUE; + + // should the event(s) be appended to the current log + WPARAM wp = bRedraw ? SF_RTF : SFF_SELECTION | SF_RTF; + + // get the number of pixels per logical inch + if (bRedraw) { + HDC hdc = GetDC(nullptr); + g_chatApi.logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY); + g_chatApi.logPixelSX = GetDeviceCaps(hdc, LOGPIXELSX); + ReleaseDC(nullptr, hdc); + m_rtf.SendMsg(WM_SETREDRAW, FALSE, 0); + bFlag = true; + } + + // stream in the event(s) + streamData.lin = lin; + streamData.bRedraw = bRedraw; + m_rtf.SendMsg(EM_STREAMIN, wp, (LPARAM)&stream); + + // 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))); + + // replace marked nicknames with hyperlinks to make the nicks clickable + if (g_Settings.bClickableNicks) { + FINDTEXTEX fi, fi2; + fi.chrg.cpMin = bRedraw ? 0 : sel.cpMin; + fi.chrg.cpMax = -1; + fi.lpstrText = CLICKNICK_BEGIN; + + while (m_rtf.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) > -1) { + fi2.chrg.cpMin = fi.chrgText.cpMin; + fi2.chrg.cpMax = -1; + fi2.lpstrText = CLICKNICK_END; + + if (m_rtf.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi2) > -1) { + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&fi.chrgText); + m_rtf.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)L""); + + fi2.chrgText.cpMin -= fi.chrgText.cpMax - fi.chrgText.cpMin; + fi2.chrgText.cpMax -= fi.chrgText.cpMax - fi.chrgText.cpMin; + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&fi2.chrgText); + m_rtf.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)L""); + + fi2.chrgText.cpMax = fi2.chrgText.cpMin; + fi2.chrgText.cpMin = fi.chrgText.cpMin; + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&fi2.chrgText); + + CHARFORMAT2 cf2; + memset(&cf2, 0, sizeof(CHARFORMAT2)); + cf2.cbSize = sizeof(cf2); + cf2.dwMask = CFM_PROTECTED; + cf2.dwEffects = CFE_PROTECTED; + m_rtf.SendMsg(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + } + fi.chrg.cpMin = fi.chrgText.cpMax; + } + m_rtf.SendMsg(EM_SETSEL, -1, -1); + } + + // run smileyadd + if (PluginConfig.g_SmileyAddAvail && bDoReplace) { + newsel.cpMax = -1; + newsel.cpMin = sel.cpMin; + if (newsel.cpMin < 0) + newsel.cpMin = 0; + + SMADD_RICHEDIT3 sm = { sizeof(sm) }; + sm.hwndRichEditControl = m_rtf.GetHwnd(); + sm.Protocolname = si->pszModule; + sm.rangeToReplace = bRedraw ? nullptr : &newsel; + sm.disableRedraw = TRUE; + sm.hContact = si->hContact; + CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&sm); + } + + // trim the message log to the number of most recent events + // 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); + + FINDTEXTEX fi; + fi.lpstrText = szPattern; + fi.chrg.cpMin = 0; + fi.chrg.cpMax = -1; + if (m_rtf.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) != 0) { + m_rtf.SendMsg(EM_SETSEL, 0, fi.chrgText.cpMax + 1); + m_rtf.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)L""); + } + si->bTrimmed = false; + } + + // scroll log to bottom if the log was previously scrolled to bottom, else restore old position + if (bRedraw || bAtBottom) + ScrollToBottom(false, false); + else + m_rtf.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&point); + + // do we need to restore the selection + if (oldsel.cpMax != oldsel.cpMin) { + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldsel); + m_rtf.SendMsg(WM_SETREDRAW, TRUE, 0); + InvalidateRect(m_rtf.GetHwnd(), nullptr, TRUE); + } + + // need to invalidate the window + if (bFlag) { + sel.cpMin = sel.cpMax = m_rtf.GetRichTextLength(); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + m_rtf.SendMsg(WM_SETREDRAW, TRUE, 0); + InvalidateRect(m_rtf.GetHwnd(), nullptr, TRUE); + } +} + +void CLogWindow::ReplaceIcons(LONG startAt, int fAppend, BOOL isSent) { wchar_t trbuffer[40]; TEXTRANGE tr; @@ -1062,39 +1486,39 @@ void CMsgDialog::ReplaceIcons(LONG startAt, int fAppend, BOOL isSent) FINDTEXTEX fi; fi.chrg.cpMin = startAt; - if (m_bClrAdded) { + if (m_pDlg.m_bClrAdded) { fi.lpstrText = L"##col##"; fi.chrg.cpMax = -1; CHARFORMAT2 cf2; memset(&cf2, 0, sizeof(cf2)); cf2.cbSize = sizeof(cf2); cf2.dwMask = CFM_COLOR; - while (m_log.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) > -1) { + while (m_rtf.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) > -1) { tr.chrg.cpMin = fi.chrgText.cpMin; tr.chrg.cpMax = tr.chrg.cpMin + 18; trbuffer[0] = 0; - m_log.SendMsg(EM_GETTEXTRANGE, 0, (LPARAM)&tr); + m_rtf.SendMsg(EM_GETTEXTRANGE, 0, (LPARAM)&tr); trbuffer[18] = 0; CHARRANGE cr; cr.cpMin = fi.chrgText.cpMin; cr.cpMax = cr.cpMin + 18; - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&cr); - m_log.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)L""); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&cr); + m_rtf.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)L""); UINT length = (unsigned int)_wtol(&trbuffer[7]); int index = _wtol(&trbuffer[14]); if (length > 0 && length < 20000 && index >= RTF_CTABLE_DEFSIZE && index < Utils::rtf_clrs.getCount()) { cf2.crTextColor = Utils::rtf_clrs[index].clr; cr.cpMin = fi.chrgText.cpMin; cr.cpMax = cr.cpMin + length; - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&cr); - m_log.SendMsg(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&cr); + m_rtf.SendMsg(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); } } } fi.chrg.cpMin = startAt; - if (m_dwFlags & MWF_LOG_SHOWICONS) { + if (m_pDlg.m_dwFlags & MWF_LOG_SHOWICONS) { fi.lpstrText = L"#~#"; fi.chrg.cpMax = -1; @@ -1104,17 +1528,17 @@ void CMsgDialog::ReplaceIcons(LONG startAt, int fAppend, BOOL isSent) cf2.dwMask = CFM_BACKCOLOR; CComPtr ole; - m_log.SendMsg(EM_GETOLEINTERFACE, 0, (LPARAM)&ole); + m_rtf.SendMsg(EM_GETOLEINTERFACE, 0, (LPARAM)&ole); if (ole != nullptr) { - while (m_log.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) > -1) { + while (m_rtf.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) > -1) { CHARRANGE cr; cr.cpMin = fi.chrgText.cpMin; cr.cpMax = fi.chrgText.cpMax + 2; - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&cr); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&cr); tr.chrg.cpMin = fi.chrgText.cpMin + 3; tr.chrg.cpMax = fi.chrgText.cpMin + 5; - m_log.SendMsg(EM_GETTEXTRANGE, 0, (LPARAM)&tr); + m_rtf.SendMsg(EM_GETTEXTRANGE, 0, (LPARAM)&tr); int bIconIndex = trbuffer[0] - '0'; if (bIconIndex >= NR_LOGICONS) { @@ -1123,14 +1547,14 @@ void CMsgDialog::ReplaceIcons(LONG startAt, int fAppend, BOOL isSent) } char bDirection = trbuffer[1]; - m_log.SendMsg(EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); + m_rtf.SendMsg(EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2); COLORREF crDefault; if (cf2.crBackColor != 0) crDefault = cf2.crBackColor; else if (bDirection == '>') - crDefault = (fAppend) ? m_pContainer->m_theme.outbg : m_pContainer->m_theme.oldoutbg; + crDefault = (fAppend) ? m_pDlg.m_pContainer->m_theme.outbg : m_pDlg.m_pContainer->m_theme.oldoutbg; else - crDefault = (fAppend) ? m_pContainer->m_theme.inbg : m_pContainer->m_theme.oldinbg; + crDefault = (fAppend) ? m_pDlg.m_pContainer->m_theme.inbg : m_pDlg.m_pContainer->m_theme.oldinbg; TLogIcon theIcon(Logicons[bIconIndex], crDefault); CImageDataObject::InsertBitmap(ole, theIcon.m_hBmp); @@ -1146,9 +1570,9 @@ void CMsgDialog::ReplaceIcons(LONG startAt, int fAppend, BOOL isSent) sel.cpMax = -1; SMADD_RICHEDIT3 smadd = { sizeof(smadd) }; - smadd.hwndRichEditControl = m_log.GetHwnd(); - smadd.Protocolname = const_cast(m_cache->getActiveProto()); - smadd.hContact = m_cache->getActiveContact(); + smadd.hwndRichEditControl = m_rtf.GetHwnd(); + smadd.Protocolname = const_cast(m_pDlg.m_cache->getActiveProto()); + smadd.hContact = m_pDlg.m_cache->getActiveContact(); smadd.flags = isSent ? SAFLRE_OUTGOING : 0; if (startAt > 0) smadd.rangeToReplace = &sel; @@ -1158,190 +1582,76 @@ void CMsgDialog::ReplaceIcons(LONG startAt, int fAppend, BOOL isSent) CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&smadd); } - if (m_hHistoryEvents && m_curHistory == m_maxHistory) { + if (m_pDlg.m_hHistoryEvents && m_pDlg.m_curHistory == m_pDlg.m_maxHistory) { wchar_t szPattern[50]; - mir_snwprintf(szPattern, L"~-+%d+-~", m_hHistoryEvents[0]); + mir_snwprintf(szPattern, L"~-+%d+-~", m_pDlg.m_hHistoryEvents[0]); FINDTEXTEX ft; ft.lpstrText = szPattern; ft.chrg.cpMin = 0; ft.chrg.cpMax = -1; - if (m_log.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&ft) != 0) { + if (m_rtf.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&ft) != 0) { CHARRANGE sel; sel.cpMin = 0; sel.cpMax = 20; - m_log.SendMsg(EM_SETSEL, 0, ft.chrgText.cpMax + 1); - m_log.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)L""); + m_rtf.SendMsg(EM_SETSEL, 0, ft.chrgText.cpMax + 1); + m_rtf.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)L""); } } } -void CMsgDialog::StreamInEvents(MEVENT hDbEventFirst, int count, int fAppend, DBEVENTINFO *dbei_s) +void CLogWindow::ScrollToBottom() { - CHARRANGE oldSel, sel; - - // calc time limit for grouping - HWND hwndrtf = m_hwndIEView ? m_hwndIWebBrowserControl : m_log.GetHwnd(); - - rtfFonts = m_pContainer->m_theme.rtfFonts ? m_pContainer->m_theme.rtfFonts : &(rtfFontsGlobal[0][0]); - time_t now = time(0); + ScrollToBottom(false, false); +} - struct tm tm_now = *localtime(&now); - struct tm tm_today = tm_now; - tm_today.tm_hour = tm_today.tm_min = tm_today.tm_sec = 0; - today = mktime(&tm_today); +void CLogWindow::ScrollToBottom(bool bImmediate, bool bRedraw) +{ + if (bRedraw) + SendMessage(m_rtf.GetHwnd(), WM_SIZE, 0, 0); - if (m_hwndIEView != nullptr || m_hwndHPP != nullptr) { - const char *pszService; - IEVIEWEVENT event = {}; - event.hContact = m_hContact; - if (m_hwndIEView != nullptr) { - event.pszProto = m_szProto; - event.hwnd = m_hwndIEView; - pszService = MS_IEVIEW_EVENT; - } - else { - event.hwnd = m_hwndHPP; - pszService = MS_HPP_EG_EVENT; - } + if (bImmediate && bRedraw) { + int len = GetWindowTextLength(m_rtf.GetHwnd()); + SendMessage(m_rtf.GetHwnd(), EM_SETSEL, len - 1, len - 1); + } - if (m_dwFlags & MWF_LOG_RTL) - event.dwFlags = IEEF_RTL; + if (bImmediate) + SendMessage(m_rtf.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0); + else + PostMessage(m_rtf.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0); - if (!fAppend) { - event.iType = IEE_CLEAR_LOG; - CallService(pszService, 0, (LPARAM)&event); - } + if (bRedraw) + InvalidateRect(m_rtf.GetHwnd(), nullptr, FALSE); +} - IEVIEWEVENTDATA evData = { 0 }; - if (dbei_s != nullptr && hDbEventFirst == 0) { - event.iType = IEE_LOG_MEM_EVENTS; - if (dbei_s->flags & DBEF_SENT) { - evData.dwFlags = IEEDF_SENT; - evData.bIsMe = true; - } - else { - evData.dwFlags = IEEDF_UNICODE_NICK; - evData.szNick.w = Clist_GetContactDisplayName(m_hContact); - } - switch (dbei_s->eventType) { - case EVENTTYPE_STATUSCHANGE: evData.iType = IEED_EVENT_STATUSCHANGE; break; - case EVENTTYPE_FILE: evData.iType = IEED_EVENT_FILE; break; - case EVENTTYPE_ERRMSG: evData.iType = IEED_EVENT_ERRMSG; break; - default: evData.iType = IEED_EVENT_MESSAGE; break; - } - evData.szText.a = (char*)dbei_s->pBlob; - evData.time = dbei_s->timestamp; - event.eventData = &evData; - event.codepage = CP_UTF8; - } - else { - event.iType = IEE_LOG_DB_EVENTS; - event.hDbEventFirst = hDbEventFirst; +void CLogWindow::UpdateOptions() +{ + COLORREF colour = m_pDlg.isChat() ? g_Settings.crLogBackground : db_get_dw(0, FONTMODULE, SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR); + m_rtf.SendMsg(EM_SETBKGNDCOLOR, 0, colour); + + if (!m_pDlg.isChat()) { + PARAFORMAT2 pf2; + pf2.wEffects = PFE_RTLPARA; + pf2.dwMask |= PFM_OFFSET; + if (m_pDlg.m_dwFlags & MWF_INITMODE) { + pf2.dwMask |= (PFM_RIGHTINDENT | PFM_OFFSETINDENT); + pf2.dxStartIndent = 30; + pf2.dxRightIndent = 30; } - event.count = count; - CallService(pszService, 0, (LPARAM)&event); - DM_ScrollToBottom(0, 0); - if (fAppend && hDbEventFirst) - m_hDbEventLast = hDbEventFirst; - else - m_hDbEventLast = db_event_last(m_hContact); - return; - } - - // separator strings used for grid lines, message separation and so on... - m_bClrAdded = false; - - if (m_szMicroLf[0] == 0) { - if (m_hHistoryEvents) - strncpy_s(m_szMicroLf, "\\v\\cf%d \\ ~-+%d+-~\\v0 ", _TRUNCATE); + pf2.dxOffset = m_pDlg.m_pContainer->m_theme.left_indent + 30; + m_rtf.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); + + m_rtf.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_rtf.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD); + + // set the scrollbars etc to RTL/LTR (only for manual RTL mode) + if (m_pDlg.m_dwFlags & MWF_LOG_RTL) + SetWindowLongPtr(m_rtf.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_rtf.GetHwnd(), GWL_EXSTYLE) | WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR); else - mir_snprintf(m_szMicroLf, "%s\\par\\ltrpar\\sl-1%s ", GetRTFFont(MSGDLGFONTCOUNT), GetRTFFont(MSGDLGFONTCOUNT)); - } - - szYourName = const_cast(m_cache->getNick()); - szMyName = m_wszMyNickname; - - m_log.SendMsg(EM_HIDESELECTION, TRUE, 0); - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldSel); - - LogStreamData streamData = { 0 }; - streamData.hContact = m_hContact; - streamData.hDbEvent = hDbEventFirst; - streamData.dlgDat = this; - streamData.eventsToInsert = count; - streamData.isEmpty = fAppend ? GetWindowTextLength(hwndrtf) == 0 : 1; - 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 }; - gtxl.codepage = 1200; - gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMCHARS; - startAt = m_log.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0); - sel.cpMin = sel.cpMax = GetWindowTextLength(hwndrtf); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - } - else { - SetWindowText(hwndrtf, L""); - sel.cpMin = 0; - sel.cpMax = GetWindowTextLength(hwndrtf); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - startAt = 0; - m_isAutoRTL = 0; + SetWindowLongPtr(m_rtf.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_rtf.GetHwnd(), GWL_EXSTYLE) & ~(WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR)); } +} - // begin to draw - m_log.SendMsg(WM_SETREDRAW, FALSE, 0); - - m_log.SendMsg(EM_STREAMIN, fAppend ? SFF_SELECTION | SF_RTF : SFF_SELECTION | SF_RTF, (LPARAM)&stream); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldSel); - m_log.SendMsg(EM_HIDESELECTION, FALSE, 0); - m_hDbEventLast = streamData.hDbEventLast; - - if (m_isAutoRTL & 1) - m_log.SendMsg(EM_SETBKGNDCOLOR, 0, (LOWORD(m_iLastEventType) & DBEF_SENT) - ? (fAppend ? m_pContainer->m_theme.outbg : m_pContainer->m_theme.oldoutbg) - : (fAppend ? m_pContainer->m_theme.inbg : m_pContainer->m_theme.oldinbg)); - - if (!(m_isAutoRTL & 1)) { - GETTEXTLENGTHEX gtxl = { 0 }; - gtxl.codepage = 1200; - gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMCHARS; - - sel.cpMax = m_log.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0); - sel.cpMin = sel.cpMax - 1; - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - m_log.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)L""); - m_isAutoRTL |= 2; - } - - BOOL isSent; - if (streamData.dbei != nullptr) - isSent = (streamData.dbei->flags & DBEF_SENT) != 0; - else { - DBEVENTINFO dbei = {}; - db_event_get(hDbEventFirst, &dbei); - isSent = (dbei.flags & DBEF_SENT) != 0; - } - - ReplaceIcons(startAt, fAppend, isSent); - m_bClrAdded = false; - - if (m_hwndIEView == nullptr && m_hwndHPP == nullptr) { - int len = GetWindowTextLength(hwndrtf)-1; - m_log.SendMsg(EM_SETSEL, len, len); - } - - DM_ScrollToBottom(0, 0); - - m_log.SendMsg(WM_SETREDRAW, TRUE, 0); - InvalidateRect(hwndrtf, nullptr, FALSE); - EnableWindow(GetDlgItem(m_hwnd, IDC_QUOTE), m_hDbEventLast != 0); - mir_free(streamData.buffer); +CSrmmLogWindow *logBuilder(CMsgDialog &pDlg) +{ + return new CLogWindow(pDlg); } diff --git a/plugins/TabSRMM/src/msgoptions.cpp b/plugins/TabSRMM/src/msgoptions.cpp index ab2cb125fa..2f8418ed32 100644 --- a/plugins/TabSRMM/src/msgoptions.cpp +++ b/plugins/TabSRMM/src/msgoptions.cpp @@ -604,27 +604,14 @@ class COptLogDlg : public CDlgBase { CCtrlSpin spnLeft, spnRight, spnLoadCount, spnLoadTime, spnTrim; CCtrlCheck chkAlwaysTrim, chkLoadUnread, chkLoadCount, chkLoadTime; - CCtrlCombo cmbLogDisplay; CCtrlButton btnModify, btnRtlModify; CCtrlTreeView logOpts; - bool have_ieview, have_hpp; - // configure the option page - hide most of the settings here when either IEView // or H++ is set as the global message log viewer. Showing these options may confuse // the user, because they are not working and the user needs to configure the 3rd // party plugin. - void ShowHide() - { - LRESULT r = cmbLogDisplay.GetCurSel(); - Utils::showDlgControl(m_hwnd, IDC_EXPLAINMSGLOGSETTINGS, r == 0 ? SW_HIDE : SW_SHOW); - logOpts.Show(r == 0); - - for (auto &it : __ctrls) - Utils::enableDlgControl(m_hwnd, it, r == 0); - } - public: COptLogDlg() : CDlgBase(g_plugin, IDD_OPT_MSGLOG), @@ -639,19 +626,13 @@ public: chkLoadTime(this, IDC_LOADTIME), chkLoadCount(this, IDC_LOADCOUNT), chkAlwaysTrim(this, IDC_ALWAYSTRIM), - chkLoadUnread(this, IDC_LOADUNREAD), - cmbLogDisplay(this, IDC_MSGLOGDIDSPLAY) + chkLoadUnread(this, IDC_LOADUNREAD) { btnModify.OnClick = Callback(this, &COptLogDlg::onClick_Modify); btnRtlModify.OnClick = Callback(this, &COptLogDlg::onClick_RtlModify); - cmbLogDisplay.OnChange = Callback(this, &COptLogDlg::onChange_Combo); - chkAlwaysTrim.OnChange = Callback(this, &COptLogDlg::onChange_Trim); chkLoadTime.OnChange = chkLoadCount.OnChange = chkLoadUnread.OnChange = Callback(this, &COptLogDlg::onChange_Load); - - have_ieview = ServiceExists(MS_IEVIEW_WINDOW) != 0; - have_hpp = ServiceExists(MS_HPP_GETVERSION) != 0; } bool OnInitDialog() override @@ -687,33 +668,11 @@ public: spnTrim.Enable(maxhist != 0); Utils::enableDlgControl(m_hwnd, IDC_TRIM, maxhist != 0); chkAlwaysTrim.SetState(maxhist != 0); - - cmbLogDisplay.AddString(TranslateT("Internal message log")); - cmbLogDisplay.SetCurSel(0); - if (have_ieview || have_hpp) { - if (have_ieview) { - cmbLogDisplay.AddString(TranslateT("IEView plugin")); - if (M.GetByte("default_ieview", 0)) - cmbLogDisplay.SetCurSel(1); - } - if (have_hpp) { - cmbLogDisplay.AddString(TranslateT("History++ plugin")); - if (M.GetByte("default_ieview", 0)) - cmbLogDisplay.SetCurSel(1); - else if (M.GetByte("default_hpp", 0)) - cmbLogDisplay.SetCurSel(have_ieview ? 2 : 1); - } - } - else cmbLogDisplay.Disable(); - - SetDlgItemText(m_hwnd, IDC_EXPLAINMSGLOGSETTINGS, TranslateT("You have chosen to use an external plugin for displaying the message history in the chat window. Most of the settings on this page are for the standard message log viewer only and will have no effect. To change the appearance of the message log, you must configure either IEView or History++.")); - ShowHide(); return true; } bool OnApply() override { - LRESULT msglogmode = cmbLogDisplay.GetCurSel(); DWORD dwFlags = M.GetDword("mwflags", MWF_LOG_DEFAULT); dwFlags &= ~(MWF_LOG_ALL); @@ -730,22 +689,6 @@ public: db_set_dw(0, SRMSGMOD_T, "IndentAmount", spnLeft.GetPosition()); db_set_dw(0, SRMSGMOD_T, "RightIndent", spnRight.GetPosition()); - db_set_b(0, SRMSGMOD_T, "default_ieview", 0); - db_set_b(0, SRMSGMOD_T, "default_hpp", 0); - switch (msglogmode) { - case 0: - break; - case 1: - if (have_ieview) - db_set_b(0, SRMSGMOD_T, "default_ieview", 1); - else - db_set_b(0, SRMSGMOD_T, "default_hpp", 1); - break; - case 2: - db_set_b(0, SRMSGMOD_T, "default_hpp", 1); - break; - } - // scan the tree view and obtain the options... TreeViewToDB(logOpts, lvItemsLog, SRMSGMOD_T, &dwFlags); db_set_dw(0, SRMSGMOD_T, "mwflags", dwFlags); @@ -788,11 +731,6 @@ public: CTemplateEditDlg *pDlg = new CTemplateEditDlg(TRUE, m_hwnd); pDlg->Show(); } - - void onChange_Combo(CCtrlCombo*) - { - ShowHide(); - } }; ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/TabSRMM/src/msgs.h b/plugins/TabSRMM/src/msgs.h index 9d299951ad..a5663202cc 100644 --- a/plugins/TabSRMM/src/msgs.h +++ b/plugins/TabSRMM/src/msgs.h @@ -248,10 +248,52 @@ struct TContainerData : public MZeroedObject } }; +///////////////////////////////////////////////////////////////////////////////////////// +// CLogWindow - built-in log window + +class CLogWindow : public CRtfLogWindow +{ + typedef CRtfLogWindow CSuper; + +public: + CLogWindow(CMsgDialog &pDlg) : + CSuper(pDlg) + { + } + + void Attach() override; + void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) override; + void LogEvents(DBEVENTINFO *dbei, bool bAppend) override; + void LogEvents(struct LOGINFO *, bool) override; + void ScrollToBottom() override; + void UpdateOptions() override; + + void DisableStaticEdge() + { + SetWindowLongPtr(m_rtf.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_rtf.GetHwnd(), GWL_EXSTYLE) & ~WS_EX_STATICEDGE); + } + + char* GetRichTextRtf(bool bText, bool bSelection) + { + return m_rtf.GetRichTextRtf(bText, bSelection); + } + + void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend, DBEVENTINFO *dbei); + void ReplaceIcons(LONG startAt, int fAppend, BOOL isSent); + void ScrollToBottom(bool, bool); + + INT_PTR WndProc(UINT msg, WPARAM wParam, LPARAM lParam) override; +}; + +///////////////////////////////////////////////////////////////////////////////////////// +// CMsgDialog - SRMM window class + class CMsgDialog : public CSrmmBaseDialog { typedef CSrmmBaseDialog CSuper; friend class CInfoPanel; + friend class CLogWindow; + friend class CProxyWindow; void BB_InitDlgButtons(void); void BB_RefreshTheme(void); @@ -298,12 +340,9 @@ class CMsgDialog : public CSrmmBaseDialog void LoadOwnAvatar(void); void LoadSplitter(void); void PlayIncomingSound(void) const; - void ReplaceIcons(LONG startAt, int fAppend, BOOL isSent); void ReplayQueue(void); - void ResizeIeView(void); void SaveAvatarToFile(HBITMAP hbm, int isOwnPic); void SendHBitmapAsFile(HBITMAP hbmp) const; - void SetMessageLog(void); void ShowPopupMenu(const CCtrlBase&, POINT pt); void UpdateWindowIcon(void); void UpdateWindowState(UINT msg); @@ -322,6 +361,7 @@ class CMsgDialog : public CSrmmBaseDialog int m_originalSplitterY; SIZE m_minEditBoxSize; int m_nTypeMode; + int m_iLogMode; DWORD m_nLastTyping; DWORD m_lastMessage; DWORD m_dwTickLastEvent; @@ -382,7 +422,6 @@ public: DWORD m_dwFlags = MWF_INITMODE, m_dwFlagsEx; DWORD m_dwUnread; HANDLE m_hTheme, m_hThemeIP, m_hThemeToolbar; - HWND m_hwndIEView, m_hwndIWebBrowserControl, m_hwndHPP; HICON m_hXStatusIcon, m_hTabStatusIcon, m_hTabIcon, m_iFlashIcon, m_hTaskbarIcon, m_hClientIcon; MEVENT m_hDbEventFirst, m_hDbEventLast; HANDLE m_hTimeZone; @@ -452,17 +491,14 @@ public: int Resizer(UTILRESIZECONTROL *urc) override; INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override; - LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override; LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override; LRESULT WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) override; void AddLog() override; void CloseTab() override; void LoadSettings() override; - void ScrollToBottom() override; void SetStatusText(const wchar_t *, HICON) override; void ShowFilterMenu() override; - void StreamInEvents(LOGINFO *lin, bool bRedraw) override; void UpdateNickList() override; void UpdateOptions() override; void UpdateStatusBar() override; @@ -476,6 +512,14 @@ public: __forceinline CCtrlRichEdit& GetEntry() { return m_message; } + __forceinline CLogWindow* LOG() { + return ((CLogWindow *)m_pLog); + } + + __forceinline void LogEvent(DBEVENTINFO *dbei) { + m_pLog->LogEvents(dbei, 1); + } + bool IsActive() const override { return m_pContainer->IsActive() && m_pContainer->m_hwndActive == m_hwnd; @@ -483,7 +527,6 @@ public: void DM_OptionsApplied(WPARAM wParam, LPARAM lParam); void DM_RecalcPictureSize(void); - void DM_SaveLogAsRTF(void) const; void DM_ScrollToBottom(WPARAM wParam, LPARAM lParam); void ActivateTooltip(int iCtrlId, const wchar_t *pwszMessage); @@ -508,7 +551,6 @@ public: void SetDialogToType(void); void ShowPicture(bool showNewPic); void SplitterMoved(int x, HWND hwnd); - void StreamInEvents(MEVENT hDbEventFirst, int count, int fAppend, DBEVENTINFO *dbei_s); void UpdateReadChars(void) const; void UpdateSaveAndSendButton(void); @@ -733,7 +775,6 @@ struct TIconDescW #define DM_SC_BUILDLIST (TM_USER+100) #define DM_SC_INITDIALOG (TM_USER+101) #define DM_SC_CONFIG (TM_USER+104) -#define DM_SCROLLIEVIEW (TM_USER+102) #define DM_UPDATEUIN (TM_USER+103) #define MINSPLITTERX 60 @@ -1058,6 +1099,9 @@ struct SKINDESC struct CMPlugin : public PLUGIN { + HANDLE hLogger; + void InitLogger(); + CMPlugin(); int Load() override; diff --git a/plugins/TabSRMM/src/resource.h b/plugins/TabSRMM/src/resource.h index 3c1ca3f16e..53f6768ff5 100644 --- a/plugins/TabSRMM/src/resource.h +++ b/plugins/TabSRMM/src/resource.h @@ -1,6 +1,6 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by ..\..\res\resource.rc +// Used by w:\miranda-ng\plugins\TabSRMM\res\resource.rc // #define IDD_TEMPLATEEDIT 1 #define IDD_USERPREFS 2 @@ -187,7 +187,6 @@ #define IDC_STMSGLOGGROUP 1139 #define IDC_PROTOCOL 1140 #define IDC_STMSGLOGGROUP2 1140 -#define IDC_STMSGLOGGROUP3 1141 #define IDC_PROTOMENU 1141 #define IDC_TYPING 1143 #define IDC_TOGGLETOOLBAR 1144 @@ -315,7 +314,6 @@ #define IDC_SINGLEROWTAB 1263 #define IDC_STREAMTHREADING 1264 #define IDC_TABBORDEROUTERBOTTOM 1264 -#define IDC_IEVIEWMODE 1265 #define IDC_TABBORDERSPINOUTERBOTTOM 1265 #define IDC_TEXTFORMATTING 1266 #define IDC_AVATARMODE 1267 @@ -439,7 +437,6 @@ #define IDC_TITLEBOX 1402 #define IDC_DESC 1404 #define IDC_LABEL_PRIVATETHEME 1405 -#define IDC_MSGLOGDIDSPLAY 1407 #define IDC_BOTTOMTOOLBAR 1414 #define IDC_BUTTON1 1415 #define IDC_PLUS_REVERT 1415 @@ -472,7 +469,6 @@ #define IDC_GROUP_OTHER 1435 #define IDC_SIZE_TIP 1436 #define IDC_IPCONFIG_PRIVATECONTAINER 1437 -#define IDC_EXPLAINMSGLOGSETTINGS 1437 #define IDC_PANELPICTUREVIS 1438 #define IDC_SKINNAME 1438 #define IDC_SKINROOTFOLDER 1439 @@ -621,7 +617,6 @@ #define ID_WINDOWFLASHING_USEDEFAULTVALUES 40106 #define ID_WINDOWFLASHING_FLASHUNTILFOCUSED 40107 #define ID_WINDOWFLASHING_DISABLEFLASHING 40108 -#define ID_FILE_SAVEMESSAGELOGAS 40109 #define ID_EVENTPOPUPS_SHOWPOPUPSIFWINDOWISMINIMIZED 40110 #define ID_EVENTPOPUPS_SHOWPOPUPSIFWINDOWISUNFOCUSED 40111 #define ID_EVENTPOPUPS_SHOWPOPUPSFORALLINACTIVESESSIONS 40112 @@ -720,3 +715,14 @@ #define ID_QUEUEMANAGER_RESUMESELECTED 40259 #define ID_QUEUEMANAGER_CANCELALLMULTISENDJOBS 40260 #define ID_QUEUEMANAGER_COPYMESSAGETOCLIPBOARD 40261 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/TabSRMM/src/sendqueue.cpp b/plugins/TabSRMM/src/sendqueue.cpp index 78744e7138..d71d647ef6 100644 --- a/plugins/TabSRMM/src/sendqueue.cpp +++ b/plugins/TabSRMM/src/sendqueue.cpp @@ -361,7 +361,7 @@ void SendQueue::logError(CMsgDialog *dat, int iSendJobIndex, const wchar_t *szEr dbei.cbBlob = (int)iMsgLen; dbei.timestamp = time(0); dbei.szModule = (char *)szErrMsg; - dat->StreamInEvents(0, 1, 1, &dbei); + dat->LogEvent(&dbei); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -557,7 +557,8 @@ int SendQueue::doSendLater(int iJobIndex, CMsgDialog *dat, MCONTACT hContact, bo dbei.timestamp = time(0); dbei.cbBlob = (int)mir_strlen(utfText) + 1; dbei.pBlob = (PBYTE)(char*)utfText; - dat->StreamInEvents(0, 1, 1, &dbei); + dat->LogEvent(&dbei); + if (dat->m_hDbEventFirst == 0) dat->RemakeLog(); dat->m_cache->saveHistory(); diff --git a/plugins/TabSRMM/src/srmm.cpp b/plugins/TabSRMM/src/srmm.cpp index 608d6b919f..00f154fd81 100644 --- a/plugins/TabSRMM/src/srmm.cpp +++ b/plugins/TabSRMM/src/srmm.cpp @@ -70,6 +70,8 @@ int CMPlugin::Load() SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfDefault), &lfDefault, FALSE); + hLogger = RegisterSrmmLog("built-in", L"tabSRMM internal log", &logBuilder); + Chat_Load(); return LoadSendRecvMessageModule(); @@ -79,6 +81,7 @@ int CMPlugin::Load() int CMPlugin::Unload() { + UnregisterSrmmLog(hLogger); FreeLogFonts(); Chat_Unload(); int iRet = SplitmsgShutdown(); diff --git a/plugins/TabSRMM/src/stdafx.h b/plugins/TabSRMM/src/stdafx.h index 97cd4a1989..61714812ac 100644 --- a/plugins/TabSRMM/src/stdafx.h +++ b/plugins/TabSRMM/src/stdafx.h @@ -247,6 +247,8 @@ void TreeViewToDB(CCtrlTreeView&, TOptionListItem *lvItems, const char *DBPath, INT_PTR CALLBACK DlgProcSetupStatusModes(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +CSrmmLogWindow *logBuilder(CMsgDialog &pDlg); + int TSAPI TBStateConvert2Flat(int state); int TSAPI RBStateConvert2Flat(int state); void TSAPI FillTabBackground(const HDC hdc, int iStateId, const CMsgDialog *dat, RECT* rc); diff --git a/plugins/TabSRMM/src/taskbar.cpp b/plugins/TabSRMM/src/taskbar.cpp index 6def0b6f2f..b4a8257695 100644 --- a/plugins/TabSRMM/src/taskbar.cpp +++ b/plugins/TabSRMM/src/taskbar.cpp @@ -275,13 +275,11 @@ void CProxyWindow::sendPreview() HDC hdc, dc; int twips = (int)(15.0f / PluginConfig.m_DPIscaleY); bool fIsChat = m_dat->isChat(); - HWND hwndRich = ::GetDlgItem(m_dat->GetHwnd(), IDC_SRMM_LOG); - LONG cx, cy; + HWND hwndRich = m_dat->m_pLog->GetHwnd(); POINT ptOrigin = { 0 }, ptBottom; if (m_dat->m_dwFlags & MWF_NEEDCHECKSIZE) { RECT rcClient; - ::SendMessage(m_dat->m_pContainer->m_hwnd, DM_QUERYCLIENTAREA, 0, (LPARAM)&rcClient); ::MoveWindow(m_dat->GetHwnd(), rcClient.left, rcClient.top, (rcClient.right - rcClient.left), (rcClient.bottom - rcClient.top), FALSE); ::SendMessage(m_dat->GetHwnd(), WM_SIZE, 0, 0); @@ -308,8 +306,8 @@ void CProxyWindow::sendPreview() ptBottom.y = rcTemp.bottom; ::ScreenToClient(m_dat->m_pContainer->m_hwnd, &ptBottom); - cx = rcLog.right - rcLog.left; - cy = rcLog.bottom - rcLog.top; + int cx = rcLog.right - rcLog.left; + int cy = rcLog.bottom - rcLog.top; rcRich.left = 0; rcRich.top = 0; rcRich.right = cx; @@ -337,9 +335,9 @@ void CProxyWindow::sendPreview() ::FillRect(hdcRich, &rcRich, br); ::DeleteObject(br); - if (m_dat->m_hwndIEView) - ::SendMessage(m_dat->m_hwndIEView, WM_PRINT, reinterpret_cast(hdcRich), PRF_CLIENT | PRF_NONCLIENT); - else if (m_dat->m_hwndHPP) { + if (m_dat->m_iLogMode == WANT_IEVIEW_LOG) + ::SendMessage(hwndRich, WM_PRINT, reinterpret_cast(hdcRich), PRF_CLIENT | PRF_NONCLIENT); + else if (m_dat->m_iLogMode == WANT_HPP_LOG) { CSkin::RenderText(hdcRich, m_dat->m_hTheme, TranslateT("Previews not available when using History++ plugin for message log display."), &rcRich, DT_VCENTER | DT_CENTER | DT_WORDBREAK, 10, m_dat->m_pContainer->m_theme.fontColors[MSGFONTID_MYMSG], false); } @@ -353,7 +351,6 @@ void CProxyWindow::sendPreview() fr.rcPage = rcRich; fr.chrg.cpMax = -1; fr.chrg.cpMin = first; - ::SendMessage(hwndRich, EM_FORMATRANGE, 1, LPARAM(&fr)); } diff --git a/plugins/TabSRMM/src/templates.cpp b/plugins/TabSRMM/src/templates.cpp index f03ba9ceab..0c40f44129 100644 --- a/plugins/TabSRMM/src/templates.cpp +++ b/plugins/TabSRMM/src/templates.cpp @@ -125,6 +125,8 @@ CTemplateEditDlg::CTemplateEditDlg(BOOL _rtl, HWND hwndParent) : { SetParent(hwndParent); + m_pLog = new CLogWindow(*this); + m_pContainer = new TContainerData(); m_pContainer->LoadOverrideTheme(); tSet = rtl ? m_pContainer->m_rtl_templates : m_pContainer->m_ltr_templates; @@ -143,10 +145,6 @@ CTemplateEditDlg::CTemplateEditDlg(BOOL _rtl, HWND hwndParent) : bool CTemplateEditDlg::OnInitDialog() { - m_log.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK); - m_log.SendMsg(EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, SES_EXTENDBACKCOLOR); - m_log.SendMsg(EM_EXLIMITTEXT, 0, 0x80000000); - // set hContact to the first found contact so that we can use the Preview window properly // also, set other parameters needed by the streaming function to display events m_hContact = db_find_first(); @@ -250,13 +248,12 @@ void CTemplateEditDlg::onClick_Preview(CCtrlButton*) dbei.flags |= (rtl ? DBEF_RTL : 0); m_lastEventTime = (iIndex == 4 || iIndex == 5) ? time(0) - 1 : 0; m_iLastEventType = MAKELONG(dbei.flags, dbei.eventType); - m_log.SetText(L""); m_dwFlags = MWF_LOG_ALL; m_dwFlags = (rtl ? 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, L"My Nickname"); - StreamInEvents(0, 1, 0, &dbei); - m_log.SendMsg(EM_SETSEL, -1, -1); + m_pLog->Clear(); + LogEvent(&dbei); if (changed) memcpy(tSet->szTemplates[inEdit], szTemp, TEMPLATE_LENGTH * sizeof(wchar_t)); } diff --git a/plugins/TabSRMM/src/themes.cpp b/plugins/TabSRMM/src/themes.cpp index a1b2368a04..64bd4d7a18 100644 --- a/plugins/TabSRMM/src/themes.cpp +++ b/plugins/TabSRMM/src/themes.cpp @@ -2155,7 +2155,7 @@ void CMsgDialog::RenderToolbarBG(HDC hdc, const RECT &rcWindow) const POINT pt; if (!(m_pContainer->m_dwFlags & CNT_BOTTOMTOOLBAR)) { - ::GetWindowRect(m_log.GetHwnd(), &rc); + ::GetWindowRect(m_pLog->GetHwnd(), &rc); pt.y = rc.bottom + 0; ::ScreenToClient(m_hwnd, &pt); rcToolbar.top = pt.y; @@ -2404,7 +2404,7 @@ void CSkin::extractSkinsAndLogo(bool fForceOverwrite) const void CMsgDialog::UpdateToolbarBG() { RECT rcUpdate, rcTmp; - ::GetWindowRect(m_log.GetHwnd(), &rcTmp); + ::GetWindowRect(m_pLog->GetHwnd(), &rcTmp); POINT pt; pt.x = rcTmp.left; diff --git a/plugins/TabSRMM/src/userprefs.cpp b/plugins/TabSRMM/src/userprefs.cpp index 7c259f6cff..1bb65f45f6 100644 --- a/plugins/TabSRMM/src/userprefs.cpp +++ b/plugins/TabSRMM/src/userprefs.cpp @@ -35,8 +35,6 @@ #define UPREF_ACTION_REMAKELOG 2 #define UPREF_ACTION_SWITCHLOGVIEWER 4 -static int have_ieview = 0, have_hpp = 0; - static INT_PTR CALLBACK DlgProcUserPrefs(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { MCONTACT hContact = (MCONTACT)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); @@ -47,16 +45,11 @@ static INT_PTR CALLBACK DlgProcUserPrefs(HWND hwndDlg, UINT msg, WPARAM wParam, { hContact = lParam; DWORD maxhist = M.GetDword(hContact, "maxhist", 0); - BYTE bIEView = M.GetByte(hContact, "ieview", 0); - BYTE bHPP = M.GetByte(hContact, "hpplog", 0); int iLocalFormat = M.GetDword(hContact, "sendformat", 0); BYTE bSplit = M.GetByte(hContact, "splitoverride", 0); BYTE bInfoPanel = M.GetByte(hContact, "infopanel", 0); BYTE bAvatarVisible = M.GetByte(hContact, "hideavatar", -1); - have_ieview = ServiceExists(MS_IEVIEW_WINDOW); - have_hpp = ServiceExists(MS_HPP_GETVERSION); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam); SendDlgItemMessage(hwndDlg, IDC_INFOPANEL, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Use global setting")); @@ -69,33 +62,6 @@ static INT_PTR CALLBACK DlgProcUserPrefs(HWND hwndDlg, UINT msg, WPARAM wParam, SendDlgItemMessage(hwndDlg, IDC_SHOWAVATAR, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Never show it at all")); SendDlgItemMessage(hwndDlg, IDC_SHOWAVATAR, CB_SETCURSEL, bAvatarVisible == 0xff ? 0 : (bAvatarVisible == 1 ? 1 : 2), 0); - SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Use global setting")); - SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Force default message log")); - - SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_SETITEMDATA, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_SETITEMDATA, 1, 1); - - if (have_hpp) { - SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Force History++")); - SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_SETITEMDATA, 2, 2); - } - - if (have_ieview) { - SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Force IEView")); - SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_SETITEMDATA, have_hpp ? 3 : 2, 3); - } - - if (bIEView == 0 && bHPP == 0) - SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_SETCURSEL, 0, 0); - else if (bIEView == 0xff && bHPP == 0xff) - SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_SETCURSEL, 1, 0); - else { - if (bHPP == 1) - SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_SETCURSEL, have_hpp ? 2 : 0, 0); - if (bIEView == 1) - SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_SETCURSEL, (have_hpp && have_ieview) ? 3 : (have_ieview ? 2 : 0), 0); - } - SendDlgItemMessage(hwndDlg, IDC_TEXTFORMATTING, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Use global setting")); SendDlgItemMessage(hwndDlg, IDC_TEXTFORMATTING, CB_INSERTSTRING, -1, (LPARAM)TranslateT("BBCode")); SendDlgItemMessage(hwndDlg, IDC_TEXTFORMATTING, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Force off")); @@ -134,46 +100,14 @@ static INT_PTR CALLBACK DlgProcUserPrefs(HWND hwndDlg, UINT msg, WPARAM wParam, case WM_USER + 100: CMsgDialog *dat = nullptr; DWORD *pdwActionToTake = (DWORD *)lParam; - unsigned int iOldIEView = 0; HWND hWnd = Srmm_FindWindow(hContact); BYTE bOldInfoPanel = M.GetByte(hContact, "infopanel", 0); - if (hWnd) { + if (hWnd) dat = (CMsgDialog*)GetWindowLongPtr(hWnd, GWLP_USERDATA); - if (dat) - iOldIEView = GetIEViewMode(dat->m_hContact); - } - int iIndex = SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_GETCURSEL, 0, 0); - int iMode = SendDlgItemMessage(hwndDlg, IDC_IEVIEWMODE, CB_GETITEMDATA, iIndex, 0); - - if (iIndex != CB_ERR && (iMode >= 0 && iMode <= 3)) { - switch (iMode) { - case 0: - db_set_b(hContact, SRMSGMOD_T, "ieview", 0); - db_set_b(hContact, SRMSGMOD_T, "hpplog", 0); - break; - case 1: - db_set_b(hContact, SRMSGMOD_T, "ieview", -1); - db_set_b(hContact, SRMSGMOD_T, "hpplog", -1); - break; - case 2: - db_set_b(hContact, SRMSGMOD_T, "ieview", -1); - db_set_b(hContact, SRMSGMOD_T, "hpplog", 1); - break; - case 3: - db_set_b(hContact, SRMSGMOD_T, "ieview", 1); - db_set_b(hContact, SRMSGMOD_T, "hpplog", -1); - break; - } - if (hWnd && dat) { - unsigned int iNewIEView = GetIEViewMode(dat->m_hContact); - if (iNewIEView != iOldIEView) { - if (pdwActionToTake) - *pdwActionToTake |= UPREF_ACTION_SWITCHLOGVIEWER; - } - } - } - if ((iIndex = SendDlgItemMessage(hwndDlg, IDC_TEXTFORMATTING, CB_GETCURSEL, 0, 0)) != CB_ERR) { + + int iIndex = SendDlgItemMessage(hwndDlg, IDC_TEXTFORMATTING, CB_GETCURSEL, 0, 0); + if (iIndex != CB_ERR) { if (iIndex == 0) db_unset(hContact, SRMSGMOD_T, "sendformat"); else diff --git a/protocols/JabberG/src/jabber_chat.cpp b/protocols/JabberG/src/jabber_chat.cpp index 915ef15c64..ea858072a7 100644 --- a/protocols/JabberG/src/jabber_chat.cpp +++ b/protocols/JabberG/src/jabber_chat.cpp @@ -1277,7 +1277,7 @@ static void sttLogListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK *g if (item == nullptr) { item = ppro->ListGetItemPtr(LIST_CHATROOM, roomJid); if (item != nullptr) { - item->type = "conference"; + replaceStr(item->type, "conference"); MCONTACT hContact = ppro->HContactFromJID(item->jid); item->name = Clist_GetContactDisplayName(hContact); ppro->AddEditBookmark(item); diff --git a/protocols/JabberG/src/jabber_disco.cpp b/protocols/JabberG/src/jabber_disco.cpp index 1b0ddb05e7..e9371fa477 100644 --- a/protocols/JabberG/src/jabber_disco.cpp +++ b/protocols/JabberG/src/jabber_disco.cpp @@ -1252,7 +1252,7 @@ void CJabberProto::ServiceDiscoveryShowMenu(CJabberSDNode *pNode, HTREELISTITEM item->name = mir_utf8decodeW(pNode->GetName()); } - item->type = "conference"; + replaceStr(item->type, "conference"); AddEditBookmark(item); } } diff --git a/protocols/JabberG/src/jabber_menu.cpp b/protocols/JabberG/src/jabber_menu.cpp index 31392c3549..7d14342722 100644 --- a/protocols/JabberG/src/jabber_menu.cpp +++ b/protocols/JabberG/src/jabber_menu.cpp @@ -519,7 +519,7 @@ INT_PTR __cdecl CJabberProto::OnMenuBookmarkAdd(WPARAM hContact, LPARAM) JABBER_LIST_ITEM *item = new JABBER_LIST_ITEM(); item->jid = mir_strdup(roomID); item->name = Clist_GetContactDisplayName(hContact); - item->type = "conference"; + item->type = mir_strdup("conference"); item->nick = getUStringA(hContact, "MyNick"); AddEditBookmark(item); delete item; diff --git a/src/core/stdmsg/src/chat_window.cpp b/src/core/stdmsg/src/chat_window.cpp index a33d411064..a2f9f2e364 100644 --- a/src/core/stdmsg/src/chat_window.cpp +++ b/src/core/stdmsg/src/chat_window.cpp @@ -62,7 +62,7 @@ void CMsgDialog::UpdateOptions() Window_SetIcon_IcoLib(m_pOwner->GetHwnd(), g_plugin.getIconHandle(IDI_CHANMGR)); - m_log.SendMsg(EM_SETBKGNDCOLOR, 0, g_Settings.crLogBackground); + m_pLog->UpdateOptions(); CHARFORMAT2 cf; cf.cbSize = sizeof(CHARFORMAT2); @@ -111,18 +111,19 @@ void CMsgDialog::UpdateStatusBar() ///////////////////////////////////////////////////////////////////////////////////////// -void CMsgDialog::StreamInEvents(LOGINFO *lin, bool bRedraw) +void CLogWindow::LogEvents(LOGINFO *lin, bool bRedraw) { - if (m_hwnd == nullptr || lin == nullptr || m_si == nullptr) + auto *si = m_pDlg.m_si; + if (lin == nullptr || si == nullptr) return; - if (!bRedraw && m_si->iType == GCW_CHATROOM && m_bFilterEnabled && (m_iLogFilterFlags & lin->iType) == 0) + if (!bRedraw && si->iType == GCW_CHATROOM && m_pDlg.m_bFilterEnabled && (m_pDlg.m_iLogFilterFlags & lin->iType) == 0) return; LOGSTREAMDATA streamData; memset(&streamData, 0, sizeof(streamData)); - streamData.hwnd = m_log.GetHwnd(); - streamData.si = m_si; + streamData.hwnd = m_rtf.GetHwnd(); + streamData.si = si; streamData.lin = lin; streamData.bStripFormat = FALSE; @@ -135,20 +136,20 @@ void CMsgDialog::StreamInEvents(LOGINFO *lin, bool bRedraw) SCROLLINFO scroll; scroll.cbSize = sizeof(SCROLLINFO); scroll.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; - GetScrollInfo(m_log.GetHwnd(), SB_VERT, &scroll); + GetScrollInfo(m_rtf.GetHwnd(), SB_VERT, &scroll); POINT point = {}; - m_log.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&point); + m_rtf.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&point); // do not scroll to bottom if there is a selection CHARRANGE oldsel, sel; - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldsel); + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldsel); if (oldsel.cpMax != oldsel.cpMin) - m_log.SendMsg(WM_SETREDRAW, FALSE, 0); + m_rtf.SendMsg(WM_SETREDRAW, FALSE, 0); //set the insertion point at the bottom - sel.cpMin = sel.cpMax = m_log.GetRichTextLength(); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + sel.cpMin = sel.cpMax = m_rtf.GetRichTextLength(); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); // fix for the indent... must be a M$ bug if (sel.cpMax == 0) @@ -163,14 +164,14 @@ void CMsgDialog::StreamInEvents(LOGINFO *lin, bool bRedraw) g_chatApi.logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY); g_chatApi.logPixelSX = GetDeviceCaps(hdc, LOGPIXELSX); ReleaseDC(nullptr, hdc); - m_log.SendMsg(WM_SETREDRAW, FALSE, 0); + m_rtf.SendMsg(WM_SETREDRAW, FALSE, 0); bFlag = true; } // stream in the event(s) streamData.lin = lin; streamData.bRedraw = bRedraw; - m_log.SendMsg(EM_STREAMIN, wp, (LPARAM)&stream); + m_rtf.SendMsg(EM_STREAMIN, wp, (LPARAM)&stream); // do smileys if (g_dat.bSmileyInstalled && (bRedraw || (lin->ptszText && lin->iType != GC_EVENT_JOIN && lin->iType != GC_EVENT_NICK && lin->iType != GC_EVENT_ADDSTATUS && lin->iType != GC_EVENT_REMOVESTATUS))) { @@ -182,11 +183,11 @@ void CMsgDialog::StreamInEvents(LOGINFO *lin, bool bRedraw) SMADD_RICHEDIT3 sm = {}; sm.cbSize = sizeof(sm); - sm.hwndRichEditControl = m_log.GetHwnd(); - sm.Protocolname = m_si->pszModule; + sm.hwndRichEditControl = m_rtf.GetHwnd(); + sm.Protocolname = si->pszModule; sm.rangeToReplace = bRedraw ? nullptr : &newsel; sm.disableRedraw = TRUE; - sm.hContact = m_si->hContact; + sm.hContact = si->hContact; CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&sm); } @@ -194,21 +195,21 @@ void CMsgDialog::StreamInEvents(LOGINFO *lin, bool bRedraw) if (bRedraw || (UINT)scroll.nPos >= (UINT)scroll.nMax - scroll.nPage - 5 || scroll.nMax - scroll.nMin - scroll.nPage < 50) ScrollToBottom(); else - m_log.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&point); + m_rtf.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&point); // do we need to restore the selection if (oldsel.cpMax != oldsel.cpMin) { - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldsel); - m_log.SendMsg(WM_SETREDRAW, TRUE, 0); - InvalidateRect(m_log.GetHwnd(), nullptr, TRUE); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldsel); + m_rtf.SendMsg(WM_SETREDRAW, TRUE, 0); + InvalidateRect(m_rtf.GetHwnd(), nullptr, TRUE); } // need to invalidate the window if (bFlag) { - sel.cpMin = sel.cpMax = m_log.GetRichTextLength(); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - m_log.SendMsg(WM_SETREDRAW, TRUE, 0); - InvalidateRect(m_log.GetHwnd(), nullptr, TRUE); + sel.cpMin = sel.cpMax = m_rtf.GetRichTextLength(); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + m_rtf.SendMsg(WM_SETREDRAW, TRUE, 0); + InvalidateRect(m_rtf.GetHwnd(), nullptr, TRUE); } } diff --git a/src/core/stdmsg/src/msgdialog.cpp b/src/core/stdmsg/src/msgdialog.cpp index d1e6bfdb9c..7081150531 100644 --- a/src/core/stdmsg/src/msgdialog.cpp +++ b/src/core/stdmsg/src/msgdialog.cpp @@ -143,9 +143,6 @@ bool CMsgDialog::OnInitDialog() int nMax = CallProtoService(m_szProto, PS_GETCAPS, PFLAG_MAXLENOFMESSAGE, m_hContact); if (nMax) m_message.SendMsg(EM_EXLIMITTEXT, 0, nMax); - - // get around a lame bug in the Windows template resource code where richedits are limited to 0x7FFF - m_log.SendMsg(EM_LIMITTEXT, sizeof(wchar_t) * 0x7FFFFFFF, 0); } m_wOldStatus = m_wStatus; @@ -157,9 +154,6 @@ bool CMsgDialog::OnInitDialog() m_iSplitterY = g_plugin.getDword(g_dat.bSavePerContact ? m_hContact : 0, "splitterPos", m_minEditInit.bottom - m_minEditInit.top); UpdateSizeBar(); - m_log.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK | ENM_SCROLL); - m_log.SendMsg(EM_AUTOURLDETECT, TRUE, 0); - m_message.SendMsg(EM_SETEVENTMASK, 0, ENM_CHANGE); if (isChat()) { @@ -384,7 +378,7 @@ void CMsgDialog::onClick_NickList(CCtrlButton *pButton) m_bNicklistEnabled = !m_bNicklistEnabled; pButton->SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(m_bNicklistEnabled ? IDI_NICKLIST : IDI_NICKLIST2, FALSE)); - ScrollToBottom(); + m_pLog->ScrollToBottom(); Resize(); } @@ -479,17 +473,21 @@ int CMsgDialog::Resizer(UTILRESIZECONTROL *urc) urc->rcItem.top = 2; urc->rcItem.left = 0; urc->rcItem.right = bNick ? urc->dlgNewSize.cx - m_iSplitterX : urc->dlgNewSize.cx; - LBL_CalcBottom: urc->rcItem.bottom = urc->dlgNewSize.cy - m_iSplitterY; if (!bToolbar) urc->rcItem.bottom += 20; + m_rcLog = urc->rcItem; return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM; case IDC_SRMM_NICKLIST: urc->rcItem.top = 2; urc->rcItem.right = urc->dlgNewSize.cx; urc->rcItem.left = urc->dlgNewSize.cx - m_iSplitterX + 2; - goto LBL_CalcBottom; +LBL_CalcBottom: + urc->rcItem.bottom = urc->dlgNewSize.cy - m_iSplitterY; + if (!bToolbar) + urc->rcItem.bottom += 20; + return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM; case IDC_SPLITTERX: urc->rcItem.top = 1; @@ -517,6 +515,7 @@ int CMsgDialog::Resizer(UTILRESIZECONTROL *urc) if (!g_dat.bShowButtons) urc->rcItem.top = 2; urc->rcItem.bottom = urc->dlgNewSize.cy - m_iSplitterY; + m_rcLog = urc->rcItem; return RD_ANCHORX_WIDTH | RD_ANCHORY_TOP; case IDC_SPLITTERY: @@ -605,10 +604,8 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_SIZE: if (!IsIconic(m_hwnd)) { - bool bottomScroll; if (isChat()) { - bottomScroll = false; bool bSend = g_dat.bSendButton; bool bNick = m_si->iType != GCW_SERVER && m_bNicklistEnabled; @@ -632,29 +629,18 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) } } else { - bottomScroll = true; SetupStatusBar(); - - if (GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL) { - SCROLLINFO si = {}; - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; - GetScrollInfo(m_log.GetHwnd(), SB_VERT, &si); - bottomScroll = (si.nPos + (int)si.nPage + 5) >= si.nMax; - } } CSuper::DlgProc(uMsg, wParam, lParam); // call built-in resizer SetButtonsPos(m_hwnd, isChat()); + m_pLog->Resize(); InvalidateRect(m_pOwner->m_hwndStatus, nullptr, true); RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); RedrawWindow(m_btnOk.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); if (g_dat.bShowAvatar && m_avatarPic) RedrawWindow(m_avatar.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); - - if (bottomScroll) - ScrollToBottom(); } return TRUE; @@ -682,21 +668,15 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) } if (hDbEvent != m_hDbEventFirst && db_event_next(m_hContact, hDbEvent) == 0) - StreamInEvents(hDbEvent, 1, 1); + m_pLog->LogEvents(hDbEvent, 1, 1); else RemakeLog(); // Flash window *only* for messages, not for custom events if (isMessage && !isSent) { if (isActive) { - if (GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL) { - SCROLLINFO si = {}; - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; - GetScrollInfo(m_log.GetHwnd(), SB_VERT, &si); - if ((si.nPos + (int)si.nPage + 5) < si.nMax) - StartFlash(); - } + if (m_pLog->AtBottom()) + StartFlash(); } else StartFlash(); } @@ -928,11 +908,11 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) case DM_UPDATETITLE: if (lParam != 0) { if (isChat()) { - if (lParam != m_hContact) + if ((MCONTACT)lParam != m_hContact) break; } else { - bool bIsMe = (lParam == m_hContact) || (m_bIsMeta && db_mc_getMeta(lParam) == m_hContact); + bool bIsMe = ((MCONTACT)lParam == m_hContact) || (m_bIsMeta && db_mc_getMeta(lParam) == m_hContact); if (!bIsMe) break; } @@ -951,7 +931,7 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_LBUTTONDBLCLK: if (LOWORD(lParam) < 30) - ScrollToBottom(); + m_pLog->ScrollToBottom(); break; case WM_ACTIVATE: @@ -971,84 +951,6 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) ///////////////////////////////////////////////////////////////////////////////////////// -static const CHARRANGE rangeAll = { 0, -1 }; - -LRESULT CMsgDialog::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) -{ - CHARRANGE sel; - - switch(msg) { - case WM_CONTEXTMENU: - // we display context menu here only for private chats, group chats are processed by the core - if (!isChat()) { - POINT pt; - GetCursorPos(&pt); - - SetFocus(m_log.GetHwnd()); - - HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_CONTEXT)); - HMENU hSubMenu = GetSubMenu(hMenu, 0); - TranslateMenu(hSubMenu); - - CHARRANGE all = { 0, -1 }; - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); - if (sel.cpMin == sel.cpMax) - EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); - - switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_hwnd, nullptr)) { - case IDM_COPY: - m_log.SendMsg(WM_COPY, 0, 0); - break; - case IDM_COPYALL: - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); - m_log.SendMsg(WM_COPY, 0, 0); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - break; - case IDM_SELECTALL: - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); - break; - case IDM_CLEAR: - ClearLog(); - m_hDbEventFirst = 0; - break; - } - DestroyMenu(hSubMenu); - DestroyMenu(hMenu); - return TRUE; - } - break; - - case WM_LBUTTONUP: - if (isChat()) { - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)& sel); - if (sel.cpMin != sel.cpMax) { - m_log.SendMsg(WM_COPY, 0, 0); - sel.cpMin = sel.cpMax; - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)& sel); - } - SetFocus(m_message.GetHwnd()); - } - break; - - case WM_KEYDOWN: - bool isShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0; - bool isCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0; - bool isAlt = (GetKeyState(VK_MENU) & 0x8000) != 0; - - if (wParam == 0x57 && isCtrl && !isAlt) { // ctrl-w (close window) - CloseTab(); - return TRUE; - } - - if (ProcessHotkeys(wParam, isShift, isCtrl, isAlt)) - return FALSE; - } - - return CSuper::WndProc_Log(msg, wParam, lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// - LRESULT CMsgDialog::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { @@ -1065,11 +967,13 @@ LRESULT CMsgDialog::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) ///////////////////////////////////////////////////////////////////////////////////////// +static const CHARRANGE rangeAll = { 0, -1 }; + LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_MOUSEWHEEL: - m_log.SendMsg(WM_MOUSEWHEEL, wParam, lParam); + LOG()->WndProc(msg, wParam, lParam); m_iLastEnterTime = 0; return TRUE; @@ -1302,7 +1206,7 @@ LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) } if (wParam == VK_NEXT || wParam == VK_PRIOR) { - m_log.SendMsg(msg, wParam, lParam); + ((CLogWindow *)m_pLog)->WndProc(msg, wParam, lParam); m_iLastEnterTime = 0; return TRUE; } @@ -1375,21 +1279,6 @@ bool CMsgDialog::IsActive() const return bRes; } -void CMsgDialog::ScrollToBottom() -{ - if (GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL) { - SCROLLINFO si = {}; - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE | SIF_RANGE; - GetScrollInfo(m_log.GetHwnd(), SB_VERT, &si); - - si.fMask = SIF_POS; - si.nPos = si.nMax - si.nPage; - SetScrollInfo(m_log.GetHwnd(), SB_VERT, &si, TRUE); - m_log.SendMsg(WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0); - } -} - void CMsgDialog::StartFlash() { ::SetTimer(m_hwnd, TIMERID_FLASHWND, 900, nullptr); @@ -1493,9 +1382,8 @@ void CMsgDialog::OnOptionsApplied(bool bUpdateAvatar) UpdateTitle(); Resize(); - COLORREF colour = g_plugin.getDword(SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR); - m_log.SendMsg(EM_SETBKGNDCOLOR, 0, colour); - m_message.SendMsg(EM_SETBKGNDCOLOR, 0, colour); + m_pLog->UpdateOptions(); + m_message.SendMsg(EM_SETBKGNDCOLOR, 0, g_plugin.getDword(SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR)); // avatar stuff m_avatarPic = nullptr; @@ -1520,19 +1408,7 @@ void CMsgDialog::OnOptionsApplied(bool bUpdateAvatar) cf.dwMask = CFM_COLOR; m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (WPARAM)&cf); - // configure message history for proper RTL formatting - PARAFORMAT2 pf2; - memset(&pf2, 0, sizeof(pf2)); - pf2.cbSize = sizeof(pf2); - - pf2.wEffects = PFE_RTLPARA; - pf2.dwMask = PFM_RTLPARA; - ClearLog(); - m_log.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); - pf2.wEffects = 0; - m_log.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); - m_log.SendMsg(EM_SETLANGOPTIONS, 0, m_log.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD); - + m_pLog->Clear(); RemakeLog(); FixTabIcons(); } @@ -1621,7 +1497,7 @@ void CMsgDialog::NotifyTyping(int mode) void CMsgDialog::RemakeLog() { - StreamInEvents(m_hDbEventFirst, -1, 0); + m_pLog->LogEvents(m_hDbEventFirst, -1, 0); } void CMsgDialog::ProcessFileDrop(HDROP hDrop) diff --git a/src/core/stdmsg/src/msglog.cpp b/src/core/stdmsg/src/msglog.cpp index b48c2365cd..bb21d6c782 100644 --- a/src/core/stdmsg/src/msglog.cpp +++ b/src/core/stdmsg/src/msglog.cpp @@ -393,75 +393,141 @@ static DWORD CALLBACK LogStreamInEvents(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG return 0; } -void CMsgDialog::StreamInEvents(MEVENT hDbEventFirst, int count, bool bAppend) +#define RTFPICTHEADERMAXSIZE 78 +void LoadMsgLogIcons(void) +{ + HBRUSH hBkgBrush = CreateSolidBrush(g_plugin.getDword(SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR)); + + BITMAPINFOHEADER bih = { sizeof(bih) }; + bih.biBitCount = 24; + bih.biCompression = BI_RGB; + bih.biHeight = 10; + bih.biPlanes = 1; + bih.biWidth = 10; + int widthBytes = ((bih.biWidth * bih.biBitCount + 31) >> 5) * 4; + + RECT rc; + rc.top = rc.left = 0; + rc.right = bih.biWidth; + rc.bottom = bih.biHeight; + + HDC hdc = GetDC(nullptr); + HBITMAP hBmp = CreateCompatibleBitmap(hdc, bih.biWidth, bih.biHeight); + HDC hdcMem = CreateCompatibleDC(hdc); + PBYTE pBmpBits = (PBYTE)mir_alloc(widthBytes * bih.biHeight); + + for (int i = 0; i < _countof(pLogIconBmpBits); i++) { + HICON hIcon = IcoLib_GetIconByHandle(iconList[i].hIcolib); + size_t size = RTFPICTHEADERMAXSIZE + (bih.biSize + widthBytes * bih.biHeight) * 2; + pLogIconBmpBits[i] = (char*)mir_alloc(size); + size_t rtfHeaderSize = mir_snprintf(pLogIconBmpBits[i], size, "{\\pict\\dibitmap0\\wbmbitspixel%u\\wbmplanes1\\wbmwidthbytes%u\\picw%u\\pich%u ", bih.biBitCount, widthBytes, bih.biWidth, bih.biHeight); + HBITMAP hoBmp = (HBITMAP)SelectObject(hdcMem, hBmp); + FillRect(hdcMem, &rc, hBkgBrush); + DrawIconEx(hdcMem, 0, 0, hIcon, bih.biWidth, bih.biHeight, 0, nullptr, DI_NORMAL); + IcoLib_ReleaseIcon(hIcon); + + SelectObject(hdcMem, hoBmp); + GetDIBits(hdc, hBmp, 0, bih.biHeight, pBmpBits, (BITMAPINFO*)&bih, DIB_RGB_COLORS); + + char *szDest = pLogIconBmpBits[i] + rtfHeaderSize; + bin2hex(&bih, sizeof(bih), szDest); szDest += sizeof(bih) * 2; + bin2hex(pBmpBits, widthBytes * bih.biHeight, szDest); szDest += widthBytes * bih.biHeight * 2; + mir_strcpy(szDest, "}"); + } + mir_free(pBmpBits); + DeleteDC(hdcMem); + DeleteObject(hBmp); + ReleaseDC(nullptr, hdc); + DeleteObject(hBkgBrush); +} + +void FreeMsgLogIcons(void) +{ + for (auto &it : pLogIconBmpBits) + mir_free(it); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CLogWindow::Attach() +{ + CSuper::Attach(); + + // get around a lame bug in the Windows template resource code where richedits are limited to 0x7FFF + m_rtf.SendMsg(EM_LIMITTEXT, sizeof(wchar_t) * 0x7FFFFFFF, 0); + m_rtf.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK | ENM_SCROLL); + m_rtf.SendMsg(EM_AUTOURLDETECT, TRUE, 0); +} + +void CLogWindow::LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) { CHARRANGE oldSel, sel; BOOL bottomScroll = TRUE; POINT scrollPos; - m_log.SendMsg(WM_SETREDRAW, FALSE, 0); - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldSel); + m_rtf.SendMsg(WM_SETREDRAW, FALSE, 0); + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldSel); LogStreamData streamData = {}; - streamData.hContact = m_hContact; + streamData.hContact = m_pDlg.m_hContact; streamData.hDbEvent = hDbEventFirst; - streamData.dlgDat = this; + streamData.dlgDat = &m_pDlg; streamData.eventsToInsert = count; - streamData.isEmpty = !bAppend || GetWindowTextLength(m_log.GetHwnd()) == 0; + streamData.isEmpty = !bAppend || GetWindowTextLength(m_rtf.GetHwnd()) == 0; EDITSTREAM stream = {}; stream.pfnCallback = LogStreamInEvents; stream.dwCookie = (DWORD_PTR)&streamData; if (!streamData.isEmpty) { - bottomScroll = (GetFocus() != m_log.GetHwnd()); - if (bottomScroll && (GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL)) { + bottomScroll = (GetFocus() != m_rtf.GetHwnd()); + if (bottomScroll && (GetWindowLongPtr(m_rtf.GetHwnd(), GWL_STYLE) & WS_VSCROLL)) { SCROLLINFO si = {}; si.cbSize = sizeof(si); si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; - GetScrollInfo(m_log.GetHwnd(), SB_VERT, &si); + GetScrollInfo(m_rtf.GetHwnd(), SB_VERT, &si); bottomScroll = (si.nPos + (int)si.nPage) >= si.nMax; } if (!bottomScroll) - m_log.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&scrollPos); + m_rtf.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&scrollPos); } FINDTEXTEXA fi; if (bAppend) { sel.cpMin = sel.cpMax = -1; - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); fi.chrg.cpMin = 0; } else { GETTEXTLENGTHEX gtxl = { 0 }; gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMCHARS; gtxl.codepage = 1200; - fi.chrg.cpMin = m_log.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0); + fi.chrg.cpMin = m_rtf.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0); - sel.cpMin = sel.cpMax = m_log.GetRichTextLength(); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + sel.cpMin = sel.cpMax = m_rtf.GetRichTextLength(); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); } mir_strcpy(szSep2, bAppend ? "\\par\\sl0" : "\\sl1000"); mir_strcpy(szSep2_RTL, bAppend ? "\\rtlpar\\rtlmark\\par\\sl1000" : "\\sl1000"); - m_log.SendMsg(EM_STREAMIN, bAppend ? SFF_SELECTION | SF_RTF : SF_RTF, (LPARAM)&stream); + m_rtf.SendMsg(EM_STREAMIN, bAppend ? SFF_SELECTION | SF_RTF : SF_RTF, (LPARAM)&stream); if (bottomScroll) { sel.cpMin = sel.cpMax = -1; - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); } else { - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldSel); - m_log.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&scrollPos); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldSel); + m_rtf.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&scrollPos); } if (g_dat.bSmileyInstalled) { SMADD_RICHEDIT3 smre; smre.cbSize = sizeof(SMADD_RICHEDIT3); - smre.hwndRichEditControl = m_log.GetHwnd(); + smre.hwndRichEditControl = m_rtf.GetHwnd(); - MCONTACT hContact = db_mc_getSrmmSub(m_hContact); - smre.Protocolname = (hContact != 0) ? GetContactProto(hContact) : m_szProto; + MCONTACT hContact = db_mc_getSrmmSub(m_pDlg.m_hContact); + smre.Protocolname = (hContact != 0) ? GetContactProto(hContact) : m_pDlg.m_szProto; if (fi.chrg.cpMin > 0) { sel.cpMin = fi.chrg.cpMin; @@ -471,70 +537,125 @@ void CMsgDialog::StreamInEvents(MEVENT hDbEventFirst, int count, bool bAppend) else smre.rangeToReplace = nullptr; smre.disableRedraw = TRUE; - smre.hContact = m_hContact; + smre.hContact = m_pDlg.m_hContact; smre.flags = 0; CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&smre); } - m_log.SendMsg(WM_SETREDRAW, TRUE, 0); + m_rtf.SendMsg(WM_SETREDRAW, TRUE, 0); if (bottomScroll) { ScrollToBottom(); - RedrawWindow(m_log.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW); + RedrawWindow(m_rtf.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW); } - m_hDbEventLast = streamData.hDbEventLast; + m_pDlg.m_hDbEventLast = streamData.hDbEventLast; } -#define RTFPICTHEADERMAXSIZE 78 -void LoadMsgLogIcons(void) +void CLogWindow::LogEvents(DBEVENTINFO*, bool) { - HBRUSH hBkgBrush = CreateSolidBrush(g_plugin.getDword(SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR)); +} - BITMAPINFOHEADER bih = { sizeof(bih) }; - bih.biBitCount = 24; - bih.biCompression = BI_RGB; - bih.biHeight = 10; - bih.biPlanes = 1; - bih.biWidth = 10; - int widthBytes = ((bih.biWidth * bih.biBitCount + 31) >> 5) * 4; +void CLogWindow::UpdateOptions() +{ + if (m_pDlg.isChat()) + m_rtf.SendMsg(EM_SETBKGNDCOLOR, 0, g_Settings.crLogBackground); + else { + // configure message history for proper RTL formatting + PARAFORMAT2 pf2; + memset(&pf2, 0, sizeof(pf2)); + pf2.cbSize = sizeof(pf2); - RECT rc; - rc.top = rc.left = 0; - rc.right = bih.biWidth; - rc.bottom = bih.biHeight; + pf2.wEffects = PFE_RTLPARA; + pf2.dwMask = PFM_RTLPARA; + m_rtf.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); - HDC hdc = GetDC(nullptr); - HBITMAP hBmp = CreateCompatibleBitmap(hdc, bih.biWidth, bih.biHeight); - HDC hdcMem = CreateCompatibleDC(hdc); - PBYTE pBmpBits = (PBYTE)mir_alloc(widthBytes * bih.biHeight); + pf2.wEffects = 0; + m_rtf.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2); - for (int i = 0; i < _countof(pLogIconBmpBits); i++) { - HICON hIcon = IcoLib_GetIconByHandle(iconList[i].hIcolib); - size_t size = RTFPICTHEADERMAXSIZE + (bih.biSize + widthBytes * bih.biHeight) * 2; - pLogIconBmpBits[i] = (char*)mir_alloc(size); - size_t rtfHeaderSize = mir_snprintf(pLogIconBmpBits[i], size, "{\\pict\\dibitmap0\\wbmbitspixel%u\\wbmplanes1\\wbmwidthbytes%u\\picw%u\\pich%u ", bih.biBitCount, widthBytes, bih.biWidth, bih.biHeight); - HBITMAP hoBmp = (HBITMAP)SelectObject(hdcMem, hBmp); - FillRect(hdcMem, &rc, hBkgBrush); - DrawIconEx(hdcMem, 0, 0, hIcon, bih.biWidth, bih.biHeight, 0, nullptr, DI_NORMAL); - IcoLib_ReleaseIcon(hIcon); + m_rtf.SendMsg(EM_SETLANGOPTIONS, 0, m_rtf.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD); + m_rtf.SendMsg(EM_SETBKGNDCOLOR, 0, g_plugin.getDword(SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR)); + } +} - SelectObject(hdcMem, hoBmp); - GetDIBits(hdc, hBmp, 0, bih.biHeight, pBmpBits, (BITMAPINFO*)&bih, DIB_RGB_COLORS); +///////////////////////////////////////////////////////////////////////////////////////// - char *szDest = pLogIconBmpBits[i] + rtfHeaderSize; - bin2hex(&bih, sizeof(bih), szDest); szDest += sizeof(bih) * 2; - bin2hex(pBmpBits, widthBytes * bih.biHeight, szDest); szDest += widthBytes * bih.biHeight * 2; - mir_strcpy(szDest, "}"); +static const CHARRANGE rangeAll = { 0, -1 }; + +INT_PTR CLogWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam) +{ + CHARRANGE sel; + + switch (msg) { + case WM_CONTEXTMENU: + // we display context menu here only for private chats, group chats are processed by the core + if (!m_pDlg.isChat()) { + POINT pt; + GetCursorPos(&pt); + + SetFocus(m_rtf.GetHwnd()); + + HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_CONTEXT)); + HMENU hSubMenu = GetSubMenu(hMenu, 0); + TranslateMenu(hSubMenu); + + CHARRANGE all = { 0, -1 }; + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin == sel.cpMax) + EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); + + switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_pDlg.m_hwnd, nullptr)) { + case IDM_COPY: + m_rtf.SendMsg(WM_COPY, 0, 0); + break; + case IDM_COPYALL: + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); + m_rtf.SendMsg(WM_COPY, 0, 0); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + break; + case IDM_SELECTALL: + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); + break; + case IDM_CLEAR: + Clear(); + m_pDlg.m_hDbEventFirst = 0; + break; + } + DestroyMenu(hSubMenu); + DestroyMenu(hMenu); + return TRUE; + } + break; + + case WM_LBUTTONUP: + if (m_pDlg.isChat()) { + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin != sel.cpMax) { + m_rtf.SendMsg(WM_COPY, 0, 0); + sel.cpMin = sel.cpMax; + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + } + SetFocus(m_pDlg.m_message.GetHwnd()); + } + break; + + case WM_KEYDOWN: + bool isShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0; + bool isCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0; + bool isAlt = (GetKeyState(VK_MENU) & 0x8000) != 0; + + if (wParam == 0x57 && isCtrl && !isAlt) { // ctrl-w (close window) + m_pDlg.CloseTab(); + return TRUE; + } + + if (m_pDlg.ProcessHotkeys(wParam, isShift, isCtrl, isAlt)) + return FALSE; } - mir_free(pBmpBits); - DeleteDC(hdcMem); - DeleteObject(hBmp); - ReleaseDC(nullptr, hdc); - DeleteObject(hBkgBrush); + + return CSuper::WndProc(msg, wParam, lParam); } -void FreeMsgLogIcons(void) +CSrmmLogWindow *logBuilder(CMsgDialog &pDlg) { - for (auto &it : pLogIconBmpBits) - mir_free(it); + return new CLogWindow(pDlg); } diff --git a/src/core/stdmsg/src/msgs.h b/src/core/stdmsg/src/msgs.h index 5a876ac547..ed2a647fe8 100644 --- a/src/core/stdmsg/src/msgs.h +++ b/src/core/stdmsg/src/msgs.h @@ -32,10 +32,29 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define EVENTTYPE_JABBER_CHATSTATES 2000 #define EVENTTYPE_JABBER_PRESENCE 2001 +class CLogWindow : public CRtfLogWindow +{ + typedef CRtfLogWindow CSuper; + +public: + CLogWindow(CMsgDialog &pDlg) : + CSuper(pDlg) + {} + + void Attach() override; + void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) override; + void LogEvents(DBEVENTINFO *dbei, bool bAppend); + void LogEvents(struct LOGINFO *, bool) override; + void UpdateOptions() override; + + INT_PTR WndProc(UINT msg, WPARAM wParam, LPARAM lParam) override; +}; + class CMsgDialog : public CSrmmBaseDialog { - typedef CSrmmBaseDialog CSuper; + friend class CLogWindow; friend class CTabbedWindow; + typedef CSrmmBaseDialog CSuper; void Init(void); void NotifyTyping(int mode); @@ -43,14 +62,12 @@ class CMsgDialog : public CSrmmBaseDialog void ShowAvatar(void); void ShowTime(bool bForce); void SetupStatusBar(void); - void StreamInEvents(MEVENT hDbEventFirst, int count, bool bAppend); void UpdateIcon(WPARAM wParam); void UpdateLastMessage(void); void UpdateSizeBar(void); static INT_PTR CALLBACK FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -protected: CCtrlBase m_avatar; CCtrlButton m_btnOk; @@ -63,6 +80,7 @@ protected: int m_iSplitterX, m_iSplitterY; SIZE m_minEditBoxSize; RECT m_minEditInit; + RECT m_rcLog; // tab autocomplete int m_iTabStart = 0; @@ -93,7 +111,6 @@ public: int Resizer(UTILRESIZECONTROL *urc) override; INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override; - LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override; LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override; LRESULT WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) override; @@ -115,11 +132,14 @@ public: void UpdateReadChars(void); - __forceinline MCONTACT getActiveContact() const - { + __forceinline MCONTACT getActiveContact() const { return (m_bIsMeta) ? db_mc_getSrmmSub(m_hContact) : m_hContact; } + __forceinline CLogWindow* LOG() { + return ((CLogWindow *)m_pLog); + } + MEVENT m_hDbEventFirst, m_hDbEventLast; int m_avatarWidth = 0, m_avatarHeight = 0; @@ -137,9 +157,7 @@ public: void CloseTab() override; bool IsActive() const override; void LoadSettings() override; - void ScrollToBottom() override; void SetStatusText(const wchar_t *, HICON) override; - void StreamInEvents(LOGINFO *lin, bool bRedraw) override; void ShowFilterMenu() override; void UpdateNickList() override; void UpdateOptions() override; diff --git a/src/core/stdmsg/src/srmm.cpp b/src/core/stdmsg/src/srmm.cpp index ebd0e2519d..6dad345b8d 100644 --- a/src/core/stdmsg/src/srmm.cpp +++ b/src/core/stdmsg/src/srmm.cpp @@ -52,6 +52,8 @@ extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_SRMM, int CMPlugin::Load() { + hLogger = RegisterSrmmLog("built-in", L"StdMsg internal log", &logBuilder); + Load_ChatModule(); return LoadSendRecvMessageModule(); } @@ -60,6 +62,7 @@ int CMPlugin::Load() int CMPlugin::Unload() { + UnregisterSrmmLog(hLogger); SplitmsgShutdown(); Unload_ChatModule(); return 0; diff --git a/src/core/stdmsg/src/stdafx.h b/src/core/stdmsg/src/stdafx.h index 918f63a017..ea7ed72a3e 100644 --- a/src/core/stdmsg/src/stdafx.h +++ b/src/core/stdmsg/src/stdafx.h @@ -155,6 +155,8 @@ struct CMPlugin : public PLUGIN { CMPlugin(); + HANDLE hLogger; + int Load() override; int Unload() override; }; @@ -171,6 +173,7 @@ void Load_ChatModule(void); // log.cpp char* Log_CreateRtfHeader(void); +CSrmmLogWindow *logBuilder(CMsgDialog &pDlg); // window.cpp SESSION_INFO* SM_GetPrevWindow(SESSION_INFO *si); diff --git a/src/core/stdmsg/src/tabs.cpp b/src/core/stdmsg/src/tabs.cpp index 8366c2d441..e9ae93b50e 100644 --- a/src/core/stdmsg/src/tabs.cpp +++ b/src/core/stdmsg/src/tabs.cpp @@ -515,7 +515,7 @@ INT_PTR CTabbedWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) if (!((rc.right - rc.left) == oldSizeX && (rc.bottom - rc.top) == oldSizeY)) { CMsgDialog *pDlg = (g_Settings.bTabsEnable) ? (CMsgDialog*)m_tab.GetActivePage() : m_pEmbed; if (pDlg != nullptr) { - pDlg->ScrollToBottom(); + pDlg->m_pLog->ScrollToBottom(); pDlg->Resize(); } } diff --git a/src/mir_app/mir_app.vcxproj b/src/mir_app/mir_app.vcxproj index 9f608d1f60..f06c30786a 100644 --- a/src/mir_app/mir_app.vcxproj +++ b/src/mir_app/mir_app.vcxproj @@ -35,7 +35,7 @@ src/mir_app64.def /ignore:4197 %(AdditionalOptions) type=%27win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27*%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;type=%27win32%27 name=%27Microsoft.Windows.Gdiplus%27 version=%271.0.0.0%27 processorArchitecture=%27amd64%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies) - libeay32.lib;%(AdditionalDependencies) + libeay32.lib;%(AdditionalDependencies) res/miranda32.exe.manifest diff --git a/src/mir_app/res/resource.rc b/src/mir_app/res/resource.rc index 50c4de9fbf..d8671c3df3 100644 --- a/src/mir_app/res/resource.rc +++ b/src/mir_app/res/resource.rc @@ -672,6 +672,17 @@ BEGIN CONTROL "Lock name to first contact",IDC_CHK_LOCKHANDLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,151,278,10 END +IDD_OPT_SRMMLOG DIALOGEX 0, 0, 306, 226 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Choose needed logger from listed below:",IDC_STATIC,2,3,299,8 + LISTBOX IDC_LIST,0,16,305,189,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + CONTROL "Enable custom log controls in group chats",IDC_ENABLE_CUSTOM, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,210,297,12 +END + IDD_OPT_LANGUAGES DIALOGEX 0, 0, 301, 191 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT @@ -1018,6 +1029,10 @@ BEGIN BOTTOMMARGIN, 164 END + IDD_OPT_SRMMLOG, DIALOG + BEGIN + END + IDD_OPT_LANGUAGES, DIALOG BEGIN VERTGUIDE, 5 @@ -1063,7 +1078,8 @@ END 1 TEXTINCLUDE BEGIN - "resource.h\0" + "#include ""../src/resource.h""\r\n" + "\0" END 2 TEXTINCLUDE @@ -1320,6 +1336,15 @@ BEGIN END END + +///////////////////////////////////////////////////////////////////////////// +// +// AFX_DIALOG_LAYOUT +// + +IDD_OPT_SRMMLOG AFX_DIALOG_LAYOUT +BEGIN + 0 END #endif // English (United States) resources diff --git a/src/mir_app/src/chat.h b/src/mir_app/src/chat.h index ee0cecafa6..3cc64078fe 100644 --- a/src/mir_app/src/chat.h +++ b/src/mir_app/src/chat.h @@ -28,8 +28,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. void Srmm_CreateToolbarIcons(HWND hwndDlg, int flags); void Srmm_ProcessToolbarHotkey(MCONTACT hContact, INT_PTR iButtonFrom, HWND hwndDlg); +class CLogWindow : public CSrmmLogWindow {}; + class CMsgDialog : public CSrmmBaseDialog { + friend void RedrawLog2(SESSION_INFO *si); + CMsgDialog(); // just to suppress compiler's warnings, never implemented }; @@ -124,6 +128,8 @@ BOOL DoTrayIcon(SESSION_INFO *si, GCEVENT *gce); BOOL DoPopup(SESSION_INFO *si, GCEVENT *gce); int ShowPopup(MCONTACT hContact, SESSION_INFO *si, HICON hIcon, char* pszProtoName, wchar_t* pszRoomName, COLORREF crBkg, const wchar_t* fmt, ...); +CSrmmLogWindow *Srmm_GetLogWindow(CMsgDialog *pDlg); + const wchar_t* my_strstri(const wchar_t* s1, const wchar_t* s2); #pragma comment(lib,"comctl32.lib") diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index 5bfcbfed5a..35f48d6460 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -348,9 +348,7 @@ Chat_UpdateOptions @418 NONAME ?ShowColorChooser@CSrmmBaseDialog@@QAEXH@Z @421 NONAME ?ShowFilterMenu@CSrmmBaseDialog@@UAEXXZ @422 NONAME ?OnInitDialog@CSrmmBaseDialog@@MAE_NXZ @423 NONAME -?StreamInEvents@CSrmmBaseDialog@@UAEXPAULOGINFO@@_N@Z @424 NONAME ?AddLog@CSrmmBaseDialog@@UAEXXZ @425 NONAME -?ScrollToBottom@CSrmmBaseDialog@@UAEXXZ @427 NONAME ?UpdateNickList@CSrmmBaseDialog@@UAEXXZ @428 NONAME ?onClick_BIU@CSrmmBaseDialog@@IAEXPAVCCtrlButton@@@Z @430 NONAME ?onClick_BkColor@CSrmmBaseDialog@@IAEXPAVCCtrlButton@@@Z @431 NONAME @@ -359,7 +357,6 @@ Chat_UpdateOptions @418 NONAME ?ProcessHotkeys@CSrmmBaseDialog@@IAE_NH_N00@Z @434 NONAME ?onClick_History@CSrmmBaseDialog@@IAEXPAVCCtrlButton@@@Z @435 NONAME ?onClick_ChanMgr@CSrmmBaseDialog@@IAEXPAVCCtrlButton@@@Z @436 NONAME -?WndProc_Log@CSrmmBaseDialog@@UAEJIIJ@Z @437 NONAME ?WndProc_Message@CSrmmBaseDialog@@UAEJIIJ@Z @438 NONAME ?WndProc_Nicklist@CSrmmBaseDialog@@UAEJIIJ@Z @439 NONAME ?onDblClick_List@CSrmmBaseDialog@@IAEXPAVCCtrlListBox@@@Z @440 NONAME @@ -696,3 +693,26 @@ Ignore_IsIgnored @781 Contact_OnList @782 Contact_PutOnList @783 Contact_RemoveFromList @784 +RegisterHppLogger @785 +UnregisterHppLogger @786 +??0CRtfLogWindow@@QAE@AAVCMsgDialog@@@Z @787 NONAME +??0CSrmmLogWindow@@IAE@AAVCMsgDialog@@@Z @788 NONAME +??1CRtfLogWindow@@UAE@XZ @789 NONAME +??1CSrmmLogWindow@@UAE@XZ @790 NONAME +??_7CRtfLogWindow@@6B@ @791 NONAME +??_7CSrmmLogWindow@@6B@ @792 NONAME +?AtBottom@CRtfLogWindow@@UAE_NXZ @793 NONAME +?Attach@CRtfLogWindow@@UAEXXZ @794 NONAME +?Clear@CRtfLogWindow@@UAEXXZ @795 NONAME +?Detach@CRtfLogWindow@@UAEXXZ @796 NONAME +?GetHwnd@CRtfLogWindow@@UAEPAUHWND__@@XZ @797 NONAME +?GetSelection@CRtfLogWindow@@UAEPA_WXZ @798 NONAME +?Notify@CRtfLogWindow@@UAEHIJ@Z @799 NONAME +?Notify@CSrmmLogWindow@@UAEHIJ@Z @800 NONAME +?Resize@CRtfLogWindow@@UAEXXZ @801 NONAME +?ScrollToBottom@CRtfLogWindow@@UAEXXZ @802 NONAME +?UpdateOptions@CSrmmLogWindow@@UAEXXZ @803 NONAME +?WndProc@CRtfLogWindow@@UAEHIIJ@Z @804 NONAME +_RegisterSrmmLog@12 @805 NONAME +_UnregisterSrmmLog@4 @806 NONAME +?GetType@CRtfLogWindow@@UAEHXZ @807 NONAME diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index 3a5645f024..95a66ca811 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -348,9 +348,7 @@ Chat_UpdateOptions @418 NONAME ?ShowColorChooser@CSrmmBaseDialog@@QEAAXH@Z @421 NONAME ?ShowFilterMenu@CSrmmBaseDialog@@UEAAXXZ @422 NONAME ?OnInitDialog@CSrmmBaseDialog@@MEAA_NXZ @423 NONAME -?StreamInEvents@CSrmmBaseDialog@@UEAAXPEAULOGINFO@@_N@Z @424 NONAME ?AddLog@CSrmmBaseDialog@@UEAAXXZ @425 NONAME -?ScrollToBottom@CSrmmBaseDialog@@UEAAXXZ @427 NONAME ?UpdateNickList@CSrmmBaseDialog@@UEAAXXZ @428 NONAME ?onClick_BIU@CSrmmBaseDialog@@IEAAXPEAVCCtrlButton@@@Z @430 NONAME ?onClick_BkColor@CSrmmBaseDialog@@IEAAXPEAVCCtrlButton@@@Z @431 NONAME @@ -359,7 +357,6 @@ Chat_UpdateOptions @418 NONAME ?ProcessHotkeys@CSrmmBaseDialog@@IEAA_NH_N00@Z @434 NONAME ?onClick_History@CSrmmBaseDialog@@IEAAXPEAVCCtrlButton@@@Z @435 NONAME ?onClick_ChanMgr@CSrmmBaseDialog@@IEAAXPEAVCCtrlButton@@@Z @436 NONAME -?WndProc_Log@CSrmmBaseDialog@@UEAA_JI_K_J@Z @437 NONAME ?WndProc_Message@CSrmmBaseDialog@@UEAA_JI_K_J@Z @438 NONAME ?WndProc_Nicklist@CSrmmBaseDialog@@UEAA_JI_K_J@Z @439 NONAME ?onDblClick_List@CSrmmBaseDialog@@IEAAXPEAVCCtrlListBox@@@Z @440 NONAME @@ -696,3 +693,26 @@ Ignore_IsIgnored @781 Contact_OnList @782 Contact_PutOnList @783 Contact_RemoveFromList @784 +RegisterHppLogger @785 +UnregisterHppLogger @786 +??0CRtfLogWindow@@QEAA@AEAVCMsgDialog@@@Z @787 NONAME +??0CSrmmLogWindow@@IEAA@AEAVCMsgDialog@@@Z @788 NONAME +??1CRtfLogWindow@@UEAA@XZ @789 NONAME +??1CSrmmLogWindow@@UEAA@XZ @790 NONAME +??_7CRtfLogWindow@@6B@ @791 NONAME +??_7CSrmmLogWindow@@6B@ @792 NONAME +?AtBottom@CRtfLogWindow@@UEAA_NXZ @793 NONAME +?Attach@CRtfLogWindow@@UEAAXXZ @794 NONAME +?Clear@CRtfLogWindow@@UEAAXXZ @795 NONAME +?Detach@CRtfLogWindow@@UEAAXXZ @796 NONAME +?GetHwnd@CRtfLogWindow@@UEAAPEAUHWND__@@XZ @797 NONAME +?GetSelection@CRtfLogWindow@@UEAAPEA_WXZ @798 NONAME +?Notify@CRtfLogWindow@@UEAA_J_K_J@Z @799 NONAME +?Notify@CSrmmLogWindow@@UEAA_J_K_J@Z @800 NONAME +?Resize@CRtfLogWindow@@UEAAXXZ @801 NONAME +?ScrollToBottom@CRtfLogWindow@@UEAAXXZ @802 NONAME +?UpdateOptions@CSrmmLogWindow@@UEAAXXZ @803 NONAME +?WndProc@CRtfLogWindow@@UEAA_JI_K_J@Z @804 NONAME +RegisterSrmmLog @805 NONAME +UnregisterSrmmLog @806 NONAME +?GetType@CRtfLogWindow@@UEAAHXZ @807 NONAME diff --git a/src/mir_app/src/resource.h b/src/mir_app/src/resource.h index fbf6d7920e..0d8e754683 100644 --- a/src/mir_app/src/resource.h +++ b/src/mir_app/src/resource.h @@ -18,6 +18,7 @@ #define IDD_OPT_PROTOCOLORDER 109 #define IDD_OPT_ICOLIB 110 #define IDD_ICOLIB_IMPORT 111 +#define IDD_OPT_SRMMLOG 112 #define IDI_LOADED_GRAY 113 #define IDI_NOTLOADED_GRAY 114 #define IDD_ADDED 115 @@ -540,6 +541,7 @@ #define IDC_RADIO1 1740 #define IDC_RADIO2 1741 #define IDC_ADDCHECK 1742 +#define IDC_ENABLE_CUSTOM 1743 #define IDC_GETMOREPLUGINS 1744 #define IDC_DISABLEMENUICONS 1745 #define IDC_SM_ENABLED 1746 diff --git a/src/mir_app/src/srmm_base.cpp b/src/mir_app/src/srmm_base.cpp index cf4685ef6b..11b955dda5 100644 --- a/src/mir_app/src/srmm_base.cpp +++ b/src/mir_app/src/srmm_base.cpp @@ -30,7 +30,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. CSrmmBaseDialog::CSrmmBaseDialog(CMPluginBase &pPlugin, int idDialog, SESSION_INFO *si) : CDlgBase(pPlugin, idDialog), - m_log(this, IDC_SRMM_LOG), m_message(this, IDC_SRMM_MESSAGE), m_nickList(this, IDC_SRMM_NICKLIST), @@ -134,193 +133,6 @@ static LRESULT CALLBACK Srmm_ButtonSubclassProc(HWND hwnd, UINT msg, WPARAM wPar ///////////////////////////////////////////////////////////////////////////////////////// -static wchar_t szTrimString[] = L":;,.!?\'\"><()[]- \r\n"; - -EXTERN_C MIR_APP_DLL(LRESULT) CALLBACK stubLogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - CSrmmBaseDialog *pDlg = (CSrmmBaseDialog*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); - if (pDlg != nullptr) - return pDlg->WndProc_Log(msg, wParam, lParam); - - return mir_callNextSubclass(hwnd, stubLogProc, msg, wParam, lParam); -} - -LRESULT CSrmmBaseDialog::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) -{ - CHARRANGE sel; - - switch (msg) { - case WM_ACTIVATE: - if (LOWORD(wParam) == WA_INACTIVE) { - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); - if (sel.cpMin != sel.cpMax) { - sel.cpMin = sel.cpMax; - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - } - } - break; - - case WM_SETCURSOR: - if (m_bInMenu) { - SetCursor(LoadCursor(nullptr, IDC_ARROW)); - return TRUE; - } - break; - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - if (!(GetKeyState(VK_RMENU) & 0x8000)) { - MSG message = { m_hwnd, msg, wParam, lParam }; - LRESULT iButtonFrom = Hotkey_Check(&message, BB_HK_SECTION); - if (iButtonFrom) { - Srmm_ProcessToolbarHotkey(m_hContact, iButtonFrom, m_hwnd); - return TRUE; - } - } - break; - - case WM_CHAR: - if (wParam >= ' ') { - SetFocus(m_message.GetHwnd()); - m_message.SendMsg(WM_CHAR, wParam, lParam); - } - else if (wParam == '\t') - SetFocus(m_message.GetHwnd()); - break; - - case WM_CONTEXTMENU: - POINT pt, ptl; - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); - if (lParam == 0xFFFFFFFF) { - m_log.SendMsg(EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)sel.cpMax); - ClientToScreen(m_log.GetHwnd(), &pt); - } - else { - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - } - ptl = pt; - ScreenToClient(m_log.GetHwnd(), (LPPOINT)&ptl); - { - wchar_t *pszWord = (wchar_t*)_alloca(8192); - pszWord[0] = '\0'; - - // get a word under cursor - if (sel.cpMin == sel.cpMax) { - int iCharIndex = m_log.SendMsg(EM_CHARFROMPOS, 0, (LPARAM)&ptl); - if (iCharIndex < 0) - break; - - sel.cpMin = m_log.SendMsg(EM_FINDWORDBREAK, WB_LEFT, iCharIndex); - sel.cpMax = m_log.SendMsg(EM_FINDWORDBREAK, WB_RIGHT, iCharIndex); - } - - if (sel.cpMax > sel.cpMin) { - TEXTRANGE tr = { 0 }; - tr.chrg = sel; - tr.lpstrText = pszWord; - int iRes = m_log.SendMsg(EM_GETTEXTRANGE, 0, (LPARAM)&tr); - if (iRes > 0) { - wchar_t *p = wcschr(pszWord, '\r'); - if (p) *p = 0; - - size_t iLen = mir_wstrlen(pszWord) - 1; - while (wcschr(szTrimString, pszWord[iLen])) { - pszWord[iLen] = '\0'; - iLen--; - } - } - } - - CHARRANGE all = { 0, -1 }; - HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_LOGMENU)); - HMENU hSubMenu = GetSubMenu(hMenu, 0); - TranslateMenu(hSubMenu); - m_bInMenu = true; - UINT uID = CreateGCMenu(m_log.GetHwnd(), hSubMenu, pt, m_si, nullptr, pszWord); - m_bInMenu = false; - switch (uID) { - case 0: - PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); - break; - - case IDM_COPYALL: - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); - m_log.SendMsg(WM_COPY, 0, 0); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); - break; - - case IDM_CLEAR: - m_log.SetText(L""); - if (m_si) { - g_chatApi.LM_RemoveAll(&m_si->pLog, &m_si->pLogEnd); - m_si->iEventCount = 0; - m_si->LastTime = 0; - } - PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); - break; - - case IDM_SEARCH_GOOGLE: - case IDM_SEARCH_BING: - case IDM_SEARCH_YANDEX: - case IDM_SEARCH_YAHOO: - case IDM_SEARCH_WIKIPEDIA: - case IDM_SEARCH_FOODNETWORK: - case IDM_SEARCH_GOOGLE_MAPS: - case IDM_SEARCH_GOOGLE_TRANSLATE: - { - CMStringW szURL; - switch (uID) { - case IDM_SEARCH_WIKIPEDIA: - szURL.Format(L"http://en.wikipedia.org/wiki/%s", pszWord); - break; - case IDM_SEARCH_YAHOO: - szURL.Format(L"http://search.yahoo.com/search?p=%s&ei=UTF-8", pszWord); - break; - case IDM_SEARCH_FOODNETWORK: - szURL.Format(L"http://search.foodnetwork.com/search/delegate.do?fnSearchString=%s", pszWord); - break; - case IDM_SEARCH_BING: - szURL.Format(L"http://www.bing.com/search?q=%s&form=OSDSRC", pszWord); - break; - case IDM_SEARCH_GOOGLE_MAPS: - szURL.Format(L"http://maps.google.com/maps?q=%s&ie=utf-8&oe=utf-8", pszWord); - break; - case IDM_SEARCH_GOOGLE_TRANSLATE: - szURL.Format(L"http://translate.google.com/?q=%s&ie=utf-8&oe=utf-8", pszWord); - break; - case IDM_SEARCH_YANDEX: - szURL.Format(L"http://yandex.ru/yandsearch?text=%s", pszWord); - break; - case IDM_SEARCH_GOOGLE: - szURL.Format(L"http://www.google.com/search?q=%s&ie=utf-8&oe=utf-8", pszWord); - break; - } - Utils_OpenUrlW(szURL); - } - PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); - break; - - default: - PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); - Chat_DoEventHook(m_si, GC_USER_LOGMENU, nullptr, nullptr, uID); - break; - } - DestroyMenu(hMenu); - } - break; - } - - LRESULT res = mir_callNextSubclass(m_log.GetHwnd(), stubLogProc, msg, wParam, lParam); - if (msg == WM_GETDLGCODE) - return res & ~DLGC_HASSETSEL; - return res; -} - -///////////////////////////////////////////////////////////////////////////////////////// - EXTERN_C MIR_APP_DLL(LRESULT) CALLBACK stubMessageProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { CSrmmBaseDialog *pDlg = (CSrmmBaseDialog*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); @@ -636,9 +448,13 @@ bool CSrmmBaseDialog::OnInitDialog() WindowList_Add(g_hWindowList, m_hwnd, m_hContact); SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG_PTR)this); - SetWindowLongPtr(m_log.GetHwnd(), GWLP_USERDATA, LPARAM(this)); - mir_subclassWindow(m_log.GetHwnd(), stubLogProc); - m_log.SetReadOnly(true); + m_pLog = Srmm_GetLogWindow((CMsgDialog*)this); + if (m_pLog->GetType() != 0) { // custom log type + HWND hwndLog = GetDlgItem(m_hwnd, IDC_SRMM_LOG); + EnableWindow(hwndLog, FALSE); + ShowWindow(hwndLog, SW_HIDE); + } + m_pLog->Attach(); SetWindowLongPtr(m_message.GetHwnd(), GWLP_USERDATA, LPARAM(this)); mir_subclassWindow(m_message.GetHwnd(), stubMessageProc); @@ -661,10 +477,12 @@ bool CSrmmBaseDialog::OnInitDialog() void CSrmmBaseDialog::OnDestroy() { + m_pLog->Detach(); + delete m_pLog; + WindowList_Remove(g_hWindowList, m_hwnd); SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0); - mir_unsubclassWindow(m_log.GetHwnd(), stubLogProc); mir_unsubclassWindow(m_message.GetHwnd(), stubMessageProc); mir_unsubclassWindow(m_nickList.GetHwnd(), stubNicklistProc); } @@ -697,65 +515,8 @@ INT_PTR CSrmmBaseDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) case WM_NOTIFY: LPNMHDR hdr = (LPNMHDR)lParam; - if (hdr->hwndFrom == m_log.GetHwnd() && hdr->code == EN_LINK) { - ENLINK *pLink = (ENLINK*)lParam; - switch (pLink->msg) { - case WM_SETCURSOR: - SetCursor(g_hCurHyperlinkHand); - SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, TRUE); - return TRUE; - - case WM_RBUTTONDOWN: - case WM_LBUTTONUP: - case WM_LBUTTONDBLCLK: - CHARRANGE sel; - m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); - if (sel.cpMin != sel.cpMax) - break; - - CMStringW wszText(' ', pLink->chrg.cpMax - pLink->chrg.cpMin + 1); - - TEXTRANGE tr; - tr.chrg = pLink->chrg; - tr.lpstrText = wszText.GetBuffer(); - m_log.SendMsg(EM_GETTEXTRANGE, 0, (LPARAM)&tr); - if (wcschr(tr.lpstrText, '@') != nullptr && wcschr(tr.lpstrText, ':') == nullptr && wcschr(tr.lpstrText, '/') == nullptr) - wszText.Insert(0, L"mailto:"); - - if (pLink->msg == WM_RBUTTONDOWN) { - HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_CONTEXT)); - HMENU hSubMenu = GetSubMenu(hMenu, 6); - TranslateMenu(hSubMenu); - - POINT pt = { GET_X_LPARAM(pLink->lParam), GET_Y_LPARAM(pLink->lParam) }; - ClientToScreen(((NMHDR *)lParam)->hwndFrom, &pt); - - switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_hwnd, nullptr)) { - case IDM_OPENLINK: - Utils_OpenUrlW(wszText); - break; - - case IDM_COPYLINK: - if (OpenClipboard(m_hwnd)) { - EmptyClipboard(); - HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, (wszText.GetLength() + 1) * sizeof(wchar_t)); - mir_wstrcpy((wchar_t*)GlobalLock(hData), wszText); - GlobalUnlock(hData); - SetClipboardData(CF_UNICODETEXT, hData); - CloseClipboard(); - } - break; - } - - DestroyMenu(hMenu); - SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, TRUE); - return TRUE; - } - - Utils_OpenUrlW(wszText); - SetFocus(m_message.GetHwnd()); - } - } + if (hdr->hwndFrom == m_pLog->GetHwnd()) + m_pLog->Notify(wParam, lParam); break; } @@ -765,14 +526,14 @@ INT_PTR CSrmmBaseDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) void CSrmmBaseDialog::AddLog() { if (m_si->pLogEnd) - StreamInEvents(m_si->pLog, false); + m_pLog->LogEvents(m_si->pLog, false); else - ClearLog(); + m_pLog->Clear(); } void CSrmmBaseDialog::ClearLog() { - m_log.SetText(L""); + m_pLog->Clear(); } void CSrmmBaseDialog::UpdateOptions() @@ -796,7 +557,7 @@ void RedrawLog2(SESSION_INFO *si) { si->LastTime = 0; if (si->pLog) - si->pDlg->StreamInEvents(si->pLogEnd, TRUE); + si->pDlg->m_pLog->LogEvents(si->pLogEnd, TRUE); } static void __cdecl phase2(SESSION_INFO *si) @@ -821,10 +582,10 @@ void CSrmmBaseDialog::RedrawLog() if (m_si->iType != GCW_CHATROOM || !m_bFilterEnabled || (m_iLogFilterFlags & pLog->iType) != 0) index++; } - StreamInEvents(pLog, true); + m_pLog->LogEvents(pLog, true); mir_forkThread(phase2, m_si); } - else StreamInEvents(m_si->pLogEnd, true); + else m_pLog->LogEvents(m_si->pLogEnd, true); } else ClearLog(); } @@ -955,7 +716,7 @@ int CSrmmBaseDialog::NotifyEvent(int code) mwe.uType = code; mwe.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH; mwe.hwndInput = m_message.GetHwnd(); - mwe.hwndLog = m_log.GetHwnd(); + mwe.hwndLog = m_pLog->GetHwnd(); return ::NotifyEventHooks(hHookSrmmEvent, 0, (LPARAM)&mwe); } diff --git a/src/mir_app/src/srmm_log.cpp b/src/mir_app/src/srmm_log.cpp new file mode 100644 index 0000000000..27bf946237 --- /dev/null +++ b/src/mir_app/src/srmm_log.cpp @@ -0,0 +1,141 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (C) 2012-19 Miranda NG team, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +///////////////////////////////////////////////////////////////////////////////////////// +// SRMM log container + +#include "stdafx.h" +#include "chat.h" + +struct LoggerClass +{ + LoggerClass(const char *p1, const wchar_t *p2, pfnSrmmLogCreator p3) : + szShortName(mir_strdup(p1)), + wszScreenName(mir_wstrdup(p2)), + pfnBuilder(p3) + {} + + ptrA szShortName; + ptrW wszScreenName; + pfnSrmmLogCreator pfnBuilder; +}; + +static OBJLIST g_arLogClasses(1, PtrKeySortT); + +static CMOption g_bEnableCustomLogs("SRMM", "EnableCustomLogs", 0); + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(HANDLE) RegisterSrmmLog(const char *pszShortName, const wchar_t *pwszScreenName, pfnSrmmLogCreator fnBuilder) +{ + if (!pszShortName || !pwszScreenName || !fnBuilder) + return nullptr; + + auto *p = new LoggerClass(pszShortName, pwszScreenName, fnBuilder); + g_arLogClasses.insert(p); + return p; +} + +MIR_APP_DLL(void) UnregisterSrmmLog(HANDLE pLogger) +{ + g_arLogClasses.remove((LoggerClass *)pLogger); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +CSrmmLogWindow* Srmm_GetLogWindow(CMsgDialog *pDlg) +{ + if (!pDlg->isChat() || g_bEnableCustomLogs) { + ptrA szCurr(db_get_sa(0, "SRMM", "Logger", "built-in")); + + for (auto &it : g_arLogClasses) + if (!mir_strcmp(szCurr, it->szShortName)) + return it->pfnBuilder(*pDlg); + } + + for (auto &it : g_arLogClasses) + if (!mir_strcmp(it->szShortName, "built-in")) + return it->pfnBuilder(*pDlg); + + return nullptr; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// options dialog + +class CSrmmLogOptionsDlg : public CDlgBase +{ + CCtrlListBox m_list; + CCtrlCheck chkCustomLogs; + +public: + CSrmmLogOptionsDlg() : + CDlgBase(g_plugin, IDD_OPT_SRMMLOG), + m_list(this, IDC_LIST), + chkCustomLogs(this, IDC_ENABLE_CUSTOM) + { + CreateLink(chkCustomLogs, g_bEnableCustomLogs); + + m_list.OnSelChange = Callback(this, &CSrmmLogOptionsDlg::onChange_List); + } + + bool OnInitDialog() override + { + ptrA szCurr(db_get_sa(0, "SRMM", "Logger", "built-in")); + + for (auto &it : g_arLogClasses) { + int idx = m_list.AddString(it->wszScreenName, LPARAM(it)); + if (!mir_strcmp(szCurr, it->szShortName)) + m_list.SetCurSel(idx); + } + + return true; + } + + bool OnApply() override + { + int idx = m_list.GetCurSel(); + if (idx == -1) + return false; + + auto *pLogger = (LoggerClass *)m_list.GetItemData(idx); + db_set_s(0, "SRMM", "Logger", pLogger->szShortName); + return true; + } + + void onChange_List(CCtrlListBox *) + { + NotifyChange(); + } +}; + +void SrmmLogOptionsInit(WPARAM wParam) +{ + OPTIONSDIALOGPAGE odp = {}; + odp.position = 910000000; + odp.szGroup.a = LPGEN("Message sessions"); + odp.szTitle.a = LPGEN("Log viewer"); + odp.flags = ODPF_BOLDGROUPS; + odp.pDialog = new CSrmmLogOptionsDlg(); + g_plugin.addOptions(wParam, &odp); +} diff --git a/src/mir_app/src/srmm_log_hpp.cpp b/src/mir_app/src/srmm_log_hpp.cpp new file mode 100644 index 0000000000..de829ebe3b --- /dev/null +++ b/src/mir_app/src/srmm_log_hpp.cpp @@ -0,0 +1,259 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (C) 2012-19 Miranda NG team, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +///////////////////////////////////////////////////////////////////////////////////////// +// CHppLogWindow class + +#include "stdafx.h" +#include "chat.h" + +#define EVENTTYPE_STATUSCHANGE 25368 +#define EVENTTYPE_ERRMSG 25366 + +class CHppLogWindow : public CSrmmLogWindow +{ + HWND m_hwnd = nullptr; + +public: + CHppLogWindow(CMsgDialog &pDlg) : + CSrmmLogWindow(pDlg) + { + } + + void Attach() override + { + IEVIEWWINDOW ieWindow = {}; + ieWindow.iType = IEW_CREATE; + ieWindow.dwMode = IEWM_TABSRMM; + ieWindow.parent = m_pDlg.GetHwnd(); + ieWindow.cx = 10; + ieWindow.cy = 10; + CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow); + m_hwnd = ieWindow.hwnd; + } + + void Detach() override + { + IEVIEWWINDOW ieWindow = {}; + ieWindow.iType = IEW_DESTROY; + ieWindow.hwnd = m_hwnd; + CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow); + } + + ////////////////////////////////////////////////////////////////////////////////////// + + bool AtBottom() override + { + return false; + } + + void Clear() override + { + IEVIEWEVENT event = {}; + event.iType = IEE_CLEAR_LOG; + event.hwnd = m_hwnd; + CallService(MS_HPP_EG_EVENT, 0, (LPARAM)&event); + } + + HWND GetHwnd() override + { + return m_hwnd; + } + + int GetType() override + { + return 2; + } + + wchar_t* GetSelection() override + { + IEVIEWEVENT event = {}; + event.hwnd = m_hwnd; + event.iType = IEE_GET_SELECTION; + event.hContact = m_pDlg.m_hContact; + event.dwFlags = 0; + return (wchar_t *)CallService(MS_HPP_EG_EVENT, 0, (LPARAM)&event); + } + + void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) override + { + if (!bAppend) + Clear(); + + IEVIEWEVENT event = {}; + event.hwnd = m_hwnd; + event.iType = IEE_LOG_DB_EVENTS; + event.hDbEventFirst = hDbEventFirst; + event.hContact = m_pDlg.m_hContact; + event.count = count; + CallService(MS_HPP_EG_EVENT, 0, (LPARAM)&event); + } + + void LogEvents(DBEVENTINFO *dbei, bool bAppend) override + { + if (!bAppend) + Clear(); + + IEVIEWEVENT event = {}; + event.hwnd = m_hwnd; + event.iType = IEE_LOG_MEM_EVENTS; + + IEVIEWEVENTDATA evData = {}; + if (dbei->flags & DBEF_SENT) { + evData.dwFlags = IEEDF_SENT; + evData.bIsMe = true; + } + else { + evData.dwFlags = IEEDF_UNICODE_NICK; + evData.szNick.w = Clist_GetContactDisplayName(m_pDlg.m_hContact); + } + switch (dbei->eventType) { + case EVENTTYPE_STATUSCHANGE: evData.iType = IEED_EVENT_STATUSCHANGE; break; + case EVENTTYPE_FILE: evData.iType = IEED_EVENT_FILE; break; + case EVENTTYPE_ERRMSG: evData.iType = IEED_EVENT_ERRMSG; break; + default: evData.iType = IEED_EVENT_MESSAGE; break; + } + evData.szText.a = (char *)dbei->pBlob; + evData.time = dbei->timestamp; + event.eventData = &evData; + event.codepage = CP_UTF8; + event.count = 1; + CallService(MS_HPP_EG_EVENT, 0, (LPARAM)&event); + } + + void CHppLogWindow::LogEvents(LOGINFO *pLog, bool) + { + IEVIEWEVENTDATA ied = {}; + ied.dwFlags = IEEDF_UNICODE_NICK | IEEDF_UNICODE_TEXT; + + IEVIEWEVENT event = {}; + event.hwnd = m_hwnd; + event.hContact = m_pDlg.m_hContact; + event.codepage = CP_ACP; + event.iType = IEE_LOG_MEM_EVENTS; + 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; + + switch (pLog->iType) { + case GC_EVENT_MESSAGE: + ied.iType = IEED_GC_EVENT_MESSAGE; + ied.dwData = IEEDD_GC_SHOW_NICK; + break; + case GC_EVENT_ACTION: + ied.iType = IEED_GC_EVENT_ACTION; + break; + case GC_EVENT_JOIN: + ied.iType = IEED_GC_EVENT_JOIN; + break; + case GC_EVENT_PART: + ied.iType = IEED_GC_EVENT_PART; + break; + case GC_EVENT_QUIT: + ied.iType = IEED_GC_EVENT_QUIT; + break; + case GC_EVENT_NICK: + ied.iType = IEED_GC_EVENT_NICK; + break; + case GC_EVENT_KICK: + ied.iType = IEED_GC_EVENT_KICK; + break; + case GC_EVENT_NOTICE: + ied.iType = IEED_GC_EVENT_NOTICE; + break; + case GC_EVENT_TOPIC: + ied.iType = IEED_GC_EVENT_TOPIC; + break; + case GC_EVENT_INFORMATION: + ied.iType = IEED_GC_EVENT_INFORMATION; + break; + case GC_EVENT_ADDSTATUS: + ied.iType = IEED_GC_EVENT_ADDSTATUS; + break; + case GC_EVENT_REMOVESTATUS: + ied.iType = IEED_GC_EVENT_REMOVESTATUS; + break; + } + ied.dwData |= g_Settings->bShowTime ? IEEDD_GC_SHOW_TIME : 0; + ied.dwData |= IEEDD_GC_SHOW_ICON; + ied.dwFlags = IEEDF_UNICODE_TEXT | IEEDF_UNICODE_NICK | IEEDF_UNICODE_TEXT2; + CallService(MS_HPP_EG_EVENT, 0, (LPARAM) & event); + } + + pLog = pLog->prev; + } + } + + void Resize() override + { + RECT rcRichEdit; + GetWindowRect(GetDlgItem(m_pDlg.GetHwnd(), IDC_SRMM_LOG), &rcRichEdit); + + POINT pt = { rcRichEdit.left, rcRichEdit.top }; + ScreenToClient(GetParent(m_hwnd), &pt); + + IEVIEWWINDOW ieWindow = { sizeof(ieWindow) }; + ieWindow.iType = IEW_SETPOS; + ieWindow.parent = m_hwnd; + ieWindow.hwnd = m_hwnd; + ieWindow.x = pt.x; + ieWindow.y = pt.y; + ieWindow.cx = rcRichEdit.right - rcRichEdit.left; + ieWindow.cy = rcRichEdit.bottom - rcRichEdit.top; + if (ieWindow.cx != 0 && ieWindow.cy != 0) + CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow); + } + + void ScrollToBottom() override + { + IEVIEWWINDOW iew = { sizeof(iew) }; + iew.iType = IEW_SCROLLBOTTOM; + iew.hwnd = m_hwnd; + CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&iew); + } +}; + +///////////////////////////////////////////////////////////////////////////////////////// + +static HANDLE hLogger; + +static CSrmmLogWindow *logBuilder(CMsgDialog &pDlg) +{ + return new CHppLogWindow(pDlg); +} + +MIR_APP_DLL(void) RegisterHppLogger() +{ + hLogger = RegisterSrmmLog("hpp", L"History++ log", &logBuilder); +} + +MIR_APP_DLL(void) UnregisterHppLogger() +{ + UnregisterSrmmLog(hLogger); +} diff --git a/src/mir_app/src/srmm_log_rtf.cpp b/src/mir_app/src/srmm_log_rtf.cpp new file mode 100644 index 0000000000..f13cfbff43 --- /dev/null +++ b/src/mir_app/src/srmm_log_rtf.cpp @@ -0,0 +1,375 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (C) 2012-19 Miranda NG team, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +///////////////////////////////////////////////////////////////////////////////////////// +// SRMM log container + +#include "stdafx.h" +#include "chat.h" + +#define EVENTTYPE_STATUSCHANGE 25368 +#define EVENTTYPE_ERRMSG 25366 + +CRtfLogWindow::CRtfLogWindow(CMsgDialog &pDlg) : + CSrmmLogWindow(pDlg), + m_rtf(*(CCtrlRichEdit*)pDlg.FindControl(IDC_SRMM_LOG)) +{ +} + +CRtfLogWindow::~CRtfLogWindow() +{ +} + +///////////////////////////////////////////////////////////////////////////////////////// + +EXTERN_C MIR_APP_DLL(LRESULT) CALLBACK stubLogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CRtfLogWindow *pLog = (CRtfLogWindow *)GetWindowLongPtr(hwnd, GWLP_USERDATA); + if (pLog != nullptr) + return pLog->WndProc(msg, wParam, lParam); + + return mir_callNextSubclass(hwnd, stubLogProc, msg, wParam, lParam); +} + +void CRtfLogWindow::Attach() +{ + SetWindowLongPtr(m_rtf.GetHwnd(), GWLP_USERDATA, LPARAM(this)); + m_rtf.SetReadOnly(true); + + mir_subclassWindow(m_rtf.GetHwnd(), stubLogProc); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CRtfLogWindow::Detach() +{ + mir_unsubclassWindow(m_rtf.GetHwnd(), stubLogProc); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +bool CRtfLogWindow::AtBottom() +{ + if (!(GetWindowLongPtr(m_rtf.GetHwnd(), GWL_STYLE) & WS_VSCROLL)) + return true; + + SCROLLINFO si = {}; + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; + GetScrollInfo(m_rtf.GetHwnd(), SB_VERT, &si); + return (si.nPos + (int)si.nPage + 5) >= si.nMax; +} + +void CRtfLogWindow::Clear() +{ + m_rtf.SetText(L""); +} + +HWND CRtfLogWindow::GetHwnd() +{ + return m_rtf.GetHwnd(); +} + +int CRtfLogWindow::GetType() +{ + return 0; +} + +wchar_t* CRtfLogWindow::GetSelection() +{ + return nullptr; +} + +INT_PTR CRtfLogWindow::Notify(WPARAM, LPARAM lParam) +{ + LPNMHDR hdr = (LPNMHDR)lParam; + if (hdr->code != EN_LINK) + return FALSE; + + ENLINK *pLink = (ENLINK *)lParam; + switch (pLink->msg) { + case WM_SETCURSOR: + SetCursor(g_hCurHyperlinkHand); + SetWindowLongPtr(m_pDlg.m_hwnd, DWLP_MSGRESULT, TRUE); + return TRUE; + + case WM_RBUTTONDOWN: + case WM_LBUTTONUP: + case WM_LBUTTONDBLCLK: + CHARRANGE sel; + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin != sel.cpMax) + break; + + CMStringW wszText(' ', pLink->chrg.cpMax - pLink->chrg.cpMin + 1); + + TEXTRANGE tr; + tr.chrg = pLink->chrg; + tr.lpstrText = wszText.GetBuffer(); + m_rtf.SendMsg(EM_GETTEXTRANGE, 0, (LPARAM)&tr); + if (wcschr(tr.lpstrText, '@') != nullptr && wcschr(tr.lpstrText, ':') == nullptr && wcschr(tr.lpstrText, '/') == nullptr) + wszText.Insert(0, L"mailto:"); + + if (pLink->msg == WM_RBUTTONDOWN) { + HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_CONTEXT)); + HMENU hSubMenu = GetSubMenu(hMenu, 6); + TranslateMenu(hSubMenu); + + POINT pt = { GET_X_LPARAM(pLink->lParam), GET_Y_LPARAM(pLink->lParam) }; + ClientToScreen(((NMHDR *)lParam)->hwndFrom, &pt); + + switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_pDlg.m_hwnd, nullptr)) { + case IDM_OPENLINK: + Utils_OpenUrlW(wszText); + break; + + case IDM_COPYLINK: + if (OpenClipboard(m_pDlg.m_hwnd)) { + EmptyClipboard(); + HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, (wszText.GetLength() + 1) * sizeof(wchar_t)); + mir_wstrcpy((wchar_t *)GlobalLock(hData), wszText); + GlobalUnlock(hData); + SetClipboardData(CF_UNICODETEXT, hData); + CloseClipboard(); + } + break; + } + + DestroyMenu(hMenu); + SetWindowLongPtr(m_pDlg.m_hwnd, DWLP_MSGRESULT, TRUE); + return TRUE; + } + + Utils_OpenUrlW(wszText); + SetFocus(m_pDlg.m_message.GetHwnd()); + } + + return FALSE; +} + +void CRtfLogWindow::Resize() +{ + bool bottomScroll = !m_pDlg.isChat(); + if (AtBottom()) + bottomScroll = true; + + // ::MoveWindow(m_rtf.GetHwnd(), x, y, cx, cy, true); + + if (bottomScroll) + ScrollToBottom(); +} + +void CRtfLogWindow::ScrollToBottom() +{ + if (!(GetWindowLongPtr(m_rtf.GetHwnd(), GWL_STYLE) & WS_VSCROLL)) + return; + + SCROLLINFO si = {}; + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(m_rtf.GetHwnd(), SB_VERT, &si); + + si.fMask = SIF_POS; + si.nPos = si.nMax - si.nPage; + SetScrollInfo(m_rtf.GetHwnd(), SB_VERT, &si, TRUE); + m_rtf.SendMsg(WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static wchar_t szTrimString[] = L":;,.!?\'\"><()[]- \r\n"; + +INT_PTR CRtfLogWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam) +{ + CHARRANGE sel; + + switch (msg) { + case WM_ACTIVATE: + if (LOWORD(wParam) == WA_INACTIVE) { + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin != sel.cpMax) { + sel.cpMin = sel.cpMax; + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + } + } + break; + + case WM_SETCURSOR: + if (m_pDlg.m_bInMenu) { + SetCursor(LoadCursor(nullptr, IDC_ARROW)); + return TRUE; + } + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + if (!(GetKeyState(VK_RMENU) & 0x8000)) { + MSG message = { m_pDlg.m_hwnd, msg, wParam, lParam }; + LRESULT iButtonFrom = Hotkey_Check(&message, BB_HK_SECTION); + if (iButtonFrom) { + Srmm_ProcessToolbarHotkey(m_pDlg.m_hContact, iButtonFrom, m_pDlg.m_hwnd); + return TRUE; + } + } + break; + + case WM_CHAR: + if (wParam >= ' ') { + SetFocus(m_pDlg.m_message.GetHwnd()); + m_pDlg.m_message.SendMsg(WM_CHAR, wParam, lParam); + } + else if (wParam == '\t') + SetFocus(m_pDlg.m_message.GetHwnd()); + break; + + case WM_CONTEXTMENU: + POINT pt, ptl; + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + if (lParam == 0xFFFFFFFF) { + m_rtf.SendMsg(EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)sel.cpMax); + ClientToScreen(m_rtf.GetHwnd(), &pt); + } + else { + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + } + ptl = pt; + ScreenToClient(m_rtf.GetHwnd(), (LPPOINT)&ptl); + { + wchar_t *pszWord = (wchar_t *)_alloca(8192); + pszWord[0] = '\0'; + + // get a word under cursor + if (sel.cpMin == sel.cpMax) { + int iCharIndex = m_rtf.SendMsg(EM_CHARFROMPOS, 0, (LPARAM)&ptl); + if (iCharIndex < 0) + break; + + sel.cpMin = m_rtf.SendMsg(EM_FINDWORDBREAK, WB_LEFT, iCharIndex); + sel.cpMax = m_rtf.SendMsg(EM_FINDWORDBREAK, WB_RIGHT, iCharIndex); + } + + if (sel.cpMax > sel.cpMin) { + TEXTRANGE tr = { 0 }; + tr.chrg = sel; + tr.lpstrText = pszWord; + int iRes = m_rtf.SendMsg(EM_GETTEXTRANGE, 0, (LPARAM)&tr); + if (iRes > 0) { + wchar_t *p = wcschr(pszWord, '\r'); + if (p) + *p = 0; + + size_t iLen = mir_wstrlen(pszWord) - 1; + while (wcschr(szTrimString, pszWord[iLen])) { + pszWord[iLen] = '\0'; + iLen--; + } + } + } + + CHARRANGE all = { 0, -1 }; + HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_LOGMENU)); + HMENU hSubMenu = GetSubMenu(hMenu, 0); + TranslateMenu(hSubMenu); + m_pDlg.m_bInMenu = true; + UINT uID = CreateGCMenu(m_rtf.GetHwnd(), hSubMenu, pt, m_pDlg.m_si, nullptr, pszWord); + m_pDlg.m_bInMenu = false; + switch (uID) { + case 0: + PostMessage(m_pDlg.m_hwnd, WM_MOUSEACTIVATE, 0, 0); + break; + + case IDM_COPYALL: + m_rtf.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); + m_rtf.SendMsg(WM_COPY, 0, 0); + m_rtf.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + PostMessage(m_pDlg.m_hwnd, WM_MOUSEACTIVATE, 0, 0); + break; + + 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->LastTime = 0; + } + PostMessage(m_pDlg.m_hwnd, WM_MOUSEACTIVATE, 0, 0); + break; + + case IDM_SEARCH_GOOGLE: + case IDM_SEARCH_BING: + case IDM_SEARCH_YANDEX: + case IDM_SEARCH_YAHOO: + case IDM_SEARCH_WIKIPEDIA: + case IDM_SEARCH_FOODNETWORK: + case IDM_SEARCH_GOOGLE_MAPS: + case IDM_SEARCH_GOOGLE_TRANSLATE: + { + CMStringW szURL; + switch (uID) { + case IDM_SEARCH_WIKIPEDIA: + szURL.Format(L"http://en.wikipedia.org/wiki/%s", pszWord); + break; + case IDM_SEARCH_YAHOO: + szURL.Format(L"http://search.yahoo.com/search?p=%s&ei=UTF-8", pszWord); + break; + case IDM_SEARCH_FOODNETWORK: + szURL.Format(L"http://search.foodnetwork.com/search/delegate.do?fnSearchString=%s", pszWord); + break; + case IDM_SEARCH_BING: + szURL.Format(L"http://www.bing.com/search?q=%s&form=OSDSRC", pszWord); + break; + case IDM_SEARCH_GOOGLE_MAPS: + szURL.Format(L"http://maps.google.com/maps?q=%s&ie=utf-8&oe=utf-8", pszWord); + break; + case IDM_SEARCH_GOOGLE_TRANSLATE: + szURL.Format(L"http://translate.google.com/?q=%s&ie=utf-8&oe=utf-8", pszWord); + break; + case IDM_SEARCH_YANDEX: + szURL.Format(L"http://yandex.ru/yandsearch?text=%s", pszWord); + break; + case IDM_SEARCH_GOOGLE: + szURL.Format(L"http://www.google.com/search?q=%s&ie=utf-8&oe=utf-8", pszWord); + break; + } + Utils_OpenUrlW(szURL); + } + PostMessage(m_pDlg.m_hwnd, WM_MOUSEACTIVATE, 0, 0); + break; + + default: + PostMessage(m_pDlg.m_hwnd, WM_MOUSEACTIVATE, 0, 0); + Chat_DoEventHook(m_pDlg.m_si, GC_USER_LOGMENU, nullptr, nullptr, uID); + break; + } + DestroyMenu(hMenu); + } + break; + } + + LRESULT res = mir_callNextSubclass(m_rtf.GetHwnd(), stubLogProc, msg, wParam, lParam); + if (msg == WM_GETDLGCODE) + return res & ~DLGC_HASSETSEL; + return res; +} diff --git a/src/mir_app/src/srmm_toolbar.cpp b/src/mir_app/src/srmm_toolbar.cpp index b3c1aba600..6f99996ca8 100644 --- a/src/mir_app/src/srmm_toolbar.cpp +++ b/src/mir_app/src/srmm_toolbar.cpp @@ -769,6 +769,8 @@ public: } }; +void SrmmLogOptionsInit(WPARAM wParam); + static int SrmmOptionsInit(WPARAM wParam, LPARAM) { OPTIONSDIALOGPAGE odp = {}; @@ -778,6 +780,8 @@ static int SrmmOptionsInit(WPARAM wParam, LPARAM) odp.flags = ODPF_BOLDGROUPS; odp.pDialog = new CSrmmToolbarOptions(); g_plugin.addOptions(wParam, &odp); + + SrmmLogOptionsInit(wParam); return 0; } diff --git a/src/mir_app/src/stdafx.h b/src/mir_app/src/stdafx.h index 9d369695a0..6f4d249864 100644 --- a/src/mir_app/src/stdafx.h +++ b/src/mir_app/src/stdafx.h @@ -74,8 +74,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include +#include #include #include +#include #include #include #include diff --git a/src/mir_core/src/CDlgBase.cpp b/src/mir_core/src/CDlgBase.cpp index 2c91c6a742..5a19c58558 100644 --- a/src/mir_core/src/CDlgBase.cpp +++ b/src/mir_core/src/CDlgBase.cpp @@ -412,6 +412,11 @@ void CDlgBase::AddControl(CCtrlBase *ctrl) m_controls.insert(ctrl); } +void CDlgBase::RemoveControl(CCtrlBase *ctrl) +{ + m_controls.remove(ctrl); +} + void CDlgBase::NotifyControls(void (CCtrlBase::*fn)()) { for (auto &it : m_controls) diff --git a/src/mir_core/src/mir_core.def b/src/mir_core/src/mir_core.def index 4bcb6da163..7069b1e3f2 100644 --- a/src/mir_core/src/mir_core.def +++ b/src/mir_core/src/mir_core.def @@ -1449,3 +1449,4 @@ XmlGetChildText @1645 ?Unsigned64Attribute@XMLElement@tinyxml2@@QBE_KPBD_K@Z @1664 NONAME ?Unsigned64Text@XMLElement@tinyxml2@@QBE_K_K@Z @1665 NONAME ?Unsigned64Value@XMLAttribute@tinyxml2@@QBE_KXZ @1666 NONAME +?RemoveControl@CDlgBase@@IAEXPAVCCtrlBase@@@Z @1667 NONAME diff --git a/src/mir_core/src/mir_core64.def b/src/mir_core/src/mir_core64.def index 8f8d58de25..7cc4be7567 100644 --- a/src/mir_core/src/mir_core64.def +++ b/src/mir_core/src/mir_core64.def @@ -1449,3 +1449,4 @@ XmlGetChildText @1645 ?Unsigned64Attribute@XMLElement@tinyxml2@@QEBA_KPEBD_K@Z @1664 NONAME ?Unsigned64Text@XMLElement@tinyxml2@@QEBA_K_K@Z @1665 NONAME ?Unsigned64Value@XMLAttribute@tinyxml2@@QEBA_KXZ @1666 NONAME +?RemoveControl@CDlgBase@@IEAAXPEAVCCtrlBase@@@Z @1667 NONAME -- cgit v1.2.3