From 3a56ba391bf176c11cc5bde6f860759a3ce4477c Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Thu, 5 Jul 2012 13:27:02 +0000 Subject: BasicHistory: folder structure change git-svn-id: http://svn.miranda-ng.org/main/trunk@773 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/BasicHistory/BasicHistory.cpp | 425 ---- plugins/BasicHistory/BasicHistory.rc | 263 -- plugins/BasicHistory/BasicHistory.vcxproj | 90 +- plugins/BasicHistory/BasicHistory.vcxproj.filters | 90 +- plugins/BasicHistory/BinaryExport.cpp | 231 -- plugins/BasicHistory/BinaryExport.h | 47 - plugins/BasicHistory/DatExport.cpp | 214 -- plugins/BasicHistory/DatExport.h | 53 - plugins/BasicHistory/Docs/ReadMe.txt | 48 + .../BasicHistory/Docs/basichistory-translation.txt | 252 ++ plugins/BasicHistory/EventList.cpp | 907 ------- plugins/BasicHistory/EventList.h | 161 -- plugins/BasicHistory/ExportManager.cpp | 391 --- plugins/BasicHistory/ExportManager.h | 59 - plugins/BasicHistory/HistoryWindow.cpp | 2572 -------------------- plugins/BasicHistory/HistoryWindow.h | 95 - plugins/BasicHistory/HotkeyHelper.cpp | 105 - plugins/BasicHistory/HotkeyHelper.h | 24 - plugins/BasicHistory/IExport.h | 49 - plugins/BasicHistory/IImport.h | 53 - plugins/BasicHistory/ImageDataObject.cpp | 171 -- plugins/BasicHistory/ImageDataObject.h | 133 - plugins/BasicHistory/Options.cpp | 2170 ----------------- plugins/BasicHistory/Options.h | 199 -- plugins/BasicHistory/PlainHtmlExport.cpp | 106 - plugins/BasicHistory/PlainHtmlExport.h | 37 - plugins/BasicHistory/ReadMe.txt | 48 - plugins/BasicHistory/RichHtmlExport.cpp | 545 ----- plugins/BasicHistory/RichHtmlExport.h | 44 - plugins/BasicHistory/Scheduler.cpp | 1576 ------------ plugins/BasicHistory/SearchContext.h | 55 - plugins/BasicHistory/Searcher.cpp | 388 --- plugins/BasicHistory/Searcher.h | 119 - plugins/BasicHistory/TxtExport.cpp | 65 - plugins/BasicHistory/TxtExport.h | 38 - plugins/BasicHistory/basichistory-translation.txt | 252 -- plugins/BasicHistory/codecvt_CodePage.h | 98 - plugins/BasicHistory/dllmain.cpp | 14 - plugins/BasicHistory/history.css | 34 - plugins/BasicHistory/history.js | 95 - plugins/BasicHistory/icons/FindNext.ico | Bin 1406 -> 0 bytes plugins/BasicHistory/icons/FindPrev.ico | Bin 1406 -> 0 bytes plugins/BasicHistory/icons/Incom.ico | Bin 1406 -> 0 bytes plugins/BasicHistory/icons/Outg.ico | Bin 1406 -> 0 bytes plugins/BasicHistory/icons/Status change.ico | Bin 1406 -> 0 bytes plugins/BasicHistory/icons/minus.ico | Bin 4286 -> 0 bytes plugins/BasicHistory/icons/mnode.ico | Bin 1150 -> 0 bytes plugins/BasicHistory/icons/plus.ico | Bin 4286 -> 0 bytes plugins/BasicHistory/icons/pnode.ico | Bin 1150 -> 0 bytes plugins/BasicHistory/res/BasicHistory.rc | 263 ++ plugins/BasicHistory/res/FindNext.ico | Bin 0 -> 1406 bytes plugins/BasicHistory/res/FindPrev.ico | Bin 0 -> 1406 bytes plugins/BasicHistory/res/Incom.ico | Bin 0 -> 1406 bytes plugins/BasicHistory/res/Outg.ico | Bin 0 -> 1406 bytes plugins/BasicHistory/res/Status change.ico | Bin 0 -> 1406 bytes plugins/BasicHistory/res/history.css | 34 + plugins/BasicHistory/res/history.js | 95 + plugins/BasicHistory/res/minus.ico | Bin 0 -> 4286 bytes plugins/BasicHistory/res/mnode.ico | Bin 0 -> 1150 bytes plugins/BasicHistory/res/plus.ico | Bin 0 -> 4286 bytes plugins/BasicHistory/res/pnode.ico | Bin 0 -> 1150 bytes plugins/BasicHistory/res/version.rc | 37 + plugins/BasicHistory/resource.h | 157 -- plugins/BasicHistory/src/BasicHistory.cpp | 425 ++++ plugins/BasicHistory/src/BinaryExport.cpp | 231 ++ plugins/BasicHistory/src/BinaryExport.h | 47 + plugins/BasicHistory/src/DatExport.cpp | 214 ++ plugins/BasicHistory/src/DatExport.h | 53 + plugins/BasicHistory/src/EventList.cpp | 907 +++++++ plugins/BasicHistory/src/EventList.h | 161 ++ plugins/BasicHistory/src/ExportManager.cpp | 391 +++ plugins/BasicHistory/src/ExportManager.h | 59 + plugins/BasicHistory/src/HistoryWindow.cpp | 2572 ++++++++++++++++++++ plugins/BasicHistory/src/HistoryWindow.h | 95 + plugins/BasicHistory/src/HotkeyHelper.cpp | 105 + plugins/BasicHistory/src/HotkeyHelper.h | 24 + plugins/BasicHistory/src/IExport.h | 49 + plugins/BasicHistory/src/IImport.h | 53 + plugins/BasicHistory/src/ImageDataObject.cpp | 171 ++ plugins/BasicHistory/src/ImageDataObject.h | 133 + plugins/BasicHistory/src/Options.cpp | 2170 +++++++++++++++++ plugins/BasicHistory/src/Options.h | 199 ++ plugins/BasicHistory/src/PlainHtmlExport.cpp | 106 + plugins/BasicHistory/src/PlainHtmlExport.h | 37 + plugins/BasicHistory/src/RichHtmlExport.cpp | 545 +++++ plugins/BasicHistory/src/RichHtmlExport.h | 44 + plugins/BasicHistory/src/Scheduler.cpp | 1576 ++++++++++++ plugins/BasicHistory/src/SearchContext.h | 55 + plugins/BasicHistory/src/Searcher.cpp | 388 +++ plugins/BasicHistory/src/Searcher.h | 119 + plugins/BasicHistory/src/TxtExport.cpp | 65 + plugins/BasicHistory/src/TxtExport.h | 38 + plugins/BasicHistory/src/codecvt_CodePage.h | 98 + plugins/BasicHistory/src/dllmain.cpp | 14 + plugins/BasicHistory/src/resource.h | 157 ++ plugins/BasicHistory/src/stdafx.cpp | 8 + plugins/BasicHistory/src/stdafx.h | 88 + plugins/BasicHistory/src/targetver.h | 8 + plugins/BasicHistory/src/version.h | 20 + plugins/BasicHistory/stdafx.cpp | 8 - plugins/BasicHistory/stdafx.h | 88 - plugins/BasicHistory/targetver.h | 8 - plugins/BasicHistory/version.h | 20 - plugins/BasicHistory/version.rc | 37 - 104 files changed, 12244 insertions(+), 12244 deletions(-) delete mode 100644 plugins/BasicHistory/BasicHistory.cpp delete mode 100644 plugins/BasicHistory/BasicHistory.rc delete mode 100644 plugins/BasicHistory/BinaryExport.cpp delete mode 100644 plugins/BasicHistory/BinaryExport.h delete mode 100644 plugins/BasicHistory/DatExport.cpp delete mode 100644 plugins/BasicHistory/DatExport.h create mode 100644 plugins/BasicHistory/Docs/ReadMe.txt create mode 100644 plugins/BasicHistory/Docs/basichistory-translation.txt delete mode 100644 plugins/BasicHistory/EventList.cpp delete mode 100644 plugins/BasicHistory/EventList.h delete mode 100644 plugins/BasicHistory/ExportManager.cpp delete mode 100644 plugins/BasicHistory/ExportManager.h delete mode 100644 plugins/BasicHistory/HistoryWindow.cpp delete mode 100644 plugins/BasicHistory/HistoryWindow.h delete mode 100644 plugins/BasicHistory/HotkeyHelper.cpp delete mode 100644 plugins/BasicHistory/HotkeyHelper.h delete mode 100644 plugins/BasicHistory/IExport.h delete mode 100644 plugins/BasicHistory/IImport.h delete mode 100644 plugins/BasicHistory/ImageDataObject.cpp delete mode 100644 plugins/BasicHistory/ImageDataObject.h delete mode 100644 plugins/BasicHistory/Options.cpp delete mode 100644 plugins/BasicHistory/Options.h delete mode 100644 plugins/BasicHistory/PlainHtmlExport.cpp delete mode 100644 plugins/BasicHistory/PlainHtmlExport.h delete mode 100644 plugins/BasicHistory/ReadMe.txt delete mode 100644 plugins/BasicHistory/RichHtmlExport.cpp delete mode 100644 plugins/BasicHistory/RichHtmlExport.h delete mode 100644 plugins/BasicHistory/Scheduler.cpp delete mode 100644 plugins/BasicHistory/SearchContext.h delete mode 100644 plugins/BasicHistory/Searcher.cpp delete mode 100644 plugins/BasicHistory/Searcher.h delete mode 100644 plugins/BasicHistory/TxtExport.cpp delete mode 100644 plugins/BasicHistory/TxtExport.h delete mode 100644 plugins/BasicHistory/basichistory-translation.txt delete mode 100644 plugins/BasicHistory/codecvt_CodePage.h delete mode 100644 plugins/BasicHistory/dllmain.cpp delete mode 100644 plugins/BasicHistory/history.css delete mode 100644 plugins/BasicHistory/history.js delete mode 100644 plugins/BasicHistory/icons/FindNext.ico delete mode 100644 plugins/BasicHistory/icons/FindPrev.ico delete mode 100644 plugins/BasicHistory/icons/Incom.ico delete mode 100644 plugins/BasicHistory/icons/Outg.ico delete mode 100644 plugins/BasicHistory/icons/Status change.ico delete mode 100644 plugins/BasicHistory/icons/minus.ico delete mode 100644 plugins/BasicHistory/icons/mnode.ico delete mode 100644 plugins/BasicHistory/icons/plus.ico delete mode 100644 plugins/BasicHistory/icons/pnode.ico create mode 100644 plugins/BasicHistory/res/BasicHistory.rc create mode 100644 plugins/BasicHistory/res/FindNext.ico create mode 100644 plugins/BasicHistory/res/FindPrev.ico create mode 100644 plugins/BasicHistory/res/Incom.ico create mode 100644 plugins/BasicHistory/res/Outg.ico create mode 100644 plugins/BasicHistory/res/Status change.ico create mode 100644 plugins/BasicHistory/res/history.css create mode 100644 plugins/BasicHistory/res/history.js create mode 100644 plugins/BasicHistory/res/minus.ico create mode 100644 plugins/BasicHistory/res/mnode.ico create mode 100644 plugins/BasicHistory/res/plus.ico create mode 100644 plugins/BasicHistory/res/pnode.ico create mode 100644 plugins/BasicHistory/res/version.rc delete mode 100644 plugins/BasicHistory/resource.h create mode 100644 plugins/BasicHistory/src/BasicHistory.cpp create mode 100644 plugins/BasicHistory/src/BinaryExport.cpp create mode 100644 plugins/BasicHistory/src/BinaryExport.h create mode 100644 plugins/BasicHistory/src/DatExport.cpp create mode 100644 plugins/BasicHistory/src/DatExport.h create mode 100644 plugins/BasicHistory/src/EventList.cpp create mode 100644 plugins/BasicHistory/src/EventList.h create mode 100644 plugins/BasicHistory/src/ExportManager.cpp create mode 100644 plugins/BasicHistory/src/ExportManager.h create mode 100644 plugins/BasicHistory/src/HistoryWindow.cpp create mode 100644 plugins/BasicHistory/src/HistoryWindow.h create mode 100644 plugins/BasicHistory/src/HotkeyHelper.cpp create mode 100644 plugins/BasicHistory/src/HotkeyHelper.h create mode 100644 plugins/BasicHistory/src/IExport.h create mode 100644 plugins/BasicHistory/src/IImport.h create mode 100644 plugins/BasicHistory/src/ImageDataObject.cpp create mode 100644 plugins/BasicHistory/src/ImageDataObject.h create mode 100644 plugins/BasicHistory/src/Options.cpp create mode 100644 plugins/BasicHistory/src/Options.h create mode 100644 plugins/BasicHistory/src/PlainHtmlExport.cpp create mode 100644 plugins/BasicHistory/src/PlainHtmlExport.h create mode 100644 plugins/BasicHistory/src/RichHtmlExport.cpp create mode 100644 plugins/BasicHistory/src/RichHtmlExport.h create mode 100644 plugins/BasicHistory/src/Scheduler.cpp create mode 100644 plugins/BasicHistory/src/SearchContext.h create mode 100644 plugins/BasicHistory/src/Searcher.cpp create mode 100644 plugins/BasicHistory/src/Searcher.h create mode 100644 plugins/BasicHistory/src/TxtExport.cpp create mode 100644 plugins/BasicHistory/src/TxtExport.h create mode 100644 plugins/BasicHistory/src/codecvt_CodePage.h create mode 100644 plugins/BasicHistory/src/dllmain.cpp create mode 100644 plugins/BasicHistory/src/resource.h create mode 100644 plugins/BasicHistory/src/stdafx.cpp create mode 100644 plugins/BasicHistory/src/stdafx.h create mode 100644 plugins/BasicHistory/src/targetver.h create mode 100644 plugins/BasicHistory/src/version.h delete mode 100644 plugins/BasicHistory/stdafx.cpp delete mode 100644 plugins/BasicHistory/stdafx.h delete mode 100644 plugins/BasicHistory/targetver.h delete mode 100644 plugins/BasicHistory/version.h delete mode 100644 plugins/BasicHistory/version.rc (limited to 'plugins/BasicHistory') diff --git a/plugins/BasicHistory/BasicHistory.cpp b/plugins/BasicHistory/BasicHistory.cpp deleted file mode 100644 index e28278e68b..0000000000 --- a/plugins/BasicHistory/BasicHistory.cpp +++ /dev/null @@ -1,425 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "stdafx.h" -#include "version.h" -#include "HistoryWindow.h" -#include "resource.h" -#include "Options.h" - -// {E25367A2-51AE-4044-BE28-131BC18B71A4} -#define MIID_BASICHISTORY { 0xe25367a2, 0x51ae, 0x4044, { 0xbe, 0x28, 0x13, 0x1b, 0xc1, 0x8b, 0x71, 0xa4 } } - -#define MS_HISTORY_DELETEALLCONTACTHISTORY "BasicHistory/DeleteAllContactHistory" -#define MS_HISTORY_EXECUTE_TASK "BasicHistory/ExecuteTask" - -HCURSOR hCurSplitNS, hCurSplitWE; -HANDLE g_hMainThread=NULL; - -extern HINSTANCE hInst; - -HANDLE hModulesLoaded, hOptionsInit, hPrebuildContactMenu, hServiceShowContactHistory, hServiceDeleteAllContactHistory, hServiceExecuteTask, hPreShutdownHistoryModule, hHistoryContactDelete, hFontsChanged,hToolBarLoaded, hSysOK; -HANDLE *hEventIcons = NULL; -int iconsNum; -HANDLE hPlusIcon, hMinusIcon, hFindNextIcon, hFindPrevIcon; -HANDLE hPlusExIcon, hMinusExIcon; -HANDLE hToolbarButton; -HGENMENU hContactMenu, hDeleteContactMenu; -HGENMENU hTaskMainMenu; -std::vector taskMenus; -bool g_SmileyAddAvail = false; -char* metaContactProto = NULL; -const IID IID_ITextDocument={0x8CC497C0, 0xA1DF, 0x11ce, {0x80, 0x98, 0x00, 0xAA, 0x00, 0x47, 0xBE, 0x5D}}; - -#define MODULE "BasicHistory" - -PLUGININFOEX pluginInfo = -{ - sizeof(PLUGININFOEX), - __PLUGIN_NAME, - PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), - __DESCRIPTION, - __AUTHOR, - __AUTHOREMAIL, - __COPYRIGHT, - __AUTHORWEB, - UNICODE_AWARE, - MIID_BASICHISTORY -}; - -TIME_API tmi = {0}; -int hLangpack = 0; - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -static const MUUID interfaces[] = {MIID_UIHISTORY, MIID_LAST}; -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} - -void InitScheduler(); -void DeinitScheduler(); -int DoLastTask(WPARAM, LPARAM); -INT_PTR ExecuteTaskService(WPARAM wParam, LPARAM lParam); - -int PrebuildContactMenu(WPARAM wParam, LPARAM lParam) -{ - int count = EventList::GetContactMessageNumber((HANDLE)wParam); - bool isInList = HistoryWindow::IsInList(GetForegroundWindow()); - CLISTMENUITEM mi = {0}; - mi.cbSize = sizeof(mi); - mi.flags = CMIM_FLAGS; - - if (!count) mi.flags |= CMIF_HIDDEN; - else mi.flags &= ~CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hContactMenu, (LPARAM)&mi); - - mi.flags = CMIM_FLAGS; - if (!count || !isInList) mi.flags |= CMIF_HIDDEN; - else mi.flags &= ~CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hDeleteContactMenu, (LPARAM)&mi); - - return 0; -} - -int ToolbarModuleLoaded(WPARAM wParam,LPARAM lParam) -{ - if(ServiceExists(MS_TB_ADDBUTTON)) - { - TBButton tbb = {0}; - tbb.cbSize = sizeof(tbb); - tbb.pszButtonID = "open_history"; - tbb.pszButtonName = LPGEN("Open History"); - tbb.pszServiceName = MS_HISTORY_SHOWCONTACTHISTORY; - tbb.lParam = 0; - tbb.pszTooltipUp = LPGEN("Open History"); - tbb.pszTooltipDn = LPGEN("Open History"); - tbb.defPos = 200; - tbb.tbbFlags = TBBF_SHOWTOOLTIP; - tbb.hPrimaryIconHandle = LoadSkinnedIconHandle(SKINICON_OTHER_HISTORY); - tbb.hSecondaryIconHandle = LoadSkinnedIconHandle(SKINICON_OTHER_HISTORY); - hToolbarButton = (HANDLE) CallService(MS_TB_ADDBUTTON,0, (LPARAM)&tbb); - } - return 0; -} - -void InitMenuItems() -{ - CLISTMENUITEM mi = { 0 }; - mi.cbSize = sizeof(mi); - mi.position = 1000090000; - mi.flags = CMIF_ICONFROMICOLIB; - mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_HISTORY); - mi.pszName = LPGEN("View &History"); - mi.pszService = MS_HISTORY_SHOWCONTACTHISTORY; - hContactMenu = Menu_AddContactMenuItem(&mi); - - mi.position = 500060000; - mi.pszService = MS_HISTORY_SHOWCONTACTHISTORY; - Menu_AddMainMenuItem(&mi); - - mi.position = 1000090001; - mi.flags = CMIF_ICONFROMICOLIB; - mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_DELETE); - mi.pszName = LPGEN("Delete All User History"); - mi.pszService = MS_HISTORY_DELETEALLCONTACTHISTORY; - hDeleteContactMenu = Menu_AddContactMenuItem(&mi); - - hPrebuildContactMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu); -} - -void InitTaskMenuItems() -{ - if(Options::instance->taskOptions.size() > 0) - { - CLISTMENUITEM mi = { 0 }; - mi.cbSize = sizeof(mi); - if(hTaskMainMenu == NULL) - { - mi.position = 500060005; - mi.flags = CMIF_ROOTPOPUP | CMIF_ICONFROMICOLIB; - mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_HISTORY); - mi.pszName = LPGEN("Execute history task"); - hTaskMainMenu = Menu_AddMainMenuItem(&mi); - } - - std::vector::iterator taskIt = Options::instance->taskOptions.begin(); - std::vector::iterator it = taskMenus.begin(); - for(; it != taskMenus.end() && taskIt != Options::instance->taskOptions.end(); ++it, ++taskIt) - { - memset(&mi, 0, sizeof(mi)); - mi.cbSize = sizeof(mi); - mi.flags = CMIM_FLAGS | CMIM_NAME | CMIF_CHILDPOPUP | CMIF_ROOTHANDLE | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED; - mi.hParentMenu = hTaskMainMenu; - mi.ptszName = (TCHAR*)taskIt->taskName.c_str(); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HGENMENU)*it, (LPARAM)&mi); - } - - for(; it != taskMenus.end(); ++it) - { - memset(&mi, 0, sizeof(mi)); - mi.cbSize = sizeof(mi); - mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP | CMIF_ROOTHANDLE | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED | CMIF_HIDDEN; - mi.hParentMenu = hTaskMainMenu; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HGENMENU)*it, (LPARAM)&mi); - } - - int pos = (int)taskMenus.size(); - for(; taskIt != Options::instance->taskOptions.end(); ++taskIt) - { - memset(&mi, 0, sizeof(mi)); - mi.cbSize = sizeof(mi); - mi.flags = CMIF_CHILDPOPUP | CMIF_ROOTHANDLE | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED; - mi.pszService = MS_HISTORY_EXECUTE_TASK; - mi.hParentMenu = hTaskMainMenu; - mi.popupPosition = pos++; - mi.ptszName = (TCHAR*)taskIt->taskName.c_str(); - HGENMENU menu = Menu_AddMainMenuItem(&mi); - taskMenus.push_back(menu); - } - } - else if(hTaskMainMenu != NULL) - { - CLISTMENUITEM mi = { 0 }; - mi.cbSize = sizeof(mi); - mi.flags = CMIM_FLAGS | CMIF_ROOTPOPUP | CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hTaskMainMenu, (LPARAM)&mi); - } -} - -void InitIcolib() -{ - TCHAR stzFile[MAX_PATH]; - - SKINICONDESC sid = {0}; - sid.cbSize = sizeof(sid); - sid.cx = sid.cy = 16; - sid.ptszDefaultFile = stzFile; - sid.ptszSection = LPGENT("History"); - sid.flags = SIDF_ALL_TCHAR; - - GetModuleFileName(hInst, stzFile, MAX_PATH); - - iconsNum = 3; - hEventIcons = new HANDLE[iconsNum]; - sid.pszName = "BasicHistory_in"; - sid.ptszDescription = LPGENT("Incoming message"); - sid.iDefaultIndex = -IDI_INM; - hEventIcons[0] = Skin_AddIcon(&sid); - - sid.pszName = "BasicHistory_out"; - sid.ptszDescription = LPGENT("Outgoing message"); - sid.iDefaultIndex = -IDI_OUTM; - hEventIcons[1] = Skin_AddIcon(&sid); - - sid.pszName = "BasicHistory_status"; - sid.ptszDescription = LPGENT("Statuschange"); - sid.iDefaultIndex = -IDI_STATUS; - hEventIcons[2] = Skin_AddIcon(&sid); - - sid.pszName = "BasicHistory_show"; - sid.ptszDescription = LPGENT("Show Contacts"); - sid.iDefaultIndex = -IDI_SHOW; - hPlusIcon = Skin_AddIcon(&sid); - - sid.pszName = "BasicHistory_hide"; - sid.ptszDescription = LPGENT("Hide Contacts"); - sid.iDefaultIndex = -IDI_HIDE; - hMinusIcon = Skin_AddIcon(&sid); - - sid.pszName = "BasicHistory_findnext"; - sid.ptszDescription = LPGENT("Find Next"); - sid.iDefaultIndex = -IDI_FINDNEXT; - hFindNextIcon = Skin_AddIcon(&sid); - - sid.pszName = "BasicHistory_findprev"; - sid.ptszDescription = LPGENT("Find Previous"); - sid.iDefaultIndex = -IDI_FINDPREV; - hFindPrevIcon = Skin_AddIcon(&sid); - - sid.pszName = "BasicHistory_plusex"; - sid.ptszDescription = LPGENT("Plus in export"); - sid.iDefaultIndex = -IDI_PLUSEX; - hPlusExIcon = Skin_AddIcon(&sid); - - sid.pszName = "BasicHistory_minusex"; - sid.ptszDescription = LPGENT("Minus in export"); - sid.iDefaultIndex = -IDI_MINUSEX; - hMinusExIcon = Skin_AddIcon(&sid); -} - -void InitUpdater() -{ - if (ServiceExists(MS_UPDATE_REGISTER)) - { - Update update = {0}; - char szVersion[16]; - update.cbSize = sizeof(Update); - update.szComponentName = pluginInfo.shortName; - update.pbVersion = (BYTE *)CreateVersionStringPluginEx(&pluginInfo, szVersion); - update.cpbVersion = (int)strlen((char *)update.pbVersion); - -#ifdef _WIN64 - update.szUpdateURL = "http://programista.free.of.pl/miranda/BasicHistory64.zip"; - update.szVersionURL = "http://programista.free.of.pl/miranda/pluginversion.php?plugin=basichistory&x64=yes"; - update.szBetaUpdateURL = "http://programista.free.of.pl/miranda/BasicHistoryBeta64.zip"; - update.szBetaVersionURL = "http://programista.free.of.pl/miranda/pluginversion.php?plugin=basichistory&beta=yes&x64=yes"; - update.szBetaChangelogURL = "http://programista.free.of.pl/miranda/BasicHistoryChangelog.txt"; -#else - update.szUpdateURL = "http://programista.free.of.pl/miranda/BasicHistory.zip"; - update.szVersionURL = "http://programista.free.of.pl/miranda/pluginversion.php?plugin=basichistory"; - update.szBetaUpdateURL = "http://programista.free.of.pl/miranda/BasicHistoryBeta.zip"; - update.szBetaVersionURL = "http://programista.free.of.pl/miranda/pluginversion.php?plugin=basichistory&beta=yes"; - update.szBetaChangelogURL = "http://programista.free.of.pl/miranda/BasicHistoryChangelog.txt"; - -#endif - update.pbBetaVersionPrefix = update.pbVersionPrefix = (BYTE *)"Basic History "; - update.cpbBetaVersionPrefix = update.cpbVersionPrefix = (int)strlen((char *)update.pbVersionPrefix); - CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); - } -} - -INT_PTR ShowContactHistory(WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact = (HANDLE)wParam; - HistoryWindow::Open(hContact); - return 0; -} - -int PreShutdownHistoryModule(WPARAM, LPARAM) -{ - HistoryWindow::Deinit(); - DeinitScheduler(); - return 0; -} - -int HistoryContactDelete(WPARAM wParam, LPARAM) -{ - HistoryWindow::Close((HANDLE)wParam); - return 0; -} - -int ModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - InitMenuItems(); - InitUpdater(); - - TCHAR ftpExe[MAX_PATH]; - if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, ftpExe))) - { - _tcscat_s(ftpExe, _T("\\WinSCP\\WinSCP.exe")); - DWORD atr = GetFileAttributes(ftpExe); - if(atr == INVALID_FILE_ATTRIBUTES || atr & FILE_ATTRIBUTE_DIRECTORY) - { -#ifdef _WIN64 - if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILESX86, NULL, SHGFP_TYPE_CURRENT, ftpExe))) - { - _tcscat_s(ftpExe, _T("\\WinSCP\\WinSCP.exe")); - atr = GetFileAttributes(ftpExe); - if(!(atr == INVALID_FILE_ATTRIBUTES || atr & FILE_ATTRIBUTE_DIRECTORY)) - { - Options::instance->ftpExePathDef = ftpExe; - } - } -#endif - } - else - Options::instance->ftpExePathDef = ftpExe; - } - - TCHAR* log = _T("%miranda_logpath%\\BasicHistory\\ftplog.txt"); - TCHAR* logAbsolute = Utils_ReplaceVarsT(log); - Options::instance->ftpLogPath = logAbsolute; - mir_free(logAbsolute); - Options::instance->Load(); - InitTaskMenuItems(); - - hPreShutdownHistoryModule = HookEvent(ME_SYSTEM_PRESHUTDOWN,PreShutdownHistoryModule); - hHistoryContactDelete = HookEvent(ME_DB_CONTACT_DELETED,HistoryContactDelete); - hFontsChanged = HookEvent(ME_FONT_RELOAD, HistoryWindow::FontsChanged); - hSysOK = HookEvent(ME_SYSTEM_OKTOEXIT, DoLastTask); - if (ServiceExists(MS_SMILEYADD_REPLACESMILEYS)) - { - g_SmileyAddAvail = true; - } - if (ServiceExists(MS_MC_GETPROTOCOLNAME)) - { - metaContactProto = (char*)CallService(MS_MC_GETPROTOCOLNAME, 0, 0); - } - - InitScheduler(); - return 0; -} - -extern "C" int __declspec(dllexport) Load(void) -{ - hTaskMainMenu = NULL; - DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),GetCurrentProcess(),&g_hMainThread,0,FALSE,DUPLICATE_SAME_ACCESS); - mir_getTMI(&tmi); - mir_getLP(&pluginInfo); - hCurSplitNS = LoadCursor(NULL, IDC_SIZENS); - hCurSplitWE = LoadCursor(NULL, IDC_SIZEWE); - hServiceShowContactHistory = CreateServiceFunction(MS_HISTORY_SHOWCONTACTHISTORY, ShowContactHistory); - hServiceDeleteAllContactHistory = CreateServiceFunction(MS_HISTORY_DELETEALLCONTACTHISTORY, HistoryWindow::DeleteAllUserHistory); - hServiceExecuteTask = CreateServiceFunction(MS_HISTORY_EXECUTE_TASK, ExecuteTaskService); - Options::instance = new Options(); - hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); - hOptionsInit = HookEvent(ME_OPT_INITIALISE, Options::InitOptions); - hToolBarLoaded = HookEvent(ME_TB_MODULELOADED,ToolbarModuleLoaded); - EventList::Init(); - InitIcolib(); - return 0; -} - -extern "C" int __declspec(dllexport) Unload(void) -{ - if(g_hMainThread) CloseHandle(g_hMainThread); - g_hMainThread=NULL; - UnhookEvent(hModulesLoaded); - UnhookEvent(hPrebuildContactMenu); - UnhookEvent(hPreShutdownHistoryModule); - UnhookEvent(hHistoryContactDelete); - UnhookEvent(hOptionsInit); - UnhookEvent(hFontsChanged); - UnhookEvent(hToolBarLoaded); - UnhookEvent(hSysOK); - DestroyServiceFunction(hServiceShowContactHistory); - DestroyServiceFunction(hServiceDeleteAllContactHistory); - DestroyServiceFunction(hServiceExecuteTask); - HistoryWindow::Deinit(); - DestroyCursor(hCurSplitNS); - DestroyCursor(hCurSplitWE); - EventList::Deinit(); - if(Options::instance != NULL) - { - Options::instance->Unload(); - delete Options::instance; - Options::instance = NULL; - } - - if(hEventIcons != NULL) - { - delete [] hEventIcons; - } - - return 0; -} diff --git a/plugins/BasicHistory/BasicHistory.rc b/plugins/BasicHistory/BasicHistory.rc deleted file mode 100644 index 4aecce1311..0000000000 --- a/plugins/BasicHistory/BasicHistory.rc +++ /dev/null @@ -1,263 +0,0 @@ -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -//#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -#include -#include -#include -#include -#include -#include - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(1250) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_HISTORY DIALOGEX 0, 0, 496, 366 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Message History" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "",IDC_LIST,WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS | LVS_SINGLESEL | LVS_SHAREIMAGELISTS ,102,27,387,73 - CONTROL "",IDC_SPLITTER,WC_STATIC,SS_ENHMETAFILE,102,100,413,2 - CONTROL "", IDC_EDIT, RICHEDIT_CLASS, WS_VSCROLL | WS_TABSTOP | WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | ES_DISABLENOSCROLL, 102,102,387,252 - CONTROL "", IDC_SHOWHIDE,"MButtonClass", WS_TABSTOP,7,7,16,14 - EDITTEXT IDC_FIND_TEXT,25,8,380,12,ES_AUTOHSCROLL - CONTROL "", IDC_TOOLBAR,TOOLBARCLASSNAME, WS_TABSTOP | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | CCS_NOPARENTALIGN | CCS_NODIVIDER | CCS_NORESIZE,413,7,76,20 - CONTROL "", IDC_LIST_CONTACTS, CLISTCONTROL_CLASS, WS_TABSTOP | CLS_USEGROUPS | CLS_NOHIDEOFFLINE | CLS_HIDEEMPTYGROUPS,7,27,93,327,WS_EX_CLIENTEDGE - CONTROL "",IDC_SPLITTERV,WC_STATIC,SS_ENHMETAFILE,100,27,2,338 -END - -IDD_OPT_MAIN DIALOGEX 0, 0, 304, 225 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - GROUPBOX "Settings",IDC_STATIC,4,5,298,220 - CONTROL "Always show contact list",IDC_SHOWCONTACTS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,23,270,10 - CONTROL "Show groups in contact list",IDC_SHOWCONTACTGROUPS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,34,270,10 - COMBOBOX IDC_DEFFILTER,172,45,122,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Default Event Filter",IDC_STATIC,12,48,145,8 - GROUPBOX "Custom filters",IDC_STATIC,12,67,282,86 - LISTBOX IDC_LIST_FILTERS,20,81,133,30, WS_TABSTOP | LBS_NOINTEGRALHEIGHT | WS_BORDER | WS_VSCROLL - LISTBOX IDC_LIST_EVENTS,20,113,133,30, WS_TABSTOP | LBS_NOINTEGRALHEIGHT | WS_BORDER | WS_VSCROLL - EDITTEXT IDC_FILTER_NAME,160,81,130,12,WS_TABSTOP|ES_AUTOHSCROLL - PUSHBUTTON "Add filter",IDC_ADD_FILTER,160,97,63,14, WS_TABSTOP - PUSHBUTTON "Delete filter",IDC_DELETE_FILTER,227,97,63,14, WS_TABSTOP - COMBOBOX IDC_EVENT,160,113,130,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Add event",IDC_ADD_EVENT,160,129,63,14, WS_TABSTOP - PUSHBUTTON "Delete event",IDC_DELETE_EVENT,227,129,63,14, WS_TABSTOP - EDITTEXT IDC_WINSCP,107,160,165,12, ES_AUTOHSCROLL | WS_TABSTOP - PUSHBUTTON "...",IDC_WINSCP_BROWSE,274,160,20,12, WS_TABSTOP - LTEXT "WinSCP path",IDC_STATIC,12,163,94,8 - EDITTEXT IDC_WINSCPLOG,107,178,165,12, ES_AUTOHSCROLL | WS_TABSTOP - PUSHBUTTON "...",IDC_WINSCPLOG_BROWSE,274,178,20,12, WS_TABSTOP - LTEXT "WinSCP log path",IDC_STATIC,12,181,94,8 -END - -IDD_OPT_GROUPLIST DIALOGEX 0, 0, 304, 225 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - GROUPBOX "Settings",IDC_STATIC,4,5,298,220 - CONTROL "New messages on top",IDC_NEWONTOP, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,23,270,10 - CONTROL "Show event icons",IDC_SHOWEVENTS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,37,270,10 - CONTROL "Show timestamps",IDC_SHOWTIME, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,51,270,10 - CONTROL "Show names",IDC_SHOWNAME, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,65,270,10 - CONTROL "Show messages",IDC_SHOWMESSAGE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,79,270,10 - EDITTEXT IDC_MESSAGELEN,172,95,30,12,WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER - LTEXT "Truncate message length to:",IDC_MESSAGELEN_DESC,24,97,145,8 - EDITTEXT IDC_GROUPTIME,172,113,30,12,WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER - LTEXT "Delta time to group messages:",IDC_STATIC,12,115,157,8 - LTEXT "hours",IDC_STATIC,205,115,80,8 - EDITTEXT IDC_LIMITMESSAGES,172,131,30,12,WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER - LTEXT "Limit messages to:",IDC_STATIC,12,133,157,8 -END - -IDD_OPT_MESSAGES DIALOGEX 0, 0, 304, 225 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - GROUPBOX "Settings",IDC_STATIC,4,5,298,220 - CONTROL "New messages on top",IDC_NEWONTOP, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,23,270,10 - CONTROL "Show date in timestamps",IDC_SHOWDATE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,37,270,10 - CONTROL "Show seconds in timestamps",IDC_SHOWSECOND, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,51,270,10 - CONTROL "Show names",IDC_SHOWNAME, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,65,270,10 - CONTROL "Show event icons",IDC_SHOWEVENTS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,79,270,10 - CONTROL "Enable Smileys",IDC_SHOWSMILEYS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,93,270,10 -END - -IDD_OPT_SEARCHING DIALOGEX 0, 0, 304, 225 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - GROUPBOX "Settings",IDC_STATIC,4,5,298,220 - CONTROL "Search forward in list group",IDC_FORLIST, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,23,270,10 - CONTROL "Search forward in message window",IDC_FORMES, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,37,270,10 - CONTROL "Match Case",IDC_MATCHCASE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,51,270,10 - CONTROL "Match Whole Word",IDC_MATCHWHOLE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,65,270,10 - CONTROL "Only Incomming Messages",IDC_ONLYIN, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,79,270,10 - CONTROL "Only Outgoing Messages",IDC_ONLYOUT, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,93,270,10 - CONTROL "Only Selected Group",IDC_ONLYGROUP, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,107,270,10 - CONTROL "All Contacts",IDC_ALLCONTACTS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,121,270,10 -END - -IDD_OPT_EXPORT DIALOGEX 0, 0, 304, 225 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - GROUPBOX "Export To Txt",IDC_STATIC,4,5,298,37 - COMBOBOX IDC_TXTENC,142,20,152,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "File encoding*",IDC_STATIC,12,23,115,8 - GROUPBOX "Export To Plain Html",IDC_STATIC,4,47,298,50 - COMBOBOX IDC_HTML1ENC,142,62,152,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "File encoding*",IDC_STATIC,12,65,115,8 - CONTROL "Show date in timestamps",IDC_HTML1DATE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,80,270,10 - GROUPBOX "Export To Rich Html",IDC_STATIC,4,102,298,80 - COMBOBOX IDC_HTML2ENC,142,117,152,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "File encoding*",IDC_STATIC,12,120,115,8 - CONTROL "Show date in timestamps",IDC_HTML2DATE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,135,270,10 - CONTROL "Enable Smileys",IDC_HTML2SHOWSMILEYS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,149,270,10 - CONTROL "External CSS file",IDC_HTML2EXTCSS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,163,115,10 - EDITTEXT IDC_HTML2EXTCSSFILE,142,162,130,12, ES_AUTOHSCROLL | WS_TABSTOP - PUSHBUTTON "...",IDC_CSS_BROWSE,274,162,20,12, WS_TABSTOP - LTEXT "* Choose encoding from combo box or enter code page number and name separated by semicolon, name is used in Content-Type header.",IDC_STATIC,12,188,270,24 -END - -IDD_OPT_SCHEDULER DIALOGEX 0, 0, 304, 225 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - GROUPBOX "Settings",IDC_STATIC,4,5,298,220 - LISTBOX IDC_LIST_TASKS,12,23,208,174, WS_TABSTOP | LBS_NOINTEGRALHEIGHT | WS_BORDER | WS_VSCROLL - PUSHBUTTON "Add task",IDC_ADD_TASK,231,23,63,14, WS_TABSTOP - PUSHBUTTON "Edit task",IDC_EDIT_TASK,231,39,63,14, WS_TABSTOP - PUSHBUTTON "Delete task",IDC_DELETE_TASK,231,55,63,14, WS_TABSTOP - CONTROL "Display errors using popups",IDC_SCHEDULER_ALERTS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,200,270,10 - CONTROL "Save errors to system history",IDC_SCHEDULER_HISTORY_ALERTS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,211,270,10 -END - -IDD_DLG_TASK DIALOGEX 0, 0, 359, 281 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Task" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - EDITTEXT IDC_TASK_NAME,85,10,109,12,WS_TABSTOP|ES_AUTOHSCROLL - LTEXT "Name",IDC_STATIC,10,13,73,8 - CONTROL "Active",IDC_TASK_ACTIVE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,28,180,10 - COMBOBOX IDC_TASK_TYPE,85,40,109,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Action type",IDC_STATIC,10,43,73,8 - COMBOBOX IDC_TASK_FILTER,85,55,109,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Filter",IDC_TASK_FILTER_LABEL,10,58,73,8 - EDITTEXT IDC_EVENT_TIME,85,70,50,12,WS_TABSTOP | ES_AUTOHSCROLL - COMBOBOX IDC_EVENT_UNIT,140,70,54,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Events older than*",IDC_EVENT_LABEL,10,73,73,8 - COMBOBOX IDC_TRIGER_TYPE,85,85,109,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Triger type",IDC_STATIC,10,88,73,8 - CONTROL "", IDC_TRIGER_TIME, DATETIMEPICK_CLASS, WS_TABSTOP | DTS_TIMEFORMAT | DTS_UPDOWN, 85,99,109,15 - LTEXT "Time",IDC_TRIGER_TIME_LABEL,10,103,73,8 - EDITTEXT IDC_TRIGER_DELTA_TIME,85,100,109,12,WS_TABSTOP | ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Delta time",IDC_TRIGER_DELTA_TIME_LABEL,10,103,73,8 - COMBOBOX IDC_TRIGER_WEEK,85,115,109,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Day of week",IDC_TRIGER_WEEK_LABEL,10,118,73,8 - EDITTEXT IDC_TRIGER_DAY,85,115,109,12,WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER - LTEXT "Day",IDC_TRIGER_DAY_LABEL,10,118,73,8 - COMBOBOX IDC_EXPORT_TYPE,85,130,109,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_IMPORT_TYPE,85,130,109,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Export to",IDC_EXPORT_TYPE_LABEL,10,133,73,8 - CONTROL "Compress output files",IDC_COMPRESS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,148,180,10 - EDITTEXT IDC_PASSWORD,85,160,109,12, ES_AUTOHSCROLL | ES_PASSWORD | WS_TABSTOP - LTEXT "Password",IDC_PASSWORD_LABEL,10,163,73,8 - CONTROL "Upload to FTP (WinSCP requred)",IDC_UPLOAD, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,178,180,10 - EDITTEXT IDC_FTP,85,190,109,12,ES_AUTOHSCROLL | WS_TABSTOP - LTEXT "Session name",IDC_FTP_LABEL,10,193,73,8 - EDITTEXT IDC_EXPORT_PATH,85,205,109,12, ES_AUTOHSCROLL | WS_TABSTOP - LTEXT "Path to file**",IDC_EXPORT_PATH_LABEL,10,208,73,8 - CONTROL "Export imported messages",IDC_EXPIMP, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,223,180,10 - LTEXT "* Use negative values to filter younger events",IDC_TASK_STAR,10,236,184,40 - CONTROL "", IDC_LIST_CONTACTSEX, CLISTCONTROL_CLASS, WS_TABSTOP | CLS_GREYALTERNATE | CLS_GROUPCHECKBOXES | CLS_MULTICOLUMN | CLS_USEGROUPS | CLS_NOHIDEOFFLINE | CLS_CHECKBOXES, - 200,25,149,233,WS_EX_CLIENTEDGE - LTEXT "Execute task for specified contacts",IDC_STATIC,200,13,149,8 - DEFPUSHBUTTON "OK",IDOK,245,261,50,14 - PUSHBUTTON "Cancel",IDCANCEL,299,261,50,14 -END - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_INM ICON "icons\\Incom.ico" -IDI_OUTM ICON "icons\\Outg.ico" -IDI_SHOW ICON "icons\\plus.ico" -IDI_HIDE ICON "icons\\minus.ico" -IDI_FINDNEXT ICON "icons\\FindNext.ico" -IDI_FINDPREV ICON "icons\\FindPrev.ico" - -IDI_STATUS ICON "icons\\Status change.ico" - -IDR_CSS CUSTOMRES "history.css" -IDR_JS CUSTOMRES "history.js" -IDI_PLUSEX ICON "icons\\pnode.ico" -IDI_MINUSEX ICON "icons\\mnode.ico" - -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// - diff --git a/plugins/BasicHistory/BasicHistory.vcxproj b/plugins/BasicHistory/BasicHistory.vcxproj index 8c0910d2b9..d5a99de3a9 100644 --- a/plugins/BasicHistory/BasicHistory.vcxproj +++ b/plugins/BasicHistory/BasicHistory.vcxproj @@ -165,55 +165,55 @@ - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + Create - + NotUsing @@ -228,8 +228,8 @@ - - + + diff --git a/plugins/BasicHistory/BasicHistory.vcxproj.filters b/plugins/BasicHistory/BasicHistory.vcxproj.filters index b9b18ec09f..8ddafb6abd 100644 --- a/plugins/BasicHistory/BasicHistory.vcxproj.filters +++ b/plugins/BasicHistory/BasicHistory.vcxproj.filters @@ -21,126 +21,126 @@ - - + + Resource Files\Docs - + Resource Files\Docs - + Resource Files\Docs - + Resource Files\Docs - + Resource Files - + Resource Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files @@ -152,24 +152,24 @@ Source Files\zip - + Source Files Source Files\zip - + Source Files - + Source Files - + Resource Files - + Resource Files diff --git a/plugins/BasicHistory/BinaryExport.cpp b/plugins/BasicHistory/BinaryExport.cpp deleted file mode 100644 index f57343cff0..0000000000 --- a/plugins/BasicHistory/BinaryExport.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "StdAfx.h" -#include "BinaryExport.h" - -#define EXP_FILE (*((std::ofstream*)IExport::stream)) -#define IMP_FILE (*((std::ifstream*)IImport::stream)) - -std::wstring GetProtocolName(HANDLE hContact); -std::wstring GetContactId(HANDLE hContact); - -#pragma pack(push, 1) - -struct BinaryFileHeader -{ - unsigned char signature[4]; - unsigned char version; - unsigned char extraFlags; - unsigned short int reserved; - unsigned int codepage; - unsigned short int dataStart; -}; - -struct BinaryFileMessageHeader -{ - DWORD timestamp; - WORD eventType; - WORD flags; -}; - -#pragma pack(pop) - -BinaryExport::~BinaryExport() -{ -} - -void BinaryExport::WriteString(const std::wstring &str) -{ - int conv = WideCharToMultiByte(codepage, 0, str.c_str(), (int)str.length() + 1, NULL, 0, NULL, NULL); - char* buf = new char[conv]; - conv = WideCharToMultiByte(codepage, 0, str.c_str(), (int)str.length() + 1, buf, conv, NULL, NULL); - EXP_FILE.write(buf, conv); - delete[] buf; -} - -bool BinaryExport::ReadString(std::wstring &str) -{ - std::string buf; - int size = 1024; - int pos = 0; - int totalSize = 0; - while(1) - { - buf.resize(size); - if(IMP_FILE.peek() == 0) - { - IMP_FILE.get(); - break; - } - - IMP_FILE.get(((char*)buf.c_str()) + pos, size - pos, 0); - if(!IMP_FILE.good()) - return false; - - int readed = IMP_FILE.gcount(); - totalSize += readed; - char end; - IMP_FILE.get(end); - if(!IMP_FILE.good()) - return false; - if(end == 0) - break; - if(size - pos - 1 != readed) - return false; - buf[size - 1] = end; - ++totalSize; - size += 1024; - pos += 1024; - } - - if(totalSize == 0) - return true; - int sizeW = MultiByteToWideChar(codepage, 0, (char*)buf.c_str(), totalSize, NULL, 0); - str.resize(sizeW); - MultiByteToWideChar(codepage, 0, (char*)buf.c_str(), totalSize, (wchar_t*)str.c_str(), sizeW); - return true; -} - -void BinaryExport::WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding) -{ - BinaryFileHeader header; - memset(&header, 0, sizeof(BinaryFileHeader)); - memcpy(header.signature, "BHBF", 4); - header.codepage = codepage = CP_UTF8; - EXP_FILE.write((char*)&header, sizeof(BinaryFileHeader)); - WriteString(filterName); - WriteString(myName); - WriteString(myId); - WriteString(name1); - WriteString(proto1); - WriteString(id1); - size_t pos = EXP_FILE.tellp(); - header.dataStart = (unsigned short)pos; - EXP_FILE.seekp(offsetof(BinaryFileHeader, dataStart), std::ios_base::beg); - EXP_FILE.write((char*)&(header.dataStart), sizeof(header.dataStart)); - EXP_FILE.seekp(pos, std::ios_base::beg); - lTime = 0; -} - -void BinaryExport::WriteFooter() -{ -} - -void BinaryExport::WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText) -{ -} - -void BinaryExport::WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei) -{ - if(dbei.timestamp >= lTime) - { - BinaryFileMessageHeader header; - header.eventType = dbei.eventType; - header.flags = dbei.flags & (~(0x800)); - header.timestamp = dbei.timestamp; - EXP_FILE.write((char*)&header, sizeof(BinaryFileMessageHeader)); - WriteString(message); - lTime = dbei.timestamp; - } -} - -bool ReadHeader(BinaryFileHeader& header, std::istream* stream) -{ - stream->read((char*)&header, sizeof(BinaryFileHeader)); - if(!stream->good()) - return false; - if(memcmp(header.signature, "BHBF", 4) != 0) - return false; - if(header.version != 0 || header.codepage == 12000 || header.codepage == 12001) - return false; - - return true; -} - -int BinaryExport::IsContactInFile(const std::vector& contacts) -{ - BinaryFileHeader header; - if(!ReadHeader(header, IImport::stream)) - return -2; - codepage = header.codepage; - std::wstring filterName; - std::wstring myName; - std::wstring myId; - std::wstring name1; - std::wstring proto1; - std::wstring id1; - if(!ReadString(filterName)) - return -2; - if(!ReadString(myName)) - return -2; - if(!ReadString(myId)) - return -2; - if(!ReadString(name1)) - return -2; - if(!ReadString(proto1)) - return -2; - if(!ReadString(id1)) - return -2; - - size_t pos = IMP_FILE.tellg(); - if(header.dataStart < pos) - return -2; - - IMP_FILE.seekg(0, std::ios_base::beg); - for(int i = 0; i < (int)contacts.size(); ++i) - { - std::wstring pn = GetProtocolName(contacts[i]); - std::wstring id = GetContactId(contacts[i]); - if(pn == proto1 && id == id1) - { - return i; - } - } - - return -1; -} - -bool BinaryExport::GetEventList(std::vector& eventList) -{ - BinaryFileHeader header; - if(!ReadHeader(header, IImport::stream)) - return false; - codepage = header.codepage; - IMP_FILE.seekg(header.dataStart, std::ios_base::beg); - BinaryFileMessageHeader messageHeader; - while(1) - { - IMP_FILE.read((char*)&messageHeader, sizeof(BinaryFileMessageHeader)); - if(IMP_FILE.eof()) - break; - if(!IMP_FILE.good()) - return false; - - IImport::ExternalMessage exMsg; - exMsg.eventType = messageHeader.eventType; - exMsg.flags = messageHeader.flags; - exMsg.timestamp = messageHeader.timestamp; - if(!ReadString(exMsg.message)) - return false; - - eventList.push_back(exMsg); - } - - return true; -} diff --git a/plugins/BasicHistory/BinaryExport.h b/plugins/BasicHistory/BinaryExport.h deleted file mode 100644 index 386625226f..0000000000 --- a/plugins/BasicHistory/BinaryExport.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once -#include "IExport.h" -#include "IImport.h" - -class BinaryExport : - public IExport, - public IImport -{ -public: - virtual const TCHAR* GetExt() - { - return _T("bin"); - } - - virtual void WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding); - virtual void WriteFooter(); - virtual void WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText); - virtual void WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei); - virtual int IsContactInFile(const std::vector& contacts); - virtual bool GetEventList(std::vector& eventList); - - virtual ~BinaryExport(); -private: - unsigned int codepage; - inline void WriteString(const std::wstring &str); - inline bool ReadString(std::wstring &str); - DWORD lTime; -}; - diff --git a/plugins/BasicHistory/DatExport.cpp b/plugins/BasicHistory/DatExport.cpp deleted file mode 100644 index bd74546393..0000000000 --- a/plugins/BasicHistory/DatExport.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "StdAfx.h" -#include "DatExport.h" -#include "EventList.h" - -#define EXP_FILE (*((std::ofstream*)IExport::stream)) -#define IMP_FILE (*((std::ifstream*)IImport::stream)) - -std::wstring GetProtocolName(HANDLE hContact); -std::wstring GetContactId(HANDLE hContact); - -#pragma pack(push, 1) - -struct MCHeader -{ - unsigned char signature[2]; - unsigned int version; - unsigned int dataSize; -}; - -#pragma pack(pop) - -typedef struct { - int cbSize; //size of the structure in bytes - DWORD szModule; //pointer to name of the module that 'owns' this - //event, ie the one that is in control of the data format - DWORD timestamp; //seconds since 00:00, 01/01/1970. Gives us times until - //2106 unless you use the standard C library which is - //signed and can only do until 2038. In GMT. - DWORD flags; //the omnipresent flags - WORD eventType; //module-defined event type field - DWORD cbBlob; //size of pBlob in bytes - DWORD pBlob; //pointer to buffer containing module-defined event data -} DBEVENTINFO86; - - -DatExport::~DatExport() -{ -} - - -int DatExport::WriteString(const std::wstring &str) -{ - int conv = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.length() + 1, NULL, 0, NULL, NULL); - if(conv > (int)memBuf.size()) - { - memBuf.resize(conv); - } - - conv = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.length() + 1, (char*)memBuf.c_str(), conv, NULL, NULL); - return conv; -} - -void DatExport::WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding) -{ - MCHeader header; - memset(&header, 0, sizeof(MCHeader)); - memcpy(header.signature, "HB", 2); - header.version = -1; - header.dataSize = 0; - dataSize = 0; - EXP_FILE.write((char*)&header, sizeof(MCHeader)); -} - -void DatExport::WriteFooter() -{ - size_t pos = EXP_FILE.tellp(); - EXP_FILE.seekp(offsetof(MCHeader, dataSize), std::ios_base::beg); - EXP_FILE.write((char*)&dataSize, sizeof(dataSize)); - EXP_FILE.seekp(pos, std::ios_base::beg); - memBuf.resize(0); -#ifdef _WIN64 - memBuf.shrink_to_fit(); -#endif -} - -void DatExport::WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText) -{ -} - -void DatExport::WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei) -{ - DBEVENTINFO86 header; - header.cbSize = sizeof(DBEVENTINFO86); - header.eventType = dbei.eventType; - header.flags = dbei.flags & (~(0x800)); - header.timestamp = dbei.timestamp; - header.szModule = 0; - header.pBlob = 0; - if(dbei.flags & 0x800) - { - //Imported - header.flags |= DBEF_UTF; - header.cbBlob = WriteString(message); - EXP_FILE.write((char*)&header, header.cbSize); - EXP_FILE.write(memBuf.c_str(), header.cbBlob); - } - else - { - //Internal - header.cbBlob = dbei.cbBlob; - EXP_FILE.write((char*)&header, header.cbSize); - EXP_FILE.write((char*)dbei.pBlob, header.cbBlob); - } - - dataSize += header.cbSize + header.cbBlob; -} - -bool ReadHeader(MCHeader& header, std::istream* stream) -{ - stream->read((char*)&header, sizeof(MCHeader)); - if(!stream->good()) - return false; - if(memcmp(header.signature, "HB", 2) != 0) - return false; - - return true; -} - -int DatExport::IsContactInFile(const std::vector& contacts) -{ - MCHeader header; - if(!ReadHeader(header, IImport::stream)) - return -2; - - if(contacts.size() == 1) - { - hContact = contacts[0]; - } - - IMP_FILE.seekg(0, std::ios_base::beg); - return -3; -} - -bool DatExport::GetEventList(std::vector& eventList) -{ - MCHeader header; - if(!ReadHeader(header, IImport::stream)) - return false; - dataSize = header.dataSize; - DBEVENTINFO86 messageHeader; - DBEVENTINFO info = {0}; - info.cbSize = sizeof(DBEVENTINFO); - info.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - TCHAR _str[MAXSELECTSTR + 8]; // for safety reason - std::multimap sortedEvents; - while(dataSize > 0) - { - messageHeader.cbSize = 0; - IMP_FILE.read((char*)&messageHeader, sizeof(DBEVENTINFO86)); - if(!IMP_FILE.good()) - return false; - - if(messageHeader.cbSize < sizeof(DBEVENTINFO86)) - return false; - - if(messageHeader.cbSize > sizeof(DBEVENTINFO86)) - { - IMP_FILE.seekg(messageHeader.cbSize - sizeof(DBEVENTINFO86), std::ios_base::cur); - } - - IImport::ExternalMessage exMsg; - exMsg.eventType = messageHeader.eventType; - exMsg.flags = messageHeader.flags; - exMsg.timestamp = messageHeader.timestamp; - if(messageHeader.cbBlob > memBuf.size()) - { - memBuf.resize(messageHeader.cbBlob); - } - - IMP_FILE.read((char*)memBuf.c_str(), messageHeader.cbBlob); - if(!IMP_FILE.good()) - return false; - - info.eventType = messageHeader.eventType; - info.flags = messageHeader.flags; - info.timestamp = messageHeader.timestamp; - info.cbBlob = messageHeader.cbBlob; - info.pBlob = (PBYTE)memBuf.c_str(); - EventList::GetObjectDescription(&info, _str, MAXSELECTSTR); - exMsg.message = _str; - sortedEvents.insert(std::pair(messageHeader.timestamp, exMsg)); - dataSize -= messageHeader.cbSize + messageHeader.cbBlob; - } - - memBuf.resize(0); -#ifdef _WIN64 - memBuf.shrink_to_fit(); -#endif - - for(std::multimap::iterator it = sortedEvents.begin(); it != sortedEvents.end(); ++it) - { - eventList.push_back(it->second); - } - - return true; -} diff --git a/plugins/BasicHistory/DatExport.h b/plugins/BasicHistory/DatExport.h deleted file mode 100644 index 980a12d148..0000000000 --- a/plugins/BasicHistory/DatExport.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once -#include "IExport.h" -#include "IImport.h" - -class DatExport : - public IExport, - public IImport -{ -public: - virtual const TCHAR* GetExt() - { - return _T("dat"); - } - - virtual void WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding); - virtual void WriteFooter(); - virtual void WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText); - virtual void WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei); - virtual int IsContactInFile(const std::vector& contacts); - virtual bool GetEventList(std::vector& eventList); - - DatExport() - { - hContact = NULL; - } - - virtual ~DatExport(); -private: - int dataSize; - HANDLE hContact; - std::string memBuf; - inline int WriteString(const std::wstring &str); - //inline bool ReadString(std::wstring &str, int size); -}; - diff --git a/plugins/BasicHistory/Docs/ReadMe.txt b/plugins/BasicHistory/Docs/ReadMe.txt new file mode 100644 index 0000000000..284d52b6c7 --- /dev/null +++ b/plugins/BasicHistory/Docs/ReadMe.txt @@ -0,0 +1,48 @@ +======================================================================== + DYNAMIC LINK LIBRARY : BasicHistory Project Overview +======================================================================== + +AppWizard has created this BasicHistory DLL for you. + +This file contains a summary of what you will find in each of the files that +make up your BasicHistory application. + + +BasicHistory.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +BasicHistory.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +BasicHistory.cpp + This is the main DLL source file. + + When created, this DLL does not export any symbols. As a result, it + will not produce a .lib file when it is built. If you wish this project + to be a project dependency of some other project, you will either need to + add code to export some symbols from the DLL so that an export library + will be produced, or you can set the Ignore Input Library property to Yes + on the General propert page of the Linker folder in the project's Property + Pages dialog box. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named BasicHistory.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/plugins/BasicHistory/Docs/basichistory-translation.txt b/plugins/BasicHistory/Docs/basichistory-translation.txt new file mode 100644 index 0000000000..c1be849b57 --- /dev/null +++ b/plugins/BasicHistory/Docs/basichistory-translation.txt @@ -0,0 +1,252 @@ +; Common strings that belong to many files +;[History] +;[%s Files (*.%s)] +;[* Use negative values to filter younger events] +;[All Contacts] +;[All events] +;[Binary] +;[Compress output files] +;[Dat (mContacts)] +;[Day] +;[Day of week] +;[Default history events] +;[Delete] +;[Delete All User History] +;[Delta time] +;[Error] +;[Export] +;[Export To Plain Html] +;[Export To Rich Html] +;[Export To Txt] +;[Export to] +;[Filter] +;[Filter:] +;[Find Next] +;[Find Previous] +;[Hide Contacts] +;[History Log] +;[Import] +;[Import from] +;[Invalid '%s' value.] +;[Invalid '%s' value.\n%s] +;[Match Case] +;[Match Whole Word] +;[Name] +;[Only Incomming Messages] +;[Only Outgoing Messages] +;[Only Selected Group] +;[Plain Html] +;[Rich Html] +;[Session name] +;[Show Contacts] +;[Some value is invalid] +;[System] +;[Time] +;[Txt] +;[Upload to FTP (WinSCP requred)] + +; ../../plugins/BasicHistory/BasicHistory.cpp +;[Execute history task] +;[Incoming message] +;[Minus in export] +;[Open History] +;[Outgoing message] +;[Plus in export] +;[Statuschange] +;[View &History] + +; ../../plugins/BasicHistory/BasicHistory.rc +;[* Choose encoding from combo box or enter code page number and name separated by semicolon, name is used in Content-Type header.] +;[Action type] +;[Active] +;[Add event] +;[Add filter] +;[Add task] +;[Always show contact list] +;[Cancel] +;[Custom filters] +;[Default Event Filter] +;[Delete event] +;[Delete filter] +;[Delete task] +;[Delta time to group messages:] +;[Display errors using popups] +;[Edit task] +;[Enable Smileys] +;[Events older than*] +;[Execute task for specified contacts] +;[Export imported messages] +;[External CSS file] +;[File encoding*] +;[Limit messages to:] +;[Message History] +;[New messages on top] +;[OK] +;[Password] +;[Path to file**] +;[Save errors to system history] +;[Search forward in list group] +;[Search forward in message window] +;[Settings] +;[Show date in timestamps] +;[Show event icons] +;[Show groups in contact list] +;[Show messages] +;[Show names] +;[Show seconds in timestamps] +;[Show timestamps] +;[Task] +;[Triger type] +;[Truncate message length to:] +;[WinSCP log path] +;[WinSCP path] +;[hours] + +; ../../plugins/BasicHistory/EventList.cpp +;[Authorisation request by %s (%s%d): %s] +;[History for %s] +;[Invalid Message] +;[Me] + +; ../../plugins/BasicHistory/ExportManager.cpp +;[*.%s] +;[File do not contain selected contact] +;[File is corrupted] + +; ../../plugins/BasicHistory/HistoryWindow.cpp +;[&Copy link] +;[&Open in existing window] +;[Are You sure?] +;[Copy] +;[Delete Group] +;[Do you want delete all imported messages for this contact?\nNote that next scheduler task import this messages again.] +;[Do you want save imported messages to local profile?] +;[Filters] +;[Fonts & Colors] +;[Hotkeys] +;[Icons] +;[Number of history items to delete: %d.\nAre you sure you want to do this?] +;[Open in &new window] +;[Options] +;[Reply &Quoted] +;[Save window position as default] +;[Save window position for all contacts] +;[Send Message] +;[This operation will PERMANENTLY REMOVE all history for this contact.\nAre you sure you want to do this?] + +; ../../plugins/BasicHistory/Options.cpp +;[** Use to insert date, to insert extension, to insert contact name] +;[** Use to insert extension, to insert contact name] +;[<< Incoming messages] +;[<< Incoming name] +;[<< Incoming timestamp] +;[>> Outgoing messages] +;[>> Outgoing name] +;[>> Outgoing timestamp] +;[Advanced] +;[All Files (*.*)] +;[At Finish] +;[At Start] +;[Authorization request] +;[Browse CSS file] +;[Browse WinSCP file] +;[Contact list background] +;[Contacts recieved] +;[Daily] +;[Delta time (hours)] +;[Delta time (minutes)] +;[Download from FTP (WinSCP requred)] +;[Enter filter name] +;[Event already exists] +;[Events older than] +;[Export To Binary] +;[Export To Dat (mContacts)] +;[Export and Delete] +;[File do not exist. Enter correct file path.] +;[File transfer] +;[Filter name exists] +;[Find] +;[Find window] +;[Find window background] +;[Friday] +;[Group list] +;[Group list background] +;[Hour] +;[Import From Binary] +;[Import From Dat (mContacts)] +;[Import and Marge] +;[Incoming background] +;[Incoming events] +;[Input files are compressed] +;[Invalid codepage] +;[Invalid event number] +;[Invalid file] +;[Link] +;[Message] +;[Messages] +;[Minute] +;[Monday] +;[Monthly] +;[Open global history] +;[Outgoing background] +;[Outgoing events] +;[SMS message] +;[SMTP Simple Email] +;[Saturday] +;[Save WinSCP log file] +;[Scheduler] +;[Searching] +;[Show/Hide Contacts] +;[Status change] +;[Sunday] +;[Switch All Contacts] +;[Switch Match Case] +;[Switch Match Whole Word] +;[Switch Only Incomming Messages] +;[Switch Only Outgoing Messages] +;[Switch Only Selected Group] +;[Thursday] +;[Tuesday] +;[Wednesday] +;[Weekly] +;[Window background] +;[You were added] +;[You've entered invalid codepage. Select codepage from combo box or enter correct number.] + +; ../../plugins/BasicHistory/PlainHtmlExport.cpp +;[Conversation started at %s] + +; ../../plugins/BasicHistory/RichHtmlExport.cpp +;[Close all] +;[Menu] +;[Open all] +;[_files] + +; ../../plugins/BasicHistory/Scheduler.cpp +;[At least one contact should be selected.] +;[Cannot compress file(s).] +;[Cannot export history for contact: %s.] +;[Cannot get FTP file(s).] +;[Cannot send FTP file(s).] +;[Cannot unzip file(s).] +;[Contacts] +;[FTP path cannot contain in import task.] +;[FTP path must contains '/' instead '\\' and starts from '/'.] +;[History task] +;[Incorrect file format: %s.] +;[Path to file] +;[Path to output file] +;[Task '%s' execution failed] +;[Task '%s' execution failed:] +;[Task '%s' finished successfully] +;[Task finished] +;[To create session open WinSCP, click New Session, enter data and save with specific name. Remember if FTP server using password you should save it in WinSCP.] +;[Unknown contact in file: %s.] +;[Unknown error] +;[Upload to FTP] + +; ../../plugins/BasicHistory/Searcher.cpp +;[Search] +;[You have reached the end of the group.] +;[You have reached the end of the history.] +;[\"%s\" not found] diff --git a/plugins/BasicHistory/EventList.cpp b/plugins/BasicHistory/EventList.cpp deleted file mode 100644 index 8ac9e2eb37..0000000000 --- a/plugins/BasicHistory/EventList.cpp +++ /dev/null @@ -1,907 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "StdAfx.h" -#include "EventList.h" -#include "Options.h" -#include "ExportManager.h" -#include - -extern int iconsNum; - -bool DeleteDirectory(LPCTSTR lpszDir, bool noRecycleBin = true); -std::wstring GetName(const std::wstring &path); - -EventList::EventList() - :hWnd(NULL), - isWnd(false), - hContact(NULL), - deltaTime(0), - isFlat(false), - useImportedMessages(true) -{ - memset(&gdbei, 0, sizeof(DBEVENTINFO)); - gdbei.cbSize = sizeof(DBEVENTINFO); - goldBlobSize = 0; -} - -EventList::EventList(HANDLE _hContact, int filter) - :hWnd(NULL), - isWnd(false), - hContact(_hContact), - deltaTime(0), - isFlat(false), - useImportedMessages(true) -{ - memset(&gdbei, 0, sizeof(DBEVENTINFO)); - gdbei.cbSize = sizeof(DBEVENTINFO); - goldBlobSize = 0; - SetDefFilter(filter); -} - - -EventList::~EventList() -{ - mir_free(gdbei.pBlob); - eventList.clear(); -} - -bool EventList::CanShowHistory(DBEVENTINFO* dbei) -{ - if(deltaTime != 0) - { - if(deltaTime > 0) - { - if(now - deltaTime < dbei->timestamp) - return false; - } - else - { - if(now + deltaTime > dbei->timestamp) - return false; - } - } - - if(hContact == NULL || defFilter == 1) - return true; - - else if(defFilter < 1) - { - switch( dbei->eventType ) - { - case EVENTTYPE_MESSAGE: - case EVENTTYPE_URL: - case EVENTTYPE_FILE: - return true; - - default: - { - DBEVENTTYPEDESCR* et = ( DBEVENTTYPEDESCR* )CallService( MS_DB_EVENT_GETTYPE, ( WPARAM )dbei->szModule, ( LPARAM )dbei->eventType ); - if ( et && ( et->flags & DETF_HISTORY )) - { - return true; - } - } - } - - return false; - } - else - { - if(filterMap.find(dbei->eventType) != filterMap.end()) - { - if(onlyInFilter) - { - return !(dbei->flags & DBEF_SENT); - } - else if(onlyOutFilter) - { - return (dbei->flags & DBEF_SENT) != 0; - } - return true; - } - return false; - } -} - -bool EventList::CanShowHistory(const IImport::ExternalMessage& message) -{ - if(deltaTime != 0) - { - if(deltaTime > 0) - { - if(now - deltaTime < message.timestamp) - return false; - } - else - { - if(now + deltaTime > message.timestamp) - return false; - } - } - - if(hContact == NULL || defFilter == 1) - return true; - - else if(defFilter < 1) - { - switch(message.eventType ) - { - case EVENTTYPE_MESSAGE: - case EVENTTYPE_URL: - case EVENTTYPE_FILE: - return true; - } - - return false; - } - else - { - if(filterMap.find(message.eventType) != filterMap.end()) - { - if(onlyInFilter) - { - return !(message.flags & DBEF_SENT); - } - else if(onlyOutFilter) - { - return (message.flags & DBEF_SENT) != 0; - } - return true; - } - return false; - } -} - -void EventList::InitFilters() -{ - filterMap.clear(); - onlyInFilter = false; - onlyOutFilter = false; - if(defFilter >= 2) - { - defFilter = 0; - for(int i = 0; i < (int)Options::instance->customFilters.size(); ++i) - { - if(filterName == Options::instance->customFilters[i].name) - { - defFilter = i + 2; - if(Options::instance->customFilters[i].onlyIncomming && !Options::instance->customFilters[i].onlyOutgoing) - { - onlyInFilter = true; - } - else if(Options::instance->customFilters[i].onlyOutgoing && !Options::instance->customFilters[i].onlyIncomming) - { - onlyOutFilter = true; - } - - for(std::vector::iterator it = Options::instance->customFilters[i].events.begin(); it != Options::instance->customFilters[i].events.end(); ++it) - { - filterMap[*it] = true; - } - - break; - } - } - } - else - filterName = L""; -} - -void EventList::SetDefFilter(int filter) -{ - defFilter = filter; - if(filter >= 2 && filter - 2 < (int)Options::instance->customFilters.size()) - { - filterName = Options::instance->customFilters[filter - 2].name; - } - else if(filter == 1) - { - filterName = TranslateT("All events"); - } - else - { - filterName = TranslateT("Default history events"); - } -} - -int EventList::GetFilterNr() -{ - return defFilter; -} - -std::wstring EventList::GetFilterName() -{ - return filterName; -} - -void EventList::GetTempList(std::list& tempList, bool noFilter, bool noExt, HANDLE _hContact) -{ - HANDLE hDbEvent; - bool isWndLocal = isWnd; - EventTempIndex ti; - EventIndex ei; - EventData data; - ti.isExternal = false; - ei.isExternal = false; - hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRST,(WPARAM)_hContact,0); - while ( hDbEvent != NULL ) - { - if (isWndLocal && !IsWindow( hWnd )) - break; - ei.hEvent = hDbEvent; - if(GetEventData(ei, data)) - { - if(noFilter || CanShowHistory(&gdbei)) - { - ti.hEvent = hDbEvent; - ti.timestamp = data.timestamp; - tempList.push_back(ti); - } - } - hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0); - } - - if(!noExt) - { - std::list::iterator itL = tempList.begin(); - ti.isExternal = true; - for(int i = 0; i < (int)importedMessages.size(); ++i) - { - if(noFilter || CanShowHistory(importedMessages[i])) - { - DWORD ts = importedMessages[i].timestamp; - while(itL != tempList.end() && itL->timestamp < ts)++itL; - if(itL == tempList.end() || itL->timestamp > ts) - { - ti.exIdx = i; - ti.timestamp = ts; - tempList.insert(itL, ti); - } - } - } - } -} - -void EventList::RefreshEventList() -{ - InitNames(); - InitFilters(); - - if(useImportedMessages) - { - std::vector messages; - - EnterCriticalSection(&criticalSection); - std::map::iterator it = contactFileMap.find(hContact); - if(it != contactFileMap.end()) - { - ExportManager imp(hWnd, hContact, 1); - imp.SetAutoImport(it->second.file); - if(!imp.Import(it->second.type, messages, NULL)) - { - messages.clear(); - } - } - - LeaveCriticalSection(&criticalSection); - - ImportMessages(messages); - } - - std::list tempList; - GetTempList(tempList, false, false, hContact); - std::list revTempList; - std::list& nrTempList = tempList; - bool isNewOnTop = Options::instance->groupNewOnTop; - if(isNewOnTop) - { - revTempList.insert(revTempList.begin(), tempList.rbegin(), tempList.rend()); - nrTempList = revTempList; - } - - eventList.clear(); - eventList.push_back(std::deque()); - DWORD lastTime = MAXDWORD; - DWORD groupTime = Options::instance->groupTime * 60 * 60; - int maxMess = Options::instance->groupMessagesNumber; - int limitator = 0; - EventIndex ei; - for(std::list::iterator itL = nrTempList.begin(); itL != nrTempList.end(); ++itL) - { - DWORD tm = isNewOnTop ? lastTime - itL->timestamp : itL->timestamp - lastTime; - if(isFlat || tm < groupTime && limitator < maxMess) - { - lastTime = itL->timestamp; - ei.isExternal = itL->isExternal; - ei.hEvent = itL->hEvent; - if(isNewOnTop) - eventList.back().push_front(ei); - else - eventList.back().push_back(ei); - ++limitator; - } - else - { - limitator = 0; - lastTime = itL->timestamp; - if(!eventList.back().empty()) - { - ei = eventList.back().front(); - AddGroup(ei); - eventList.push_back(std::deque()); - } - ei.isExternal = itL->isExternal; - ei.hEvent = itL->hEvent; - eventList.back().push_front(ei); - } - } - - if(!eventList.back().empty()) - { - ei = eventList.back().front(); - AddGroup(ei); - } -} - -bool EventList::SearchInContact(HANDLE hContact, TCHAR *strFind, ComparatorInterface* compFun) -{ - InitFilters(); - - if(useImportedMessages) - { - std::vector messages; - - EnterCriticalSection(&criticalSection); - std::map::iterator it = contactFileMap.find(hContact); - if(it != contactFileMap.end()) - { - ExportManager imp(hWnd, hContact, 1); - imp.SetAutoImport(it->second.file); - if(!imp.Import(it->second.type, messages, NULL)) - { - messages.clear(); - } - } - - LeaveCriticalSection(&criticalSection); - for(int i = 0; i < (int)importedMessages.size(); ++i) - { - if(compFun->Compare((importedMessages[i].flags & DBEF_SENT) != 0, importedMessages[i].message, strFind)) - { - return true; - } - } - } - - std::list tempList; - GetTempList(tempList, false, true, hContact); - - EventIndex ei; - EventData ed; - TCHAR str[MAXSELECTSTR + 8]; // for safety reason - for(std::list::iterator itL = tempList.begin(); itL != tempList.end(); ++itL) - { - ei.isExternal = itL->isExternal; - ei.hEvent = itL->hEvent; - if(GetEventData(ei, ed)) - { - GetEventMessage(ei, str); - if(compFun->Compare(ed.isMe, str, strFind)) - { - return true; - } - } - } - - return false; -} - -void EventList::InitNames() -{ - TCHAR str[200]; - if(hContact) - { - _tcscpy_s(contactName, 256, (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR )); - mir_sntprintf(str,200,TranslateT("History for %s"),contactName); - } - else - { - _tcscpy_s(contactName, 256, TranslateT("System")); - mir_sntprintf(str,200,TranslateT("History")); - } - - if(isWnd) - { - SetWindowText(hWnd,str); - } - - _tcscpy_s(myName, GetMyName().c_str()); -} - -void EventList::AddGroup(const EventIndex& ev) -{ - EventData data; - GetEventData(ev, data); - TCHAR eventText[256]; - int i; - eventText[0] = 0; - tmi.printTimeStamp(NULL, data.timestamp, _T("d t"), eventText, 64, 0); - std::wstring time = eventText; - std::wstring user; - if(data.isMe) - user = myName; - else - user = contactName; - GetEventMessage(ev, eventText, 256); - for(i = 0; eventText[i] != 0 && eventText[i] != _T('\r') && eventText[i] != _T('\n'); ++i); - eventText[i] = 0; - if(i > Options::instance->groupMessageLen) - { - eventText[Options::instance->groupMessageLen - 3] = '.'; - eventText[Options::instance->groupMessageLen - 2] = '.'; - eventText[Options::instance->groupMessageLen - 1] = '.'; - eventText[Options::instance->groupMessageLen] = 0; - } - - int ico = 0; - GetEventIcon(data.isMe, data.eventType, ico); - AddGroup(data.isMe, time, user, eventText, ico); -} - -std::wstring EventList::GetContactName() -{ - if(hContact) - { - return (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR ); - } - else - { - return TranslateT("System"); - } -} - -void GetInfo(CONTACTINFO& ci, std::wstring& str) -{ - if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) - { - if (ci.type == CNFT_ASCIIZ) - { - str = ci.pszVal; - mir_free(ci.pszVal); - - } - else if (ci.type == CNFT_DWORD) - { - TCHAR buf[20]; - _ltot_s(ci.dVal, buf, 10 ); - str = buf; - } - else if (ci.type == CNFT_WORD) - { - TCHAR buf[20]; - _ltot_s(ci.wVal, buf, 10 ); - str = buf; - } - } -} - -std::wstring EventList::GetMyName() -{ - std::wstring myName; - CONTACTINFO ci; - ZeroMemory(&ci, sizeof(ci)); - ci.cbSize = sizeof(ci); - ci.szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - ci.hContact = 0; - ci.dwFlag = CNF_DISPLAY | CNF_TCHAR; - GetInfo(ci, myName); - if(myName.empty()) - { - return TranslateT("Me"); - } - - return myName; -} - -inline std::wstring GetProtocolName(HANDLE hContact) -{ - char* ac = (char *)CallService(MS_PROTO_GETCONTACTBASEACCOUNT, (WPARAM)hContact, 0); - std::wstring proto1; - if(ac != NULL) - { - PROTOACCOUNT* acnt = ProtoGetAccount(ac); - if(acnt != NULL && acnt->szModuleName != NULL) - { - wchar_t* proto = mir_a2u(acnt->szProtoName); - proto1 = proto; - mir_free(proto); - } - } - - return proto1; -} - -std::wstring EventList::GetProtocolName() -{ - return ::GetProtocolName(hContact); -} - -std::string EventList::GetBaseProtocol() -{ - char* proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - return proto == NULL ? "" : proto; -} - -std::wstring EventList::GetMyId() -{ - std::wstring myId; - CONTACTINFO ci; - ZeroMemory(&ci, sizeof(ci)); - ci.cbSize = sizeof(ci); - ci.szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - ci.hContact = 0; - ci.dwFlag = CNF_DISPLAYUID | CNF_TCHAR; - GetInfo(ci, myId); - return myId; -} - -inline std::wstring GetContactId(HANDLE hContact) -{ - std::wstring id; - CONTACTINFO ci; - ZeroMemory(&ci, sizeof(ci)); - ci.cbSize = sizeof(ci); - ci.szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - ci.hContact = hContact; - ci.dwFlag = CNF_DISPLAYUID | CNF_TCHAR; - GetInfo(ci, id); - return id; -} - -std::wstring EventList::GetContactId() -{ - return ::GetContactId(hContact); -} - -static void GetMessageDescription( DBEVENTINFO *dbei, TCHAR* buf, int cbBuf ) -{ - TCHAR* msg = DbGetEventTextT( dbei, CP_ACP ); - _tcsncpy_s(buf, cbBuf, msg ? msg : TranslateT("Invalid Message"), cbBuf - 1 ); - buf[ cbBuf-1 ] = 0; - mir_free( msg ); -} - -static void GetAuthRequestDescription( DBEVENTINFO *dbei, TCHAR* buf, int cbBuf ) -{ - std::wstring allName; - buf[0] = 0; - size_t pos = sizeof( DWORD ) + sizeof( HANDLE ); - if(pos >= dbei->cbBlob) - return; - DWORD uin = *((DWORD*)dbei->pBlob); - HANDLE hContact = *((HANDLE*)(dbei->pBlob + sizeof( DWORD ))); - char* nick, *firstName, *lastName, *jid, *reason; - nick = ( char* )( dbei->pBlob + sizeof( DWORD )+ sizeof( HANDLE )); - pos += strnlen_s(nick, dbei->cbBlob - pos) + 1; - if(pos >= dbei->cbBlob) - return; - firstName = ( char* )dbei->pBlob + pos; - pos += strnlen_s(firstName, dbei->cbBlob - pos) + 1; - if(pos >= dbei->cbBlob) - return; - lastName = ( char* )dbei->pBlob + pos; - pos += strnlen_s(lastName, dbei->cbBlob - pos) + 1; - if(pos >= dbei->cbBlob) - return; - jid = (char*)dbei->pBlob + pos; - pos += strnlen_s(jid, dbei->cbBlob - pos) + 1; - if(pos >= dbei->cbBlob) - return; - reason = (char*)dbei->pBlob + pos; - TCHAR *newNick, *newFirstName, *newLastName, *newJid, *newReason; - if(dbei->flags & DBEF_UTF) - { - newNick = mir_utf8decodeT( nick ); - newFirstName = mir_utf8decodeT( firstName ); - newLastName = mir_utf8decodeT( lastName ); - newJid = mir_utf8decodeT( jid ); - newReason = mir_utf8decodeT( reason ); - } - else - { - newNick = mir_a2t( nick ); - newFirstName = mir_a2t( firstName ); - newLastName = mir_a2t( lastName ); - newJid = mir_a2t( jid ); - newReason = mir_a2t( reason ); - } - - if(newFirstName[0] != 0) - { - allName += newFirstName; - if(newLastName[0] != 0) - allName += _T(" "); - } - - if(newLastName[0] != 0) - allName += newLastName; - if(!allName.empty()) - allName += _T(", "); - if(newJid[0] != 0) - { - allName += newJid; - allName += _T(", "); - } - - _sntprintf_s(buf, cbBuf, _TRUNCATE, TranslateT("Authorisation request by %s (%s%d): %s"), - (newNick[0] == 0 ? (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR) : newNick), - allName.c_str(), uin, newReason); - mir_free( newNick ); - mir_free( newFirstName ); - mir_free( newLastName ); - mir_free( newJid ); - mir_free( newReason ); -} - -void EventList::GetObjectDescription( DBEVENTINFO *dbei, TCHAR* str, int cbStr ) -{ - switch( dbei->eventType ) - { - case EVENTTYPE_AUTHREQUEST: - GetAuthRequestDescription( dbei, str, cbStr ); - break; - - default: - GetMessageDescription( dbei, str, cbStr ); - } -} - -bool EventList::GetEventIcon(bool isMe, int eventType, int &id) -{ - switch(eventType) - { - case EVENTTYPE_MESSAGE: - id = isMe ? 1 : 0; - return true; - case EVENTTYPE_STATUSCHANGE: - id = 2; - return true; - case EVENTTYPE_FILE: - id = iconsNum; - return true; - case EVENTTYPE_URL: - id = iconsNum + 1; - return true; - case EVENTTYPE_AUTHREQUEST: - id = iconsNum + 2; - return true; - default: - id = isMe ? 1 : 0; - return false; - } -} - -void EventList::ImportMessages(const std::vector& messages) -{ - DWORD lastTime = 0; - importedMessages.clear(); - for(int i = 0; i < (int)messages.size(); ++i) - { - if(messages[i].timestamp >= lastTime) - { - importedMessages.push_back(messages[i]); - lastTime = messages[i].timestamp; - } - else - { - assert(FALSE); - } - } -} - -void EventList::MargeMessages(const std::vector& messages) -{ - ImportMessages(messages); - std::list tempList; - GetTempList(tempList, true, false, hContact); - DBEVENTINFO dbei = {0}; - dbei.cbSize = sizeof(DBEVENTINFO); - dbei.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - CallService(MS_DB_SETSAFETYMODE, (WPARAM)FALSE, 0); - for(std::list::iterator it = tempList.begin(); it != tempList.end(); ++it) - { - if(it->isExternal) - { - IImport::ExternalMessage& msg = importedMessages[it->exIdx]; - dbei.flags = msg.flags & (~(DBEF_FIRST)); - dbei.flags |= DBEF_READ; - dbei.timestamp = msg.timestamp; - // For now I do not convert event data from string to blob, and event type must be message to handle it properly - dbei.eventType = EVENTTYPE_MESSAGE; - UINT cp = dbei.flags & DBEF_UTF ? CP_UTF8 : CP_ACP; - dbei.cbBlob = WideCharToMultiByte(cp, 0, msg.message.c_str(), (int)msg.message.length() + 1, NULL, 0, NULL, NULL); - char* buf = new char[dbei.cbBlob]; - dbei.cbBlob = WideCharToMultiByte(cp, 0, msg.message.c_str(), (int)msg.message.length() + 1, buf, dbei.cbBlob, NULL, NULL); - dbei.pBlob = (PBYTE)buf; - CallService(MS_DB_EVENT_ADD, (WPARAM) hContact, (LPARAM) & dbei); - delete buf; - } - } - - CallService(MS_DB_SETSAFETYMODE, (WPARAM)TRUE, 0); - std::vector emessages; - ImportMessages(emessages); -} - -bool EventList::GetEventData(const EventIndex& ev, EventData& data) -{ - if(!ev.isExternal) - { - DWORD newBlobSize=CallService(MS_DB_EVENT_GETBLOBSIZE,(WPARAM)ev.hEvent,0); - if(newBlobSize>goldBlobSize) - { - gdbei.pBlob=(PBYTE)mir_realloc(gdbei.pBlob,newBlobSize); - goldBlobSize=newBlobSize; - } - - gdbei.cbBlob = goldBlobSize; - if (CallService(MS_DB_EVENT_GET,(WPARAM)ev.hEvent,(LPARAM)&gdbei) == 0) - { - data.isMe = (gdbei.flags & DBEF_SENT) != 0; - data.eventType = gdbei.eventType; - data.timestamp = gdbei.timestamp; - return true; - } - } - else - { - if(ev.exIdx >= 0 && ev.exIdx < (int)importedMessages.size()) - { - IImport::ExternalMessage& em = importedMessages[ev.exIdx]; - data.isMe = (em.flags & DBEF_SENT) != 0; - data.eventType = em.eventType; - data.timestamp = em.timestamp; - return true; - } - } - - return false; -} - -void EventList::GetExtEventDBei(const EventIndex& ev) -{ - IImport::ExternalMessage& em = importedMessages[ev.exIdx]; - gdbei.flags = (em.flags & (~(DBEF_FIRST))) | 0x800; - gdbei.eventType = em.eventType; - gdbei.timestamp = em.timestamp; -} - -HICON EventList::GetEventCoreIcon(const EventIndex& ev) -{ - if(ev.isExternal) - return NULL; - HICON ico; - ico = (HICON)CallService(MS_DB_EVENT_GETICON, LR_SHARED, (LPARAM)&gdbei); - HICON icoMsg = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE); - if(icoMsg == ico) - { - return NULL; - } - - return ico; -} - -void EventList::RebuildGroup(int selected) -{ - std::deque newGroup; - for(size_t i = 0; i < eventList[selected].size(); ++i) - { - EventIndex& ev = eventList[selected][i]; - if(!ev.isExternal) - { - if(CallService(MS_DB_EVENT_GETBLOBSIZE,(WPARAM)(HANDLE)ev.hEvent,0) >= 0) - { - // If event exist, we add it to new group - newGroup.push_back(eventList[selected][i]); - } - } - else - { - newGroup.push_back(eventList[selected][i]); - } - } - eventList[selected].clear(); - eventList[selected].insert(eventList[selected].begin(), newGroup.begin(), newGroup.end()); -} - -CRITICAL_SECTION EventList::criticalSection; -std::map EventList::contactFileMap; -std::wstring EventList::contactFileDir; - -void EventList::AddImporter(HANDLE hContact, IImport::ImportType type, const std::wstring& file) -{ - EnterCriticalSection(&criticalSection); - TCHAR buf[32]; - _stprintf_s(buf, _T("%016llx"), (unsigned long long int)hContact); - std::wstring internalFile = contactFileDir; - ImportDiscData data; - data.file = contactFileDir + buf; - data.type = type; - CopyFile(file.c_str(), data.file.c_str(), FALSE); - contactFileMap[hContact] = data; - LeaveCriticalSection(&criticalSection); -} - -void EventList::Init() -{ - InitializeCriticalSection(&EventList::criticalSection); - TCHAR temp[MAX_PATH]; - temp[0] = 0; - GetTempPath(MAX_PATH, temp); - contactFileDir = temp; - contactFileDir += L"BasicHistoryImportDir\\"; - DeleteDirectory(contactFileDir.c_str()); - CreateDirectory(contactFileDir.c_str(), NULL); -} - -void EventList::Deinit() -{ - DeleteCriticalSection(&EventList::criticalSection); -} - -int EventList::GetContactMessageNumber(HANDLE hContact) -{ - int count = CallService(MS_DB_EVENT_GETCOUNT,(WPARAM)hContact,0); - EnterCriticalSection(&criticalSection); - std::map::iterator it = contactFileMap.find(hContact); - if(it != contactFileMap.end()) - { - ++count; - } - - LeaveCriticalSection(&criticalSection); - return count; -} - -bool EventList::IsImportedHistory(HANDLE hContact) -{ - bool count = false; - EnterCriticalSection(&criticalSection); - std::map::iterator it = contactFileMap.find(hContact); - if(it != contactFileMap.end()) - { - count = true; - } - - LeaveCriticalSection(&criticalSection); - return count; -} - -void EventList::DeleteImporter(HANDLE hContact) -{ - EnterCriticalSection(&criticalSection); - std::map::iterator it = contactFileMap.find(hContact); - if(it != contactFileMap.end()) - { - DeleteFile(it->second.file.c_str()); - contactFileMap.erase(it); - } - - LeaveCriticalSection(&criticalSection); -} diff --git a/plugins/BasicHistory/EventList.h b/plugins/BasicHistory/EventList.h deleted file mode 100644 index 36628ff278..0000000000 --- a/plugins/BasicHistory/EventList.h +++ /dev/null @@ -1,161 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once -#include "IImport.h" - -#define MAXSELECTSTR 8184 - -class ComparatorInterface -{ -public: - virtual bool Compare(const bool isMe, const std::wstring& message, TCHAR *strFind) = 0; -}; - -class EventList -{ -public: - struct EventData - { - bool isMe; - WORD eventType; - DWORD timestamp; - }; - struct EventIndex - { - union - { - HANDLE hEvent; - int exIdx; - }; - bool isExternal; - }; -private: - std::map filterMap; - bool onlyInFilter; - bool onlyOutFilter; - int defFilter; - std::wstring filterName; - std::vector importedMessages; - DWORD goldBlobSize; - static CRITICAL_SECTION criticalSection; - - struct EventTempIndex - { - union - { - HANDLE hEvent; - int exIdx; - }; - bool isExternal; - DWORD timestamp; - }; - - struct ImportDiscData - { - IImport::ImportType type; - std::wstring file; - }; - - static std::map contactFileMap; - static std::wstring contactFileDir; - - bool CanShowHistory(DBEVENTINFO* dbei); - bool CanShowHistory(const IImport::ExternalMessage& message); - void InitFilters(); - void InitNames(); - void AddGroup(const EventIndex& ev); - void GetTempList(std::list& tempList, bool noFilter, bool noExt, HANDLE _hContact); - void ImportMessages(const std::vector& messages); -protected: - TCHAR contactName[256]; - TCHAR myName[256]; - bool isWnd; - int deltaTime; - DWORD now; - bool isFlat; - DBEVENTINFO gdbei; - - virtual void AddGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText, int ico) = 0; - bool GetEventIcon(bool isMe, int eventType, int &id); - void DeleteEvent(const EventIndex& ev) - { - if(!ev.isExternal) - CallService(MS_DB_EVENT_DELETE,(WPARAM)hContact,(LPARAM)(HANDLE)ev.hEvent); - } - - void RebuildGroup(int selected); -public: - EventList(); - EventList(HANDLE _hContact, int filter); - ~EventList(); - - HWND hWnd; - HANDLE hContact; - std::vector > eventList; - bool useImportedMessages; - - static void Init(); - static void Deinit(); - void SetDefFilter(int filter); - int GetFilterNr(); - std::wstring GetFilterName(); - void RefreshEventList(); - bool SearchInContact(HANDLE hContact, TCHAR *strFind, ComparatorInterface* compFun); - std::wstring GetContactName(); - std::wstring GetMyName(); - std::wstring GetProtocolName(); - std::wstring GetMyId(); - std::wstring GetContactId(); - std::string GetBaseProtocol(); - void MargeMessages(const std::vector& messages); - static void AddImporter(HANDLE hContact, IImport::ImportType type, const std::wstring& file); - static int GetContactMessageNumber(HANDLE hContact); - static bool IsImportedHistory(HANDLE hContact); - static void DeleteImporter(HANDLE hContact); - static void GetObjectDescription( DBEVENTINFO *dbei, TCHAR* str, int cbStr ); - bool GetEventData(const EventIndex& ev, EventData& data); - void GetExtEventDBei(const EventIndex& ev); - HICON GetEventCoreIcon(const EventIndex& ev); - void GetEventMessage(const EventIndex& ev, TCHAR* message) // must be allocated with MAXSELECTSTR len - { - if(!ev.isExternal) - GetObjectDescription(&gdbei, message, MAXSELECTSTR); - else - _tcscpy_s(message, MAXSELECTSTR, importedMessages[ev.exIdx].message.c_str()); - } - void GetEventMessage(const EventIndex& ev, TCHAR* message, int strLen) - { - if(!ev.isExternal) - GetObjectDescription(&gdbei, message, strLen); - else - { - std::wstring& meg = importedMessages[ev.exIdx].message; - if((int)meg.size() >= strLen) - { - memcpy_s(message, strLen * sizeof(TCHAR), meg.c_str(), (strLen - 1) * sizeof(TCHAR)); - message[strLen - 1] = 0; - } - else - { - _tcscpy_s(message, strLen, meg.c_str()); - } - } - } -}; - diff --git a/plugins/BasicHistory/ExportManager.cpp b/plugins/BasicHistory/ExportManager.cpp deleted file mode 100644 index 897561ef26..0000000000 --- a/plugins/BasicHistory/ExportManager.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "StdAfx.h" -#include "ExportManager.h" -#include "TxtExport.h" -#include "PlainHtmlExport.h" -#include "RichHtmlExport.h" -#include "BinaryExport.h" -#include "DatExport.h" -#include "Options.h" -#include "codecvt_CodePage.h" - -ExportManager::ExportManager(HWND _hwnd, HANDLE _hContact, int filter) - :EventList(_hContact, filter), - hwnd(_hwnd), - oldOnTop(false) -{ -} - -std::wstring GetFile(const TCHAR* ext, HWND hwnd, bool open) -{ - TCHAR filter[512]; - std::locale loc; - TCHAR extUpper[32]; - _tcscpy_s(extUpper, ext); - extUpper[0] = std::toupper(ext[0], loc); - _stprintf_s(filter, TranslateT("%s Files (*.%s)"), extUpper, ext); - size_t len = _tcslen(filter) + 1; - _stprintf_s(filter + len, 512 - len, TranslateT("*.%s"), ext); - len += _tcslen(filter + len); - filter[++len] = 0; - TCHAR stzFilePath[1024]; - _tcscpy_s(stzFilePath, TranslateT("History")); - _tcscat_s(stzFilePath, _T(".")); - _tcscat_s(stzFilePath, ext); - len = _tcslen(stzFilePath) + 1; - stzFilePath[len] = 0; - OPENFILENAME ofn = {0}; - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hwnd; - ofn.lpstrFilter = filter; - ofn.nFilterIndex = 1; - ofn.lpstrFile = stzFilePath; - ofn.lpstrTitle = open ? TranslateT("Import") : TranslateT("Export"); - ofn.nMaxFile = 1024; - ofn.lpstrDefExt = ext; - if(open) - { - ofn.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - if(GetOpenFileName(&ofn)) - { - return stzFilePath; - } - } - else - { - ofn.Flags = OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR; - if(GetSaveFileName(&ofn)) - { - return stzFilePath; - } - } - - return L""; -} - -std::wstring ReplaceExt(const std::wstring& file, const TCHAR* ext) -{ - size_t pos = file.find(_T("")); - if(pos < file.length()) - { - std::wstring fileName = file.substr(0, pos); - fileName += ext; - fileName += file.substr(pos + 5); - return fileName; - } - - return file; -} - -bool ExportManager::Export(IExport::ExportType type) -{ - exp = NULL; - UINT cp; - std::wstring encoding; - bool isBin = false; - switch(type) - { - case IExport::Txt: - exp = new TxtExport(); - cp = Options::instance->codepageTxt; - encoding = Options::instance->encodingTxt; - isFlat = true; - break; - case IExport::PlainHtml: - exp = new PlainHtmlExport(); - cp = Options::instance->codepageHtml1; - encoding = Options::instance->encodingHtml1; - break; - case IExport::RichHtml: - exp = new RichHtmlExport(); - cp = Options::instance->codepageHtml2; - encoding = Options::instance->encodingHtml2; - break; - case IExport::Binary: - exp = new BinaryExport(); - cp = CP_UTF8; - encoding = L"UTF8"; - isFlat = true; - oldOnTop = true; - isBin = true; - break; - case IExport::Dat: - exp = new DatExport(); - cp = CP_UTF8; - encoding = L"UTF8"; - isFlat = true; - oldOnTop = true; - isBin = true; - break; - default: - return false; - } - - std::wstring fileName; - if(file.empty()) - fileName = GetFile(exp->GetExt(), hwnd, false); - else - { - fileName = ReplaceExt(file, exp->GetExt()); - } - - if(fileName.empty()) - return false; - - std::wofstream* stream; - if(!isBin) - { - stream = new std::wofstream (fileName.c_str()); - if(!stream->is_open()) - return false; - - std::locale filelocale(std::locale(), new codecvt_CodePage(cp)); - stream->imbue(filelocale); - exp->SetStream(stream); - } - else - { - std::ofstream* cstream = new std::ofstream (fileName.c_str(), std::ios_base::binary); - if(!cstream->is_open()) - return false; - - stream = (std::wofstream*)cstream; - exp->SetStream(stream); - } - - exp->WriteHeader(fileName, GetFilterName(), GetMyName(), GetMyId(), GetContactName(), GetProtocolName(), GetContactId(), GetBaseProtocol(), encoding); - - RefreshEventList(); - - exp->WriteFooter(); - if(!isBin) - { - stream->close(); - delete stream; - } - else - { - std::ofstream* cstream = (std::ofstream*)stream; - cstream->close(); - delete cstream; - } - - delete exp; - return true; -} - -const TCHAR* ExportManager::GetExt(IImport::ImportType type) -{ - IImport* imp = NULL; - switch(type) - { - case IImport::Binary: - imp = new BinaryExport(); - break; - case IImport::Dat: - imp = new DatExport(); - break; - default: - return L""; - } - - const TCHAR* ext = imp->GetExt(); - delete imp; - return ext; -} - -int ExportManager::Import(IImport::ImportType type, const std::vector& contacts) -{ - IImport* imp = NULL; - switch(type) - { - case IImport::Binary: - imp = new BinaryExport(); - break; - case IImport::Dat: - imp = new DatExport(); - break; - default: - return -2; - } - - std::wstring fileName; - if(file.empty()) - return -2; - else - { - fileName = ReplaceExt(file, imp->GetExt()); - } - - if(fileName.empty()) - return -2; - - std::ifstream* stream = new std::ifstream (fileName.c_str(), std::ios_base::binary); - if(!stream->is_open()) - return -2; - - imp->SetStream(stream); - int t = imp->IsContactInFile(contacts); - stream->close(); - delete stream; - delete imp; - return t; -} - -bool ExportManager::Import(IImport::ImportType type, std::vector& eventList, std::wstring* err) -{ - IImport* imp = NULL; - switch(type) - { - case IImport::Binary: - imp = new BinaryExport(); - break; - case IImport::Dat: - imp = new DatExport(); - break; - default: - return false; - } - - std::wstring fileName; - if(file.empty()) - file = fileName = GetFile(imp->GetExt(), hwnd, true); - else - { - fileName = ReplaceExt(file, imp->GetExt()); - } - - std::ifstream* stream = new std::ifstream (fileName.c_str(), std::ios_base::binary); - if(!stream->is_open()) - return false; - - imp->SetStream(stream); - std::vector v; - v.push_back(hContact); - bool ret = true; - int contInFile = imp->IsContactInFile(v); - if(contInFile != 0 && contInFile != -3) - { - ret = false; - if(err != NULL) - *err = TranslateT("File do not contain selected contact"); - } - else - { - ret = imp->GetEventList(eventList); - if(!ret && err != NULL) - *err = TranslateT("File is corrupted"); - } - stream->close(); - delete stream; - delete imp; - return ret; -} - -void ExportManager::AddGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText, int ico) -{ - if(exp == NULL) - return; - exp->WriteGroup(isMe, time, user, eventText); - TCHAR str[MAXSELECTSTR + 8]; // for safety reason - str[0] = 0; - tm lastTime; - bool isFirst = true; - bool lastMe = false; - EventData data; - std::deque revDeq; - std::deque& deq = eventList.back(); - if(!oldOnTop && Options::instance->messagesNewOnTop) - { - revDeq.insert(revDeq.begin(), deq.rbegin(), deq.rend()); - deq = revDeq; - } - for(std::deque::iterator it = deq.begin(); it != deq.end(); ++it) - { - EventIndex hDbEvent = *it; - if(GetEventData(hDbEvent, data)) - { - lastMe = data.isMe; - - TCHAR* formatDate = Options::instance->messagesShowSec ? _T("d s") : _T("d t"); - TCHAR* longFormatDate = Options::instance->messagesShowSec ? _T("d s") : _T("d t"); - if(!Options::instance->messagesShowDate) - { - if(isFirst) - { - isFirst = false; - formatDate = Options::instance->messagesShowSec ? _T("s") : _T("t"); - time_t tt = data.timestamp; - localtime_s(&lastTime, &tt); - } - else - { - time_t tt = data.timestamp; - tm t; - localtime_s(&t, &tt); - if(lastTime.tm_yday == t.tm_yday && lastTime.tm_year == t.tm_year) - formatDate = Options::instance->messagesShowSec ? _T("s") : _T("t"); - } - } - - tmi.printTimeStamp(NULL, data.timestamp, longFormatDate, str , MAXSELECTSTR, 0); - std::wstring longDate = str; - tmi.printTimeStamp(NULL, data.timestamp, formatDate, str , MAXSELECTSTR, 0); - std::wstring shortDate = str; - - std::wstring user; - if(lastMe) - user = myName; - else - user = contactName; - - GetEventMessage(hDbEvent, str); - std::wstring strMessage = str; - if(strMessage.length() + 1 >= MAXSELECTSTR) - continue; - - if(hDbEvent.isExternal) - { - GetExtEventDBei(hDbEvent); - } - - exp->WriteMessage(lastMe, longDate, shortDate, user, strMessage, gdbei); - } - } -} - -void ExportManager::DeleteExportedEvents() -{ - for(size_t j = 0; j < eventList.size(); ++j) - { - for(size_t i = 0; i < eventList[j].size(); ++i) - { - DeleteEvent(eventList[j][i]); - } - } -} - -void ExportManager::SetDeleteWithoutExportEvents(int _deltaTime, DWORD _now) -{ - exp = NULL; - deltaTime = _deltaTime; - now = _now; - RefreshEventList(); -} diff --git a/plugins/BasicHistory/ExportManager.h b/plugins/BasicHistory/ExportManager.h deleted file mode 100644 index d99ff077a6..0000000000 --- a/plugins/BasicHistory/ExportManager.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once -#include "EventList.h" -#include "IExport.h" -#include "IImport.h" -class ExportManager : public EventList -{ -private: - IExport* exp; - std::wstring file; - HWND hwnd; - bool oldOnTop; -protected: - virtual void AddGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText, int ico); -public: - ExportManager(HWND _hwnd, HANDLE _hContact, int filter); - - void SetAutoExport(const std::wstring _file, int _deltaTime, DWORD _now) - { - file = _file; - deltaTime = _deltaTime; - now = _now; - } - - void SetAutoImport(const std::wstring _file) - { - file = _file; - } - - std::wstring GetFileName() - { - return file; - } - - bool Export(IExport::ExportType type); - void SetDeleteWithoutExportEvents(int _deltaTime, DWORD _now); - void DeleteExportedEvents(); - int Import(IImport::ImportType type, const std::vector& contacts); - bool Import(IImport::ImportType type, std::vector& eventList, std::wstring* err = NULL); - static const TCHAR* GetExt(IImport::ImportType type); -}; - diff --git a/plugins/BasicHistory/HistoryWindow.cpp b/plugins/BasicHistory/HistoryWindow.cpp deleted file mode 100644 index d5c3948cb7..0000000000 --- a/plugins/BasicHistory/HistoryWindow.cpp +++ /dev/null @@ -1,2572 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "StdAfx.h" -#include "HistoryWindow.h" -#include "resource.h" -#include "Options.h" -#include "HotkeyHelper.h" -#include "ImageDataObject.h" -#include "ExportManager.h" - -#define MODULE "BasicHistory" -extern HINSTANCE hInst; -extern HCURSOR hCurSplitNS, hCurSplitWE; -extern HANDLE *hEventIcons; -extern int iconsNum; -extern HANDLE hPlusIcon, hMinusIcon, hFindNextIcon, hFindPrevIcon; -extern bool g_SmileyAddAvail; -extern char* metaContactProto; -#define DM_HREBUILD (WM_USER+11) -#define DM_SPLITTERMOVED (WM_USER+15) - -#define MIN_PANELHEIGHT 40 - -void ResetCList(HWND hWnd); - -HistoryWindow::HistoryWindow(HANDLE _hContact) : - isDestroyed(true), - OldSplitterProc(0), - splitterY(0), - splitterOrgY(0), - splitterX(0), - splitterOrgX(0), - plusIco(NULL), - minusIco(NULL), - findNextIco(NULL), - findPrevIco(NULL), - configIco(NULL), - deleteIco(NULL), - isContactList(false), - isLoading(false), - isGroupImages(false), - allIconNumber(0), - eventIcoms(NULL), - bkBrush(NULL), - bkFindBrush(NULL), - hSystem(NULL), - splitterXhWnd(NULL), - splitterYhWnd(NULL) -{ - searcher.SetContect(this); - hContact = _hContact; - selected = -1; - searcher.SetMatchCase(Options::instance->searchMatchCase); - searcher.SetMatchWholeWords(Options::instance->searchMatchWhole); - searcher.SetOnlyIn(Options::instance->searchOnlyIn); - searcher.SetOnlyOut(Options::instance->searchOnlyOut); - searcher.SetOnlyGroup(Options::instance->searchOnlyGroup); - searcher.SetAllUsers(Options::instance->searchAllContacts); - searcher.SetSearchForInLG(Options::instance->searchForInList); - searcher.SetSearchForInMes(Options::instance->searchForInMess); -} - - -HistoryWindow::~HistoryWindow() -{ - if(eventIcoms != NULL) - { - for(int i = 0; i < iconsNum; ++i) - { - if(eventIcoms[i] != NULL) - { - CallService(MS_SKIN2_RELEASEICON, (LPARAM)eventIcoms[i], 0); - } - } - - delete[] eventIcoms; - } - - if(plusIco != NULL) - { - CallService(MS_SKIN2_RELEASEICON, (LPARAM)plusIco, 0); - } - if(minusIco != NULL) - { - CallService(MS_SKIN2_RELEASEICON, (LPARAM)minusIco, 0); - } - if(findNextIco != NULL) - { - CallService(MS_SKIN2_RELEASEICON, (LPARAM)findNextIco, 0); - } - if(findPrevIco != NULL) - { - CallService(MS_SKIN2_RELEASEICON, (LPARAM)findPrevIco, 0); - } - if(himlSmall != NULL) - { - ImageList_Destroy(himlSmall); - } - if(himlNone != NULL) - { - ImageList_Destroy(himlNone); - } - if(bkBrush != NULL) - { - DeleteObject(bkBrush); - } - if(bkFindBrush != NULL) - { - DeleteObject(bkFindBrush); - } -} - -std::map HistoryWindow::windows; -std::vector HistoryWindow::freeWindows; - -void HistoryWindow::Deinit() -{ - bool destroyed = true; - std::vector keys; - for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) - { - if(!it->second->isDestroyed) - { - keys.push_back(it->first); - } - } - for(std::vector::iterator it = keys.begin(); it != keys.end(); ++it) - { - std::map::iterator it1 = windows.find(*it); - if(it1 != windows.end()) - { - DestroyWindow(it1->second->hWnd); - it1 = windows.find(*it); - destroyed &= it1 == windows.end(); - } - } - - std::vector keys1; - for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) - { - if(!(*it)->isDestroyed) - { - keys1.push_back(*it); - } - } - for(std::vector::iterator it = keys1.begin(); it != keys1.end(); ++it) - { - DestroyWindow((*it)->hWnd); - } - for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) - { - if(!(*it)->isDestroyed) - { - destroyed = false; - break; - } - } - - if(destroyed) - { - for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) - { - delete it->second; - } - - windows.clear(); - - for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) - { - delete *it; - } - - freeWindows.clear(); - } -} - -void HistoryWindow::Open(HANDLE hContact) -{ - if(hContact == NULL) - { - HistoryWindow *hw = new HistoryWindow(hContact); - freeWindows.push_back(hw); - hw->Show(); - } - else - { - std::map::iterator it = windows.find(hContact); - if(it != windows.end()) - { - it->second->Focus(); - } - else - { - windows[hContact] = new HistoryWindow(hContact); - windows[hContact]->Show(); - } - } -} - -void HistoryWindow::Close(HANDLE hContact) -{ - std::map::iterator it = windows.find(hContact); - if(it != windows.end()) - { - if(it->second->isDestroyed) - { - delete it->second; - windows.erase(it); - } - else - { - DestroyWindow(it->second->hWnd); - } - } -} - -void HistoryWindow::Close(HistoryWindow* historyWindow) -{ - if(!historyWindow->isDestroyed) - { - DestroyWindow(historyWindow->hWnd); - return; - } - std::map::iterator it = windows.find(historyWindow->hContact); - if(it != windows.end() && it->second == historyWindow) - { - delete it->second; - windows.erase(it); - } - else - { - for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) - { - if(*it == historyWindow) - { - freeWindows.erase(it); - delete historyWindow; - return; - } - } - } -} - -void HistoryWindow::RebuildEvents(HANDLE hContact) -{ - if(hContact != NULL) - { - std::map::iterator it = windows.find(hContact); - if(it != windows.end() && !it->second->isDestroyed) - { - SendMessage(it->second->hWnd,DM_HREBUILD,0,0); - } - } - - for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) - { - if((*it)->hContact == hContact && !(*it)->isDestroyed) - { - SendMessage((*it)->hWnd,DM_HREBUILD,0,0); - } - } -} - -void HistoryWindow::ChangeToFreeWindow(HistoryWindow* historyWindow) -{ - std::map::iterator it = windows.find(historyWindow->hContact); - if(it != windows.end() && it->second == historyWindow) - { - windows.erase(it); - freeWindows.push_back(historyWindow); - } -} - -void HistoryWindow::Show() -{ - CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_HISTORY),NULL,HistoryWindow::DlgProcHistory,(LPARAM)this); -} - -void HistoryWindow::Focus() -{ - if(IsIconic(hWnd)) - { - ShowWindow(hWnd, SW_RESTORE); - } - else - { - SetForegroundWindow(hWnd); - SetFocus(hWnd); - } - SendMessage(hWnd,DM_HREBUILD,0,0); -} - -int HistoryWindow::FontsChanged(WPARAM wParam, LPARAM lParam) -{ - for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) - { - if(!it->second->isDestroyed) - { - it->second->FontsChanged(); - } - } - - for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) - { - if(!(*it)->isDestroyed) - { - (*it)->FontsChanged(); - } - } - - return 0; -} - -void HistoryWindow::FontsChanged() -{ - if(bkBrush != NULL) - { - DeleteObject(bkBrush); - } - if(bkFindBrush != NULL) - { - DeleteObject(bkFindBrush); - } - - bkBrush = CreateSolidBrush(Options::instance->GetColor(Options::WindowBackground)); - bkFindBrush = CreateSolidBrush(Options::instance->GetColor(Options::FindBackground)); - - ResetCList(hWnd); - COLORREF bkColor = Options::instance->GetColor(Options::GroupListBackground); - ListView_SetBkColor(listWindow, bkColor); - ListView_SetTextBkColor(listWindow, bkColor); - LOGFONT font; - ListView_SetTextColor(listWindow, Options::instance->GetFont(Options::GroupList, &font)); - InvalidateRect(listWindow, NULL, TRUE); - InvalidateRect(hWnd, NULL, TRUE); - SelectEventGroup(selected); -} - -void OptionsGroupChanged() -{ - HistoryWindow::OptionsGroupChanged(); -} - -void HistoryWindow::OptionsGroupChanged() -{ - for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) - { - if(!it->second->isDestroyed) - { - it->second->GroupImagesChanged(); - SendMessage(it->second->hWnd,DM_HREBUILD,0,0); - } - } - - for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) - { - if(!(*it)->isDestroyed) - { - (*it)->GroupImagesChanged(); - SendMessage((*it)->hWnd,DM_HREBUILD,0,0); - } - } -} - -void OptionsMainChanged() -{ - HistoryWindow::OptionsMainChanged(); -} - -void HistoryWindow::OptionsMainChanged() -{ - for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) - { - if(!it->second->isDestroyed) - { - it->second->ReloadMainOptions(); - } - } - - for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) - { - if(!(*it)->isDestroyed) - { - (*it)->ReloadMainOptions(); - } - } -} - -void HistoryWindow::ReloadMainOptions() -{ - SendDlgItemMessage(hWnd, IDC_LIST_CONTACTS, CLM_SETUSEGROUPS, Options::instance->showContactGroups, 0); - SendMessage(hWnd,DM_HREBUILD,0,0); -} - -void OptionsMessageChanged() -{ - HistoryWindow::FontsChanged(0, 0); -} - -void OptionsSearchingChanged() -{ - HistoryWindow::OptionsSearchingChanged(); -} - -void HistoryWindow::OptionsSearchingChanged() -{ - for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) - { - if(!it->second->isDestroyed) - { - it->second->searcher.SetSearchForInLG(Options::instance->searchForInList); - it->second->searcher.SetSearchForInMes(Options::instance->searchForInMess); - } - } - - for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) - { - if(!(*it)->isDestroyed) - { - (*it)->searcher.SetSearchForInLG(Options::instance->searchForInList); - (*it)->searcher.SetSearchForInMes(Options::instance->searchForInMess); - } - } -} - -INT_PTR HistoryWindow::DeleteAllUserHistory(WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact = (HANDLE)wParam; - HWND hWnd = NULL; - int start = 0; - int end = 0; - int count = EventList::GetContactMessageNumber(hContact); - if(!count) - return FALSE; - - for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) - { - if(!it->second->isDestroyed) - { - if(it->second->hContact == hContact) - { - if(hWnd == NULL) - { - hWnd = it->second->hWnd; - } - else if(GetForegroundWindow() == it->second->hWnd) - { - hWnd = it->second->hWnd; - } - } - } - } - - for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) - { - if(!(*it)->isDestroyed) - { - if((*it)->hContact == hContact) - { - if(hWnd == NULL) - { - hWnd = (*it)->hWnd; - } - else if(GetForegroundWindow() == (*it)->hWnd) - { - hWnd = (*it)->hWnd; - } - } - } - } - - TCHAR *message = TranslateT("This operation will PERMANENTLY REMOVE all history for this contact.\nAre you sure you want to do this?"); - if(MessageBox(hWnd, message, TranslateT("Are You sure?"), MB_OKCANCEL | MB_ICONERROR) != IDOK) - return FALSE; - - std::deque toRemove; - HANDLE hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRST,(WPARAM)hContact,0); - while ( hDbEvent != NULL ) - { - toRemove.push_back(hDbEvent); - hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0); - } - - for(std::deque::iterator it = toRemove.begin(); it != toRemove.end(); ++it) - { - CallService(MS_DB_EVENT_DELETE,(WPARAM)hContact,(LPARAM)(HANDLE)*it); - } - - if(EventList::IsImportedHistory(hContact)) - { - TCHAR *message = TranslateT("Do you want delete all imported messages for this contact?\nNote that next scheduler task import this messages again."); - if(MessageBox(hWnd, message, TranslateT("Are You sure?"), MB_YESNO | MB_ICONERROR) == IDYES) - { - EventList::DeleteImporter(hContact); - } - } - - RebuildEvents(hContact); - return TRUE; -} - -bool HistoryWindow::IsInList(HWND hWnd) -{ - for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) - { - if(!it->second->isDestroyed) - { - if(it->second->hWnd == hWnd) - { - return true; - } - } - } - - for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) - { - if(!(*it)->isDestroyed) - { - if((*it)->hWnd == hWnd) - { - return true; - } - } - } - - return false; -} - -void ClickLink(HWND hwnd, ENLINK *penLink) -{ - TCHAR buf[1024]; - if(penLink->msg != WM_LBUTTONUP) - return; - if(penLink->chrg.cpMin >= 0 && penLink->chrg.cpMax > penLink->chrg.cpMin) - { - // selection - int len = penLink->chrg.cpMax - penLink->chrg.cpMin; - if(len < 1023) - { - TEXTRANGE tr; - CHARRANGE sel; - - SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM) & sel); - if (sel.cpMin != sel.cpMax) - return; - tr.chrg = penLink->chrg; - tr.lpstrText = buf; - SendMessage(hwnd, EM_GETTEXTRANGE, 0, (LPARAM) & tr); - CallService(MS_UTILS_OPENURL, (penLink->nmhdr.code == IDM_OPENNEW ? OUF_NEWWINDOW : 0) | OUF_TCHAR, (LPARAM) tr.lpstrText); - } - } -} - -void ConvertSize(HWND hwndSrc, HWND hwndDest, RECT& rc) -{ - POINT pt; - pt.x = rc.left; - pt.y = rc.top; - ClientToScreen(hwndSrc, &pt); - ScreenToClient(hwndDest, &pt); - rc.left = pt.x; - rc.top = pt.y; - - pt.x = rc.right; - pt.y = rc.bottom; - ClientToScreen(hwndSrc, &pt); - ScreenToClient(hwndDest, &pt); - rc.right = pt.x; - rc.bottom = pt.y; -} - -void OpenOptions(char* group, char* page, char* tab = NULL) -{ - OPENOPTIONSDIALOG op; - op.cbSize = sizeof(OPENOPTIONSDIALOG); - op.pszGroup = group; - op.pszPage = page; - op.pszTab = tab; - CallService(MS_OPT_OPENOPTIONS, 0, (LPARAM)&op); -} - -#define DlgReturn(ret){\ - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (ret));\ - return (ret);\ -} - -class ShowMessageData -{ -public: - ShowMessageData(HANDLE _hContact) - :hContact(_hContact) - { - } - - ShowMessageData(HANDLE _hContact, const std::wstring &_str) - :hContact(_hContact), - str(_str) - { - } - - HANDLE hContact; - std::wstring str; -}; - -void __stdcall ShowMessageWindow(void* arg) -{ - ShowMessageData* dt = (ShowMessageData*)arg; - if(dt->str.empty()) - CallService(MS_MSG_SENDMESSAGE, (WPARAM)dt->hContact, 0); - else - CallService(MS_MSG_SENDMESSAGET, (WPARAM)dt->hContact, (LPARAM)dt->str.c_str()); - delete dt; -} - -INT_PTR CALLBACK HistoryWindow::DlgProcHistory(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_GETMINMAXINFO: - ((MINMAXINFO*)lParam)->ptMinTrackSize.x=500; - ((MINMAXINFO*)lParam)->ptMinTrackSize.y=380; - - case WM_SIZE: - { - UTILRESIZEDIALOG urd={0}; - urd.cbSize=sizeof(urd); - urd.hwndDlg=hwndDlg; - urd.hInstance=hInst; - urd.lpTemplate=MAKEINTRESOURCEA(IDD_HISTORY); - urd.lParam=(LPARAM)NULL; - urd.pfnResizer=HistoryWindow::HistoryDlgResizer; - CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd); - ListView_SetColumnWidth(GetDlgItem(hwndDlg,IDC_LIST), 0, LVSCW_AUTOSIZE_USEHEADER); - DlgReturn(TRUE); - } - case WM_COMMAND: - switch ( LOWORD( wParam )) { - case IDOK: - case IDCANCEL: - DestroyWindow(hwndDlg); - DlgReturn(TRUE); - - case IDM_FIND: - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - historyWindow->searcher.Find(); - DlgReturn(TRUE); - } - - case IDM_CONFIG: - { - OPENOPTIONSDIALOG opd = {0}; - opd.cbSize = sizeof(OPENOPTIONSDIALOG); - opd.pszPage = LPGEN("History"); - CallService(MS_OPT_OPENOPTIONS, 0, (LPARAM)&opd); - DlgReturn(TRUE); - } - - case IDM_DELETE: - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - historyWindow->Delete(0); - DlgReturn(TRUE); - } - - case IDC_FIND_TEXT: - if(HIWORD(wParam) == EN_CHANGE) - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - historyWindow->searcher.ClearFind(); - } - - DlgReturn(TRUE); - - case IDC_SHOWHIDE: - { - if(HIWORD( wParam ) == BN_CLICKED) - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - if(Button_GetCheck(GetDlgItem(hwndDlg,IDC_SHOWHIDE)) & BST_CHECKED) - { - SendDlgItemMessage( hwndDlg, IDC_SHOWHIDE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)historyWindow->minusIco); - SendDlgItemMessage( hwndDlg, IDC_SHOWHIDE, BUTTONADDTOOLTIP, (WPARAM)LPGENT("Hide Contacts"), BATF_TCHAR); - historyWindow->isContactList = true; - ShowWindow(GetDlgItem(hwndDlg,IDC_LIST_CONTACTS), SW_SHOW); - ShowWindow(historyWindow->splitterYhWnd, SW_SHOW); - } - else - { - SendDlgItemMessage( hwndDlg, IDC_SHOWHIDE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)historyWindow->plusIco); - SendDlgItemMessage( hwndDlg, IDC_SHOWHIDE, BUTTONADDTOOLTIP, (WPARAM)LPGENT("Show Contacts"), BATF_TCHAR); - historyWindow->isContactList = false; - ShowWindow(GetDlgItem(hwndDlg,IDC_LIST_CONTACTS), SW_HIDE); - ShowWindow(historyWindow->splitterYhWnd, SW_HIDE); - } - - SendMessage(hwndDlg, WM_SIZE, 0, 0); - } - - DlgReturn(TRUE); - } - } - break; - case WM_NOTIFY: - { - LPNMHDR pNmhdr; - - pNmhdr = (LPNMHDR)lParam; - switch(pNmhdr->idFrom) - { - case IDC_LIST_CONTACTS: - if(pNmhdr->code == CLN_LISTREBUILT)// || pNmhdr->code == CLN_CONTACTMOVED || pNmhdr->code == CLN_NEWCONTACT) - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - if(historyWindow != NULL) - { - historyWindow->ReloadContacts(); - } - - DlgReturn(TRUE); - } - else if(pNmhdr->code == CLN_MYSELCHANGED) - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - if(historyWindow->ContactChanged()) - { - MSGFILTER* msgFilter = (MSGFILTER *) lParam; - if(msgFilter->msg == WM_LBUTTONDOWN) - { - SendMessage(pNmhdr->hwndFrom, WM_LBUTTONUP, msgFilter->wParam, msgFilter->lParam); - } - } - - DlgReturn(TRUE); - } - else if(pNmhdr->code == CLN_OPTIONSCHANGED) - { - ResetCList(hwndDlg); - return FALSE; - } - - //fall through - //case IDC_LIST_CONTACTS: - case IDC_SHOWHIDE: - case IDC_FIND_TEXT: - case IDC_EDIT: - if ( pNmhdr->code == EN_LINK ) - { - ClickLink(GetDlgItem(hwndDlg, IDC_EDIT), (ENLINK *) lParam); - return FALSE; - } - else if( pNmhdr->code == EN_SELCHANGE) - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - historyWindow->searcher.ClearFind(); - } - else if(pNmhdr->code == EN_MSGFILTER) - { - MSGFILTER* msgFilter = (MSGFILTER *) lParam; - if (msgFilter->msg == WM_KEYDOWN || msgFilter->msg == WM_SYSKEYDOWN) - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - if(historyWindow->DoHotkey(msgFilter->msg, msgFilter->lParam, msgFilter->wParam, pNmhdr->idFrom)) - DlgReturn(TRUE); - } - else if (msgFilter->msg == WM_RBUTTONDOWN || msgFilter->msg == WM_RBUTTONDBLCLK || msgFilter->msg == WM_NCRBUTTONUP || msgFilter->msg == WM_NCRBUTTONDBLCLK || msgFilter->msg == WM_NCRBUTTONDOWN) - { - DlgReturn(TRUE); - } - else if (msgFilter->msg == WM_RBUTTONUP) - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - POINT clicked; - LPNMITEMACTIVATE nmlv = (LPNMITEMACTIVATE)lParam; - HWND window = historyWindow->editWindow; - POINTL p; - POINT scrool; - LVHITTESTINFO info = {0}; - p.x = clicked.x = info.pt.x = GET_X_LPARAM(msgFilter->lParam); - p.y = clicked.y = info.pt.y = GET_Y_LPARAM(msgFilter->lParam); - ClientToScreen(window, &clicked); - SetFocus(window); - int selChar = SendMessage(window, EM_CHARFROMPOS, 0, (LPARAM)&p); - CHARRANGE chrg; - SendMessage(window,EM_EXGETSEL,0,(LPARAM)&chrg); - SendMessage(window,EM_GETSCROLLPOS,0,(LPARAM)&scrool); - if(selChar < chrg.cpMin || selChar > chrg.cpMax) - { - chrg.cpMin = chrg.cpMax = selChar; - } - - if(chrg.cpMin == chrg.cpMax) - { - CHARRANGE chrgNew; - chrgNew.cpMin = chrg.cpMin; - chrgNew.cpMax = chrg.cpMax + 1; - SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrgNew); - } - CHARFORMAT2 chf; - memset(&chf, 0, sizeof(CHARFORMAT2)); - chf.cbSize = sizeof(CHARFORMAT2); - chf.dwMask = CFM_LINK; - SendMessage(window, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&chf); - if(chrg.cpMin == chrg.cpMax) - SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrg); - - HMENU hPopupMenu = CreatePopupMenu(); - if(hPopupMenu != NULL) - { - if(chf.dwEffects & CFE_LINK) - { - AppendMenu(hPopupMenu, MF_STRING, IDM_OPENNEW, TranslateT("Open in &new window")); - AppendMenu(hPopupMenu, MF_STRING, IDM_OPENEXISTING, TranslateT("&Open in existing window")); - AppendMenu(hPopupMenu, MF_STRING, IDM_COPYLINK, TranslateT("&Copy link")); - } - else - { - AppendMenu(hPopupMenu, MF_STRING, IDM_COPY, TranslateT("Copy")); - AppendMenu(hPopupMenu, MF_STRING, IDM_DELETE, TranslateT("Delete")); - AppendMenu(hPopupMenu, MFT_SEPARATOR, 0, NULL); - AppendMenu(hPopupMenu, MF_STRING, IDM_MESSAGE, TranslateT("Send Message")); - AppendMenu(hPopupMenu, MF_STRING, IDM_QUOTE, TranslateT("Reply &Quoted")); - AppendMenu(hPopupMenu, MF_STRING, IDM_DELETEGROUP, TranslateT("Delete Group")); - AppendMenu(hPopupMenu, MF_STRING, IDM_DELETEUSER, TranslateT("Delete All User History")); - } - - int selected = TrackPopupMenu(hPopupMenu, TPM_RETURNCMD, clicked.x, clicked.y, 0, hwndDlg, 0); - switch (selected) - { - case IDM_COPY: - { - if(chrg.cpMax == chrg.cpMin && historyWindow->currentGroup.size() > 0) - { - size_t start = 0; - while(start < historyWindow->currentGroup.size() && chrg.cpMin >= historyWindow->currentGroup[start].endPos) ++start; - if(start < historyWindow->currentGroup.size()) - { - CHARRANGE chrgNew; - chrgNew.cpMin = 0; - if(start > 0) - chrgNew.cpMin = historyWindow->currentGroup[start - 1].endPos; - chrgNew.cpMax = historyWindow->currentGroup[start].endPos; - SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrgNew); - SendMessage(window,WM_COPY,0,0); - SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrg); - } - } - else - { - SendMessage(window,WM_COPY,0,0); - } - } - break; - case IDM_MESSAGE: - //CallService(MS_MSG_SENDMESSAGE, (WPARAM)historyWindow->hContact, 0); - CallFunctionAsync(ShowMessageWindow, new ShowMessageData(historyWindow->hContact)); - break; - case IDM_QUOTE: - { - if(historyWindow->currentGroup.size() > 0) - { - std::wstring quote; - if(chrg.cpMax == chrg.cpMin) - { - size_t start = 0; - while(start < historyWindow->currentGroup.size() && chrg.cpMin >= historyWindow->currentGroup[start].endPos) ++start; - if(start < historyWindow->currentGroup.size()) - { - historyWindow->FormatQuote(quote, historyWindow->currentGroup[start], historyWindow->currentGroup[start].description); - } - } - else - { - size_t start = 0; - while(start < historyWindow->currentGroup.size() && chrg.cpMin >= historyWindow->currentGroup[start].endPos) ++start; - size_t end = 0; - while(end < historyWindow->currentGroup.size() && chrg.cpMax > historyWindow->currentGroup[end].endPos) ++end; - if(end >= historyWindow->currentGroup.size()) - end = historyWindow->currentGroup.size() - 1; - if(start == end && start < historyWindow->currentGroup.size()) - { - int iStart = historyWindow->currentGroup[start].startPos; - if(chrg.cpMin > iStart) - iStart = chrg.cpMin; - int iEnd = historyWindow->currentGroup[start].endPos; - if(chrg.cpMax < iEnd) - iEnd = chrg.cpMax; - if(iEnd > iStart) - { - TEXTRANGE tr; - tr.chrg.cpMin = iStart; - tr.chrg.cpMax = iEnd; - tr.lpstrText = new TCHAR[iEnd - iStart + 1]; - SendMessage(historyWindow->editWindow, EM_GETTEXTRANGE, 0, (LPARAM) & tr); - historyWindow->FormatQuote(quote, historyWindow->currentGroup[start], tr.lpstrText); - delete [] tr.lpstrText; - } - } - else - { - while(start <= end) - { - historyWindow->FormatQuote(quote, historyWindow->currentGroup[start], historyWindow->currentGroup[start].description); - ++start; - } - } - } - - if(!quote.empty()) - { - CallFunctionAsync(ShowMessageWindow, new ShowMessageData(historyWindow->hContact, quote)); - } - } - } - break; - case IDM_DELETE: - historyWindow->Delete(0); - break; - case IDM_DELETEGROUP: - historyWindow->Delete(1); - break; - case IDM_DELETEUSER: - historyWindow->Delete(2); - break; - case IDM_OPENNEW: - case IDM_OPENEXISTING: - case IDM_COPYLINK: - { - int start = chrg.cpMin, end = chrg.cpMin; - CHARRANGE chrgNew; - chrgNew.cpMin = start-1; - chrgNew.cpMax = start; - do - { - memset(&chf, 0, sizeof(CHARFORMAT2)); - chf.cbSize = sizeof(CHARFORMAT2); - chf.dwMask = CFM_LINK; - int sel = SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrgNew); - if(sel != chrgNew.cpMax) - break; - SendMessage(window, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&chf); - --chrgNew.cpMin; - --chrgNew.cpMax; - --start; - } while(start >= 0 && chf.dwEffects & CFE_LINK); - - ++start; - chrgNew.cpMin = end; - chrgNew.cpMax = end + 1; - do - { - memset(&chf, 0, sizeof(CHARFORMAT2)); - chf.cbSize = sizeof(CHARFORMAT2); - chf.dwMask = CFM_LINK; - int sel = SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrgNew); - if(sel != chrgNew.cpMax) - break; - SendMessage(window, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&chf); - ++chrgNew.cpMin; - ++chrgNew.cpMax; - ++end; - } while(chf.dwEffects & CFE_LINK); - - --end; - if(selected == IDM_COPYLINK) - { - chrgNew.cpMin = start; - chrgNew.cpMax = end; - SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrgNew); - SendMessage(window,WM_COPY,0,0); - SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrg); - } - else - { - ENLINK link; - link.chrg.cpMin = start; - link.chrg.cpMax = end; - link.msg = WM_LBUTTONUP; - link.nmhdr.code = selected; - SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrg); - ClickLink(window, &link); - } - } - break; - } - - DestroyMenu(hPopupMenu); - } - SendMessage(window,EM_SETSCROLLPOS,0,(LPARAM)&scrool); - DlgReturn(TRUE); - } - } - break; - case IDC_LIST: - if( pNmhdr->code == LVN_ITEMCHANGED) - { - NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam; - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - if((nmlv->uChanged & LVIF_STATE) && (nmlv->uNewState & LVIS_SELECTED) && historyWindow->selected != nmlv->iItem && nmlv->iItem >= 0) - { - historyWindow->SelectEventGroup(nmlv->iItem); - DlgReturn(TRUE); - } - } - else if( pNmhdr->code == LVN_KEYDOWN) - { - LPNMLVKEYDOWN nmlv = (LPNMLVKEYDOWN)lParam; - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - if(historyWindow->DoHotkey(WM_KEYDOWN, 0, nmlv->wVKey, IDC_LIST)) - DlgReturn(TRUE); - } - else if(pNmhdr->code == NM_RCLICK) - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - POINT clicked; - LPNMITEMACTIVATE nmlv = (LPNMITEMACTIVATE)lParam; - HWND window = historyWindow->listWindow; - LVHITTESTINFO info = {0}; - clicked.x = info.pt.x = nmlv->ptAction.x; - clicked.y = info.pt.y = nmlv->ptAction.y; - ClientToScreen(window, &clicked); - int newSel = SendMessage(window, LVM_SUBITEMHITTEST, 0, (LPARAM)&info); - int curSel = historyWindow->selected; - - if(newSel >= 0) - { - HMENU hPopupMenu = CreatePopupMenu(); - if(hPopupMenu != NULL) - { - AppendMenu(hPopupMenu, MF_STRING, IDM_COPY, TranslateT("Copy")); - AppendMenu(hPopupMenu, MF_STRING, IDM_DELETEGROUP, TranslateT("Delete Group")); - AppendMenu(hPopupMenu, MFT_SEPARATOR, 0, NULL); - AppendMenu(hPopupMenu, MF_STRING, IDM_MESSAGE, TranslateT("Send Message")); - AppendMenu(hPopupMenu, MF_STRING, IDM_DELETEUSER, TranslateT("Delete All User History")); - - int selected = TrackPopupMenu(hPopupMenu, TPM_RETURNCMD, clicked.x, clicked.y, 0, hwndDlg, 0); - switch (selected) - { - case IDM_COPY: - { - CHARRANGE chrg; - SendMessage(historyWindow->editWindow,EM_EXGETSEL,0,(LPARAM)&chrg); - CHARRANGE chrgNew; - chrgNew.cpMin = 0; - chrgNew.cpMax = -1; - SendMessage(historyWindow->editWindow,EM_EXSETSEL,0,(LPARAM)&chrgNew); - SendMessage(historyWindow->editWindow,WM_COPY,0,0); - SendMessage(historyWindow->editWindow,EM_EXSETSEL,0,(LPARAM)&chrg); - } - break; - case IDM_MESSAGE: - CallService(MS_MSG_SENDMESSAGE, (WPARAM)historyWindow->hContact, 0); - break; - case IDM_DELETEGROUP: - historyWindow->Delete(1); - break; - case IDM_DELETEUSER: - historyWindow->Delete(2); - break; - } - - DestroyMenu(hPopupMenu); - } - } - - DlgReturn(TRUE); - } - - break; - case IDC_TOOLBAR: - if( pNmhdr->code == TBN_DROPDOWN) - { - LPNMTOOLBAR lpnmTB= (LPNMTOOLBAR)lParam; - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - if(lpnmTB->iItem == IDM_FIND) - { - historyWindow->FindToolbarClicked(lpnmTB); - } - else if(lpnmTB->iItem == IDM_CONFIG) - { - historyWindow->ConfigToolbarClicked(lpnmTB); - } - else if(lpnmTB->iItem == IDM_DELETE) - { - historyWindow->DeleteToolbarClicked(lpnmTB); - } - - DlgReturn(TBDDRET_DEFAULT); - } - else if( pNmhdr->code == NM_KEYDOWN) - { - LPNMKEY nmlv = (LPNMKEY)lParam; - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - if(historyWindow->DoHotkey(WM_KEYDOWN, 0, nmlv->nVKey, IDC_TOOLBAR)) - DlgReturn(TRUE); - } - break; - } - break; - } - case WM_CTLCOLORDLG: - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - DlgReturn((LONG_PTR)historyWindow->bkBrush); - } - case WM_CTLCOLORSTATIC: - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - HWND curhWnd = (HWND)lParam; - if(historyWindow->splitterXhWnd == curhWnd || historyWindow->splitterYhWnd == curhWnd) - { - DlgReturn((LONG_PTR)historyWindow->bkBrush); - } - - break; - } - case WM_CTLCOLOREDIT: - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - HWND curhWnd = (HWND)lParam; - if(historyWindow->findWindow == curhWnd) - { - HDC edithdc = (HDC)wParam; - LOGFONT font; - SetTextColor(edithdc, Options::instance->GetFont(Options::Find, &font)); - SetBkColor(edithdc, Options::instance->GetColor(Options::FindBackground)); - DlgReturn((LONG_PTR)historyWindow->bkFindBrush); - } - - break; - } - case DM_SPLITTERMOVED: - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - historyWindow->SplitterMoved((HWND)lParam, wParam, true); - break; - } - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - HistoryWindow* historyWindow = (HistoryWindow*)lParam; - historyWindow->hWnd = hwndDlg; - historyWindow->isWnd = true; - SetWindowLongPtr(hwndDlg,GWLP_USERDATA,(LONG_PTR)lParam); - historyWindow->Initialise(); - } - DlgReturn(TRUE); - - case DM_HREBUILD: - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - if(!historyWindow->isLoading) - { - historyWindow->isLoading = true; - historyWindow->ReloadContacts(); - mir_forkthread(HistoryWindow::FillHistoryThread, historyWindow); - } - } - DlgReturn(TRUE); - - case WM_DESTROY: - { - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); - historyWindow->Destroy(); - } - DlgReturn(TRUE); - } - return FALSE; -} - -void HistoryWindow::Initialise() -{ - splitterXhWnd = GetDlgItem(hWnd, IDC_SPLITTER); - splitterYhWnd = GetDlgItem(hWnd, IDC_SPLITTERV); - OldSplitterProc = (WNDPROC)SetWindowLongPtr(splitterXhWnd, GWLP_WNDPROC, (LONG_PTR) SplitterSubclassProc); - SetWindowLongPtr(splitterYhWnd, GWLP_WNDPROC, (LONG_PTR) SplitterSubclassProc); - - editWindow = GetDlgItem(hWnd, IDC_EDIT); - findWindow = GetDlgItem(hWnd, IDC_FIND_TEXT); - toolbarWindow = GetDlgItem(hWnd, IDC_TOOLBAR); - listWindow = GetDlgItem(hWnd, IDC_LIST); - - RECT rc; - POINT pt; - GetWindowRect(splitterXhWnd, &rc); - pt.y = (rc.top + rc.bottom) / 2; - pt.x = 0; - ScreenToClient(hWnd, &pt); - splitterOrgY = pt.y; - splitterY = pt.y; - GetWindowRect(splitterYhWnd, &rc); - pt.y = 0; - pt.x = (rc.left + rc.right) / 2; - ScreenToClient(hWnd, &pt); - splitterOrgX = pt.x; - splitterX = pt.x; - GetWindowRect(GetDlgItem(hWnd, IDC_LIST_CONTACTS), &rc); - pt.y = rc.top; - pt.x = rc.left; - ScreenToClient(hWnd, &pt); - listOryginalPos = pt.x; - - plusIco = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 1, (LPARAM)hPlusIcon); - minusIco = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 1, (LPARAM)hMinusIcon); - SendDlgItemMessage( hWnd, IDC_SHOWHIDE, BUTTONSETASPUSHBTN, TRUE, 0 ); - SendDlgItemMessage( hWnd, IDC_SHOWHIDE, BUTTONSETASFLATBTN, TRUE, 0 ); - if(hContact == NULL || Options::instance->showContacts) - { - SendDlgItemMessage( hWnd, IDC_SHOWHIDE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)minusIco); - SendDlgItemMessage( hWnd, IDC_SHOWHIDE, BUTTONADDTOOLTIP, (WPARAM)LPGENT("Hide Contacts"), BATF_TCHAR); - Button_SetCheck(GetDlgItem(hWnd,IDC_SHOWHIDE), BST_CHECKED); - isContactList = true; - } - else - { - SendDlgItemMessage( hWnd, IDC_SHOWHIDE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)plusIco); - SendDlgItemMessage( hWnd, IDC_SHOWHIDE, BUTTONADDTOOLTIP, (WPARAM)LPGENT("Show Contacts"), BATF_TCHAR); - Button_SetCheck(GetDlgItem(hWnd,IDC_SHOWHIDE), BST_UNCHECKED); - ShowWindow(GetDlgItem(hWnd,IDC_LIST_CONTACTS), SW_HIDE); - ShowWindow(splitterYhWnd, SW_HIDE); - isContactList = false; - } - RegisterHotkeyControl(GetDlgItem(hWnd, IDC_SHOWHIDE)); - RegisterHotkeyControl(GetDlgItem(hWnd, IDC_LIST_CONTACTS)); - - ResetCList(hWnd); - - RestorePos(); - SendMessage(hWnd, WM_SETICON, ICON_BIG, ( LPARAM )LoadSkinnedIconBig( SKINICON_OTHER_HISTORY )); - SendMessage(hWnd, WM_SETICON, ICON_SMALL, ( LPARAM )LoadSkinnedIcon( SKINICON_OTHER_HISTORY )); - SendMessage(editWindow,EM_AUTOURLDETECT,TRUE,0); - SendMessage(editWindow,EM_SETEVENTMASK,0,ENM_LINK | ENM_SELCHANGE | ENM_KEYEVENTS | ENM_MOUSEEVENTS); - SendMessage(editWindow,EM_SETEDITSTYLE,SES_EXTENDBACKCOLOR,SES_EXTENDBACKCOLOR); - - himlSmall = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 2, 2); - himlNone = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 2, 2); - ImageList_SetIconSize(himlNone, 0, 16); - if(himlSmall) - { - allIconNumber = iconsNum + 3; - eventIcoms = new HICON[allIconNumber]; - for(int i = 0; i < iconsNum; ++i) - { - eventIcoms[i] = hEventIcons[i] == NULL ? NULL : (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hEventIcons[i]); - ImageList_AddIcon(himlSmall, eventIcoms[i]); - } - - int id = iconsNum; - eventIcoms[id] = LoadSkinnedIcon(SKINICON_EVENT_FILE); - ImageList_AddIcon(himlSmall, eventIcoms[id]); - - eventIcoms[++id] = LoadSkinnedIcon(SKINICON_EVENT_URL); - ImageList_AddIcon(himlSmall, eventIcoms[id]); - - eventIcoms[++id] = LoadSkinnedIcon(SKINICON_OTHER_WINDOWS); - ImageList_AddIcon(himlSmall, eventIcoms[id]); - - if((isGroupImages = Options::instance->groupShowEvents) != false) - ListView_SetImageList(listWindow, himlSmall, LVSIL_SMALL); - } - - bkBrush = CreateSolidBrush(Options::instance->GetColor(Options::WindowBackground)); - bkFindBrush = CreateSolidBrush(Options::instance->GetColor(Options::FindBackground)); - - LVCOLUMN col = {0}; - col.mask = LVCF_WIDTH | LVCF_TEXT; - col.cx = 470; - col.pszText = _T(""); - ListView_InsertColumn(listWindow, 0, &col); - ListView_SetColumnWidth(listWindow, 0, LVSCW_AUTOSIZE_USEHEADER); - ListView_SetExtendedListViewStyleEx(listWindow, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); - COLORREF bkColor = Options::instance->GetColor(Options::GroupListBackground); - ListView_SetBkColor(listWindow, bkColor); - ListView_SetTextBkColor(listWindow, bkColor); - LOGFONT font; - ListView_SetTextColor(listWindow, Options::instance->GetFont(Options::GroupList, &font)); - - Edit_LimitText(findWindow, 100); - RegisterHotkeyControl(findWindow); - - HIMAGELIST himlButtons = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 3, 3); - if(himlButtons) - { - findNextIco = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hFindNextIcon); - ImageList_AddIcon(himlButtons, findNextIco); - findPrevIco = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hFindPrevIcon); - ImageList_AddIcon(himlButtons, findPrevIco); - configIco = LoadSkinnedIcon(SKINICON_OTHER_OPTIONS); - ImageList_AddIcon(himlButtons, configIco); - deleteIco = LoadSkinnedIcon(SKINICON_OTHER_DELETE); - ImageList_AddIcon(himlButtons, deleteIco); - - // Set the image list. - SendMessage(toolbarWindow, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)himlButtons); - - // Load the button images. - SendMessage(toolbarWindow, TB_LOADIMAGES, (WPARAM)IDB_STD_SMALL_COLOR, (LPARAM)HINST_COMMCTRL); - } - - TBBUTTON tbButtons[] = - { - { 0, IDM_FIND, TBSTATE_ENABLED, BTNS_DROPDOWN, {0}, 0, (INT_PTR)TranslateT("Find Next") }, - { 3, IDM_DELETE, TBSTATE_ENABLED, BTNS_DROPDOWN, {0}, 0, (INT_PTR)TranslateT("Delete")}, - { 2, IDM_CONFIG, TBSTATE_ENABLED, BTNS_DROPDOWN, {0}, 0, (INT_PTR)TranslateT("Options")}, - }; - SendMessage(toolbarWindow, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); - SendMessage(toolbarWindow, TB_ADDBUTTONS, (WPARAM)SIZEOF(tbButtons), (LPARAM)&tbButtons); - SendMessage(toolbarWindow, TB_SETBUTTONSIZE, 0, MAKELPARAM(16, 16)); - SendMessage(toolbarWindow, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS); - SendMessage(toolbarWindow, TB_SETMAXTEXTROWS, 0, 0); - - SetDefFilter(Options::instance->defFilter); - - SendMessage(hWnd, DM_SETDEFID, IDM_FIND, 0); - SendMessage(hWnd, WM_SIZE, 0, 0); - SendMessage(hWnd,DM_HREBUILD,0,0); - isDestroyed = false; -} - -void HistoryWindow::Destroy() -{ - HICON hIcon = (HICON)SendMessage(hWnd, WM_SETICON, ICON_BIG, 0); - CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0); - - hIcon = (HICON)SendMessage(hWnd, WM_SETICON, ICON_SMALL, 0); - CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0); - - UnregisterHotkeyControl(GetDlgItem(hWnd, IDC_SHOWHIDE)); - UnregisterHotkeyControl(GetDlgItem(hWnd, IDC_LIST_CONTACTS)); - UnregisterHotkeyControl(findWindow); - - isDestroyed = true; - HistoryWindow::Close(this); -} - -void HistoryWindow::SplitterMoved(HWND splitter, LONG pos, bool screenPos) -{ - POINT pt; - RECT rc1; - RECT rc2; - POINT pt1; - POINT pt2; - - if(splitter == splitterXhWnd) - { - GetWindowRect(listWindow, &rc1); - GetWindowRect(editWindow, &rc2); - pt.x = 0; - pt.y = pos; - pt1.x = rc1.left; - pt1.y = rc1.top; - pt2.x = rc2.right; - pt2.y = rc2.bottom; - if(screenPos) - ScreenToClient(hWnd, &pt); - ScreenToClient(hWnd, &pt1); - ScreenToClient(hWnd, &pt2); - if ((pt.y >= pt1.y + MIN_PANELHEIGHT) && (pt.y < pt2.y - MIN_PANELHEIGHT)) - { - splitterY = pt.y; - if(!screenPos) - SendMessage(hWnd, WM_SIZE, 0, 0); - //if(M->isAero()) - // InvalidateRect(GetParent(hwndDlg), NULL, FALSE); - } - } - else - { - GetWindowRect(GetDlgItem(hWnd, IDC_LIST_CONTACTS), &rc1); - GetWindowRect(listWindow, &rc2); - pt.x = pos; - pt.y = 0; - pt1.x = rc1.left; - pt1.y = rc1.top; - pt2.x = rc2.right; - pt2.y = rc2.bottom; - if(screenPos) - ScreenToClient(hWnd, &pt); - ScreenToClient(hWnd, &pt1); - ScreenToClient(hWnd, &pt2); - if ((pt.x >= pt1.x + MIN_PANELHEIGHT) && (pt.x < pt2.x - MIN_PANELHEIGHT)) - { - splitterX = pt.x; - if(!screenPos) - SendMessage(hWnd, WM_SIZE, 0, 0); - //if(M->isAero()) - // InvalidateRect(GetParent(hwndDlg), NULL, FALSE); - } - } -} - -int HistoryWindow::HistoryDlgResizer(HWND hwnd, LPARAM, UTILRESIZECONTROL *urc) -{ - HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwnd,GWLP_USERDATA); - switch(urc->wId) { - case IDC_LIST: - { - urc->rcItem.bottom += historyWindow->splitterY - historyWindow->splitterOrgY; - urc->rcItem.left += historyWindow->splitterX - historyWindow->splitterOrgX; - if(!historyWindow->isContactList) - urc->rcItem.left = historyWindow->listOryginalPos; - return RD_ANCHORX_WIDTH|RD_ANCHORY_TOP; - } - case IDC_LIST_CONTACTS: - { - urc->rcItem.right += historyWindow->splitterX - historyWindow->splitterOrgX; - return RD_ANCHORX_LEFT|RD_ANCHORY_HEIGHT; - } - case IDC_SPLITTER: - { - urc->rcItem.top += historyWindow->splitterY - historyWindow->splitterOrgY; - urc->rcItem.bottom += historyWindow->splitterY - historyWindow->splitterOrgY; - urc->rcItem.left += historyWindow->splitterX - historyWindow->splitterOrgX; - if(!historyWindow->isContactList) - urc->rcItem.left = 0; - return RD_ANCHORX_WIDTH|RD_ANCHORY_TOP; - } - case IDC_SPLITTERV: - { - urc->rcItem.left += historyWindow->splitterX - historyWindow->splitterOrgX; - urc->rcItem.right += historyWindow->splitterX - historyWindow->splitterOrgX; - return RD_ANCHORX_LEFT|RD_ANCHORY_HEIGHT; - } - case IDC_EDIT: - { - urc->rcItem.top += historyWindow->splitterY - historyWindow->splitterOrgY; - urc->rcItem.left += historyWindow->splitterX - historyWindow->splitterOrgX; - if(!historyWindow->isContactList) - urc->rcItem.left = historyWindow->listOryginalPos; - return RD_ANCHORX_WIDTH|RD_ANCHORY_HEIGHT; - } - case IDC_FIND_TEXT: - return RD_ANCHORX_WIDTH|RD_ANCHORY_TOP; - case IDC_SHOWHIDE: - return RD_ANCHORX_LEFT|RD_ANCHORY_TOP; - case IDC_TOOLBAR: - return RD_ANCHORX_RIGHT|RD_ANCHORY_TOP; - } - return RD_ANCHORX_LEFT|RD_ANCHORY_TOP; -} - -void HistoryWindow::FillHistoryThread(void* param) -{ - HistoryWindow *hInfo = ( HistoryWindow* )param; - HWND hwndList = hInfo->listWindow; - ListView_DeleteAllItems(hwndList); - hInfo->SelectEventGroup(-1); - hInfo->EnableWindows(FALSE); - bool isNewOnTop = Options::instance->groupNewOnTop; - - hInfo->RefreshEventList(); - - LVITEM item = {0}; - item.mask = LVIF_STATE; - item.iItem = 0; - item.state = LVIS_SELECTED; - item.stateMask = LVIS_SELECTED; - if(!isNewOnTop) - { - item.iItem = ListView_GetItemCount(hwndList) - 1; - if(item.iItem < 0) - item.iItem = 0; - } - - ListView_SetItem(hwndList, &item); - ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE_USEHEADER); - ListView_EnsureVisible(hwndList, item.iItem, FALSE); - hInfo->EnableWindows(TRUE); - SetFocus(hwndList); -} - -void HistoryWindow::AddGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText, int ico) -{ - TCHAR msg[256]; - msg[0] = 0; - if(Options::instance->groupShowTime) - { - _tcscpy_s(msg, time.c_str()); - } - if(Options::instance->groupShowName) - { - if(msg[0] != 0) - _tcscat_s(msg, _T(" ")); - _tcscat_s(msg, user.c_str()); - } - - if(Options::instance->groupShowMessage) - { - if(msg[0] != 0) - _tcscat_s(msg, _T(" ")); - _tcscat_s(msg, eventText.c_str()); - } - - LVITEM item = {0}; - item.mask = LVIF_TEXT | LVIF_IMAGE; - item.iItem = MAXINT; - item.pszText = msg; - item.iImage = ico; - ListView_InsertItem(listWindow, &item); -} - -void HistoryWindow::ReplaceIcons(HWND hwndDlg, int selStart, BOOL isSent) -{ - if(g_SmileyAddAvail) - { - CHARRANGE sel; - SMADD_RICHEDIT3 smadd = {0}; - - sel.cpMin = selStart; - sel.cpMax = -1; - - smadd.cbSize = sizeof(smadd); - smadd.hwndRichEditControl = hwndDlg; - smadd.Protocolname = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - smadd.hContact = hContact; - smadd.flags = isSent ? SAFLRE_OUTGOING : 0; - if (selStart > 0) - smadd.rangeToReplace = &sel; - CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&smadd); - } -} - -void SetFontFromOptions(ITextFont *TextFont, int caps, Options::Fonts fontId) -{ - COLORREF fontColor; - LOGFONT font; - fontColor = Options::instance->GetFont(fontId, &font); - BSTR bstrFont = SysAllocString(font.lfFaceName); - TextFont->SetName(bstrFont); - SysFreeString(bstrFont); - TextFont->SetForeColor(fontColor); - TextFont->SetWeight(font.lfWeight); - font.lfHeight = (font.lfHeight * 72) / caps; - TextFont->SetSize(font.lfHeight < 0 ? -font.lfHeight : font.lfHeight); - TextFont->SetItalic(font.lfItalic ? tomTrue : tomFalse); - TextFont->SetItalic(font.lfUnderline ? tomTrue : tomFalse); - TextFont->SetItalic(font.lfStrikeOut ? tomTrue : tomFalse); -} - -void HistoryWindow::SelectEventGroup(int sel) -{ - SendMessage(editWindow, WM_SETTEXT, 0, (LPARAM)_T("")); - currentGroup.clear(); - selected = sel; - if(sel < 0 || sel >= (int)eventList.size()) - return; - - TCHAR _str[MAXSELECTSTR + 8]; // for safety reason - TCHAR *str = _str + sizeof(int)/sizeof(TCHAR); - BSTR pStr = str; - unsigned int *strLen = (unsigned int*)_str; - str[0] = 0; - tm lastTime; - bool isFirst = true; - bool lastMe = false; - long startAt, endAt; - long cnt; - std::wstring strStl; - IRichEditOle* RichEditOle; - EventData data; - if (SendMessage(editWindow, EM_GETOLEINTERFACE, 0, (LPARAM)&RichEditOle) == 0) - return; - ITextDocument* TextDocument; - if (RichEditOle->QueryInterface(IID_ITextDocument, (void**)&TextDocument) != S_OK) - { - RichEditOle->Release(); - return; - } - ITextSelection* TextSelection; - ITextFont *TextFont; - SendMessage(editWindow, EM_SETREADONLY, FALSE, 0); - TextDocument->Freeze(&cnt); - TextDocument->GetSelection(&TextSelection); - HDC hDC = GetDC(NULL); - int caps = GetDeviceCaps(hDC, LOGPIXELSY); - std::deque revDeq; - std::deque& deq = eventList[sel]; - if(Options::instance->messagesNewOnTop) - { - revDeq.insert(revDeq.begin(), deq.rbegin(), deq.rend()); - deq = revDeq; - } - COLORREF backColor = GetSysColor(COLOR_WINDOW); - for(std::deque::iterator it = deq.begin(); it != deq.end(); ++it) - { - EventIndex hDbEvent = *it; - if(GetEventData(hDbEvent, data)) - { - bool isUser = Options::instance->messagesShowName && (isFirst || (!lastMe && data.isMe) || (lastMe && !data.isMe)); - lastMe = data.isMe; - backColor = Options::instance->GetColor(lastMe ? Options::OutBackground : Options::InBackground); - if(Options::instance->messagesShowEvents) - { - str[0] = _T('>'); - str[1] = 0; - *strLen = 1 * sizeof(TCHAR); - TextSelection->SetStart(MAXLONG); - TextSelection->GetFont(&TextFont); - TextFont->SetBackColor(backColor); - TextSelection->SetText(pStr); - TextFont->Release(); - int imId; - HICON ico; - if(GetEventIcon(lastMe, data.eventType, imId)) - { - ico = eventIcoms[imId]; - } - else - { - ico = GetEventCoreIcon(hDbEvent); - if(ico == NULL) - { - ico = eventIcoms[imId]; - } - } - - ImageDataObject::InsertIcon(RichEditOle, ico, backColor, 16, 16); - } - - TCHAR* formatDate = Options::instance->messagesShowSec ? (isUser ? _T("d s ") : _T("d s\n")) : (isUser ? _T("d t ") : _T("d t\n")); - if(!Options::instance->messagesShowDate) - { - if(isFirst) - { - isFirst = false; - formatDate = Options::instance->messagesShowSec ? (isUser ? _T("s ") : _T("s\n")) : (isUser ? _T("t ") : _T("t\n")); - time_t tt = data.timestamp; - localtime_s(&lastTime, &tt); - } - else - { - time_t tt = data.timestamp; - tm t; - localtime_s(&t, &tt); - if(lastTime.tm_yday == t.tm_yday && lastTime.tm_year == t.tm_year) - formatDate = Options::instance->messagesShowSec ? (isUser ? _T("s ") : _T("s\n")) : (isUser ? _T("t ") : _T("t\n")); - } - } - - tmi.printTimeStamp(NULL, data.timestamp, formatDate, str , MAXSELECTSTR, 0); - *strLen = (unsigned int)_tcslen(str) * sizeof(TCHAR); - TextSelection->SetStart(MAXLONG); - TextSelection->GetFont(&TextFont); - SetFontFromOptions(TextFont, caps, lastMe ? Options::OutTimestamp : Options::InTimestamp); - TextFont->SetBackColor(backColor); - TextSelection->SetText(pStr); - TextFont->Release(); - - if(isUser) - { - if(lastMe) - mir_sntprintf( str, MAXSELECTSTR, _T("%s\n"), myName ); - else - mir_sntprintf( str, MAXSELECTSTR, _T("%s\n"), contactName ); - *strLen = (unsigned int)_tcslen(str) * sizeof(TCHAR); - TextSelection->SetStart(MAXLONG); - TextSelection->GetFont(&TextFont); - SetFontFromOptions(TextFont, caps, lastMe ? Options::OutName : Options::InName); - TextSelection->SetText(pStr); - TextFont->Release(); - } - - GetEventMessage(hDbEvent, str); - strStl = str; - size_t i = strStl.length(); - if(i + 1 >= MAXSELECTSTR) - continue; - str[i++] = _T('\n'); - str[i] = 0; - *strLen = (unsigned int)i * sizeof(TCHAR); - TextSelection->SetStart(MAXLONG); - TextSelection->GetFont(&TextFont); - SetFontFromOptions(TextFont, caps, lastMe ? Options::OutMessages : Options::InMessages); - TextFont->SetBackColor(backColor); - TextSelection->GetStart(&startAt); - TextSelection->SetText(pStr); - TextFont->Release(); - - if(Options::instance->messagesUseSmileys) - ReplaceIcons(editWindow, startAt, lastMe); - TextSelection->SetStart(MAXLONG); - TextSelection->GetStart(&endAt); - currentGroup.push_back(MessageData(strStl, startAt, endAt, lastMe, data.timestamp)); - } - } - - TextSelection->SetRange(0, 0); - TextSelection->Release(); - TextDocument->Unfreeze(&cnt); - TextDocument->Release(); - RichEditOle->Release(); - SendMessage(editWindow, EM_SETREADONLY, TRUE, 0); - SendMessage(editWindow,EM_SETBKGNDCOLOR,0, backColor); - if (cnt == 0) - { - UpdateWindow(editWindow); - } -} - -LRESULT CALLBACK HistoryWindow::SplitterSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HWND hwndParent = GetParent(hwnd); - HistoryWindow *dat = (HistoryWindow*)GetWindowLongPtr(hwndParent, GWLP_USERDATA); - if(dat == NULL || dat->isDestroyed) - return FALSE; - - switch (msg) { - case WM_NCHITTEST: - return HTCLIENT; - case WM_SETCURSOR: { - RECT rc; - GetClientRect(hwnd, &rc); - SetCursor(rc.right > rc.bottom ? hCurSplitNS : hCurSplitWE); - return TRUE; - } - case WM_LBUTTONDOWN: { - SetCapture(hwnd); - return 0; - } - case WM_MOUSEMOVE: - if (GetCapture() == hwnd) { - RECT rc; - GetClientRect(hwnd, &rc); - SendMessage(hwndParent, DM_SPLITTERMOVED, rc.right > rc.bottom ? (short) HIWORD(GetMessagePos()) + rc.bottom / 2 : (short) LOWORD(GetMessagePos()) + rc.right / 2, (LPARAM) hwnd); - } - return 0; - case WM_ERASEBKGND: - return(1); - case WM_LBUTTONUP: { - HWND hwndCapture = GetCapture(); - - ReleaseCapture(); - SendMessage(hwndParent, WM_SIZE, 0, 0); - RedrawWindow(hwndParent, NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW); - return 0; - } - } - return CallWindowProc(dat->OldSplitterProc, hwnd, msg, wParam, lParam); -} - -void HistoryWindow::EnableWindows(BOOL enable) -{ - EnableWindow(GetDlgItem(hWnd,IDC_LIST_CONTACTS), enable); - EnableWindow(listWindow, enable); - EnableWindow(findWindow, enable); - EnableWindow(toolbarWindow, enable); - isLoading = !enable; -} - -void HistoryWindow::ReloadContacts() -{ - HWND contactList = GetDlgItem(hWnd,IDC_LIST_CONTACTS); - if(EventList::GetContactMessageNumber(NULL)) - { - if(hSystem == NULL) - { - CLCINFOITEM cii = { 0 }; - cii.cbSize = sizeof(cii); - cii.flags = CLCIIF_GROUPFONT | CLCIIF_BELOWCONTACTS; - cii.pszText = TranslateT("System"); - hSystem = (HANDLE) SendMessage(contactList, CLM_ADDINFOITEM, 0, (LPARAM) & cii); - } - } - else - { - if(hSystem != NULL) - { - SendMessage(contactList, CLM_DELETEITEM, (WPARAM)hSystem, 0); - hSystem = NULL; - } - } - - HANDLE _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while(_hContact) - { - if(EventList::GetContactMessageNumber(_hContact) && (metaContactProto == NULL || DBGetContactSettingByte(_hContact, metaContactProto, "IsSubcontact", 0) == 0)) - { - HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); - if(hItem == NULL) - { - SendMessage(contactList, CLM_ADDCONTACT, (WPARAM)_hContact, 0); - } - } - else - { - HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); - if(hItem != NULL) - { - SendMessage(contactList, CLM_DELETEITEM, (WPARAM)_hContact, 0); - } - } - - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); - } - - if(hContact != NULL) - { - HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)hContact, 0); - if(hItem != NULL) - { - SendMessage(contactList, CLM_ENSUREVISIBLE, (WPARAM)hItem, 0); - SendMessage(contactList, CLM_SELECTITEM, (WPARAM)hItem, 0); - } - } - else if(hSystem != NULL) - { - SendMessage(contactList, CLM_ENSUREVISIBLE, (WPARAM)hSystem, 0); - SendMessage(contactList, CLM_SELECTITEM, (WPARAM)hSystem, 0); - } -} - -bool HistoryWindow::DoHotkey(UINT msg, LPARAM lParam, WPARAM wParam, int window) -{ - MSG message; - message.hwnd = hWnd; - message.message = msg; - message.lParam = lParam; - message.wParam = wParam; - LRESULT mim_hotkey_check = CallService(MS_HOTKEY_CHECK, (WPARAM)&message, (LPARAM)("History")); - switch(mim_hotkey_check) - { - case HISTORY_HK_FIND: - SetFocus(findWindow); - Edit_SetSel(findWindow, 0, -1); - break; - case HISTORY_HK_FINDNEXT: - searcher.ChangeFindDirection(false); - break; - case HISTORY_HK_FINDPREV: - searcher.ChangeFindDirection(true); - break; - case HISTORY_HK_MATCHCASE: - searcher.SetMatchCase(!searcher.IsMatchCase()); - break; - case HISTORY_HK_MATCHWHOLE: - searcher.SetMatchWholeWords(!searcher.IsMatchWholeWords()); - break; - case HISTORY_HK_SHOWCONTACTS: - Button_SetCheck(GetDlgItem(hWnd, IDC_SHOWHIDE), Button_GetCheck(GetDlgItem(hWnd, IDC_SHOWHIDE)) & BST_CHECKED ? BST_UNCHECKED : BST_CHECKED); - SendMessage(hWnd, WM_COMMAND, MAKELONG(IDC_SHOWHIDE, BN_CLICKED), NULL); - break; - case HISTORY_HK_ONLYIN: - searcher.SetOnlyIn(!searcher.IsOnlyIn()); - break; - case HISTORY_HK_ONLYOUT: - searcher.SetOnlyOut(!searcher.IsOnlyOut()); - break; - case HISTORY_HK_ONLYGROUP: - searcher.SetOnlyGroup(!searcher.IsOnlyGroup()); - break; - case HISTORY_HK_ALLCONTACTS: - searcher.SetAllUsers(!searcher.IsAllUsers()); - break; - case HISTORY_HK_EXRHTML: - { - ExportManager exp(hWnd, hContact, GetFilterNr()); - exp.Export(IExport::RichHtml); - } - break; - case HISTORY_HK_EXPHTML: - { - ExportManager exp(hWnd, hContact, GetFilterNr()); - exp.Export(IExport::PlainHtml); - } - break; - case HISTORY_HK_EXTXT: - { - ExportManager exp(hWnd, hContact, GetFilterNr()); - exp.Export(IExport::Txt); - } - break; - case HISTORY_HK_EXBIN: - { - ExportManager exp(hWnd, hContact, GetFilterNr()); - exp.Export(IExport::Binary); - } - break; - case HISTORY_HK_EXDAT: - { - ExportManager exp(hWnd, hContact, GetFilterNr()); - exp.Export(IExport::Dat); - } - break; - case HISTORY_HK_IMPBIN: - { - DoImport(IImport::Binary); - } - break; - case HISTORY_HK_IMPDAT: - { - DoImport(IImport::Dat); - } - break; - case HISTORY_HK_DELETE: - { - int what = window == IDC_EDIT ? 0 : (window == IDC_LIST ? 1 : (window == IDC_LIST_CONTACTS ? 2 : -1)); - Delete(what); - return what != -1; - } - break; - default: - return false; - } - - return true; -} - -void HistoryWindow::RestorePos() -{ - HANDLE contactToLoad = hContact; - if(hContact == NULL) - { - Utils_RestoreWindowPosition(hWnd,NULL,MODULE,"history_"); - contactToLoad = NULL; - } - else if(Utils_RestoreWindowPosition(hWnd,hContact,MODULE,"history_") != 0) - { - Utils_RestoreWindowPosition(hWnd,NULL,MODULE,"history_"); - contactToLoad = NULL; - } - if(DBGetContactSettingByte(contactToLoad, MODULE, "history_ismax", 0)) - { - ShowWindow(hWnd, SW_SHOWMAXIMIZED); - } - - LONG pos = DBGetContactSettingDword(contactToLoad, MODULE, "history_splitterv", 0); - if(pos > 0) - { - SplitterMoved(splitterYhWnd, pos, false); - } - - pos = DBGetContactSettingDword(contactToLoad, MODULE, "history_splitter", 0); - if(pos > 0) - { - SplitterMoved(splitterXhWnd, pos, false); - } -} - -void HistoryWindow::SavePos(bool all) -{ - HANDLE contactToSave = hContact; - if(all) - { - HANDLE _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while(_hContact) - { - DBDeleteContactSetting(_hContact, MODULE, "history_x"); - DBDeleteContactSetting(_hContact, MODULE, "history_y"); - DBDeleteContactSetting(_hContact, MODULE, "history_width"); - DBDeleteContactSetting(_hContact, MODULE, "history_height"); - DBDeleteContactSetting(_hContact, MODULE, "history_ismax"); - DBDeleteContactSetting(_hContact, MODULE, "history_splitterv"); - DBDeleteContactSetting(_hContact, MODULE, "history_splitter"); - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); - } - - contactToSave = NULL; - } - - Utils_SaveWindowPosition(hWnd,contactToSave,MODULE,"history_"); - WINDOWPLACEMENT wp; - wp.length=sizeof(wp); - GetWindowPlacement(hWnd,&wp); - DBWriteContactSettingByte(contactToSave, MODULE, "history_ismax", wp.showCmd == SW_MAXIMIZE ? 1 : 0); - DBWriteContactSettingDword(contactToSave, MODULE, "history_splitterv", splitterX); - DBWriteContactSettingDword(contactToSave, MODULE, "history_splitter", splitterY); -} - -#define DEF_FILTERS_START 50000 -void HistoryWindow::FindToolbarClicked(LPNMTOOLBAR lpnmTB) -{ - RECT rc; - SendMessage(lpnmTB->hdr.hwndFrom, TB_GETRECT, (WPARAM)lpnmTB->iItem, (LPARAM)&rc); - MapWindowPoints(lpnmTB->hdr.hwndFrom, HWND_DESKTOP, (LPPOINT)&rc, 2); - HMENU hPopupMenu = CreatePopupMenu(); - if(hPopupMenu != NULL) - { - AppendMenu(hPopupMenu, MF_STRING, IDM_FINDNEXT, TranslateT("Find Next")); - AppendMenu(hPopupMenu, MF_STRING, IDM_FINDPREV, TranslateT("Find Previous")); - AppendMenu(hPopupMenu, MFT_SEPARATOR, 0, NULL); - AppendMenu(hPopupMenu, searcher.IsMatchCase() ? MF_STRING | MF_CHECKED : MF_STRING, IDM_MATCHCASE, TranslateT("Match Case")); - AppendMenu(hPopupMenu, searcher.IsMatchWholeWords() ? MF_STRING | MF_CHECKED : MF_STRING, IDM_MATCHWHOLE, TranslateT("Match Whole Word")); - AppendMenu(hPopupMenu, searcher.IsOnlyIn() ? MF_STRING | MF_CHECKED : MF_STRING, IDM_ONLYIN, TranslateT("Only Incomming Messages")); - AppendMenu(hPopupMenu, searcher.IsOnlyOut() ? MF_STRING | MF_CHECKED : MF_STRING, IDM_ONLYOUT, TranslateT("Only Outgoing Messages")); - AppendMenu(hPopupMenu, searcher.IsOnlyGroup() ? MF_STRING | MF_CHECKED : MF_STRING, IDM_ONLYGROUP, TranslateT("Only Selected Group")); - AppendMenu(hPopupMenu, searcher.IsAllUsers() ? MF_STRING | MF_CHECKED : MF_STRING, IDM_ALLUSERS, TranslateT("All Contacts")); - AppendMenu(hPopupMenu, MFT_SEPARATOR, 0, NULL); - HMENU hFilterMenu = CreatePopupMenu(); - int filter = GetFilterNr(); - AppendMenu(hFilterMenu, filter == 0 ? MF_STRING | MF_CHECKED : MF_STRING, IDM_FILTERDEF, TranslateT("Default history events")); - AppendMenu(hFilterMenu, filter == 1 ? MF_STRING | MF_CHECKED : MF_STRING, IDM_FILTERALL, TranslateT("All events")); - for(size_t i = 0 ; i < Options::instance->customFilters.size(); ++i) - { - UINT flags = MF_STRING; - if(filter - 2 == i) - flags |= MF_CHECKED; - - AppendMenu(hFilterMenu, flags, DEF_FILTERS_START + i, Options::instance->customFilters[i].name.c_str()); - } - AppendMenu(hPopupMenu, MF_STRING | MF_POPUP, (UINT_PTR)hFilterMenu, TranslateT("Filters")); - if(searcher.IsFindBack()) - SetMenuDefaultItem(hPopupMenu, IDM_FINDPREV, FALSE); - else - SetMenuDefaultItem(hPopupMenu, IDM_FINDNEXT, FALSE); - - int selected = TrackPopupMenu(hPopupMenu, TPM_RETURNCMD, rc.left, rc.bottom, 0, hWnd, 0); - switch (selected) - { - case IDM_FINDNEXT: - searcher.ChangeFindDirection(false); - break; - case IDM_FINDPREV: - searcher.ChangeFindDirection(true); - break; - case IDM_MATCHCASE: - searcher.SetMatchCase(!searcher.IsMatchCase()); - break; - case IDM_MATCHWHOLE: - searcher.SetMatchWholeWords(!searcher.IsMatchWholeWords()); - break; - case IDM_ONLYIN: - searcher.SetOnlyIn(!searcher.IsOnlyIn()); - break; - case IDM_ONLYOUT: - searcher.SetOnlyOut(!searcher.IsOnlyOut()); - break; - case IDM_ONLYGROUP: - searcher.SetOnlyGroup(!searcher.IsOnlyGroup()); - break; - case IDM_ALLUSERS: - searcher.SetAllUsers(!searcher.IsAllUsers()); - break; - case IDM_FILTERDEF: - SetDefFilter(0); - SendMessage(hWnd,DM_HREBUILD,0,0); - break; - case IDM_FILTERALL: - SetDefFilter(1); - SendMessage(hWnd,DM_HREBUILD,0,0); - break; - default: - if(selected >= DEF_FILTERS_START) - { - SetDefFilter(selected - DEF_FILTERS_START + 2); - SendMessage(hWnd,DM_HREBUILD,0,0); - } - break; - } - - DestroyMenu(hFilterMenu); - DestroyMenu(hPopupMenu); - } -} - -void HistoryWindow::ConfigToolbarClicked(LPNMTOOLBAR lpnmTB) -{ - RECT rc; - SendMessage(lpnmTB->hdr.hwndFrom, TB_GETRECT, (WPARAM)lpnmTB->iItem, (LPARAM)&rc); - MapWindowPoints(lpnmTB->hdr.hwndFrom, HWND_DESKTOP, (LPPOINT)&rc, 2); - HMENU hPopupMenu = CreatePopupMenu(); - if(hPopupMenu != NULL) - { - AppendMenu(hPopupMenu, MF_STRING, IDM_OPTIONS, TranslateT("Options")); - AppendMenu(hPopupMenu, MF_STRING, IDM_FONTS, TranslateT("Fonts & Colors")); - AppendMenu(hPopupMenu, MF_STRING, IDM_ICONS, TranslateT("Icons")); - AppendMenu(hPopupMenu, MF_STRING, IDM_HOTKEYS, TranslateT("Hotkeys")); - AppendMenu(hPopupMenu, MFT_SEPARATOR, 0, NULL); - - HMENU hExportMenu = CreatePopupMenu(); - AppendMenu(hExportMenu, MF_STRING, IDM_EXPORTRHTML, TranslateT("Rich Html")); - AppendMenu(hExportMenu, MF_STRING, IDM_EXPORTPHTML, TranslateT("Plain Html")); - AppendMenu(hExportMenu, MF_STRING, IDM_EXPORTTXT, TranslateT("Txt")); - AppendMenu(hExportMenu, MF_STRING, IDM_EXPORTBINARY, TranslateT("Binary")); - AppendMenu(hExportMenu, MF_STRING, IDM_EXPORTDAT, TranslateT("Dat (mContacts)")); - - HMENU hImportMenu = CreatePopupMenu(); - AppendMenu(hImportMenu, MF_STRING, IDM_IMPORTBINARY, TranslateT("Binary")); - AppendMenu(hImportMenu, MF_STRING, IDM_IMPORTDAT, TranslateT("Dat (mContacts)")); - - AppendMenu(hPopupMenu, MF_STRING | MF_POPUP, (UINT_PTR)hExportMenu, TranslateT("Export")); - AppendMenu(hPopupMenu, MF_STRING | MF_POPUP, (UINT_PTR)hImportMenu, TranslateT("Import")); - - AppendMenu(hPopupMenu, MFT_SEPARATOR, 0, NULL); - AppendMenu(hPopupMenu, MF_STRING, IDM_SAVEPOS, TranslateT("Save window position as default")); - AppendMenu(hPopupMenu, MF_STRING, IDM_SAVEPOSALL, TranslateT("Save window position for all contacts")); - SetMenuDefaultItem(hPopupMenu, IDM_OPTIONS, FALSE); - - int selected = TrackPopupMenu(hPopupMenu, TPM_RETURNCMD, rc.left, rc.bottom, 0, hWnd, 0); - switch (selected) - { - case IDM_OPTIONS: - SendMessage(hWnd, WM_COMMAND, IDM_CONFIG, 0); - break; - case IDM_FONTS: - OpenOptions("Customize", "Fonts & Colors"); - break; - case IDM_ICONS: - OpenOptions("Customize", "Icons"); - break; - case IDM_HOTKEYS: - OpenOptions("Customize", "Hotkeys"); - break; - case IDM_SAVEPOS: - SavePos(false); - break; - case IDM_SAVEPOSALL: - SavePos(true); - break; - case IDM_EXPORTRHTML: - { - ExportManager exp(hWnd, hContact, GetFilterNr()); - exp.Export(IExport::RichHtml); - } - - break; - case IDM_EXPORTPHTML: - { - ExportManager exp(hWnd, hContact, GetFilterNr()); - exp.Export(IExport::PlainHtml); - } - - break; - case IDM_EXPORTTXT: - { - ExportManager exp(hWnd, hContact, GetFilterNr()); - exp.Export(IExport::Txt); - } - - break; - case IDM_EXPORTBINARY: - { - ExportManager exp(hWnd, hContact, GetFilterNr()); - exp.Export(IExport::Binary); - } - - break; - case IDM_EXPORTDAT: - { - ExportManager exp(hWnd, hContact, GetFilterNr()); - exp.Export(IExport::Dat); - } - - break; - case IDM_IMPORTBINARY: - { - DoImport(IImport::Binary); - } - - break; - case IDM_IMPORTDAT: - { - DoImport(IImport::Dat); - } - - break; - } - - DestroyMenu(hExportMenu); - DestroyMenu(hImportMenu); - DestroyMenu(hPopupMenu); - } -} - -void HistoryWindow::DoImport(IImport::ImportType type) -{ - ExportManager exp(hWnd, hContact, GetFilterNr()); - std::vector messages; - std::wstring err; - if(exp.Import(type, messages, &err)) - { - int act = MessageBox(hWnd, TranslateT("Do you want save imported messages to local profile?"), TranslateT("Import"), MB_ICONQUESTION | MB_YESNOCANCEL | MB_DEFBUTTON2); - if(act == IDYES) - { - MargeMessages(messages); - HistoryWindow::RebuildEvents(hContact); - } - else if(act == IDNO) - { - EventList::AddImporter(hContact, type, exp.GetFileName()); - HistoryWindow::RebuildEvents(hContact); - } - } - else if(!err.empty()) - { - MessageBox(hWnd, err.c_str(), TranslateT("Error"), MB_ICONERROR); - } -} - -void HistoryWindow::DeleteToolbarClicked(LPNMTOOLBAR lpnmTB) -{ - RECT rc; - SendMessage(lpnmTB->hdr.hwndFrom, TB_GETRECT, (WPARAM)lpnmTB->iItem, (LPARAM)&rc); - MapWindowPoints(lpnmTB->hdr.hwndFrom, HWND_DESKTOP, (LPPOINT)&rc, 2); - HMENU hPopupMenu = CreatePopupMenu(); - if(hPopupMenu != NULL) - { - AppendMenu(hPopupMenu, MF_STRING, IDM_DELETE, TranslateT("Delete")); - AppendMenu(hPopupMenu, MF_STRING, IDM_DELETEGROUP, TranslateT("Delete Group")); - AppendMenu(hPopupMenu, MF_STRING, IDM_DELETEUSER, TranslateT("Delete All User History")); - SetMenuDefaultItem(hPopupMenu, IDM_DELETE, FALSE); - - int selected = TrackPopupMenu(hPopupMenu, TPM_RETURNCMD, rc.left, rc.bottom, 0, hWnd, 0); - switch (selected) - { - case IDM_DELETE: - Delete(0); - break; - case IDM_DELETEGROUP: - Delete(1); - break; - case IDM_DELETEUSER: - Delete(2); - break; - } - - DestroyMenu(hPopupMenu); - } -} - -void HistoryWindow::Delete(int what) -{ - int toDelete = 1; - size_t start = 0; - size_t end = 0; - if(selected < 0 || selected >= (int)eventList.size() || what > 2 || what < 0) - return; - if(what == 0) - { - CHARRANGE chrg; - SendMessage(editWindow,EM_EXGETSEL,0,(LPARAM)&chrg); - if(chrg.cpMin == 0 && chrg.cpMax == -1) - { - toDelete = (int)currentGroup.size(); - } - else - { - while(start < currentGroup.size() && chrg.cpMin >= currentGroup[start].endPos) ++start; - end = start; - while(end < currentGroup.size() && chrg.cpMax > currentGroup[end].endPos) ++end; - if(start >= currentGroup.size()) - return; - if(end < currentGroup.size()) - ++end; - toDelete = (int)(end - start); - } - } - else if(what == 1) - { - end = currentGroup.size(); - toDelete = (int)end; - } - else - { - if(eventList.size() == 0) - return; - toDelete = 1; - } - - if(toDelete == 0) - return; - TCHAR message[256]; - if(what == 2) - _tcscpy_s(message, TranslateT("This operation will PERMANENTLY REMOVE all history for this contact.\nAre you sure you want to do this?")); - else - _stprintf_s(message, TranslateT("Number of history items to delete: %d.\nAre you sure you want to do this?"), toDelete); - if(MessageBox(hWnd, message, TranslateT("Are You sure?"), MB_OKCANCEL | MB_ICONERROR) != IDOK) - return; - - bool areImpMessages = false; - bool rebuild = false; - if(what == 2) - { - for(size_t j = 0; j < eventList.size(); ++j) - { - for(size_t i = 0; i < eventList[j].size(); ++i) - { - DeleteEvent(eventList[j][i]); - } - } - - areImpMessages = EventList::IsImportedHistory(hContact); - rebuild = true; - } - else - { - for(size_t i = start; i < end; ++i) - { - EventIndex& ev = eventList[selected][i]; - DeleteEvent(ev); - areImpMessages |= ev.isExternal; - } - - if(start == 0 && end == currentGroup.size()) - { - rebuild = true; - } - else - { - rebuild = false; - } - } - - if(areImpMessages) - { - TCHAR *message = TranslateT("Do you want delete all imported messages for this contact?\nNote that next scheduler task import this messages again."); - if(MessageBox(hWnd, message, TranslateT("Are You sure?"), MB_YESNO | MB_ICONERROR) == IDYES) - { - EventList::DeleteImporter(hContact); - rebuild = true; - } - } - - if(rebuild) - { - RebuildEvents(hContact); - } - else - { - RebuildGroup(selected); - SelectEventGroup(selected); - } -} - -bool HistoryWindow::ContactChanged(bool sync) -{ - if(!isLoading) - { - HANDLE hItem = (HANDLE)SendDlgItemMessage(hWnd, IDC_LIST_CONTACTS, CLM_GETSELECTION, 0, 0); - if(hItem != NULL) - { - int typeOf = SendDlgItemMessage(hWnd, IDC_LIST_CONTACTS, CLM_GETITEMTYPE,(WPARAM)hItem,0); - if(typeOf == CLCIT_CONTACT) - { - if(hContact != hItem) - { - ChangeToFreeWindow(this); - isLoading = true; - hContact = hItem; - ReloadContacts(); - if(sync) - FillHistoryThread(this); - else - mir_forkthread(HistoryWindow::FillHistoryThread, this); - return true; - } - } - else if(typeOf == CLCIT_INFO && hSystem == hItem) - { - if(hContact != NULL) - { - ChangeToFreeWindow(this); - isLoading = true; - hContact = NULL; - ReloadContacts(); - if(sync) - FillHistoryThread(this); - else - mir_forkthread(HistoryWindow::FillHistoryThread, this); - return true; - } - } - } - } - - return false; -} - -void HistoryWindow::GroupImagesChanged() -{ - if(isGroupImages != Options::instance->groupShowEvents) - { - isGroupImages = Options::instance->groupShowEvents; - if(isGroupImages) - { - ListView_SetImageList(listWindow, himlSmall, LVSIL_SMALL); - } - else - { - ListView_SetImageList(listWindow, himlNone, LVSIL_SMALL); - } - } -} - -void HistoryWindow::FormatQuote(std::wstring& quote, const MessageData& md, const std::wstring& msg) -{ - if(md.isMe) - quote += myName; - else - quote += contactName; - TCHAR str[32]; - tmi.printTimeStamp(NULL, md.timestamp, _T("d t"), str , 32, 0); - quote += _T(", "); - quote += str; - quote += _T("\n"); - int f = 0; - do - { - int nf = (int)msg.find_first_of(_T("\r\n"), f); - if(nf >= 0 && nf < (int)msg.length()) - { - if(nf - f >= 0 ) - { - quote += _T(">"); - quote += msg.substr(f, nf - f); - quote += _T("\n"); - } - - f = nf + 1; - if(msg[nf] == _T('\r') && f < (int)msg.length() && msg[f] == _T('\n')) - ++f; - } - else if(msg.length() - f > 0) - { - quote += _T(">"); - quote += msg.substr(f, msg.length() - f); - quote += _T("\n"); - f = -1; - } - else - f = -1; - } - while(f > 0 && f < (int)msg.length()); -} - -HANDLE HistoryWindow::GetNextContact(HANDLE hContact, int adder) -{ - HWND contactList = GetDlgItem(hWnd,IDC_LIST_CONTACTS); - bool find = false; - HANDLE _hContact; - if(adder > 0) - { - if(hContact != NULL) - { - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); - while(_hContact) - { - HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); - if(hItem != NULL) - { - find = true; - break; - } - - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); - } - - if(!find && EventList::GetContactMessageNumber(NULL)) - { - _hContact = NULL; - find = true; - } - } - - if(!find) - { - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while(_hContact && _hContact != hContact) - { - HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); - if(hItem != NULL) - { - find = true; - break; - } - - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); - } - } - } - else - { - HANDLE lastContact = NULL; - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while(_hContact && _hContact != hContact) - { - HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); - if(hItem != NULL) - { - lastContact = _hContact; - } - - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); - } - - if(hContact != NULL) - { - if(lastContact == NULL && !EventList::GetContactMessageNumber(NULL)) - { - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); - while(_hContact) - { - HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); - if(hItem != NULL) - { - lastContact = _hContact; - } - - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); - } - } - - if(lastContact != NULL || EventList::GetContactMessageNumber(NULL)) - { - _hContact = lastContact; - find = true; - } - } - else if(lastContact != NULL) - { - _hContact = lastContact; - find = true; - } - } - - if(find) - { - return _hContact; - } - else - { - return hContact; - } -} - -void HistoryWindow::SelectContact(HANDLE _hContact) -{ - if(hContact != _hContact) - { - HWND contactList = GetDlgItem(hWnd,IDC_LIST_CONTACTS); - if(_hContact != NULL) - { - HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); - if(hItem != NULL) - { - SendMessage(contactList, CLM_ENSUREVISIBLE, (WPARAM)hItem, 0); - SendMessage(contactList, CLM_SELECTITEM, (WPARAM)hItem, 0); - } - } - else - { - SendMessage(contactList, CLM_ENSUREVISIBLE, (WPARAM)hSystem, 0); - SendMessage(contactList, CLM_SELECTITEM, (WPARAM)hSystem, 0); - } - - while(isLoading) - Sleep(100); - ContactChanged(true); - } -} - -void ResetCList(HWND hWnd) -{ - COLORREF bkCLColor = Options::instance->GetColor(Options::ContactListBackground); - SendDlgItemMessage(hWnd, IDC_LIST_CONTACTS, CLM_SETBKBITMAP, 0, (LPARAM)(HBITMAP) NULL); - SendDlgItemMessage(hWnd, IDC_LIST_CONTACTS, CLM_SETBKCOLOR, bkCLColor, 0); - SendDlgItemMessage(hWnd, IDC_LIST_CONTACTS, CLM_SETUSEGROUPS, Options::instance->showContactGroups, 0); -} diff --git a/plugins/BasicHistory/HistoryWindow.h b/plugins/BasicHistory/HistoryWindow.h deleted file mode 100644 index 8a31d9194a..0000000000 --- a/plugins/BasicHistory/HistoryWindow.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once -#include "Searcher.h" - -class HistoryWindow : public SearchContext -{ -private: - HistoryWindow(HANDLE _hContact); - void Initialise(); - void Destroy(); - void SplitterMoved(HWND splitter, LONG pos, bool screenPos); - static INT_PTR CALLBACK DlgProcHistory(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK SplitterSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - static int HistoryDlgResizer(HWND, LPARAM, UTILRESIZECONTROL *urc); - static void FillHistoryThread(void* param); - static void Close(HistoryWindow* historyWindow); - static void ChangeToFreeWindow(HistoryWindow* historyWindow); - void ReplaceIcons(HWND hwndDlg, int selStart, BOOL isSent); - void EnableWindows(BOOL enable); - void ReloadContacts(); - bool DoHotkey(UINT msg, LPARAM lParam, WPARAM wParam, int window); - void RestorePos(); - void SavePos(bool all); - void FindToolbarClicked(LPNMTOOLBAR lpnmTB); - void ConfigToolbarClicked(LPNMTOOLBAR lpnmTB); - void DeleteToolbarClicked(LPNMTOOLBAR lpnmTB); - void Delete(int what); - bool ContactChanged(bool sync = false); - void GroupImagesChanged(); - void FormatQuote(std::wstring& quote, const MessageData& md, const std::wstring& msg); - void FontsChanged(); - void ReloadMainOptions(); - void DoImport(IImport::ImportType type); - - static std::map windows; - static std::vector freeWindows; - bool isDestroyed; - LONG splitterY; - LONG splitterOrgY; - LONG splitterX; - LONG splitterOrgX; - HICON *eventIcoms; - int allIconNumber; - HICON plusIco, minusIco, findNextIco, findPrevIco, configIco, deleteIco; - WNDPROC OldSplitterProc; - bool isContactList; - LONG listOryginalPos; - bool isLoading; - Searcher searcher; - bool isGroupImages; - HIMAGELIST himlSmall, himlNone; - HBRUSH bkBrush; - HBRUSH bkFindBrush; - HANDLE hSystem; - HWND splitterXhWnd, splitterYhWnd; -protected: - virtual void AddGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText, int ico); -public: - ~HistoryWindow(); - static void Deinit(); - static void Open(HANDLE hContact); - static void Close(HANDLE hContact); - static void RebuildEvents(HANDLE hContact); - static bool IsInList(HWND hWnd); - static int FontsChanged(WPARAM wParam, LPARAM lParam); - static INT_PTR DeleteAllUserHistory(WPARAM wParam, LPARAM lParam); - static void OptionsMainChanged(); - static void OptionsGroupChanged(); - static void OptionsSearchingChanged(); - void Show(); - void Focus(); - - // SearchContext interface - virtual void SelectEventGroup(int sel); - virtual HANDLE GetNextContact(HANDLE hContact, int adder); - virtual void SelectContact(HANDLE _hContact); -}; - diff --git a/plugins/BasicHistory/HotkeyHelper.cpp b/plugins/BasicHistory/HotkeyHelper.cpp deleted file mode 100644 index eeb537456a..0000000000 --- a/plugins/BasicHistory/HotkeyHelper.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "StdAfx.h" -#include "HotkeyHelper.h" - -LRESULT CALLBACK HotkeySubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - -void RegisterHotkeyControl(HWND control) -{ - WNDPROC oldProc = (WNDPROC)SetWindowLongPtr(control, GWLP_WNDPROC, (LONG_PTR) HotkeySubclassProc); - SetWindowLongPtr(control, GWLP_USERDATA, (LONG_PTR) oldProc); -} - -void UnregisterHotkeyControl(HWND control) -{ - WNDPROC oldProc = (WNDPROC)GetWindowLongPtr(control, GWLP_USERDATA); - if(oldProc != NULL) - { - SetWindowLongPtr(control, GWLP_WNDPROC, (LONG_PTR) oldProc); - SetWindowLongPtr(control, GWLP_USERDATA, NULL); - } -} - -static bool isPresed = false; - -LRESULT CALLBACK HotkeySubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WNDPROC oldProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA); - - switch (msg) { - case WM_CHAR: - case WM_SYSCHAR: - case WM_UNICHAR: - case WM_DEADCHAR: - case WM_SYSDEADCHAR: - if(isPresed) - return 0; - break; - case WM_KEYUP: - case WM_SYSKEYUP: - if(isPresed) - { - isPresed = false; - return 0; - } - break; - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - { - isPresed = false; - HWND hwndParent = GetParent(hwnd); - MSGFILTER filter; - filter.msg = msg; - filter.lParam = lParam; - filter.wParam = wParam; - filter.nmhdr.hwndFrom = hwnd; - filter.nmhdr.code = EN_MSGFILTER; - filter.nmhdr.idFrom = GetDlgCtrlID(hwnd); - if(SendMessage(hwndParent, WM_NOTIFY, NULL, (LPARAM)&filter)) - { - isPresed = true; - return 0; - } - - LRESULT res = CallWindowProc(oldProc, hwnd, msg, wParam, lParam); - filter.nmhdr.code = CLN_MYSELCHANGED; - SendMessage(hwndParent, WM_NOTIFY, NULL, (LPARAM)&filter); - return res; - } - break; - case WM_LBUTTONDOWN: - { - HWND hwndParent = GetParent(hwnd); - MSGFILTER filter; - filter.msg = msg; - filter.lParam = lParam; - filter.wParam = wParam; - filter.nmhdr.hwndFrom = hwnd; - filter.nmhdr.code = CLN_MYSELCHANGED; - filter.nmhdr.idFrom = GetDlgCtrlID(hwnd); - - LRESULT res = CallWindowProc(oldProc, hwnd, msg, wParam, lParam); - SendMessage(hwndParent, WM_NOTIFY, NULL, (LPARAM)&filter); - return res; - } - break; - } - return CallWindowProc(oldProc, hwnd, msg, wParam, lParam); -} \ No newline at end of file diff --git a/plugins/BasicHistory/HotkeyHelper.h b/plugins/BasicHistory/HotkeyHelper.h deleted file mode 100644 index f31b1c6666..0000000000 --- a/plugins/BasicHistory/HotkeyHelper.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once - -#define CLN_MYSELCHANGED (CLN_FIRST-50) - -void RegisterHotkeyControl(HWND control); -void UnregisterHotkeyControl(HWND control); diff --git a/plugins/BasicHistory/IExport.h b/plugins/BasicHistory/IExport.h deleted file mode 100644 index d024a084e4..0000000000 --- a/plugins/BasicHistory/IExport.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once -class IExport -{ -protected: - std::wostream* stream; -public: - enum ExportType - { - RichHtml, - PlainHtml, - Txt, - Binary, - Dat - }; - - void SetStream(std::wostream *str) - { - stream = str; - } - - virtual const TCHAR* GetExt() = 0; - virtual void WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding) = 0; - virtual void WriteFooter() = 0; - virtual void WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText) = 0; - virtual void WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei) = 0; - - virtual ~IExport() - { - } -}; - diff --git a/plugins/BasicHistory/IImport.h b/plugins/BasicHistory/IImport.h deleted file mode 100644 index aef3b35179..0000000000 --- a/plugins/BasicHistory/IImport.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once - -class IImport -{ -protected: - std::istream* stream; -public: - enum ImportType - { - Binary, - Dat - }; - - struct ExternalMessage - { - DWORD timestamp; - WORD eventType; - WORD flags; - std::wstring message; - }; - - void SetStream(std::istream *str) - { - stream = str; - } - - virtual const TCHAR* GetExt() = 0; - virtual int IsContactInFile(const std::vector& contacts) = 0; - virtual bool GetEventList(std::vector& eventList) = 0; - - virtual ~IImport() - { - } -}; - diff --git a/plugins/BasicHistory/ImageDataObject.cpp b/plugins/BasicHistory/ImageDataObject.cpp deleted file mode 100644 index 15cb67f6ce..0000000000 --- a/plugins/BasicHistory/ImageDataObject.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -//code taken partly from public example on the internet, source unknown. - -#include "StdAfx.h" -#include "ImageDataObject.h" - -HBITMAP CacheIconToBMP(HICON hIcon, COLORREF backgroundColor, int sizeX, int sizeY) -{ - RECT rc; - HBRUSH hBkgBrush = CreateSolidBrush(backgroundColor); - rc.top = rc.left = 0; - rc.right = sizeY; - rc.bottom = sizeX; - HDC hdc = GetDC(0); - HBITMAP hBmp = CreateCompatibleBitmap(hdc, sizeY, sizeX); - HDC hdcMem = CreateCompatibleDC(hdc); - HBITMAP hoBmp = (HBITMAP)SelectObject(hdcMem, hBmp); - FillRect(hdcMem, &rc, hBkgBrush); - DrawIconEx(hdcMem, 0, 0, hIcon, sizeY, sizeX, 0, NULL, DI_NORMAL); - SelectObject(hdcMem, hoBmp); - DeleteDC(hdcMem); - ReleaseDC(NULL, hdc); - DeleteObject(hBkgBrush); - return hBmp; -} - -// returns true on success, false on failure -bool ImageDataObject::InsertIcon(IRichEditOle* pRichEditOle, HICON hIcon, - COLORREF backgroundColor, int sizeX, int sizeY) -{ - bool result; - HBITMAP hBmp = CacheIconToBMP(hIcon, backgroundColor, sizeX, sizeY); - result = InsertBitmap(pRichEditOle, hBmp); - DeleteObject(hBmp); - return result; -} - -// returns true on success, false on failure -bool ImageDataObject::InsertBitmap(IRichEditOle* pRichEditOle, HBITMAP hBitmap) -{ - SCODE sc; - BITMAP bminfo; - - // Get the image data object - // - ImageDataObject *pods = new ImageDataObject; - - GetObject(hBitmap, sizeof(bminfo), &bminfo); - pods->SetBitmap(hBitmap); - - // Get the RichEdit container site - // - IOleClientSite *pOleClientSite; - pRichEditOle->GetClientSite(&pOleClientSite); - - // Initialize a Storage Object - // - IStorage *pStorage; - - LPLOCKBYTES lpLockBytes = NULL; - sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes); - if (sc != S_OK) { - pOleClientSite->Release(); - return false; - } - sc = ::StgCreateDocfileOnILockBytes(lpLockBytes, - STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage); - if (sc != S_OK) { - lpLockBytes = NULL; - pOleClientSite->Release(); - return false; - } - // The final ole object which will be inserted in the richedit control - // - IOleObject *pOleObject; - pOleObject = pods->GetOleObject(pOleClientSite, pStorage); - if (pOleObject == NULL) { - pStorage->Release(); - pOleClientSite->Release(); - return false; - } - - // all items are "contained" -- this makes our reference to this object - // weak -- which is needed for links to embedding silent update. - OleSetContainedObject(pOleObject, TRUE); - - // Now Add the object to the RichEdit - // - REOBJECT reobject; - ZeroMemory(&reobject, sizeof(REOBJECT)); - reobject.cbStruct = sizeof(REOBJECT); - - CLSID clsid; - sc = pOleObject->GetUserClassID(&clsid); - if (sc != S_OK) { - pOleObject->Release(); - pStorage->Release(); - pOleClientSite->Release(); - return false; - } - - reobject.clsid = clsid; - reobject.cp = REO_CP_SELECTION ; - reobject.dvaspect = DVASPECT_CONTENT; - reobject.poleobj = pOleObject; - reobject.polesite = pOleClientSite; - reobject.pstg = pStorage; - reobject.dwFlags = bminfo.bmHeight <= 12 ? 0 : REO_BELOWBASELINE; - - // Insert the bitmap at the current location in the richedit control - // - sc = pRichEditOle->InsertObject(&reobject); - - // Release all unnecessary interfaces - // - pOleObject->Release(); - pOleClientSite->Release(); - lpLockBytes->Release(); - pStorage->Release(); - if (sc != S_OK) - return false; - else - return true; -} - - -void ImageDataObject::SetBitmap(HBITMAP hBitmap) -{ - STGMEDIUM stgm; - stgm.tymed = TYMED_GDI; // Storage medium = HBITMAP handle - stgm.hBitmap = hBitmap; - stgm.pUnkForRelease = NULL; // Use ReleaseStgMedium - - FORMATETC fm; - fm.cfFormat = CF_BITMAP; // Clipboard format = CF_BITMAP - fm.ptd = NULL; // Target Device = Screen - fm.dwAspect = DVASPECT_CONTENT; // Level of detail = Full content - fm.lindex = -1; // Index = Not applicaple - fm.tymed = TYMED_GDI; // Storage medium = HBITMAP handle - - this->SetData(&fm, &stgm, TRUE); -} - - -IOleObject *ImageDataObject::GetOleObject(IOleClientSite *pOleClientSite, IStorage *pStorage) -{ - SCODE sc; - IOleObject *pOleObject; - sc = ::OleCreateStaticFromData(this, IID_IOleObject, OLERENDER_FORMAT, - &m_format, pOleClientSite, pStorage, (void **) & pOleObject); - if (sc != S_OK) - pOleObject = NULL; - return pOleObject; -} diff --git a/plugins/BasicHistory/ImageDataObject.h b/plugins/BasicHistory/ImageDataObject.h deleted file mode 100644 index 309c220e36..0000000000 --- a/plugins/BasicHistory/ImageDataObject.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -//code taken partly from public example on the internet, source unknown. - -#pragma once - -class ImageDataObject : IDataObject -{ -public: - // returns true on success, false on failure - static bool InsertBitmap(IRichEditOle* pRichEditOle, HBITMAP hBitmap); - // returns true on success, false on failure - static bool InsertIcon(IRichEditOle* pRichEditOle, HICON hIcon, - COLORREF backgroundColor, int sizeX = 0, int sizeY = 0); - -private: - ULONG m_ulRefCnt; - BOOL m_bRelease; - - STGMEDIUM m_stgmed; - FORMATETC m_format; - - // ULONG m_nIndex; // current enumerator index - -public: - ImageDataObject() : m_ulRefCnt(0) - { - m_bRelease = FALSE; - } - - ~ImageDataObject() - { - if (m_bRelease) - ::ReleaseStgMedium(&m_stgmed); - } - - // IUnknown interface - STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) - { - if (iid == IID_IUnknown || iid == IID_IDataObject) - { - *ppvObject = this; - AddRef(); - return S_OK; - } - else - return E_NOINTERFACE; - } - - STDMETHOD_(ULONG, AddRef)(void) - { - m_ulRefCnt++; - return m_ulRefCnt; - } - - STDMETHOD_(ULONG, Release)(void) - { - m_ulRefCnt--; - if (m_ulRefCnt == 0) - delete this; - return m_ulRefCnt; - } - - // IDataObject Interface - STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium) { - HANDLE hDst; - hDst = ::OleDuplicateData(m_stgmed.hBitmap, CF_BITMAP, 0); - if (hDst == NULL) - return E_HANDLE; - - pmedium->tymed = TYMED_GDI; - pmedium->hBitmap = (HBITMAP)hDst; - pmedium->pUnkForRelease = NULL; - return S_OK; - } - - STDMETHOD(GetDataHere)(FORMATETC* pformatetc, STGMEDIUM* pmedium ) { - return E_NOTIMPL; - } - - STDMETHOD(QueryGetData)(FORMATETC* pformatetc ) { - return E_NOTIMPL; - } - - STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* pformatectIn ,FORMATETC* pformatetcOut ) { - return E_NOTIMPL; - } - - STDMETHOD(SetData)(FORMATETC* pformatetc , STGMEDIUM* pmedium , BOOL fRelease ) { - m_format = *pformatetc; - m_stgmed = *pmedium; - - return S_OK; - } - - STDMETHOD(EnumFormatEtc)(DWORD dwDirection , IEnumFORMATETC** ppenumFormatEtc ) { - return E_NOTIMPL; - } - - STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, - DWORD *pdwConnection) { - return E_NOTIMPL; - } - - STDMETHOD(DUnadvise)(DWORD dwConnection) { - return E_NOTIMPL; - } - - STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise) { - return E_NOTIMPL; - } - - // Other - void SetBitmap(HBITMAP hBitmap); - IOleObject *GetOleObject(IOleClientSite *pOleClientSite, IStorage *pStorage); -}; - diff --git a/plugins/BasicHistory/Options.cpp b/plugins/BasicHistory/Options.cpp deleted file mode 100644 index 218e721f03..0000000000 --- a/plugins/BasicHistory/Options.cpp +++ /dev/null @@ -1,2170 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "StdAfx.h" -#include "Options.h" -#include "resource.h" - -extern HINSTANCE hInst; -extern bool g_SmileyAddAvail; -extern bool bPopupsEnabled; - -#define MODULE "BasicHistory" - -Options *Options::instance; - -struct EventNamesType -{ - int id; - TCHAR* name; -} EventNames[] = -{ - EVENTTYPE_MESSAGE, LPGENT("Message"), - EVENTTYPE_FILE, LPGENT("File transfer"), - EVENTTYPE_URL, LPGENT("Link"), - EVENTTYPE_STATUSCHANGE, LPGENT("Status change"), - EVENTTYPE_AUTHREQUEST, LPGENT("Authorization request"), - EVENTTYPE_ADDED, LPGENT("You were added"), - EVENTTYPE_CONTACTS, LPGENT("Contacts recieved"), - EVENTTYPE_SMTPSIMPLE, LPGENT("SMTP Simple Email"), - ICQEVENTTYPE_SMS, LPGENT("SMS message") -}; - -struct TCpTable { - UINT cpId; - TCHAR *cpName; -} -cpTable[] = { - { CP_UTF8, _T("UTF-8") }, - { 1250, _T("windows-1250") }, - { 1251, _T("windows-1251") }, - { 1252, _T("windows-1252") }, - { 1253, _T("windows-1253") }, - { 1254, _T("windows-1254") }, - { 1255, _T("windows-1255") }, - { 1256, _T("windows-1256") }, - { 1257, _T("windows-1257") }, - { 1258, _T("windows-1258") }, - { 28591, _T("iso-8859-1") }, - { 28592, _T("iso-8859-2") }, - { 28593, _T("iso-8859-3") }, - { 28594, _T("iso-8859-4") }, - { 28595, _T("iso-8859-5") }, - { 28596, _T("iso-8859-6") }, - { 28597, _T("iso-8859-7") }, - { 28598, _T("iso-8859-8") }, - { 28599, _T("iso-8859-9") }, - { 28603, _T("iso-8859-13") }, - { 28605, _T("iso-8859-15") }, -}; - -Options::Options() -{ - showContacts = false; - showContactGroups = true; - groupNewOnTop = true; - groupShowEvents = true; - groupShowTime = true; - groupShowName = false; - groupShowMessage = true; - groupMessageLen = 43; - groupTime = 5; - groupMessagesNumber = 100; - messagesNewOnTop = false; - messagesShowDate = false; - messagesShowSec = false; - messagesShowName = true; - messagesShowEvents = false; - messagesUseSmileys = true; - searchForInList = true; - searchForInMess = true; - searchMatchCase = false; - searchMatchWhole = false; - searchOnlyIn = false; - searchOnlyOut = false; - searchOnlyGroup = false; - searchAllContacts = false; - schedulerAlerts = true; - schedulerHistoryAlerts = true; - defFilter = 0; - codepageTxt = CP_UTF8; - codepageHtml1 = CP_UTF8; - codepageHtml2 = CP_UTF8; - encodingTxt = _T("UTF-8"); - encodingHtml1 = _T("UTF-8"); - encodingHtml2 = _T("UTF-8"); - exportHtml1ShowDate = true; - exportHtml2ShowDate = false; - exportHtml2UseSmileys = true; -} - -Options::~Options() -{ -} - -int Options::InitOptions(WPARAM wParam, LPARAM lParam) -{ - OPTIONSDIALOGPAGE odp = {0}; - - odp.cbSize = sizeof(odp); - odp.position = 100000000; - odp.hInstance = hInst; - odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; - odp.ptszTitle = LPGENT("History"); - - odp.ptszTab = LPGENT("Group list"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_GROUPLIST); - odp.pfnDlgProc = Options::DlgProcOptsGroupList; - Options_AddPage(wParam, &odp); - - odp.ptszTab = LPGENT("Messages"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MESSAGES); - odp.pfnDlgProc = Options::DlgProcOptsMessages; - Options_AddPage(wParam, &odp); - - odp.ptszTab = LPGENT("Searching"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_SEARCHING); - odp.pfnDlgProc = Options::DlgProcOptsSearching; - Options_AddPage(wParam, &odp); - - odp.ptszTab = LPGENT("Export"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_EXPORT); - odp.pfnDlgProc = Options::DlgProcOptsExport; - Options_AddPage(wParam, &odp); - - odp.ptszTab = LPGENT("Scheduler"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_SCHEDULER); - odp.pfnDlgProc = Options::DlgProcOptsScheduler; - Options_AddPage(wParam, &odp); - - odp.ptszTab = LPGENT("Advanced"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MAIN); - odp.pfnDlgProc = Options::DlgProcOptsMain; - Options_AddPage(wParam, &odp); - - return 0; -} - -struct FontOptionsList { - TCHAR* szDescr; - COLORREF defColour; - TCHAR* szDefFace; - BYTE defStyle; - char defSize; - TCHAR* szBackgroundName; - DWORD flags; -}; - -struct ColorOptionsList { - TCHAR* tszName; - COLORREF def; -}; - -struct HotkeyOptionsList { - const char *pszName; - const TCHAR *ptszDescription; - const TCHAR *ptszSection; - const char *pszService; - WORD DefHotKey; - LPARAM lParam; -}; - -static FontOptionsList g_FontOptionsList[] = { - {LPGENT(">> Outgoing timestamp"), RGB(0, 0, 0), _T("MS Shell Dlg 2"), DBFONTF_BOLD, -11, LPGENT("Outgoing background"), FIDF_ALLOWEFFECTS}, - {LPGENT("<< Incoming timestamp"), RGB(0, 0, 0), _T("MS Shell Dlg 2"), DBFONTF_BOLD, -11, LPGENT("Incoming background"), FIDF_ALLOWEFFECTS}, - {LPGENT(">> Outgoing name"), RGB(100,100,100), _T("MS Shell Dlg 2"), DBFONTF_BOLD, -11, LPGENT("Outgoing background"), FIDF_ALLOWEFFECTS}, - {LPGENT("<< Incoming name"), RGB(90,160,90), _T("MS Shell Dlg 2"), DBFONTF_BOLD, -11, LPGENT("Incoming background"), FIDF_ALLOWEFFECTS}, - {LPGENT(">> Outgoing messages"), RGB(0, 0, 0), _T("MS Shell Dlg 2"), 0, -11, LPGENT("Outgoing background"), FIDF_ALLOWEFFECTS}, - {LPGENT("<< Incoming messages"), RGB(0, 0, 0), _T("MS Shell Dlg 2"), 0, -11, LPGENT("Incoming background"), FIDF_ALLOWEFFECTS}, - {LPGENT("Group list"), RGB(0, 0, 0), _T("MS Shell Dlg 2"), 0, -11, LPGENT("Group list background"), FIDF_DISABLESTYLES}, - {LPGENT("Find window"), RGB(0, 0, 0), _T("MS Shell Dlg 2"), 0, -11, LPGENT("Find window background"), FIDF_DISABLESTYLES}, -}; - -static ColorOptionsList g_ColorOptionsList[] = { - LPGENT("Outgoing background"), RGB(245,245,255), - LPGENT("Incoming background"), RGB(245,255,245), - LPGENT("Group list background"), GetSysColor(COLOR_3DFACE), - LPGENT("Window background"), GetSysColor(COLOR_3DFACE), - LPGENT("Contact list background"), GetSysColor(COLOR_3DFACE), - LPGENT("Find window background"), GetSysColor(COLOR_WINDOW), -}; - -static HotkeyOptionsList g_HotkeyOptionsList[] = { - { "basichistory_hot_showall", LPGENT("Open global history"), LPGENT("History"), MS_HISTORY_SHOWCONTACTHISTORY, HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, 'H') | HKF_MIRANDA_LOCAL, 0 }, - { "basichistory_hot_find", LPGENT("Find"), LPGENT("History"), 0, HOTKEYCODE(HOTKEYF_CONTROL, 'F'), HISTORY_HK_FIND }, - { "basichistory_hot_findnext", LPGENT("Find Next"), LPGENT("History"), 0, VK_F3, HISTORY_HK_FINDNEXT }, - { "basichistory_hot_findprev", LPGENT("Find Previous"), LPGENT("History"), 0, VK_F2, HISTORY_HK_FINDPREV }, - { "basichistory_hot_matchcase", LPGENT("Switch Match Case"), LPGENT("History"), 0, 0, HISTORY_HK_MATCHCASE }, - { "basichistory_hot_matchwhole", LPGENT("Switch Match Whole Word"), LPGENT("History"), 0, 0, HISTORY_HK_MATCHWHOLE }, - { "basichistory_hot_showcontacts", LPGENT("Show/Hide Contacts"), LPGENT("History"), 0, 0, HISTORY_HK_SHOWCONTACTS }, - { "basichistory_hot_onlyin", LPGENT("Switch Only Incomming Messages"), LPGENT("History"), 0, 0, HISTORY_HK_ONLYIN }, - { "basichistory_hot_onlyout", LPGENT("Switch Only Outgoing Messages"), LPGENT("History"), 0, 0, HISTORY_HK_ONLYOUT }, - { "basichistory_hot_onlygroup", LPGENT("Switch Only Selected Group"), LPGENT("History"), 0, 0, HISTORY_HK_ONLYGROUP }, - { "basichistory_hot_allcontacts", LPGENT("Switch All Contacts"), LPGENT("History"), 0, 0, HISTORY_HK_ALLCONTACTS }, - { "basichistory_hot_delete", LPGENT("Delete"), LPGENT("History"), 0, VK_DELETE, HISTORY_HK_DELETE }, - { "basichistory_hot_exrhtml", LPGENT("Export To Rich Html"), LPGENT("History"), 0, 0, HISTORY_HK_EXRHTML }, - { "basichistory_hot_exphtml", LPGENT("Export To Plain Html"), LPGENT("History"), 0, 0, HISTORY_HK_EXPHTML }, - { "basichistory_hot_extxt", LPGENT("Export To Txt"), LPGENT("History"), 0, 0, HISTORY_HK_EXTXT }, - { "basichistory_hot_exbin", LPGENT("Export To Binary"), LPGENT("History"), 0, 0, HISTORY_HK_EXBIN }, - { "basichistory_hot_impbin", LPGENT("Import From Binary"), LPGENT("History"), 0, 0, HISTORY_HK_IMPBIN }, - { "basichistory_hot_exdat", LPGENT("Export To Dat (mContacts)"), LPGENT("History"), 0, 0, HISTORY_HK_EXDAT }, - { "basichistory_hot_impdat", LPGENT("Import From Dat (mContacts)"), LPGENT("History"), 0, 0, HISTORY_HK_IMPDAT }, -}; - -const int g_fontsSize = SIZEOF(g_FontOptionsList); - -const int g_colorsSize = SIZEOF(g_ColorOptionsList); - -const int g_hotkeysSize = SIZEOF(g_HotkeyOptionsList); - -void Options::Unload() -{ - DeleteCriticalSection(&criticalSection); -} - -void Options::Load(void) -{ - InitializeCriticalSection(&criticalSection); - FontIDT fid = {0}; - ColourIDT cid = {0}; - HOTKEYDESC hid = {0}; - fid.cbSize = sizeof(FontIDT); - cid.cbSize = sizeof(ColourIDT); - hid.cbSize = sizeof(HOTKEYDESC); - strncpy_s(fid.dbSettingsGroup, "BasicHistory_Fonts", SIZEOF(fid.dbSettingsGroup)); - _tcsncpy_s(fid.backgroundGroup, _T("History"), SIZEOF(fid.backgroundGroup)); - _tcsncpy_s(fid.group, LPGENT("History"), SIZEOF(fid.group)); - for(int i = 0; i < g_fontsSize; ++i) - { - fid.order = i; - _tcsncpy_s(fid.deffontsettings.szFace, g_FontOptionsList[i].szDefFace, LF_FACESIZE); - fid.deffontsettings.size = g_FontOptionsList[i].defSize; - fid.deffontsettings.colour = g_FontOptionsList[i].defColour; - fid.deffontsettings.style = g_FontOptionsList[i].defStyle; - fid.deffontsettings.charset = DEFAULT_CHARSET; - sprintf_s(fid.prefix, SIZEOF(fid.prefix), "Font%d", i); - _tcsncpy_s(fid.name, g_FontOptionsList[i].szDescr, SIZEOF(fid.name)); - _tcsncpy_s(fid.backgroundName, g_FontOptionsList[i].szBackgroundName, SIZEOF(fid.name)); - fid.flags = FIDF_DEFAULTVALID | FIDF_CLASSGENERAL | g_FontOptionsList[i].flags; - FontRegisterT(&fid); - } - - strncpy_s(cid.dbSettingsGroup, "BasicHistory_Fonts", SIZEOF(fid.dbSettingsGroup)); - _tcsncpy_s(cid.group, LPGENT("History"), SIZEOF(fid.group)); - for(int i = 0; i < g_colorsSize; ++i) - { - _tcsncpy_s(cid.name, g_ColorOptionsList[i].tszName, SIZEOF(cid.name)); - sprintf_s(cid.setting, SIZEOF(cid.setting), "Color%d", i); - cid.order = i; - cid.defcolour = g_ColorOptionsList[i].def; - ColourRegisterT(&cid); - } - - hid.dwFlags = HKD_TCHAR; - for(int i = 0; i < g_hotkeysSize; ++i) - { - hid.pszName = g_HotkeyOptionsList[i].pszName; - hid.ptszDescription = g_HotkeyOptionsList[i].ptszDescription; - hid.ptszSection = g_HotkeyOptionsList[i].ptszSection; - hid.pszService = g_HotkeyOptionsList[i].pszService; - hid.DefHotKey = g_HotkeyOptionsList[i].DefHotKey; - hid.lParam = g_HotkeyOptionsList[i].lParam; - Hotkey_Register(&hid); - } - - showContacts = DBGetContactSettingByte(0, MODULE, "showContacts", 0) ? true : false; - showContactGroups = DBGetContactSettingByte(0, MODULE, "showContactGroups", 1) ? true : false; - groupNewOnTop = DBGetContactSettingByte(0, MODULE, "groupNewOnTop", 1) ? true : false; - groupShowEvents = DBGetContactSettingByte(0, MODULE, "groupShowEvents", 1) ? true : false; - groupShowTime = DBGetContactSettingByte(0, MODULE, "groupShowTime", 1) ? true : false; - groupShowName = DBGetContactSettingByte(0, MODULE, "groupShowName", 0) ? true : false; - groupShowMessage = DBGetContactSettingByte(0, MODULE, "groupShowMessage", 1) ? true : false; - groupMessageLen = DBGetContactSettingDword(0, MODULE, "groupMessageLen", 43); - if(groupMessageLen < 5) groupMessageLen = 5; - groupTime = DBGetContactSettingDword(0, MODULE, "groupTime", 5); - if(groupTime < 1) groupTime = 1; - groupMessagesNumber = DBGetContactSettingDword(0, MODULE, "groupMessagesNumber", 100); - if(groupMessagesNumber < 1) groupMessagesNumber = 1; - messagesNewOnTop = DBGetContactSettingByte(0, MODULE, "messagesNewOnTop", 0) ? true : false; - messagesShowDate = DBGetContactSettingByte(0, MODULE, "messagesShowDate", 0) ? true : false; - messagesShowSec = DBGetContactSettingByte(0, MODULE, "messagesShowSec", 0) ? true : false; - messagesShowName = DBGetContactSettingByte(0, MODULE, "messagesShowName", 1) ? true : false; - messagesShowEvents = DBGetContactSettingByte(0, MODULE, "messagesShowEvents", 0) ? true : false; - messagesUseSmileys = DBGetContactSettingByte(0, MODULE, "messagesUseSmileys", 1) ? true : false; - searchForInList = DBGetContactSettingByte(0, MODULE, "searchForInList", 1) ? true : false; - searchForInMess = DBGetContactSettingByte(0, MODULE, "searchForInMess", 1) ? true : false; - searchMatchCase = DBGetContactSettingByte(0, MODULE, "searchMatchCase", 0) ? true : false; - searchMatchWhole = DBGetContactSettingByte(0, MODULE, "searchMatchWhole", 0) ? true : false; - searchOnlyIn = DBGetContactSettingByte(0, MODULE, "searchOnlyIn", 0) ? true : false; - searchOnlyOut = DBGetContactSettingByte(0, MODULE, "searchOnlyOut", 0) ? true : false; - searchOnlyGroup = DBGetContactSettingByte(0, MODULE, "searchOnlyGroup", 0) ? true : false; - searchAllContacts = DBGetContactSettingByte(0, MODULE, "searchAllContacts", 0) ? true : false; - schedulerAlerts = DBGetContactSettingByte(0, MODULE, "schedulerAlerts", 1) ? true : false; - schedulerHistoryAlerts = DBGetContactSettingByte(0, MODULE, "schedulerHistoryAlerts", 1) ? true : false; - - defFilter = DBGetContactSettingByte(0, MODULE, "defFilter", defFilter); - int filtersCount = DBGetContactSettingDword(0, MODULE, "customFiltersCount", 0); - for(int i = 0; i < filtersCount; ++i) - { - char buf[256]; - FilterOptions fo; - sprintf_s(buf, "filterName_%d", i); - DBVARIANT nameV; - if(!DBGetContactSettingWString(0, MODULE, buf, &nameV)) - { - fo.name = nameV.pwszVal; - DBFreeVariant(&nameV); - } - else break; - sprintf_s(buf, "filterInOut_%d", i); - int inOut = DBGetContactSettingByte(0, MODULE, buf, 0); - if(inOut == 1) - fo.onlyIncomming = true; - else if(inOut == 2) - fo.onlyOutgoing = true; - sprintf_s(buf, "filterEvents_%d", i); - DBVARIANT eventsV; - if(!DBGetContactSettingString(0, MODULE, buf, &eventsV)) - { - int k = 0; - char* id = eventsV.pszVal; - while(eventsV.pszVal[k]) - { - if(eventsV.pszVal[k] == ';') - { - eventsV.pszVal[k] = 0; - fo.events.push_back(strtol(id, NULL, 16)); - id = eventsV.pszVal + k + 1; - } - - ++k; - } - DBFreeVariant(&eventsV); - } - else break; - - customFilters.insert(customFilters.end(), fo); - } - - if(defFilter > 1) - { - defFilter = 0; - - DBVARIANT defFilterStrV; - if(!DBGetContactSettingWString(0, MODULE, "defFilterStr", &defFilterStrV)) - { - std::wstring filterName = defFilterStrV.pwszVal; - for(int i = 0; i < (int)customFilters.size(); ++i) - { - if(filterName == customFilters[i].name) - { - defFilter = i + 2; - break; - } - } - DBFreeVariant(&defFilterStrV); - } - } - - codepageTxt = DBGetContactSettingDword(0, MODULE, "codepageTxt", CP_UTF8); - codepageHtml1 = DBGetContactSettingDword(0, MODULE, "codepageHtml1", CP_UTF8); - codepageHtml2 = DBGetContactSettingDword(0, MODULE, "codepageHtml2", CP_UTF8); - DBVARIANT encodingV; - if(!DBGetContactSettingWString(0, MODULE, "encodingTxt", &encodingV)) - { - encodingTxt = encodingV.pwszVal; - DBFreeVariant(&encodingV); - } - else - { - encodingTxt = _T("UTF-8"); - } - if(!DBGetContactSettingWString(0, MODULE, "encodingHtml1", &encodingV)) - { - encodingHtml1 = encodingV.pwszVal; - DBFreeVariant(&encodingV); - } - else - { - encodingHtml1 = _T("UTF-8"); - } - if(!DBGetContactSettingWString(0, MODULE, "encodingHtml2", &encodingV)) - { - encodingHtml2 = encodingV.pwszVal; - DBFreeVariant(&encodingV); - } - else - { - encodingHtml2 = _T("UTF-8"); - } - - exportHtml1ShowDate = DBGetContactSettingByte(0, MODULE, "exportHtml1ShowDate", 1) ? true : false; - exportHtml2ShowDate = DBGetContactSettingByte(0, MODULE, "exportHtml2ShowDate", 0) ? true : false; - exportHtml2UseSmileys = DBGetContactSettingByte(0, MODULE, "exportHtml2UseSmileys", 1) ? true : false; - if(!DBGetContactSettingWString(0, MODULE, "extCssHtml2", &encodingV)) - { - extCssHtml2 = encodingV.pwszVal; - DBFreeVariant(&encodingV); - } - else - { - extCssHtml2 = _T(""); - } - - if(!DBGetContactSettingWString(0, MODULE, "ftpLogPath", &encodingV)) - { - ftpLogPath = encodingV.pwszVal; - DBFreeVariant(&encodingV); - } - - if(!DBGetContactSettingWString(0, MODULE, "ftpExePath", &encodingV)) - { - ftpExePath = encodingV.pwszVal; - DBFreeVariant(&encodingV); - } - else - { - ftpExePath = ftpExePathDef; - } - - LoadTasks(); -} - -COLORREF Options::GetFont(Fonts fontId, PLOGFONT font) -{ - FontIDT fid = {0}; - fid.cbSize = sizeof(FontIDT); - _tcsncpy_s(fid.group, LPGENT("History"), SIZEOF(fid.group)); - _tcsncpy_s(fid.name, g_FontOptionsList[fontId].szDescr, SIZEOF(fid.name)); - return (COLORREF)CallService(MS_FONT_GETT, (WPARAM)&fid, (LPARAM)font); -} - -COLORREF Options::GetColor(Colors colorId) -{ - ColourIDT cid = {0}; - cid.cbSize = sizeof(ColourIDT); - _tcsncpy_s(cid.group, LPGENT("History"), SIZEOF(cid.group)); - _tcsncpy_s(cid.name, g_ColorOptionsList[colorId].tszName, SIZEOF(cid.name)); - return (COLORREF)CallService(MS_COLOUR_GETT, (WPARAM)&cid, NULL); -} - -void Options::Save() -{ - DBWriteContactSettingByte(0, MODULE, "showContacts", showContacts ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "showContactGroups", showContactGroups ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "groupNewOnTop", groupNewOnTop ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "groupShowEvents", groupShowEvents ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "groupShowTime", groupShowTime ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "groupShowName", groupShowName ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "groupShowMessage", groupShowMessage ? 1 : 0); - if(groupMessageLen < 5) groupMessageLen = 5; - DBWriteContactSettingDword(0, MODULE, "groupMessageLen", groupMessageLen); - if(groupTime < 1) groupTime = 1; - DBWriteContactSettingDword(0, MODULE, "groupTime", groupTime); - if(groupMessagesNumber < 1) groupMessagesNumber = 1; - DBWriteContactSettingDword(0, MODULE, "groupMessagesNumber", groupMessagesNumber); - DBWriteContactSettingByte(0, MODULE, "messagesNewOnTop", messagesNewOnTop ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "messagesShowDate", messagesShowDate ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "messagesShowSec", messagesShowSec ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "messagesShowName", messagesShowName ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "messagesShowEvents", messagesShowEvents ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "messagesUseSmileys", messagesUseSmileys ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "searchForInList", searchForInList ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "searchForInMess", searchForInMess ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "searchMatchCase", searchMatchCase ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "searchMatchWhole", searchMatchWhole ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "searchOnlyIn", searchOnlyIn ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "searchOnlyOut", searchOnlyOut ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "searchOnlyGroup", searchOnlyGroup ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "searchAllContacts", searchAllContacts ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "schedulerAlerts", schedulerAlerts ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "schedulerHistoryAlerts", schedulerHistoryAlerts ? 1 : 0); - if(defFilter < 0 || defFilter - 2 >= (int)customFilters.size()) defFilter = 0; - DBWriteContactSettingByte(0, MODULE, "defFilter", defFilter < 2 ? defFilter : 2); - if(defFilter >= 2) - DBWriteContactSettingWString(0, MODULE, "defFilterStr", customFilters[defFilter - 2].name.c_str()); - DBWriteContactSettingDword(0, MODULE, "customFiltersCount", (DWORD)customFilters.size()); - for(int i = 0 ; i < (int)customFilters.size(); ++i) - { - char buf[256]; - sprintf_s(buf, "filterName_%d", i); - DBWriteContactSettingWString(0, MODULE, buf, customFilters[i].name.c_str()); - sprintf_s(buf, "filterInOut_%d", i); - DBWriteContactSettingByte(0, MODULE, buf, customFilters[i].onlyIncomming ? 1 : (customFilters[i].onlyOutgoing ? 2 : 0)); - std::string events; - for(std::vector::iterator it = customFilters[i].events.begin(); it != customFilters[i].events.end(); ++it) - { - _itoa_s(*it, buf, 16); - events += buf; - events += ";"; - } - - sprintf_s(buf, "filterEvents_%d", i); - DBWriteContactSettingString(0, MODULE, buf, events.c_str()); - } - - DBWriteContactSettingDword(0, MODULE, "codepageTxt", codepageTxt); - DBWriteContactSettingDword(0, MODULE, "codepageHtml1", codepageHtml1); - DBWriteContactSettingDword(0, MODULE, "codepageHtml2", codepageHtml2); - DBWriteContactSettingWString(0, MODULE, "encodingTxt", encodingTxt.c_str()); - DBWriteContactSettingWString(0, MODULE, "encodingHtml1", encodingHtml1.c_str()); - DBWriteContactSettingWString(0, MODULE, "encodingHtml2", encodingHtml2.c_str()); - DBWriteContactSettingByte(0, MODULE, "exportHtml1ShowDate", exportHtml1ShowDate ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "exportHtml2ShowDate", exportHtml2ShowDate ? 1 : 0); - DBWriteContactSettingByte(0, MODULE, "exportHtml2UseSmileys", exportHtml2UseSmileys ? 1 : 0); - DBWriteContactSettingWString(0, MODULE, "extCssHtml2", extCssHtml2.c_str()); - DBWriteContactSettingWString(0, MODULE, "ftpLogPath", ftpLogPath.c_str()); - if(ftpExePath != ftpExePathDef) - { - DBWriteContactSettingWString(0, MODULE, "ftpExePath", ftpExePath.c_str()); - } - else - { - DBDeleteContactSetting(0, MODULE, "ftpExePath"); - } -} - -void Options::SaveTasks(std::list* tasks) -{ - EnterCriticalSection(&criticalSection); - int oldTaskNr = (int)taskOptions.size(); - taskOptions.clear(); - int i = 0; - char buf[256]; - for(std::list::iterator it = tasks->begin(); it != tasks->end(); ++it) - { - sprintf_s(buf, "Task_compress_%d", i); - DBWriteContactSettingByte(0, MODULE, buf, it->compress); - sprintf_s(buf, "Task_useFtp_%d", i); - DBWriteContactSettingByte(0, MODULE, buf, it->useFtp); - sprintf_s(buf, "Task_isSystem_%d", i); - DBWriteContactSettingByte(0, MODULE, buf, it->isSystem); - sprintf_s(buf, "Task_active_%d", i); - DBWriteContactSettingByte(0, MODULE, buf, it->active); - sprintf_s(buf, "Task_exportImported_%d", i); - DBWriteContactSettingByte(0, MODULE, buf, it->exportImported); - sprintf_s(buf, "Task_type_%d", i); - DBWriteContactSettingByte(0, MODULE, buf, it->type); - sprintf_s(buf, "Task_eventUnit_%d", i); - DBWriteContactSettingByte(0, MODULE, buf, it->eventUnit); - sprintf_s(buf, "Task_trigerType_%d", i); - DBWriteContactSettingByte(0, MODULE, buf, it->trigerType); - sprintf_s(buf, "Task_exportType_%d", i); - DBWriteContactSettingByte(0, MODULE, buf, it->exportType); - sprintf_s(buf, "Task_importType_%d", i); - DBWriteContactSettingByte(0, MODULE, buf, it->importType); - sprintf_s(buf, "Task_eventDeltaTime_%d", i); - DBWriteContactSettingDword(0, MODULE, buf, it->eventDeltaTime); - sprintf_s(buf, "Task_filterId_%d", i); - DBWriteContactSettingDword(0, MODULE, buf, it->filterId); - sprintf_s(buf, "Task_dayTime_%d", i); - DBWriteContactSettingDword(0, MODULE, buf, it->dayTime); - sprintf_s(buf, "Task_dayOfWeek_%d", i); - DBWriteContactSettingDword(0, MODULE, buf, it->dayOfWeek); - sprintf_s(buf, "Task_dayOfMonth_%d", i); - DBWriteContactSettingDword(0, MODULE, buf, it->dayOfMonth); - sprintf_s(buf, "Task_deltaTime_%d", i); - DBWriteContactSettingDword(0, MODULE, buf, it->deltaTime); - sprintf_s(buf, "Task_lastExport_low_%d", i); - DBWriteContactSettingDword(0, MODULE, buf, (int)it->lastExport); - sprintf_s(buf, "Task_lastExport_hi_%d", i); - DBWriteContactSettingDword(0, MODULE, buf, ((unsigned long long int)it->lastExport) >> 32); - sprintf_s(buf, "Task_ftpName_%d", i); - DBWriteContactSettingWString(0, MODULE, buf, it->ftpName.c_str()); - sprintf_s(buf, "Task_filterName_%d", i); - DBWriteContactSettingWString(0, MODULE, buf, it->filterName.c_str()); - sprintf_s(buf, "Task_filePath_%d", i); - DBWriteContactSettingWString(0, MODULE, buf, it->filePath.c_str()); - sprintf_s(buf, "Task_taskName_%d", i); - DBWriteContactSettingWString(0, MODULE, buf, it->taskName.c_str()); - sprintf_s(buf, "Task_zipPassword_%d", i); - DBWriteContactSettingString(0, MODULE, buf, it->zipPassword.c_str()); - - HANDLE _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - sprintf_s(buf, "IsInTask_%d", i); - while(_hContact) - { - DBDeleteContactSetting(_hContact, MODULE, buf); - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); - } - - for(size_t j = 0; j < it->contacts.size(); ++j) - { - DBWriteContactSettingByte(it->contacts[j], MODULE, buf, 1); - } - - it->orderNr = i++; - taskOptions.push_back(*it); - } - - DBWriteContactSettingDword(0, MODULE, "Task_count", i); - - for(i = (int)tasks->size(); i < oldTaskNr; ++i) - { - sprintf_s(buf, "Task_compress_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_useFtp_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_isSystem_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_active_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_type_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_eventUnit_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_trigerType_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_exportType_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_eventDeltaTime_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_filterId_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_dayTime_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_dayOfWeek_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_dayOfMonth_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_deltaTime_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_lastExport_low_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_lastExport_hi_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_ftpName_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_filterName_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_filePath_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - sprintf_s(buf, "Task_taskName_%d", i); - DBDeleteContactSetting(NULL, MODULE, buf); - - HANDLE _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - sprintf_s(buf, "IsInTask_%d", i); - while(_hContact) - { - DBDeleteContactSetting(_hContact, MODULE, buf); - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); - } - } - - LeaveCriticalSection(&criticalSection); -} - -void Options::SaveTaskTime(TaskOptions& to) -{ - int i = to.orderNr; - char buf[256]; - sprintf_s(buf, "Task_lastExport_low_%d", i); - DBWriteContactSettingDword(0, MODULE, buf, (int)to.lastExport); - sprintf_s(buf, "Task_lastExport_hi_%d", i); - DBWriteContactSettingDword(0, MODULE, buf, ((unsigned long long int)to.lastExport) >> 32); -} - -void Options::LoadTasks() -{ - int taskCount = DBGetContactSettingDword(0, MODULE, "Task_count", 0); - char buf[256]; - for(int i = 0; i < taskCount; ++i) - { - TaskOptions to; - sprintf_s(buf, "Task_compress_%d", i); - to.compress = DBGetContactSettingByte(0, MODULE, buf, to.compress) != 0; - sprintf_s(buf, "Task_useFtp_%d", i); - to.useFtp = DBGetContactSettingByte(0, MODULE, buf, to.useFtp) != 0; - sprintf_s(buf, "Task_isSystem_%d", i); - to.isSystem = DBGetContactSettingByte(0, MODULE, buf, to.isSystem) != 0; - sprintf_s(buf, "Task_active_%d", i); - to.active = DBGetContactSettingByte(0, MODULE, buf, to.active) != 0; - sprintf_s(buf, "Task_exportImported_%d", i); - to.exportImported = DBGetContactSettingByte(0, MODULE, buf, to.exportImported) != 0; - sprintf_s(buf, "Task_type_%d", i); - to.type = (TaskOptions::TaskType)DBGetContactSettingByte(0, MODULE, buf, to.type); - sprintf_s(buf, "Task_eventUnit_%d", i); - to.eventUnit = (TaskOptions::EventUnit)DBGetContactSettingByte(0, MODULE, buf, to.eventUnit); - sprintf_s(buf, "Task_trigerType_%d", i); - to.trigerType = (TaskOptions::TrigerType)DBGetContactSettingByte(0, MODULE, buf, to.trigerType); - sprintf_s(buf, "Task_exportType_%d", i); - to.exportType = (IExport::ExportType)DBGetContactSettingByte(0, MODULE, buf, to.exportType); - sprintf_s(buf, "Task_importType_%d", i); - to.importType = (IImport::ImportType)DBGetContactSettingByte(0, MODULE, buf, to.importType); - sprintf_s(buf, "Task_eventDeltaTime_%d", i); - to.eventDeltaTime = DBGetContactSettingDword(0, MODULE, buf, to.eventDeltaTime); - sprintf_s(buf, "Task_filterId_%d", i); - to.filterId = DBGetContactSettingDword(0, MODULE, buf, to.filterId); - sprintf_s(buf, "Task_dayTime_%d", i); - to.dayTime = DBGetContactSettingDword(0, MODULE, buf, to.dayTime); - sprintf_s(buf, "Task_dayOfWeek_%d", i); - to.dayOfWeek = DBGetContactSettingDword(0, MODULE, buf, to.dayOfWeek); - sprintf_s(buf, "Task_dayOfMonth_%d", i); - to.dayOfMonth = DBGetContactSettingDword(0, MODULE, buf, to.dayOfMonth); - sprintf_s(buf, "Task_deltaTime_%d", i); - to.deltaTime = DBGetContactSettingDword(0, MODULE, buf, to.deltaTime); - unsigned long long int le = to.lastExport; - sprintf_s(buf, "Task_lastExport_low_%d", i); - to.lastExport = DBGetContactSettingDword(0, MODULE, buf, (int)le) & 0xffffffff; - sprintf_s(buf, "Task_lastExport_hi_%d", i); - to.lastExport |= ((unsigned long long int)DBGetContactSettingDword(0, MODULE, buf, le >> 32)) << 32; - sprintf_s(buf, "Task_ftpName_%d", i); - DBVARIANT var; - if(!DBGetContactSettingWString(0, MODULE, buf, &var)) - { - to.ftpName = var.ptszVal; - DBFreeVariant(&var); - } - sprintf_s(buf, "Task_filterName_%d", i); - if(!DBGetContactSettingWString(0, MODULE, buf, &var)) - { - to.filterName = var.ptszVal; - DBFreeVariant(&var); - } - sprintf_s(buf, "Task_filePath_%d", i); - if(!DBGetContactSettingWString(0, MODULE, buf, &var)) - { - to.filePath = var.ptszVal; - DBFreeVariant(&var); - } - sprintf_s(buf, "Task_taskName_%d", i); - if(!DBGetContactSettingWString(0, MODULE, buf, &var)) - { - to.taskName = var.ptszVal; - DBFreeVariant(&var); - } - sprintf_s(buf, "Task_zipPassword_%d", i); - if(!DBGetContactSettingString(0, MODULE, buf, &var)) - { - to.zipPassword = var.pszVal; - DBFreeVariant(&var); - } - - HANDLE _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - sprintf_s(buf, "IsInTask_%d", i); - while(_hContact) - { - if(DBGetContactSettingByte(_hContact, MODULE, buf, 0) == 1) - { - to.contacts.push_back(_hContact); - } - - _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); - } - - to.orderNr = i; - taskOptions.push_back(to); - } -} - -void OptionsMainChanged(); -void OptionsGroupChanged(); -void OptionsMessageChanged(); -void OptionsSearchingChanged(); -void OptionsSchedulerChanged(); -void InitTaskMenuItems(); - -void SetEventCB(HWND hwndCB, int eventId) -{ - int cpCount = SIZEOF(EventNames); - int selCpIdx = -1; - for(int i = 0; i < cpCount; ++i) - { - if(EventNames[i].id == eventId) - selCpIdx = i; - } - - if(selCpIdx == -1) - { - TCHAR buf[24]; - _stprintf_s(buf, 24, _T("%d"), eventId); - ComboBox_SetText(hwndCB, buf); - } - else - { - ComboBox_SetCurSel(hwndCB, selCpIdx); - } -} - -int GetEventCB(HWND hwndCB, bool errorReport, int &eventId) -{ - int selCpIdx = ComboBox_GetCurSel(hwndCB); - if(selCpIdx < 0) - { - TCHAR text[24]; - ComboBox_GetText(hwndCB, text, 24); - TCHAR * stopOn = NULL; - long cp = _tcstol(text, &stopOn, 10); - if(errorReport && (stopOn == text || *stopOn != '\0' || cp < 0)) - { - MessageBox(GetParent(hwndCB), TranslateT("Invalid event number"), TranslateT("Error"), MB_OK | MB_ICONERROR); - SetFocus(hwndCB); - return -1; - } - - eventId = cp; - } - else if(selCpIdx > 1) - eventId = EventNames[selCpIdx - 2].id; - else - return selCpIdx + 1; - - return 0; -} - -void ClearLB(HWND hwndLB) -{ - while(ListBox_GetCount(hwndLB) > 0) - ListBox_DeleteString(hwndLB, 0); -} - -void ReloadEventLB(HWND hwndLB, const FilterOptions &sel) -{ - while(ListBox_GetCount(hwndLB) > 0) - ListBox_DeleteString(hwndLB, 0); - if(sel.onlyIncomming && !sel.onlyOutgoing) - { - ListBox_AddString(hwndLB, TranslateT("Incoming events")); - } - else if(sel.onlyOutgoing && !sel.onlyIncomming) - { - ListBox_AddString(hwndLB, TranslateT("Outgoing events")); - } - - for(std::vector::const_iterator it = sel.events.begin(); it != sel.events.end(); ++it) - { - int cpCount = SIZEOF(EventNames); - int selCpIdx = -1; - for(int i = 0; i < cpCount; ++i) - { - if(EventNames[i].id == *it) - selCpIdx = i; - } - if(selCpIdx == -1) - { - TCHAR buf[24]; - _stprintf_s(buf, 24, _T("%d"), *it); - ListBox_AddString(hwndLB, buf); - } - else - { - ListBox_AddString(hwndLB, TranslateTS(EventNames[selCpIdx].name)); - } - } -} - -bool CheckFile(HWND hwndEdit) -{ - TCHAR buf[MAX_PATH]; - Edit_GetText(hwndEdit, buf, MAX_PATH); - DWORD atr = GetFileAttributes(buf); - if(atr == INVALID_FILE_ATTRIBUTES || atr & FILE_ATTRIBUTE_DIRECTORY) - { - MessageBox(GetParent(hwndEdit), TranslateT("File do not exist. Enter correct file path."), TranslateT("Invalid file"), MB_OK | MB_ICONERROR); - SetFocus(hwndEdit); - return false; - } - - return true; -} - -bool OpenFileDlg(HWND hwndDlg, HWND hwndEdit, const TCHAR* defName, const TCHAR* ext, const TCHAR* title, bool open) -{ - TCHAR filter[1024]; - std::locale loc; - TCHAR extUpper[32]; - _tcscpy_s(extUpper, ext); - extUpper[0] = std::toupper(ext[0], loc); - _stprintf_s(filter, TranslateT("%s Files (*.%s)"), extUpper, ext); - size_t len = _tcslen(filter) + 1; - _stprintf_s(filter + len, 1024 - len, _T("*.%s"), ext); - len += _tcslen(filter + len) + 1; - _tcscpy_s(filter + len, 1024 - len, TranslateT("All Files (*.*)")); - len += _tcslen(filter + len) + 1; - _tcscpy_s(filter + len, 1024 - len, _T("*.*")); - len += _tcslen(filter + len) + 1; - filter[len] = 0; - TCHAR stzFilePath[1024]; - - Edit_GetText(hwndEdit, stzFilePath, 1023); - if(stzFilePath[0] == 0) - { - _tcscpy_s(stzFilePath, defName); - len = _tcslen(stzFilePath) + 1; - stzFilePath[len] = 0; - } - else - { - len = _tcslen(stzFilePath) + 1; - stzFilePath[len] = 0; - } - - OPENFILENAME ofn = {0}; - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hwndDlg; - ofn.lpstrFilter = filter; - ofn.nFilterIndex = 1; - ofn.lpstrFile = stzFilePath; - ofn.lpstrTitle = title; - ofn.nMaxFile = 1024; - ofn.lpstrDefExt = ext; - if(open) - { - ofn.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - if(GetOpenFileName(&ofn)) - { - Edit_SetText(hwndEdit, stzFilePath); - return true; - } - } - else - { - ofn.Flags = OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_NOCHANGEDIR; - if(GetSaveFileName(&ofn)) - { - Edit_SetText(hwndEdit, stzFilePath); - return true; - } - } - - return false; -} - -INT_PTR CALLBACK Options::DlgProcOptsMain(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)FALSE); - CheckDlgButton(hwndDlg, IDC_SHOWCONTACTS, instance->showContacts ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_SHOWCONTACTGROUPS, instance->showContactGroups ? 1 : 0); - HWND events = GetDlgItem(hwndDlg, IDC_EVENT); - HWND defFilter = GetDlgItem(hwndDlg, IDC_DEFFILTER); - HWND listFilter = GetDlgItem(hwndDlg, IDC_LIST_FILTERS); - HWND ftp = GetDlgItem(hwndDlg, IDC_WINSCP); - HWND ftpLog = GetDlgItem(hwndDlg, IDC_WINSCPLOG); - ComboBox_AddString(events, TranslateT("Incoming events")); - ComboBox_AddString(events, TranslateT("Outgoing events")); - for(int i = 0 ; i < SIZEOF(EventNames); ++i) - { - ComboBox_AddString(events, TranslateTS(EventNames[i].name)); - } - - ComboBox_AddString(defFilter, TranslateT("Default history events")); - ComboBox_AddString(defFilter, TranslateT("All events")); - Edit_LimitText(GetDlgItem(hwndDlg, IDC_FILTER_NAME), 20); - ComboBox_LimitText(events, 20); - - instance->customFiltersTemp.clear(); - instance->customFiltersTemp.insert(instance->customFiltersTemp.begin(), instance->customFilters.begin(), instance->customFilters.end()); - for(std::vector::iterator it = instance->customFiltersTemp.begin(); it != instance->customFiltersTemp.end(); ++it) - { - ComboBox_AddString(defFilter, it->name.c_str()); - ListBox_AddString(listFilter, it->name.c_str()); - } - ComboBox_SetCurSel(defFilter, instance->defFilter); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_FILTER), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_EVENT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_EVENT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), FALSE); - - Edit_LimitText(ftp, MAX_PATH); - Edit_LimitText(ftpLog, MAX_PATH); - Edit_SetText(ftp, instance->ftpExePath.c_str()); - Edit_SetText(ftpLog, instance->ftpLogPath.c_str()); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)TRUE); - return TRUE; - } - case WM_COMMAND: - { - BOOL init = (BOOL)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - if (HIWORD(wParam) == BN_CLICKED) - { - HWND listFilter = GetDlgItem(hwndDlg, IDC_LIST_FILTERS); - HWND listEvents = GetDlgItem(hwndDlg, IDC_LIST_EVENTS); - HWND nameFilter = GetDlgItem(hwndDlg, IDC_FILTER_NAME); - HWND defFilter = GetDlgItem(hwndDlg, IDC_DEFFILTER); - HWND eventCB = GetDlgItem(hwndDlg, IDC_EVENT); - switch(LOWORD(wParam)) - { - case IDC_ADD_FILTER: - { - TCHAR name[24]; - Edit_GetText(nameFilter, name, 24); - if(name[0] == 0) - { - MessageBox(hwndDlg, TranslateT("Enter filter name"), TranslateT("Error"), MB_ICONERROR); - return TRUE; - } - - FilterOptions fo(name); - for(std::vector::iterator it = instance->customFiltersTemp.begin(); it != instance->customFiltersTemp.end(); ++it) - { - if(it->name == fo.name) - { - MessageBox(hwndDlg, TranslateT("Filter name exists"), TranslateT("Error"), MB_ICONERROR); - return TRUE; - } - } - - instance->customFiltersTemp.insert(instance->customFiltersTemp.end(), fo); - int i = ListBox_AddString(listFilter, name); - ListBox_SetCurSel(listFilter, i); - ComboBox_AddString(defFilter, name); - name[0] = 0; - Edit_SetText(nameFilter, name); - ReloadEventLB(listEvents, instance->customFiltersTemp[i]); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_FILTER), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_EVENT), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_EVENT), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), FALSE); - } - break; - case IDC_DELETE_FILTER: - { - int sel = ListBox_GetCurSel(listFilter); - if(sel < 0) - return TRUE; - for(size_t i = sel; i < instance->customFiltersTemp.size() - 1; ++i) - { - instance->customFiltersTemp[i] = instance->customFiltersTemp[i + 1]; - } - - instance->customFiltersTemp.resize(instance->customFiltersTemp.size() - 1); - ListBox_DeleteString(listFilter, sel); - ComboBox_DeleteString(defFilter, sel + 2); - if(ComboBox_GetCurSel(defFilter) < 0) - { - ComboBox_SetCurSel(defFilter, 0); - } - - ClearLB(listEvents); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_FILTER), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_EVENT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_EVENT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), FALSE); - } - break; - case IDC_ADD_EVENT: - { - int sel = ListBox_GetCurSel(listFilter); - if(sel < 0) - return TRUE; - int eventId; - int selCB = GetEventCB(eventCB, true, eventId); - if(selCB < 0) - return TRUE; - if(selCB == 1) - { - if(instance->customFiltersTemp[sel].onlyIncomming) - { - MessageBox(hwndDlg, TranslateT("Event already exists"), TranslateT("Error"), MB_ICONERROR); - return TRUE; - } - - if(instance->customFiltersTemp[sel].onlyOutgoing) - instance->customFiltersTemp[sel].onlyOutgoing = false; - else - instance->customFiltersTemp[sel].onlyIncomming = true; - } - else if(selCB == 2) - { - if(instance->customFiltersTemp[sel].onlyOutgoing) - { - MessageBox(hwndDlg, TranslateT("Event already exists"), TranslateT("Error"), MB_ICONERROR); - return TRUE; - } - - if(instance->customFiltersTemp[sel].onlyIncomming) - instance->customFiltersTemp[sel].onlyIncomming = false; - else - instance->customFiltersTemp[sel].onlyOutgoing = true; - } - else - { - if(std::find(instance->customFiltersTemp[sel].events.begin(), instance->customFiltersTemp[sel].events.end(), eventId) != instance->customFiltersTemp[sel].events.end()) - { - MessageBox(hwndDlg, TranslateT("Event already exists"), TranslateT("Error"), MB_ICONERROR); - return TRUE; - } - - instance->customFiltersTemp[sel].events.push_back(eventId); - } - - ReloadEventLB(listEvents, instance->customFiltersTemp[sel]); - ComboBox_SetCurSel(eventCB, -1); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), FALSE); - } - break; - case IDC_DELETE_EVENT: - { - int sel = ListBox_GetCurSel(listFilter); - if(sel < 0) - return TRUE; - int eventSel = ListBox_GetCurSel(listEvents); - if(eventSel < 0) - return TRUE; - int stId = 0; - if(instance->customFiltersTemp[sel].onlyIncomming || instance->customFiltersTemp[sel].onlyOutgoing) - ++stId; - if(eventSel >= stId) - { - --eventSel; - for(int i = eventSel; i < (int)instance->customFiltersTemp[sel].events.size() - 1; ++i) - { - instance->customFiltersTemp[sel].events[i] = instance->customFiltersTemp[sel].events[i + 1]; - } - - instance->customFiltersTemp[sel].events.resize(instance->customFiltersTemp[sel].events.size() - 1); - } - else - { - instance->customFiltersTemp[sel].onlyIncomming = false; - instance->customFiltersTemp[sel].onlyOutgoing = false; - } - - ReloadEventLB(listEvents, instance->customFiltersTemp[sel]); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), FALSE); - } - break; - case IDC_WINSCP_BROWSE: - if(!OpenFileDlg(hwndDlg, GetDlgItem(hwndDlg, IDC_WINSCP), _T("WinSCP.exe"), _T("exe"), TranslateT("Browse WinSCP file"), true)) - { - return TRUE; - } - - break; - case IDC_WINSCPLOG_BROWSE: - if(!OpenFileDlg(hwndDlg, GetDlgItem(hwndDlg, IDC_WINSCPLOG), _T("ftplog.txt"), _T("txt"), TranslateT("Save WinSCP log file"), false)) - { - return TRUE; - } - - break; - } - } - else if(HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_LIST_FILTERS) - { - HWND listFilter = GetDlgItem(hwndDlg, IDC_LIST_FILTERS); - HWND listEvents = GetDlgItem(hwndDlg, IDC_LIST_EVENTS); - int sel = ListBox_GetCurSel(listFilter); - if(sel < 0) - ClearLB(listEvents); - else - ReloadEventLB(listEvents, instance->customFiltersTemp[sel]); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_FILTER), sel >= 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_EVENT), sel >= 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_EVENT), sel >= 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), FALSE); - } - else if(HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_LIST_EVENTS) - { - HWND listEvents = GetDlgItem(hwndDlg, IDC_LIST_EVENTS); - int sel = ListBox_GetCurSel(listEvents); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), sel >= 0); - } - - if (init && (HIWORD(wParam) == BN_CLICKED || (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_DEFFILTER) || (HIWORD(wParam) == EN_CHANGE && LOWORD(wParam) != IDC_FILTER_NAME))) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - return TRUE; - } - case WM_NOTIFY: - { - if(((LPNMHDR)lParam)->code == PSN_APPLY) - { - HWND ftp = GetDlgItem(hwndDlg, IDC_WINSCP); - TCHAR buf[MAX_PATH]; - Edit_GetText(ftp, buf, MAX_PATH); - if(buf[0] != 0 && !CheckFile(ftp)) - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - return TRUE; - } - - instance->ftpExePath = buf; - Edit_GetText(GetDlgItem(hwndDlg, IDC_WINSCPLOG), buf, MAX_PATH); - instance->ftpLogPath = buf; - - instance->showContacts = IsDlgButtonChecked(hwndDlg, IDC_SHOWCONTACTS) ? true : false; - instance->showContactGroups = IsDlgButtonChecked(hwndDlg, IDC_SHOWCONTACTGROUPS) ? true : false; - instance->defFilter = ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_DEFFILTER)); - instance->customFilters.clear(); - instance->customFilters.insert(instance->customFilters.begin(), instance->customFiltersTemp.begin(), instance->customFiltersTemp.end()); - Options::instance->Save(); - OptionsMainChanged(); - } - return TRUE; - } - } - - return FALSE; -} - -class OptsData -{ -public: - OptsData() - { - init = false; - } - - bool init; -}; - -INT_PTR CALLBACK Options::DlgProcOptsGroupList(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - OptsData* optsData = new OptsData(); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)optsData); - - CheckDlgButton(hwndDlg, IDC_NEWONTOP, instance->groupNewOnTop ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_SHOWEVENTS, instance->groupShowEvents ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_SHOWTIME, instance->groupShowTime ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_SHOWNAME, instance->groupShowName ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_SHOWMESSAGE, instance->groupShowMessage ? 1 : 0); - Edit_LimitText(GetDlgItem(hwndDlg, IDC_MESSAGELEN), 4); - SetDlgItemInt(hwndDlg, IDC_MESSAGELEN, instance->groupMessageLen, FALSE); - SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_SHOWMESSAGE, BN_CLICKED), NULL); - Edit_LimitText(GetDlgItem(hwndDlg, IDC_GROUPTIME), 2); - Edit_LimitText(GetDlgItem(hwndDlg, IDC_LIMITMESSAGES), 3); - SetDlgItemInt(hwndDlg, IDC_GROUPTIME, instance->groupTime, FALSE); - SetDlgItemInt(hwndDlg, IDC_LIMITMESSAGES, instance->groupMessagesNumber, FALSE); - - optsData->init = true; - return TRUE; - } - case WM_COMMAND: - { - OptsData* optsData = (OptsData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_SHOWMESSAGE) - { - if(IsDlgButtonChecked(hwndDlg, IDC_SHOWMESSAGE)) - { - EnableWindow(GetDlgItem(hwndDlg, IDC_MESSAGELEN), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_MESSAGELEN_DESC), TRUE); - } - else - { - EnableWindow(GetDlgItem(hwndDlg, IDC_MESSAGELEN), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_MESSAGELEN_DESC), FALSE); - } - } - if (optsData->init && (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == EN_CHANGE)) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - return TRUE; - } - case WM_NOTIFY: - { - if(((LPNMHDR)lParam)->code == PSN_APPLY) - { - instance->groupNewOnTop = IsDlgButtonChecked(hwndDlg, IDC_NEWONTOP) ? true : false; - instance->groupShowEvents = IsDlgButtonChecked(hwndDlg, IDC_SHOWEVENTS) ? true : false; - instance->groupShowTime = IsDlgButtonChecked(hwndDlg, IDC_SHOWTIME) ? true : false; - instance->groupShowName = IsDlgButtonChecked(hwndDlg, IDC_SHOWNAME) ? true : false; - instance->groupShowMessage = IsDlgButtonChecked(hwndDlg, IDC_SHOWMESSAGE) ? true : false; - BOOL success; - instance->groupMessageLen = GetDlgItemInt(hwndDlg, IDC_MESSAGELEN, &success, FALSE); - instance->groupTime = GetDlgItemInt(hwndDlg, IDC_GROUPTIME, &success, FALSE); - instance->groupMessagesNumber = GetDlgItemInt(hwndDlg, IDC_LIMITMESSAGES, &success, FALSE); - - Options::instance->Save(); - OptionsGroupChanged(); - } - return TRUE; - } - } - - return FALSE; -} - -INT_PTR CALLBACK Options::DlgProcOptsMessages(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - - CheckDlgButton(hwndDlg, IDC_NEWONTOP, instance->messagesNewOnTop ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_SHOWDATE, instance->messagesShowDate ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_SHOWSECOND, instance->messagesShowSec ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_SHOWNAME, instance->messagesShowName ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_SHOWEVENTS, instance->messagesShowEvents ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_SHOWSMILEYS, instance->messagesUseSmileys ? 1 : 0); - if(!g_SmileyAddAvail) - EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWSMILEYS), FALSE); - return TRUE; - } - case WM_COMMAND: - { - if (HIWORD(wParam) == BN_CLICKED) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - return TRUE; - } - case WM_NOTIFY: - { - if(((LPNMHDR)lParam)->code == PSN_APPLY) - { - instance->messagesNewOnTop = IsDlgButtonChecked(hwndDlg, IDC_NEWONTOP) ? true : false; - instance->messagesShowDate = IsDlgButtonChecked(hwndDlg, IDC_SHOWDATE) ? true : false; - instance->messagesShowSec = IsDlgButtonChecked(hwndDlg, IDC_SHOWSECOND) ? true : false; - instance->messagesShowName = IsDlgButtonChecked(hwndDlg, IDC_SHOWNAME) ? true : false; - instance->messagesShowEvents = IsDlgButtonChecked(hwndDlg, IDC_SHOWEVENTS) ? true : false; - instance->messagesUseSmileys = IsDlgButtonChecked(hwndDlg, IDC_SHOWSMILEYS) ? true : false; - - Options::instance->Save(); - OptionsMessageChanged(); - } - return TRUE; - } - } - - return FALSE; -} - -INT_PTR CALLBACK Options::DlgProcOptsSearching(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - - CheckDlgButton(hwndDlg, IDC_FORLIST, instance->searchForInList ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_FORMES, instance->searchForInMess ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_MATCHCASE, instance->searchMatchCase ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_MATCHWHOLE, instance->searchMatchWhole ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_ONLYIN, instance->searchOnlyIn ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_ONLYOUT, instance->searchOnlyOut ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_ONLYGROUP, instance->searchOnlyGroup ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_ALLCONTACTS, instance->searchAllContacts ? 1 : 0); - return TRUE; - } - case WM_COMMAND: - { - if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ONLYIN) - { - if(IsDlgButtonChecked(hwndDlg, IDC_ONLYIN) && IsDlgButtonChecked(hwndDlg, IDC_ONLYOUT)) - { - CheckDlgButton(hwndDlg, IDC_ONLYOUT, 0); - } - } - else if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ONLYOUT) - { - if(IsDlgButtonChecked(hwndDlg, IDC_ONLYOUT) && IsDlgButtonChecked(hwndDlg, IDC_ONLYIN)) - { - CheckDlgButton(hwndDlg, IDC_ONLYIN, 0); - } - } - - if (HIWORD(wParam) == BN_CLICKED) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - return TRUE; - } - case WM_NOTIFY: - { - if(((LPNMHDR)lParam)->code == PSN_APPLY) - { - instance->searchForInList = IsDlgButtonChecked(hwndDlg, IDC_FORLIST) ? true : false; - instance->searchForInMess = IsDlgButtonChecked(hwndDlg, IDC_FORMES) ? true : false; - instance->searchMatchCase = IsDlgButtonChecked(hwndDlg, IDC_MATCHCASE) ? true : false; - instance->searchMatchWhole = IsDlgButtonChecked(hwndDlg, IDC_MATCHWHOLE) ? true : false; - instance->searchOnlyIn = IsDlgButtonChecked(hwndDlg, IDC_ONLYIN) ? true : false; - instance->searchOnlyOut = IsDlgButtonChecked(hwndDlg, IDC_ONLYOUT) ? true : false; - instance->searchOnlyGroup = IsDlgButtonChecked(hwndDlg, IDC_ONLYGROUP) ? true : false; - instance->searchAllContacts = IsDlgButtonChecked(hwndDlg, IDC_ALLCONTACTS) ? true : false; - - Options::instance->Save(); - OptionsSearchingChanged(); - } - return TRUE; - } - } - - return FALSE; -} - -void InitCodepageCB(HWND hwndCB, unsigned int codepage, const std::wstring& name) -{ - int cpCount = sizeof(cpTable) / sizeof(cpTable[0]); - int selCpIdx = -1; - ComboBox_LimitText(hwndCB, 256); - for(int i = 0; i < cpCount; ++i) - { - ComboBox_AddString(hwndCB, TranslateTS(cpTable[i].cpName)); - if(cpTable[i].cpId == codepage && name == cpTable[i].cpName) - selCpIdx = i; - } - - if(selCpIdx == -1) - { - TCHAR buf[300]; - _stprintf_s(buf, 300, _T("%d;%s"), codepage, name.c_str()); - ComboBox_SetText(hwndCB, buf); - } - else - { - ComboBox_SetCurSel(hwndCB, selCpIdx); - } - - ComboBox_LimitText(hwndCB, 127); -} - -unsigned int GetCodepageCB(HWND hwndCB, bool errorReport, unsigned int defCp, const std::wstring& defName, std::wstring& name) -{ - int selCpIdx = ComboBox_GetCurSel(hwndCB); - if(selCpIdx < 0) - { - TCHAR text[128]; - ComboBox_GetText(hwndCB, text, 128); - std::wstring str = text; - name = _T(""); - size_t pos = str.find_first_of(_T(';')); - if(pos < str.length()) - { - text[pos] = 0; - name = str.substr(pos + 1); - } - - TCHAR * stopOn = NULL; - long cp = _tcstol(text, &stopOn, 10); - if((pos >= str.length() || name.empty() || stopOn == text || *stopOn != '\0' || cp < 0 || cp > 0xffff)) - { - if(errorReport) - { - MessageBox(GetParent(hwndCB), TranslateT("You've entered invalid codepage. Select codepage from combo box or enter correct number."), TranslateT("Invalid codepage"), MB_OK | MB_ICONERROR); - SetFocus(hwndCB); - } - - name = defName; - return -1; - } - - return cp; - } - else - { - name = cpTable[selCpIdx].cpName; - return cpTable[selCpIdx].cpId; - } -} - -INT_PTR CALLBACK Options::DlgProcOptsExport(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)FALSE); - InitCodepageCB(GetDlgItem(hwndDlg, IDC_TXTENC), instance->codepageTxt, instance->encodingTxt); - InitCodepageCB(GetDlgItem(hwndDlg, IDC_HTML1ENC), instance->codepageHtml1, instance->encodingHtml1); - InitCodepageCB(GetDlgItem(hwndDlg, IDC_HTML2ENC), instance->codepageHtml2, instance->encodingHtml2); - CheckDlgButton(hwndDlg, IDC_HTML1DATE, instance->exportHtml1ShowDate ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_HTML2DATE, instance->exportHtml2ShowDate ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_HTML2SHOWSMILEYS, instance->exportHtml2UseSmileys ? 1 : 0); - Edit_LimitText(GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE), MAX_PATH); - if(instance->extCssHtml2.empty()) - { - EnableWindow(GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_CSS_BROWSE), FALSE); - } - else - { - CheckDlgButton(hwndDlg, IDC_HTML2EXTCSS, TRUE); - Edit_SetText(GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE), instance->extCssHtml2.c_str()); - } - - if(!g_SmileyAddAvail) - EnableWindow(GetDlgItem(hwndDlg, IDC_HTML2SHOWSMILEYS), FALSE); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)TRUE); - return TRUE; - } - case WM_COMMAND: - { - BOOL init = (BOOL)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_HTML2EXTCSS) - { - BOOL en = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_HTML2EXTCSS); - EnableWindow(GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE), en); - EnableWindow(GetDlgItem(hwndDlg, IDC_CSS_BROWSE), en); - } - else if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_CSS_BROWSE) - { - if(!OpenFileDlg(hwndDlg, GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE), _T(""), _T("css"), TranslateT("Browse CSS file"), true)) - { - return TRUE; - } - } - - if (init && (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)==CBN_EDITCHANGE || HIWORD(wParam) == EN_CHANGE)) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - return TRUE; - } - case WM_NOTIFY: - { - if(((LPNMHDR)lParam)->code == PSN_APPLY) - { - std::wstring newName1, newName2, newName3; - unsigned int cp1 = GetCodepageCB(GetDlgItem(hwndDlg, IDC_TXTENC), true, instance->codepageTxt, instance->encodingTxt, newName1); - if(cp1 == -1) - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - return TRUE; - } - unsigned int cp2 = GetCodepageCB(GetDlgItem(hwndDlg, IDC_HTML1ENC), true, instance->codepageHtml1, instance->encodingHtml1, newName2); - if(cp2 == -1) - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - return TRUE; - } - unsigned int cp3 = GetCodepageCB(GetDlgItem(hwndDlg, IDC_HTML2ENC), true, instance->codepageHtml2, instance->encodingHtml2, newName3); - if(cp3 == -1) - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - return TRUE; - } - if(IsDlgButtonChecked(hwndDlg, IDC_HTML2EXTCSS)) - { - if(!CheckFile(GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE))) - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - return TRUE; - } - - TCHAR buf[MAX_PATH]; - Edit_GetText(GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE), buf, MAX_PATH); - instance->extCssHtml2 = buf; - } - else - { - instance->extCssHtml2 = _T(""); - } - - instance->codepageTxt = cp1; - instance->encodingTxt = newName1; - instance->codepageHtml1 = cp2; - instance->encodingHtml1 = newName2; - instance->codepageHtml2 = cp3; - instance->encodingHtml2 = newName3; - instance->exportHtml1ShowDate = IsDlgButtonChecked(hwndDlg, IDC_HTML1DATE) ? true : false; - instance->exportHtml2ShowDate = IsDlgButtonChecked(hwndDlg, IDC_HTML2DATE) ? true : false; - instance->exportHtml2UseSmileys = IsDlgButtonChecked(hwndDlg, IDC_HTML2SHOWSMILEYS) ? true : false; - - Options::instance->Save(); - } - return TRUE; - } - } - - return FALSE; -} - - -struct DlgTaskOpt -{ - std::list* tasks; - TaskOptions* to; -}; - -INT_PTR CALLBACK Options::DlgProcOptsScheduler(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - std::list* tasks = new std::list(Options::instance->taskOptions.begin(), Options::instance->taskOptions.end()); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)tasks); - HWND listTasks = GetDlgItem(hwndDlg, IDC_LIST_TASKS); - for(std::list::iterator it = tasks->begin(); it != tasks->end(); ++it) - { - ListBox_AddString(listTasks, it->taskName.c_str()); - } - - if(!bPopupsEnabled) - { - EnableWindow(GetDlgItem(hwndDlg, IDC_SCHEDULER_ALERTS), FALSE); - } - - CheckDlgButton(hwndDlg, IDC_SCHEDULER_ALERTS, instance->schedulerAlerts ? 1 : 0); - CheckDlgButton(hwndDlg, IDC_SCHEDULER_HISTORY_ALERTS, instance->schedulerHistoryAlerts ? 1 : 0); - - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_TASK), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_TASK), FALSE); - return TRUE; - } - case WM_COMMAND: - { - if(HIWORD(wParam) == BN_CLICKED) - { - std::list* tasks = (std::list*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - HWND listTasks = GetDlgItem(hwndDlg, IDC_LIST_TASKS); - int sel = ListBox_GetCurSel(listTasks); - TaskOptions toAdd; - TaskOptions* to = &toAdd; - switch(LOWORD(wParam)) - { - case IDC_EDIT_TASK: - if(sel >= 0) - { - std::list::iterator it = tasks->begin(); - while(sel-- > 0 && it != tasks->end()) - ++it; - if(it == tasks->end()) - break; - to = &(*it); - } - else - break; - case IDC_ADD_TASK: - { - DlgTaskOpt top; - top.tasks = tasks; - top.to = to; - if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_DLG_TASK), hwndDlg, DlgProcOptsTask, (LPARAM)&top) == IDOK) - { - if(LOWORD(wParam) == IDC_ADD_TASK) - { - tasks->push_back(*to); - ListBox_AddString(listTasks, to->taskName.c_str()); - ListBox_SetCurSel(listTasks, tasks->size() - 1); - } - else - { - sel = ListBox_GetCurSel(listTasks); - ListBox_DeleteString(listTasks, sel); - ListBox_InsertString(listTasks, sel, to->taskName.c_str()); - ListBox_SetCurSel(listTasks, sel); - } - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_TASK), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_TASK), TRUE); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - - break; - case IDC_DELETE_TASK: - if(sel >= 0) - { - ListBox_DeleteString(listTasks, sel); - std::list::iterator it = tasks->begin(); - while(sel-- > 0 && it != tasks->end()) - ++it; - if(it != tasks->end()) - tasks->erase(it); - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_TASK), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_TASK), FALSE); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - - break; - default: - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - else if(HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_LIST_TASKS) - { - HWND listTasks = GetDlgItem(hwndDlg, IDC_LIST_TASKS); - int sel = ListBox_GetCurSel(listTasks); - if(sel < 0) - { - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_TASK), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_TASK), FALSE); - } - else - { - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_TASK), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_TASK), TRUE); - } - } - return TRUE; - } - case WM_NOTIFY: - { - if(((LPNMHDR)lParam)->code == PSN_APPLY) - { - std::list* tasks = (std::list*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - instance->schedulerAlerts = IsDlgButtonChecked(hwndDlg, IDC_SCHEDULER_ALERTS) ? true : false; - instance->schedulerHistoryAlerts = IsDlgButtonChecked(hwndDlg, IDC_SCHEDULER_HISTORY_ALERTS) ? true : false; - Options::instance->SaveTasks(tasks); - OptionsSchedulerChanged(); - InitTaskMenuItems(); - } - return TRUE; - } - case WM_DESTROY: - { - std::list* tasks = (std::list*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - delete tasks; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, NULL); - break; - } - } - - return FALSE; -} - -void ResetListOptions(HWND hwnd) -{ - SendMessage(hwnd, CLM_SETGREYOUTFLAGS, 0, 0); - SendMessage(hwnd, CLM_SETLEFTMARGIN, 2, 0); - SendMessage(hwnd, CLM_SETBKBITMAP, 0, (LPARAM)(HBITMAP) NULL); - SendMessage(hwnd, CLM_SETBKCOLOR, GetSysColor(COLOR_WINDOW), 0); - SendMessage(hwnd, CLM_SETINDENT, 10, 0); - for (int i = 0; i <= FONTID_MAX; i++) - SendMessage(hwnd, CLM_SETTEXTCOLOR, i, GetSysColor(COLOR_WINDOWTEXT)); -} - -void RebuildList(HWND hwnd, HANDLE hSystem, TaskOptions* to) -{ - HANDLE hItem; - if(to->isSystem && hSystem) - { - SendMessage(hwnd, CLM_SETCHECKMARK, (WPARAM) hSystem, 1); - } - - for(size_t i = 0; i < to->contacts.size(); ++i) - { - hItem = (HANDLE) SendMessage(hwnd, CLM_FINDCONTACT, (WPARAM) to->contacts[i], 0); - if (hItem) - SendMessage(hwnd, CLM_SETCHECKMARK, (WPARAM) hItem, 1); - } -} - -void SaveList(HWND hwnd, HANDLE hSystem, TaskOptions* to) -{ - HANDLE hContact, hItem; - - to->contacts.clear(); - if (hSystem) - to->isSystem = SendMessage(hwnd, CLM_GETCHECKMARK, (WPARAM) hSystem, 0) != 0; - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - do - { - hItem = (HANDLE) SendMessage(hwnd, CLM_FINDCONTACT, (WPARAM) hContact, 0); - if (hItem && SendMessage(hwnd, CLM_GETCHECKMARK, (WPARAM) hItem, 0)) - to->contacts.push_back(hContact); - } - while (hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0)); -} - -bool IsValidTask(TaskOptions& to, std::list* top = NULL, std::wstring* err = NULL, std::wstring* errDescr = NULL); - -#ifndef LOCALE_SSHORTTIME -#define LOCALE_SSHORTTIME 0x00000079 -#endif - -INT_PTR CALLBACK Options::DlgProcOptsTask(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static HANDLE hSystem; - switch(msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - DlgTaskOpt* top = (DlgTaskOpt*)lParam; - TaskOptions* to = top->to; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - HWND comboType = GetDlgItem(hwndDlg, IDC_TASK_TYPE); - HWND filter = GetDlgItem(hwndDlg, IDC_TASK_FILTER); - HWND eventUnit = GetDlgItem(hwndDlg, IDC_EVENT_UNIT); - HWND trigerType = GetDlgItem(hwndDlg, IDC_TRIGER_TYPE); - HWND exportType = GetDlgItem(hwndDlg, IDC_EXPORT_TYPE); - HWND importType = GetDlgItem(hwndDlg, IDC_IMPORT_TYPE); - HWND compress = GetDlgItem(hwndDlg, IDC_COMPRESS); - HWND exportPath = GetDlgItem(hwndDlg, IDC_EXPORT_PATH); - HWND ftpFile = GetDlgItem(hwndDlg, IDC_FTP); - HWND ftpFileButton = GetDlgItem(hwndDlg, IDC_UPLOAD); - HWND contactList = GetDlgItem(hwndDlg, IDC_LIST_CONTACTSEX); - HWND weekList = GetDlgItem(hwndDlg, IDC_TRIGER_WEEK); - HWND day = GetDlgItem(hwndDlg, IDC_TRIGER_DAY); - HWND deltaTime = GetDlgItem(hwndDlg, IDC_TRIGER_DELTA_TIME); - HWND time = GetDlgItem(hwndDlg, IDC_TRIGER_TIME); - HWND name = GetDlgItem(hwndDlg, IDC_TASK_NAME); - HWND active = GetDlgItem(hwndDlg, IDC_TASK_ACTIVE); - HWND star = GetDlgItem(hwndDlg, IDC_TASK_STAR); - HWND password = GetDlgItem(hwndDlg, IDC_PASSWORD); - HWND expImp = GetDlgItem(hwndDlg, IDC_EXPIMP); - - Edit_LimitText(name, 16); - Edit_SetText(name, to->taskName.c_str()); - - Button_SetCheck(active, to->active); - - Button_SetCheck(expImp, to->exportImported); - - ComboBox_AddString(comboType, TranslateT("Export")); - ComboBox_AddString(comboType, TranslateT("Delete")); - ComboBox_AddString(comboType, TranslateT("Export and Delete")); - ComboBox_AddString(comboType, TranslateT("Import")); - ComboBox_AddString(comboType, TranslateT("Import and Marge")); - ComboBox_SetCurSel(comboType, to->type); - - Edit_LimitText(GetDlgItem(hwndDlg, IDC_EVENT_TIME), 6); - SetDlgItemInt(hwndDlg, IDC_EVENT_TIME, to->eventDeltaTime, TRUE); - ComboBox_AddString(eventUnit, TranslateT("Minute")); - ComboBox_AddString(eventUnit, TranslateT("Hour")); - ComboBox_AddString(eventUnit, TranslateT("Day")); - ComboBox_SetCurSel(eventUnit, to->eventUnit); - - ComboBox_AddString(filter, TranslateT("Default history events")); - ComboBox_AddString(filter, TranslateT("All events")); - int selFilter = to->filterId; - if(selFilter > 1) - selFilter = 0; - int i = 1; - for(std::vector::iterator it = instance->customFilters.begin(); it != instance->customFilters.end(); ++it) - { - ++i; - ComboBox_AddString(filter, it->name.c_str()); - if(to->filterId > 1 && it->name == to->filterName) - { - selFilter = i; - } - } - ComboBox_SetCurSel(filter, selFilter); - - ComboBox_AddString(trigerType, TranslateT("At Start")); - ComboBox_AddString(trigerType, TranslateT("At Finish")); - ComboBox_AddString(trigerType, TranslateT("Daily")); - ComboBox_AddString(trigerType, TranslateT("Weekly")); - ComboBox_AddString(trigerType, TranslateT("Monthly")); - ComboBox_AddString(trigerType, TranslateT("Delta time (minutes)")); - ComboBox_AddString(trigerType, TranslateT("Delta time (hours)")); - ComboBox_SetCurSel(trigerType, to->trigerType); - - ComboBox_AddString(exportType, TranslateT("Rich Html")); - ComboBox_AddString(exportType, TranslateT("Plain Html")); - ComboBox_AddString(exportType, TranslateT("Txt")); - ComboBox_AddString(exportType, TranslateT("Binary")); - ComboBox_AddString(exportType, TranslateT("Dat (mContacts)")); - ComboBox_SetCurSel(exportType, to->exportType); - - ComboBox_AddString(importType, TranslateT("Binary")); - ComboBox_AddString(importType, TranslateT("Dat (mContacts)")); - ComboBox_SetCurSel(importType, to->importType); - - Button_SetCheck(compress, to->compress); - Edit_LimitText(password, 99); - SetWindowTextA(password, to->zipPassword.c_str()); - - Edit_LimitText(exportPath, MAX_PATH); - Edit_SetText(exportPath, to->filePath.c_str()); - - if(!FTPAvail()) - { - EnableWindow(ftpFile, FALSE); - EnableWindow(ftpFileButton, FALSE); - to->useFtp = false; - } - - Button_SetCheck(ftpFileButton, to->useFtp); - Edit_SetText(ftpFile, to->ftpName.c_str()); - - ComboBox_AddString(weekList, TranslateT("Monday")); - ComboBox_AddString(weekList, TranslateT("Tuesday")); - ComboBox_AddString(weekList, TranslateT("Wednesday")); - ComboBox_AddString(weekList, TranslateT("Thursday")); - ComboBox_AddString(weekList, TranslateT("Friday")); - ComboBox_AddString(weekList, TranslateT("Saturday")); - ComboBox_AddString(weekList, TranslateT("Sunday")); - ComboBox_SetCurSel(weekList, to->dayOfWeek); - - Edit_LimitText(day, 2); - SetDlgItemInt(hwndDlg, IDC_TRIGER_DAY, to->dayOfMonth, FALSE); - - Edit_LimitText(deltaTime, 4); - SetDlgItemInt(hwndDlg, IDC_TRIGER_DELTA_TIME, to->deltaTime, FALSE); - - TCHAR timeFormat[10]; - if(GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SSHORTTIME, timeFormat, 10) == 0) - { - TCHAR sep = _T(':'); - if(GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIME, timeFormat, 10) > 0) - sep = timeFormat[0]; - _stprintf_s(timeFormat, _T("HH%cmm"), sep); - } - - SYSTEMTIME st; - GetSystemTime (&st); - st.wHour = to->dayTime/60; - st.wMinute = to->dayTime%60; - st.wSecond = 0; - st.wMilliseconds = 0; - DateTime_SetFormat(time, timeFormat); - DateTime_SetSystemtime(time, GDT_VALID, &st); - - CLCINFOITEM cii = { 0 }; - cii.cbSize = sizeof(cii); - cii.flags = CLCIIF_GROUPFONT | CLCIIF_CHECKBOX | CLCIIF_BELOWCONTACTS; - cii.pszText = TranslateT("System"); - hSystem = (HANDLE) SendMessage(contactList, CLM_ADDINFOITEM, 0, (LPARAM) & cii); - SendMessage(contactList, CLM_AUTOREBUILD, 0, 0); - ResetListOptions(contactList); - RebuildList(contactList, hSystem, to); - - SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_TASK_TYPE, CBN_SELCHANGE), NULL); - SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_TRIGER_TYPE, CBN_SELCHANGE), NULL); - SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_COMPRESS, BN_CLICKED), NULL); - SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_UPLOAD, BN_CLICKED), NULL); - SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_COMPRESS, BN_CLICKED), NULL); - return TRUE; - } - case WM_COMMAND: - { - if (HIWORD(wParam) == BN_CLICKED) - { - if (LOWORD(wParam) == IDOK) - { - DlgTaskOpt* top = (DlgTaskOpt*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - TaskOptions* to = top->to; - TaskOptions toCp(*to); - toCp.taskName.resize(17); - int nameLen = Edit_GetText(GetDlgItem(hwndDlg, IDC_TASK_NAME), (wchar_t*)toCp.taskName.c_str(), 17); - toCp.taskName.resize(nameLen); - toCp.active = Button_GetCheck(GetDlgItem(hwndDlg, IDC_TASK_ACTIVE)) != 0; - toCp.exportImported = Button_GetCheck(GetDlgItem(hwndDlg, IDC_EXPIMP)) != 0; - toCp.type = (enum TaskOptions::TaskType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_TASK_TYPE)); - toCp.filterId = ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_TASK_FILTER)); - if(toCp.filterId > 1) - toCp.filterName = instance->customFilters[toCp.filterId - 2].name; - BOOL isOK = FALSE; - toCp.eventDeltaTime = GetDlgItemInt(hwndDlg, IDC_EVENT_TIME, &isOK, TRUE); - if(!isOK) - { - TCHAR msg[256]; - _stprintf_s(msg, TranslateT("Invalid '%s' value."), TranslateT("Events older than")); - MessageBox(hwndDlg, msg, TranslateT("Error"), MB_ICONERROR); - break; - } - toCp.eventUnit = (enum TaskOptions::EventUnit)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_EVENT_UNIT)); - toCp.trigerType = (enum TaskOptions::TrigerType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_TRIGER_TYPE)); - toCp.exportType = (enum IExport::ExportType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_EXPORT_TYPE)); - toCp.importType = (enum IImport::ImportType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_IMPORT_TYPE)); - toCp.compress = Button_GetCheck(GetDlgItem(hwndDlg, IDC_COMPRESS)) != 0; - char bufC[100]; - GetWindowTextA(GetDlgItem(hwndDlg, IDC_PASSWORD), bufC, 100); - toCp.zipPassword = bufC; - HWND exportPath = GetDlgItem(hwndDlg, IDC_EXPORT_PATH); - int exLen = Edit_GetTextLength(exportPath); - toCp.filePath.resize(exLen + 1); - Edit_GetText(exportPath, (wchar_t*)toCp.filePath.c_str(), exLen + 1); - toCp.filePath.resize(exLen); - toCp.useFtp = Button_GetCheck(GetDlgItem(hwndDlg, IDC_UPLOAD)) != 0; - HWND ftpFile = GetDlgItem(hwndDlg, IDC_FTP); - exLen = Edit_GetTextLength(ftpFile); - toCp.ftpName.resize(exLen + 1); - Edit_GetText(ftpFile, (wchar_t*)toCp.ftpName.c_str(), exLen + 1); - toCp.ftpName.resize(exLen); - SYSTEMTIME st; - DateTime_GetSystemtime(GetDlgItem(hwndDlg, IDC_TRIGER_TIME), &st); - toCp.dayTime = st.wHour * 60 + st.wMinute; - toCp.dayOfWeek = ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_TRIGER_WEEK)); - toCp.dayOfMonth = GetDlgItemInt(hwndDlg, IDC_TRIGER_DAY, &isOK, FALSE); - if(!isOK) - { - if(toCp.trigerType == TaskOptions::Monthly) - { - TCHAR msg[256]; - _stprintf_s(msg, TranslateT("Invalid '%s' value."), TranslateT("Day")); - MessageBox(hwndDlg, msg, TranslateT("Error"), MB_ICONERROR); - break; - } - else - toCp.dayOfMonth = to->dayOfMonth; - } - toCp.deltaTime = GetDlgItemInt(hwndDlg, IDC_TRIGER_DELTA_TIME, &isOK, FALSE); - if(!isOK) - { - if(toCp.trigerType == TaskOptions::DeltaMin || toCp.trigerType == TaskOptions::DeltaHour) - { - TCHAR msg[256]; - _stprintf_s(msg, TranslateT("Invalid '%s' value."), TranslateT("Delta time")); - MessageBox(hwndDlg, msg, TranslateT("Error"), MB_ICONERROR); - break; - } - else - toCp.deltaTime = to->deltaTime; - } - SaveList(GetDlgItem(hwndDlg, IDC_LIST_CONTACTSEX), hSystem, &toCp); - std::wstring err; - std::wstring errDescr; - std::wstring lastName = to->taskName; - to->taskName = L""; - if(!IsValidTask(toCp, top->tasks, &err, &errDescr)) - { - to->taskName = lastName; - TCHAR msg[256]; - if(err.empty()) - _tcscpy_s(msg, TranslateT("Some value is invalid")); - else if(errDescr.empty()) - { - _stprintf_s(msg, TranslateT("Invalid '%s' value."), err.c_str()); - } - else - { - _stprintf_s(msg, TranslateT("Invalid '%s' value.\n%s"), err.c_str(), errDescr.c_str()); - } - - MessageBox(hwndDlg, msg, TranslateT("Error"), MB_ICONERROR); - break; - } - - toCp.lastExport = time(NULL); - - *to = toCp; - EndDialog(hwndDlg, IDOK); - } - else if (LOWORD(wParam) == IDCANCEL) - { - EndDialog(hwndDlg, IDCANCEL); - } - else if (LOWORD(wParam) == IDC_UPLOAD) - { - if(Button_GetCheck(GetDlgItem(hwndDlg, IDC_UPLOAD)) == 0) - { - EnableWindow(GetDlgItem(hwndDlg, IDC_FTP), FALSE); - } - else - { - EnableWindow(GetDlgItem(hwndDlg, IDC_FTP), TRUE); - } - } - else if(LOWORD(wParam) == IDC_COMPRESS) - { - if(Button_GetCheck(GetDlgItem(hwndDlg, IDC_COMPRESS)) == 0) - { - EnableWindow(GetDlgItem(hwndDlg, IDC_PASSWORD), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_PASSWORD_LABEL), FALSE); - } - else - { - EnableWindow(GetDlgItem(hwndDlg, IDC_PASSWORD), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_PASSWORD_LABEL), TRUE); - } - } - } - else if (HIWORD(wParam) == CBN_SELCHANGE) - { - if(LOWORD(wParam) == IDC_TASK_TYPE) - { - TaskOptions::TaskType sel = (enum TaskOptions::TaskType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_TASK_TYPE)); - int show = sel == TaskOptions::Delete ? SW_HIDE : SW_SHOW; - int showFilter = (sel == TaskOptions::Import || sel == TaskOptions::ImportAndMarge) ? SW_HIDE : SW_SHOW; - int showImport = (sel == TaskOptions::Import || sel == TaskOptions::ImportAndMarge) ? SW_SHOW : SW_HIDE; - ShowWindow(GetDlgItem(hwndDlg, IDC_EXPORT_TYPE), show); - ShowWindow(GetDlgItem(hwndDlg, IDC_EXPORT_TYPE_LABEL), show); - ShowWindow(GetDlgItem(hwndDlg, IDC_COMPRESS), show); - ShowWindow(GetDlgItem(hwndDlg, IDC_PASSWORD), show); - ShowWindow(GetDlgItem(hwndDlg, IDC_PASSWORD_LABEL), show); - ShowWindow(GetDlgItem(hwndDlg, IDC_EXPORT_PATH), show); - ShowWindow(GetDlgItem(hwndDlg, IDC_EXPORT_PATH_LABEL), show); - ShowWindow(GetDlgItem(hwndDlg, IDC_FTP), show); - ShowWindow(GetDlgItem(hwndDlg, IDC_UPLOAD), show); - ShowWindow(GetDlgItem(hwndDlg, IDC_FTP_LABEL), show); - ShowWindow(GetDlgItem(hwndDlg, IDC_EXPIMP), show); - ShowWindow(GetDlgItem(hwndDlg, IDC_TASK_FILTER), showFilter); - ShowWindow(GetDlgItem(hwndDlg, IDC_TASK_FILTER_LABEL), showFilter); - ShowWindow(GetDlgItem(hwndDlg, IDC_EVENT_TIME), showFilter); - ShowWindow(GetDlgItem(hwndDlg, IDC_EVENT_UNIT), showFilter); - ShowWindow(GetDlgItem(hwndDlg, IDC_EVENT_LABEL), showFilter); - if(show != showFilter) - { - ShowWindow(GetDlgItem(hwndDlg, IDC_EXPORT_TYPE), SW_HIDE); - ShowWindow(GetDlgItem(hwndDlg, IDC_EXPIMP), SW_HIDE); - } - - ShowWindow(GetDlgItem(hwndDlg, IDC_IMPORT_TYPE), showImport); - std::wstring str; - TCHAR* compressText = TranslateT("Compress output files"); - TCHAR* uploadText = TranslateT("Upload to FTP (WinSCP requred)"); - TCHAR* typeText = TranslateT("Export to"); - if(showFilter == SW_HIDE) - { - str = TranslateT("** Use to insert extension, to insert contact name"); - compressText = TranslateT("Input files are compressed"); - uploadText = TranslateT("Download from FTP (WinSCP requred)"); - typeText = TranslateT("Import from"); - } - else if(show == SW_HIDE) - { - str = TranslateT("* Use negative values to filter younger events"); - } - else - { - str = TranslateT("* Use negative values to filter younger events"); - str += _T("\n"); - str += TranslateT("** Use to insert date, to insert extension, to insert contact name"); - } - - Static_SetText(GetDlgItem(hwndDlg, IDC_TASK_STAR), str.c_str()); - Button_SetText(GetDlgItem(hwndDlg, IDC_COMPRESS), compressText); - Button_SetText(GetDlgItem(hwndDlg, IDC_UPLOAD), uploadText); - Static_SetText(GetDlgItem(hwndDlg, IDC_EXPORT_TYPE_LABEL), typeText); - } - else if(LOWORD(wParam) == IDC_TRIGER_TYPE) - { - TaskOptions::TrigerType sel = (enum TaskOptions::TrigerType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_TRIGER_TYPE)); - int showT = (sel == TaskOptions::Daily || sel == TaskOptions::Weekly || sel == TaskOptions::Monthly) ? SW_SHOW : SW_HIDE; - int showW = sel == TaskOptions::Weekly ? SW_SHOW : SW_HIDE; - int showM = sel == TaskOptions::Monthly ? SW_SHOW : SW_HIDE; - int showDT = (sel == TaskOptions::DeltaMin || sel == TaskOptions::DeltaHour) ? SW_SHOW : SW_HIDE; - ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_TIME), showT); - ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_TIME_LABEL), showT); - ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_WEEK), showW); - ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_WEEK_LABEL), showW); - ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_DAY), showM); - ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_DAY_LABEL), showM); - ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_DELTA_TIME), showDT); - ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_DELTA_TIME_LABEL), showDT); - } - } - return TRUE; - } - case WM_NOTIFY: - { - NMHDR* nmhdr = (NMHDR *) lParam; - if (nmhdr->idFrom == IDC_LIST_CONTACTSEX && nmhdr->code == CLN_OPTIONSCHANGED) - { - ResetListOptions(hwndDlg); - } - - return TRUE; - } - } - - return FALSE; -} - -bool Options::FTPAvail() -{ - DWORD atr = GetFileAttributes(instance->ftpExePath.c_str()); - return !(atr == INVALID_FILE_ATTRIBUTES || atr & FILE_ATTRIBUTE_DIRECTORY); -} diff --git a/plugins/BasicHistory/Options.h b/plugins/BasicHistory/Options.h deleted file mode 100644 index 4a5d17229c..0000000000 --- a/plugins/BasicHistory/Options.h +++ /dev/null @@ -1,199 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once -#include "IImport.h" -#include "IExport.h" - -struct FilterOptions -{ - FilterOptions() - :onlyIncomming(false), - onlyOutgoing(false) - { - } - - FilterOptions(const std::wstring& _name) - :name(_name), - onlyIncomming(false), - onlyOutgoing(false) - { - } - - std::wstring name; - std::vector events; - bool onlyIncomming; - bool onlyOutgoing; -}; - -struct TaskOptions -{ - bool compress; - bool useFtp; - bool isSystem; - bool active; - bool forceExecute; - bool showMBAfterExecute; - bool exportImported; - enum TaskType - { - Export, - Delete, - ExportAndDelete, - Import, - ImportAndMarge - } type; - - enum EventUnit - { - Minute, - Hour, - Day - } eventUnit; - - enum TrigerType - { - AtStart, - AtEnd, - Daily, - Weekly, - Monthly, - DeltaMin, - DeltaHour - } trigerType; - - IExport::ExportType exportType; - IImport::ImportType importType; - int eventDeltaTime; - int filterId; - int dayTime; - int dayOfWeek; - int dayOfMonth; - int deltaTime; - int orderNr; - time_t lastExport; - std::wstring ftpName; - std::wstring filterName; - std::wstring filePath; - std::wstring taskName; - std::string zipPassword; // char* because zip file using ANSI password - std::vector contacts; - TaskOptions() - { - forceExecute = false; - showMBAfterExecute = false; - exportImported = true; - type = Export; - eventUnit = Hour; - trigerType = AtStart; - exportType = IExport::RichHtml; - importType = IImport::Binary; - eventDeltaTime = 0; - filterId = 0; - compress = true; - useFtp = false; - isSystem = false; - active = true; - dayTime = 20 * 60; - dayOfWeek = 0; - dayOfMonth = 1; - deltaTime = 24; - orderNr = 0; - TCHAR buf[MAX_PATH]; - if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, buf))) - { - filePath = buf; - filePath += _T("\\"); - } - - filePath += TranslateT("History"); - filePath += _T("__."); - lastExport = time(NULL); - } -}; - -class Options -{ -private: - std::vector customFiltersTemp; -public: - Options(); - ~Options(); - static int InitOptions(WPARAM wParam, LPARAM lParam); - - static INT_PTR CALLBACK DlgProcOptsMain(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK DlgProcOptsGroupList(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK DlgProcOptsMessages(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK DlgProcOptsSearching(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK DlgProcOptsExport(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK DlgProcOptsScheduler(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK DlgProcOptsTask(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - static bool FTPAvail(); - - static Options *instance; - void Save(); - void SaveTasks(std::list* tasks); - void SaveTaskTime(TaskOptions& to); - void Load(void); - void LoadTasks(); - void Unload(); - - bool showContacts, showContactGroups, groupNewOnTop, groupShowEvents, groupShowTime, groupShowName, groupShowMessage; - bool messagesNewOnTop, messagesShowDate, messagesShowSec, messagesShowName, messagesShowEvents, messagesUseSmileys; - bool searchForInList, searchForInMess, searchMatchCase, searchMatchWhole, searchOnlyIn, searchOnlyOut, searchOnlyGroup, searchAllContacts; - bool schedulerAlerts, schedulerHistoryAlerts; - int groupMessageLen, groupTime, groupMessagesNumber; - - std::vector customFilters; - int defFilter; - unsigned int codepageTxt, codepageHtml1, codepageHtml2; - std::wstring encodingTxt, encodingHtml1, encodingHtml2; - bool exportHtml1ShowDate, exportHtml2ShowDate, exportHtml2UseSmileys; - std::wstring extCssHtml2; - std::vector taskOptions; - std::wstring ftpLogPath; - std::wstring ftpExePathDef; - std::wstring ftpExePath; - CRITICAL_SECTION criticalSection; - - enum Fonts - { - OutTimestamp = 0, - InTimestamp, - OutName, - InName, - OutMessages, - InMessages, - GroupList, - Find, - }; - - enum Colors - { - OutBackground = 0, - InBackground, - GroupListBackground, - WindowBackground, - ContactListBackground, - FindBackground, - }; - - COLORREF GetFont(Fonts fontId, PLOGFONT font); - COLORREF GetColor(Colors colorId); -}; - diff --git a/plugins/BasicHistory/PlainHtmlExport.cpp b/plugins/BasicHistory/PlainHtmlExport.cpp deleted file mode 100644 index 050b4e457e..0000000000 --- a/plugins/BasicHistory/PlainHtmlExport.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "StdAfx.h" -#include "PlainHtmlExport.h" -#include "Options.h" -#define EXP_FILE (*stream) - -PlainHtmlExport::~PlainHtmlExport() -{ -} - -extern std::wstring MakeTextHtmled(const std::wstring& message, std::queue >* positionMap = NULL); -extern std::wstring UrlHighlightHtml(const std::wstring& message, bool& isUrl); - -void PlainHtmlExport::WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding) -{ - EXP_FILE << _T("\n"); - EXP_FILE << _T("\n\n"); - EXP_FILE << _T("") << TranslateT("History Log") << _T(" [") << MakeTextHtmled(myName) << _T("] - [") << MakeTextHtmled(name1) << _T("]\n"); - EXP_FILE << _T("\n\n

") << TranslateT("History Log") << _T("

\n

"); - EXP_FILE << MakeTextHtmled(myName); - if(proto1.length() || myId.length()) - { - EXP_FILE << _T(" (") << MakeTextHtmled(proto1) << _T(": ") << MakeTextHtmled(myId) << _T(") - "); - } - else - { - EXP_FILE << _T(" - "); - } - - EXP_FILE << MakeTextHtmled(name1); - if(proto1.length() || id1.length()) - { - EXP_FILE << _T(" (") << MakeTextHtmled(proto1) << _T(": ") << MakeTextHtmled(id1) << _T(")

\n"); - } - else - { - EXP_FILE << _T("\n"); - } - - EXP_FILE << _T("
") << TranslateT("Filter:") << _T(" ") << MakeTextHtmled(filterName) << _T("
\n"); -} - -void PlainHtmlExport::WriteFooter() -{ - EXP_FILE << _T("
\n\n"); -} - -void PlainHtmlExport::WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText) -{ - TCHAR buf[256]; - EXP_FILE << _T("
\n"); - _stprintf_s(buf, TranslateT("Conversation started at %s"), time.c_str()); - EXP_FILE << _T("
") << buf << _T("
\n"); - EXP_FILE << _T("
\n"); -} - -void PlainHtmlExport::WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei) -{ - TCHAR *id = isMe ? _T("out") : _T("inc"); - TCHAR* ev = (isMe ? _T("1") : _T("0")); - bool isUrl = false; - std::wstring& mes = UrlHighlightHtml(MakeTextHtmled(message), isUrl); - if(isUrl) - ev = _T("2"); - EXP_FILE << _T("
\n"); - EXP_FILE << _T("
") << MakeTextHtmled(user) << _T(":
\n"); - EXP_FILE << _T("
") << (Options::instance->exportHtml1ShowDate ? longDate : shortDate) << _T("
\n"); - EXP_FILE << _T("
\n"); - EXP_FILE << mes; - EXP_FILE << _T("\n
\n"); - EXP_FILE << _T("
\n"); -} diff --git a/plugins/BasicHistory/PlainHtmlExport.h b/plugins/BasicHistory/PlainHtmlExport.h deleted file mode 100644 index bb1c971ea3..0000000000 --- a/plugins/BasicHistory/PlainHtmlExport.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once -#include "IExport.h" -class PlainHtmlExport : - public IExport -{ -public: - virtual const TCHAR* GetExt() - { - return _T("html"); - } - - virtual void WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding); - virtual void WriteFooter(); - virtual void WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText); - virtual void WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei); - - virtual ~PlainHtmlExport(); -}; - diff --git a/plugins/BasicHistory/ReadMe.txt b/plugins/BasicHistory/ReadMe.txt deleted file mode 100644 index 284d52b6c7..0000000000 --- a/plugins/BasicHistory/ReadMe.txt +++ /dev/null @@ -1,48 +0,0 @@ -======================================================================== - DYNAMIC LINK LIBRARY : BasicHistory Project Overview -======================================================================== - -AppWizard has created this BasicHistory DLL for you. - -This file contains a summary of what you will find in each of the files that -make up your BasicHistory application. - - -BasicHistory.vcxproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -BasicHistory.vcxproj.filters - This is the filters file for VC++ projects generated using an Application Wizard. - It contains information about the association between the files in your project - and the filters. This association is used in the IDE to show grouping of files with - similar extensions under a specific node (for e.g. ".cpp" files are associated with the - "Source Files" filter). - -BasicHistory.cpp - This is the main DLL source file. - - When created, this DLL does not export any symbols. As a result, it - will not produce a .lib file when it is built. If you wish this project - to be a project dependency of some other project, you will either need to - add code to export some symbols from the DLL so that an export library - will be produced, or you can set the Ignore Input Library property to Yes - on the General propert page of the Linker folder in the project's Property - Pages dialog box. - -///////////////////////////////////////////////////////////////////////////// -Other standard files: - -StdAfx.h, StdAfx.cpp - These files are used to build a precompiled header (PCH) file - named BasicHistory.pch and a precompiled types file named StdAfx.obj. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/plugins/BasicHistory/RichHtmlExport.cpp b/plugins/BasicHistory/RichHtmlExport.cpp deleted file mode 100644 index 5a772a4914..0000000000 --- a/plugins/BasicHistory/RichHtmlExport.cpp +++ /dev/null @@ -1,545 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "StdAfx.h" -#include "RichHtmlExport.h" -#include "Options.h" -#include "resource.h" -#define EXP_FILE (*stream) - -RichHtmlExport::~RichHtmlExport() -{ -} - -extern HINSTANCE hInst; -extern HANDLE *hEventIcons; -extern HANDLE hPlusExIcon, hMinusExIcon; -extern bool g_SmileyAddAvail; - -std::wstring MakeTextHtmled(const std::wstring& message, std::queue >* positionMap = NULL) -{ - std::wstring ret; - std::wstring search = _T("&<>\t\r\n"); - size_t start = 0; - size_t find; - size_t currentAdd = 0; - while((find = message.find_first_of(search, start)) < message.length()) - { - ret += message.substr(start, find - start); - switch(message[find]) - { - case _T('&'): - ret += _T("&"); - break; - case _T('<'): - ret += _T("<"); - break; - case _T('>'): - ret += _T(">"); - break; - case _T('\t'): - ret += _T(" "); - break; - case _T('\n'): - ret += _T("
"); - break; - } - - start = find + 1; - if(positionMap != NULL) - { - size_t len = ret.length() - start - currentAdd; - if(len != 0) - { - positionMap->push(std::pair(start + currentAdd, len)); - currentAdd += len; - } - } - } - - ret += message.substr(start, message.length() - start); - return ret; -} - -std::wstring UrlHighlightHtml(const std::wstring& message, bool& isUrl) -{ - std::wstring ret; - std::wstring htmlStop = _T("\'\" []<>\r\n"); - std::wstring search = _T("://"); - size_t start = 0; - size_t find; - while((find = message.find(search, start)) < message.length()) - { - size_t urlStart = message.find_last_of(htmlStop, find); - size_t urlEnd = message.find_first_of(htmlStop, find + 3); - if(urlStart >= message.length()) - urlStart = -1; - if(urlEnd >= message.length()) - urlEnd = message.length(); - if(((int)urlEnd -3 - (int)find > 0) && ((int)find - (int)urlStart -1 > 0)) - { - ret += message.substr(start, (urlStart + 1) - start); - std::wstring url = message.substr(urlStart + 1, urlEnd - urlStart - 1); - start = urlEnd; - ret += _T("") + url + _T(""); - isUrl = true; - } - else - { - ret += message.substr(start, (find + 3) - start); - start = find + 3; - } - } - - ret += message.substr(start, message.length() - start); - return ret; -} - -std::wstring RemoveExt(const std::wstring &fileName) -{ - size_t find = fileName.find_last_of(L'.'); - if(find < fileName.length()) - { - return fileName.substr(0, find); - } - - return fileName; -} - -std::wstring GetName(const std::wstring &path) -{ - size_t find = path.find_last_of(L"\\/"); - if(find < path.length()) - { - return path.substr(find + 1); - } - - return path; -} - -void ExtractFile(short int res, const std::wstring &fileName) -{ - HRSRC rSrc = FindResource(hInst, MAKEINTRESOURCE(res), MAKEINTRESOURCE(CUSTOMRES)); - if(rSrc != NULL) - { - HGLOBAL res = LoadResource(hInst, rSrc); - int size = SizeofResource(hInst, rSrc); - if(res != NULL) - { - char* resData = (char*)LockResource(res); - if(resData != NULL) - { - std::ofstream stream (fileName.c_str(), std::ios_base::binary); - if(stream.is_open()) - { - stream.write(resData, size); - stream.close(); - } - } - - FreeResource(res); - } - } -} - -#pragma pack(push, 2) -typedef struct -{ - BYTE bWidth; // Width, in pixels, of the image - BYTE bHeight; // Height, in pixels, of the image - BYTE bColorCount; // Number of colors in image (0 if >=8bpp) - BYTE bReserved; // Reserved ( must be 0) - WORD wPlanes; // Color Planes - WORD wBitCount; // Bits per pixel - DWORD dwBytesInRes; // How many bytes in this resource? - DWORD dwImageOffset; // Where in the file is this image? -} ICONDIRENTRY, *LPICONDIRENTRY; - -typedef struct -{ - WORD idReserved; // Reserved (must be 0) - WORD idType; // Resource Type (1 for icons) - WORD idCount; // How many images? - //ICONDIRENTRY idEntries; // An entry for each image (idCount of 'em) -} ICONDIR, *LPICONDIR; - -#pragma pack(pop) - -typedef struct tagMyBITMAPINFO { - BITMAPINFOHEADER bmiHeader; - RGBQUAD bmiColors[256]; -} MYBITMAPINFO; - -void IcoSave(const std::wstring &fileName, HICON hicon) -{ - std::ofstream store (fileName.c_str(), std::ios_base::binary); - if(!store.is_open()) - return; - ICONINFO ii; - if(!GetIconInfo(hicon,&ii)) - { - store.close(); - return; - } - - HBITMAP hbmMask = ii.hbmMask; - HBITMAP hbmColor = ii.hbmColor; - BITMAP bmiMask; - BITMAP bmiColor; - if( - GetObject(hbmColor,sizeof(bmiColor),&bmiColor) && - GetObject(hbmMask,sizeof(bmiMask),&bmiMask) && - (bmiColor.bmWidth==bmiMask.bmWidth) && - (bmiColor.bmHeight==bmiMask.bmHeight) && - (bmiMask.bmHeight) > 0 && - (bmiMask.bmWidth) > 0 - ) - { - BITMAPINFOHEADER icobmi = {0}; - MYBITMAPINFO info1 = {0}; - MYBITMAPINFO info2 = {0}; - - HDC hDC = CreateCompatibleDC(NULL); - info1.bmiHeader.biSize = sizeof(info1.bmiHeader); - info1.bmiHeader.biWidth = bmiColor.bmWidth; - info1.bmiHeader.biHeight = bmiColor.bmHeight; - info1.bmiHeader.biPlanes = 1; - info1.bmiHeader.biBitCount = bmiColor.bmBitsPixel; - unsigned int size = GetDIBits(hDC,hbmColor,0,info1.bmiHeader.biHeight,NULL,(BITMAPINFO*)&info1,DIB_RGB_COLORS); - char* bits1 = new char[info1.bmiHeader.biSizeImage]; - size = GetDIBits(hDC,hbmColor,0,info1.bmiHeader.biHeight,bits1,(BITMAPINFO*)&info1,DIB_RGB_COLORS); - info2.bmiHeader.biSize = sizeof(info2.bmiHeader); - info2.bmiHeader.biWidth = bmiMask.bmWidth; - info2.bmiHeader.biHeight = bmiMask.bmHeight; - info2.bmiHeader.biPlanes = 1; - info2.bmiHeader.biBitCount = bmiMask.bmBitsPixel; - size = GetDIBits(hDC,hbmColor,0,info1.bmiHeader.biHeight,NULL,(BITMAPINFO*)&info2,DIB_RGB_COLORS); - char* bits2 = new char[info2.bmiHeader.biSizeImage]; - size = GetDIBits(hDC,hbmMask,0,info2.bmiHeader.biHeight,bits2,(BITMAPINFO*)&info2,DIB_RGB_COLORS); - - ICONDIR icodir; - ICONDIRENTRY icoent; - icodir.idReserved = 0; - icodir.idType = 1; - icodir.idCount = 1; - - icoent.bWidth = (unsigned char)bmiColor.bmWidth; - icoent.bHeight = (unsigned char)bmiColor.bmHeight; - icoent.bColorCount = 8<=bmiColor.bmBitsPixel?0:1<extCssHtml2.empty()) - { - cssCopied = CopyFile(Options::instance->extCssHtml2.c_str(), css.c_str(), FALSE); - } - - if(!cssCopied) - ExtractFile(IDR_CSS, css); - ExtractFile(IDR_JS, folder + _T("\\history.js")); - - HICON ico = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hPlusExIcon); - IcoSave(folder + _T("\\pnode.ico"), ico); - CallService(MS_SKIN2_RELEASEICON, (LPARAM)ico, 0); - ico = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hMinusExIcon); - IcoSave(folder + _T("\\mnode.ico"), ico); - CallService(MS_SKIN2_RELEASEICON, (LPARAM)ico, 0); - ico = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hEventIcons[0]); - IcoSave(folder + _T("\\event0.ico"), ico); - CallService(MS_SKIN2_RELEASEICON, (LPARAM)ico, 0); - ico = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hEventIcons[1]); - IcoSave(folder + _T("\\event1.ico"), ico); - CallService(MS_SKIN2_RELEASEICON, (LPARAM)ico, 0); - - EXP_FILE << _T("\n"); - EXP_FILE << _T("\n\n"); - EXP_FILE << _T("") << TranslateT("History Log") << _T(" [") << MakeTextHtmled(myName) << _T("] - [") << MakeTextHtmled(name1) << _T("]\n"); - EXP_FILE << _T("\n"); - EXP_FILE << _T("\n"); - EXP_FILE << _T("\n"); - - EXP_FILE << _T("\n"); - EXP_FILE << _T("") << TranslateT("Menu") << _T("\n"); - EXP_FILE << _T("\n"); - EXP_FILE << _T("\n"); - EXP_FILE << _T("\n"); - EXP_FILE << _T("
\n"); - EXP_FILE << _T("\n"); - - EXP_FILE << _T("

") << TranslateT("History Log") << _T("

\n

"); - EXP_FILE << MakeTextHtmled(myName); - if(proto1.length() || myId.length()) - { - EXP_FILE << _T(" (") << MakeTextHtmled(proto1) << _T(": ") << MakeTextHtmled(myId) << _T(") - "); - } - else - { - EXP_FILE << _T(" - "); - } - - EXP_FILE << MakeTextHtmled(name1); - if(proto1.length() || id1.length()) - { - EXP_FILE << _T(" (") << MakeTextHtmled(proto1) << _T(": ") << MakeTextHtmled(id1) << _T(")

\n"); - } - else - { - EXP_FILE << _T("\n"); - } - - EXP_FILE << _T("
") << TranslateT("Filter:") << _T(" ") << MakeTextHtmled(filterName) << _T("
\n"); - groupId = 0; -} - -void RichHtmlExport::WriteFooter() -{ - if(groupId > 0) - { - EXP_FILE << _T("\n"); - } - - EXP_FILE << _T("
\n\n"); -} - -void RichHtmlExport::WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText) -{ - TCHAR *id = isMe ? _T("out") : _T("inc"); - TCHAR* ev = (isMe ? _T("1") : _T("0")); - if(groupId > 0) - { - EXP_FILE << _T("\n"); - } - - bool isUrl = false; - std::wstring& mes = ReplaceSmileys(isMe, eventText, isUrl); - EXP_FILE << _T("
\n"); - EXP_FILE << _T(""); - EXP_FILE << _T("\n"); - EXP_FILE << _T("") << time << _T("\n\n") << mes; - EXP_FILE << _T("\n
\n"); - EXP_FILE << _T("
\n"); - ++groupId; -} - -void RichHtmlExport::WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei) -{ - TCHAR *id = isMe ? _T("out") : _T("inc"); - TCHAR* ev = (isMe ? _T("1") : _T("0")); - TCHAR* ev1 = ev; - bool isUrl = false; - std::wstring& mes = ReplaceSmileys(isMe, message, isUrl); - if(isUrl) - ev = _T("2"); - EXP_FILE << _T("
\n"); - EXP_FILE << _T("
") << _T("
\n"); - EXP_FILE << _T("
") << (Options::instance->exportHtml2ShowDate ? longDate : shortDate) << _T("
\n"); - EXP_FILE << _T("
") << MakeTextHtmled(user) << _T("
\n"); - EXP_FILE << _T("
\n"); - EXP_FILE << mes; - EXP_FILE << _T("\n
\n"); - EXP_FILE << _T("
\n"); -} - -std::wstring RichHtmlExport::ReplaceSmileys(bool isMe, const std::wstring &msg, bool &isUrl) -{ - if(Options::instance->exportHtml2UseSmileys && g_SmileyAddAvail) - { - TCHAR* msgbuf = new TCHAR[msg.length() + 1]; - memcpy_s(msgbuf, (msg.length() + 1) * sizeof(TCHAR), msg.c_str(), (msg.length() + 1) * sizeof(TCHAR)); - SMADD_BATCHPARSE2 sp = {0}; - SMADD_BATCHPARSERES *spr; - sp.cbSize = sizeof(sp); - sp.Protocolname = baseProto.length() == 0 ? NULL : baseProto.c_str(); - sp.str = msgbuf; - sp.flag = SAFL_TCHAR | SAFL_PATH | (isMe ? SAFL_OUTGOING : 0); - spr = (SMADD_BATCHPARSERES*)CallService(MS_SMILEYADD_BATCHPARSE, 0, (LPARAM)&sp); - delete[] msgbuf; - - if (spr == NULL || (INT_PTR)spr == CALLSERVICE_NOTFOUND) - { - // Did not find a simley - return UrlHighlightHtml(MakeTextHtmled(msg), isUrl); - } - - std::queue > positionMap; - std::wstring newMsg = MakeTextHtmled(msg, &positionMap); - std::wstring smileyMsg; - - size_t last_pos=0; - std::pair pos(0, 0); - size_t currentAdd = 0; - if(!positionMap.empty()) - { - pos = positionMap.front(); - positionMap.pop(); - } - - for (unsigned i = 0; i < sp.numSmileys; ++i) - { - size_t startChar = spr[i].startChar + currentAdd; - while(startChar >= pos.first && pos.second) - { - startChar += pos.second; - currentAdd += pos.second; - if(!positionMap.empty()) - { - pos = positionMap.front(); - positionMap.pop(); - } - else - { - pos = std::pair(0, 0); - } - } - - size_t endChar = spr[i].startChar + spr[i].size + currentAdd; - while(endChar >= pos.first && pos.second) - { - endChar += pos.second; - currentAdd += pos.second; - if(!positionMap.empty()) - { - pos = positionMap.front(); - positionMap.pop(); - } - else - { - pos = std::pair(0, 0); - } - } - - size_t size = endChar - startChar; - - if (spr[i].filepath != NULL) // For deffective smileypacks - { - // Add text - if (startChar - last_pos > 0) - { - smileyMsg += newMsg.substr(last_pos, startChar - last_pos); - } - - std::wstring smileyName = GetName(spr[i].filepath); - if(smileys.find(smileyName) == smileys.end()) - { - smileys.insert(smileyName); - CopyFile(spr[i].filepath, (folder + _T("\\") + smileyName).c_str(), FALSE); - } - - std::wstring smileyText = newMsg.substr(startChar, size); - smileyMsg += _T("\"");"); - } - - // Get next - last_pos = endChar; - } - - // Add rest of text - if (last_pos < newMsg.length()) - { - smileyMsg += newMsg.substr(last_pos); - } - - CallService(MS_SMILEYADD_BATCHFREE, 0, (LPARAM)spr); - return UrlHighlightHtml(smileyMsg, isUrl); - } - else - { - return UrlHighlightHtml(MakeTextHtmled(msg), isUrl); - } -} diff --git a/plugins/BasicHistory/RichHtmlExport.h b/plugins/BasicHistory/RichHtmlExport.h deleted file mode 100644 index f4f6686964..0000000000 --- a/plugins/BasicHistory/RichHtmlExport.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once -#include "IExport.h" -class RichHtmlExport : - public IExport -{ -private: - int groupId; - std::wstring folder; - std::wstring folderName; - std::string baseProto; - stdext::hash_set smileys; - std::wstring ReplaceSmileys(bool isMe, const std::wstring &msg, bool &isUrl); -public: - virtual const TCHAR* GetExt() - { - return _T("html"); - } - - virtual void WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding); - virtual void WriteFooter(); - virtual void WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText); - virtual void WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei); - - virtual ~RichHtmlExport(); -}; - diff --git a/plugins/BasicHistory/Scheduler.cpp b/plugins/BasicHistory/Scheduler.cpp deleted file mode 100644 index 3b2ba18ab9..0000000000 --- a/plugins/BasicHistory/Scheduler.cpp +++ /dev/null @@ -1,1576 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "StdAfx.h" -#include "Options.h" -#include "ExportManager.h" -#include "HistoryWindow.h" -#include "zip\zip.h" -#include "zip\unzip.h" -#include "zip\iowin32.h" - -// Sorry for plain C implementation -#define MODULE "BasicHistory" -extern HANDLE g_hMainThread; -bool bPopupsEnabled; -bool DoTask(TaskOptions& to); -bool IsValidTask(TaskOptions& to, std::list* top = NULL, std::wstring* err = NULL, std::wstring* errDescr = NULL); -std::wstring GetFileName(const std::wstring &baseName, std::wstring contactName, std::map& existingContacts, bool replaceContact); -std::wstring GetDirectoryName(const std::wstring &path); -std::wstring GetName(const std::wstring &path); -bool DeleteDirectory(LPCTSTR lpszDir, bool noRecycleBin = true); -void ListDirectory(const std::wstring &basePath, const std::wstring &path, std::list& files); -std::wstring ReplaceStr(const std::wstring& str, wchar_t oldCh, wchar_t newCh); -time_t GetNextExportTime(TaskOptions& to); -void SchedulerThreadFunc(void*); -volatile bool finishThread = false; -bool initTask = false; -HANDLE thread = NULL; -HANDLE threadEvent; -time_t nextExportTime; -void StartThread(bool init); -void StopThread(); -bool GetNextExportTime(bool init, time_t now); -bool ExecuteCurrentTask(time_t now); -void GetZipFileTime(const TCHAR *file, uLong *dt); -std::wstring ReplaceExt(const std::wstring& file, const TCHAR* ext); -bool ZipFiles(const std::wstring& dir, std::wstring zipFilePath, const std::string& password); -bool UnzipFiles(const std::wstring& dir, std::wstring& zipFilePath, const std::string& password); -bool FtpFiles(const std::wstring& dir, const std::wstring& filePath, const std::wstring& ftpName); -bool FtpGetFiles(const std::wstring& dir, const std::list& files, const std::wstring& ftpName); -void CreatePath(const TCHAR *szDir); -void DoError(const TaskOptions& to, const std::wstring error); - -void OptionsSchedulerChanged() -{ - StartThread(false); -} - -void InitScheduler() -{ - bPopupsEnabled = ServiceExists(MS_POPUP_ADDPOPUPT) || ServiceExists(MS_POPUP_ADDPOPUPCLASS); - if (ServiceExists(MS_POPUP_REGISTERCLASS)) - { - //hPopupIcon = LoadIconEx(I_CHKUPD); - POPUPCLASS test = {0}; - test.cbSize = sizeof(POPUPCLASS); - test.flags = PCF_TCHAR; - test.hIcon = LoadSkinnedIcon(SKINICON_OTHER_HISTORY); - test.iSeconds = 10; - test.ptszDescription = TranslateT("History task"); - test.pszName = MODULE; - CallService(MS_POPUP_REGISTERCLASS, 0, (WPARAM)&test); - } - - StartThread(true); -} - -void DeinitScheduler() -{ - StopThread(); -} - -int DoLastTask(WPARAM, LPARAM) -{ - for(std::vector::iterator it = Options::instance->taskOptions.begin(); it != Options::instance->taskOptions.end(); ++it) - { - if(it->trigerType == TaskOptions::AtEnd && it->active) - { - DoTask(*it); - } - } - - return 0; -} - -bool IsValidTask(TaskOptions& to, std::list* top, std::wstring* err, std::wstring* errDescr) -{ - if(to.taskName.empty()) - { - if(err != NULL) - *err = TranslateT("Name"); - return false; - } - if(top != NULL) - { - for(std::list::iterator it = top->begin(); it != top->end(); ++it) - { - if(it->taskName == to.taskName) - { - if(err != NULL) - *err = TranslateT("Name"); - return false; - } - } - } - if(!to.isSystem && to.contacts.size() == 0) - { - if(err != NULL) - *err = TranslateT("Contacts"); - if(errDescr != NULL) - *errDescr = TranslateT("At least one contact should be selected."); - return false; - } - - bool isImportTask = to.type == TaskOptions::Import || to.type == TaskOptions::ImportAndMarge; - if(!isImportTask) - { - if(to.filterId > 1) - { - int filter = 0; - - for(int i = 0; i < (int)Options::instance->customFilters.size(); ++i) - { - if(to.filterName == Options::instance->customFilters[i].name) - { - filter = i + 2; - break; - } - } - - if(filter < 2) - { - if(err != NULL) - *err = TranslateT("Filter"); - return false; - } - - to.filterId = filter; - } - else if(to.filterId < 0) - { - if(err != NULL) - *err = TranslateT("Filter"); - return false; - } - } - - if(to.type == TaskOptions::Delete) - { - return true; - } - - if(!Options::FTPAvail() && to.useFtp) - { - if(err != NULL) - *err = TranslateT("Upload to FTP"); - return false; - } - if(to.filePath.empty()) - { - if(err != NULL) - *err = TranslateT("Path to output file"); - return false; - } - if(to.useFtp && to.ftpName.empty()) - { - if(err != NULL) - *err = TranslateT("Session name"); - if(errDescr != NULL) - *errDescr = TranslateT("To create session open WinSCP, click New Session, enter data and save with specific name. Remember if FTP server using password you should save it in WinSCP."); - return false; - } - if(to.useFtp && (to.filePath.find(_T('\\')) < to.filePath.length() || to.filePath.find(_T(':')) < to.filePath.length() || to.filePath[0] != L'/')) - { - if(err != NULL) - *err = TranslateT("Path to file"); - if(errDescr != NULL) - *errDescr = TranslateT("FTP path must contains '/' instead '\\' and starts from '/'."); - return false; - } - if(isImportTask && to.filePath.find(_T("")) < to.filePath.length()) - { - if(err != NULL) - *err = TranslateT("Path to file"); - if(errDescr != NULL) - *errDescr = TranslateT("FTP path cannot contain in import task."); - return false; - } - if(!isImportTask && (to.exportType < IExport::RichHtml || to.exportType > IExport::Dat)) - { - if(err != NULL) - *err = TranslateT("Export to"); - return false; - } - if(isImportTask && (to.importType < IImport::Binary || to.importType > IImport::Dat)) - { - if(err != NULL) - *err = TranslateT("Import from"); - return false; - } - if((to.trigerType == TaskOptions::Daily || to.trigerType == TaskOptions::Weekly || to.trigerType == TaskOptions::Monthly) && (to.dayTime < 0 || to.dayTime >= 24 * 60)) - { - if(err != NULL) - *err = TranslateT("Time"); - return false; - } - if(to.trigerType == TaskOptions::Weekly && (to.dayOfWeek < 0 || to.dayOfWeek >= 7)) - { - if(err != NULL) - *err = TranslateT("Day of week"); - return false; - } - if(to.trigerType == TaskOptions::Monthly && (to.dayOfMonth <= 0 || to.dayOfMonth >= 32)) - { - if(err != NULL) - *err = TranslateT("Day"); - return false; - } - if((to.trigerType == TaskOptions::DeltaMin || to.trigerType == TaskOptions::DeltaHour) && (to.deltaTime < 0 || to.deltaTime >= 10000)) - { - if(err != NULL) - *err = TranslateT("Delta time"); - return false; - } - - return true; -} - -static void CALLBACK DoRebuildEventsInMainAPCFunc(ULONG_PTR dwParam) -{ - HANDLE* contacts = (HANDLE*) dwParam; - size_t size = (size_t)contacts[0]; - for(size_t i = 1; i <= size; ++i) - { - HistoryWindow::RebuildEvents(contacts[i]); - } - - delete[] contacts; -} - -bool DoTask(TaskOptions& to) -{ - std::wstring err; - std::wstring errDescr; - if(!IsValidTask(to, NULL, &err, &errDescr)) - { - TCHAR msg[256]; - if(err.empty()) - _tcscpy_s(msg, TranslateT("Some value is invalid")); - else if(errDescr.empty()) - { - _stprintf_s(msg, TranslateT("Invalid '%s' value."), err.c_str()); - } - else - { - _stprintf_s(msg, TranslateT("Invalid '%s' value.\n%s"), err.c_str(), errDescr.c_str()); - } - DoError(to, msg); - return true; - } - - DWORD now = time(NULL); - long long int t = to.eventDeltaTime * 60; - if(to.eventUnit > TaskOptions::Minute) - t *= 60LL; - if(to.eventUnit > TaskOptions::Hour) - t *= 24LL; - if(t > 2147483647LL) - { - DoError(to, TranslateT("Unknown error")); - return true; - } - - bool error = false; - std::wstring errorStr; - std::list managers; - if(to.type == TaskOptions::Delete) - { - if(to.isSystem) - { - ExportManager *exp = new ExportManager(NULL, NULL, to.filterId); - exp->SetDeleteWithoutExportEvents(t, now); - managers.push_back(exp); - } - - for(size_t i = 0; i < to.contacts.size(); ++i) - { - ExportManager *exp = new ExportManager(NULL, to.contacts[i], to.filterId); - exp->SetDeleteWithoutExportEvents(t, now); - managers.push_back(exp); - } - } - else if(to.type == TaskOptions::Import || to.type == TaskOptions::ImportAndMarge) - { - std::map existingContacts1; - ExportManager mExp = ExportManager(NULL, NULL, 1); - std::wstring filePath = to.filePath; - std::wstring dir; - std::list files; - std::vector contacts; - if(to.useFtp || to.compress) - { - std::map existingContacts; - TCHAR temp[MAX_PATH]; - temp[0] = 0; - GetTempPath(MAX_PATH, temp); - dir = temp; - dir += GetName(filePath); - dir = GetFileName(dir, L"", existingContacts, true); - dir = ReplaceExt(dir, L""); - size_t pos = dir.find_last_of(_T('.')); - if(pos < dir.length()) - { - dir = dir.substr(0, pos); - } - - DeleteDirectory(dir.c_str()); - CreateDirectory(dir.c_str(), NULL); - } - - const TCHAR* ext = ExportManager::GetExt(to.importType); - if(to.isSystem) - { - std::wstring n = GetFileName(filePath, mExp.GetContactName(), existingContacts1, true); - n = ReplaceExt(n, ext); - files.push_back(n); - contacts.push_back(NULL); - } - - for(size_t i = 0; i < to.contacts.size(); ++i) - { - mExp.hContact = to.contacts[i]; - std::wstring n = GetFileName(filePath, mExp.GetContactName(), existingContacts1, true); - n = ReplaceExt(n, ext); - files.push_back(n); - contacts.push_back(to.contacts[i]); - } - - if(to.useFtp) - { - if(to.compress) - { - std::map existingContacts; - std::wstring n = GetFileName(filePath, L"", existingContacts, true); - n = ReplaceExt(n, L"zip"); - files.clear(); - files.push_back(n); - filePath = dir + L"\\" + GetName(filePath); - } - - error = FtpGetFiles(dir, files, to.ftpName); - if(error) - { - if(!errorStr.empty()) - { - errorStr += L"\n"; - } - - errorStr += TranslateT("Cannot get FTP file(s)."); - } - } - - if(!error && to.compress) - { - error = UnzipFiles(dir, filePath, to.zipPassword); - if(error) - { - if(!errorStr.empty()) - { - errorStr += L"\n"; - } - - errorStr += TranslateT("Cannot unzip file(s)."); - } - - if(to.useFtp) - DeleteFile(filePath.c_str()); - } - - if(!error && (to.useFtp || to.compress)) - { - files.clear(); - std::list files1; - ListDirectory(dir, L"\\", files1); - for(std::list::iterator it = files1.begin(); it != files1.end(); ++it) - { - files.push_back(dir + *it); - } - } - - if(!error) - { - std::list contactList; - for(std::list::iterator it = files.begin(); it != files.end(); ++it) - { - mExp.SetAutoImport(*it); - int ret = mExp.Import(to.importType, contacts); - if(ret == -3) - { - if(contacts.size() == 1) - { - ret = 0; - } - else - { - std::map existingContacts; - std::wstring name = GetName(*it); - for(ret = 0; ret < (int)contacts.size(); ++ret) - { - mExp.hContact = contacts[ret]; - std::wstring n = GetFileName(to.filePath, mExp.GetContactName(), existingContacts, true); - n = ReplaceExt(n, ext); - n = GetName(n); - if(n == name) - break; - } - - if(ret >= (int)contacts.size()) - ret = -1; - } - } - - if(ret >= 0) - { - mExp.hContact = contacts[ret]; - if(to.type == TaskOptions::Import) - { - EventList::AddImporter(mExp.hContact, to.importType, *it); - contactList.push_back(mExp.hContact); - } - else - { - std::vector messages; - if(mExp.Import(to.importType, messages, NULL)) - { - mExp.MargeMessages(messages); - contactList.push_back(mExp.hContact); - } - } - } - else if(ret != -1) - { - if(!errorStr.empty()) - { - errorStr += L"\n"; - } - - TCHAR msg[1024]; - - _stprintf_s(msg, TranslateT("Incorrect file format: %s."), GetName(*it).c_str()); - errorStr += msg; - } - else - { - if(!errorStr.empty()) - { - errorStr += L"\n"; - } - - TCHAR msg[1024]; - - _stprintf_s(msg, TranslateT("Unknown contact in file: %s."), GetName(*it).c_str()); - errorStr += msg; - } - } - - if(contactList.size() > 0) - { - HANDLE* contacts = new HANDLE[contactList.size() + 1]; - contacts[0] = (HANDLE)contactList.size(); - int i = 1; - for(std::list::iterator it = contactList.begin(); it != contactList.end(); ++it) - { - contacts[i++] = *it; - } - - QueueUserAPC(DoRebuildEventsInMainAPCFunc, g_hMainThread, (ULONG_PTR) contacts); - } - } - - if(to.useFtp || to.compress) - { - DeleteDirectory(dir.c_str()); - } - } - else - { - std::map existingContacts; - std::wstring filePath = to.filePath; - std::wstring dir; - if(!to.useFtp && !to.compress) - { - dir = GetDirectoryName(filePath); - if(!dir.empty()) - { - CreateDirectory(dir.c_str(), NULL); - } - } - else - { - filePath = GetName(filePath); - TCHAR temp[MAX_PATH]; - temp[0] = 0; - GetTempPath(MAX_PATH, temp); - dir = temp; - dir += filePath; - dir = GetFileName(dir, L"", existingContacts, true); - dir = ReplaceExt(dir, L""); - size_t pos = dir.find_last_of(_T('.')); - if(pos < dir.length()) - { - dir = dir.substr(0, pos); - } - - DeleteDirectory(dir.c_str()); - CreateDirectory(dir.c_str(), NULL); - filePath = dir + L"\\" + filePath; - } - if(to.isSystem) - { - ExportManager *exp = new ExportManager(NULL, NULL, to.filterId); - exp->SetAutoExport(GetFileName(filePath, exp->GetContactName(), existingContacts, true), t, now); - exp->useImportedMessages = to.exportImported; - if(!exp->Export(to.exportType)) - { - error = true; - if(!errorStr.empty()) - { - errorStr += L"\n"; - } - - TCHAR msg[1024]; - - _stprintf_s(msg, TranslateT("Cannot export history for contact: %s."), exp->GetContactName().c_str()); - errorStr += msg; - } - - if(to.type == TaskOptions::Export) - { - delete exp; - } - else - { - managers.push_back(exp); - } - } - - if(!error) - { - for(size_t i = 0; i < to.contacts.size(); ++i) - { - ExportManager *exp = new ExportManager(NULL, to.contacts[i], to.filterId); - exp->SetAutoExport(GetFileName(filePath, exp->GetContactName(), existingContacts, true), t, now); - exp->useImportedMessages = to.exportImported; - if(!exp->Export(to.exportType)) - { - error = true; - if(!errorStr.empty()) - { - errorStr += L"\n"; - } - - TCHAR msg[1024]; - - _stprintf_s(msg, TranslateT("Cannot export history for contact: %s."), exp->GetContactName().c_str()); - errorStr += msg; - break; - } - - if(to.type == TaskOptions::Export) - { - delete exp; - } - else - { - managers.push_back(exp); - } - } - } - - if(error) - { - if(to.compress && !to.useFtp) - { - DeleteDirectory(dir.c_str()); - } - } - else if(to.compress) - { - std::wstring zipFilePath = to.filePath; - std::wstring zipDir = dir; - if(!to.useFtp) - { - zipDir = GetDirectoryName(zipFilePath); - if(!zipDir.empty()) - { - CreateDirectory(zipDir.c_str(), NULL); - } - } - else - { - zipFilePath = GetName(zipFilePath); - TCHAR temp[MAX_PATH]; - temp[0] = 0; - GetTempPath(MAX_PATH, temp); - zipDir = temp; - zipDir += L"zip"; - zipDir = GetFileName(zipDir, L"", existingContacts, true); - DeleteDirectory(zipDir.c_str()); - CreateDirectory(zipDir.c_str(), NULL); - zipFilePath = zipDir + L"\\" + zipFilePath; - } - error = ZipFiles(dir + L"\\", zipFilePath, to.zipPassword); - dir = zipDir; - if(error) - { - if(!errorStr.empty()) - { - errorStr += L"\n"; - } - - errorStr += TranslateT("Cannot compress file(s)."); - } - } - - if(to.useFtp) - { - if(!error) - { - error = FtpFiles(dir, to.filePath, to.ftpName); - if(error) - { - if(!errorStr.empty()) - { - errorStr += L"\n"; - } - - errorStr += TranslateT("Cannot send FTP file(s)."); - } - } - - DeleteDirectory(dir.c_str()); - } - } - - if(to.type == TaskOptions::Delete || to.type == TaskOptions::ExportAndDelete) - { - for(std::list::iterator it = managers.begin(); it != managers.end(); ++it) - { - if(!error) - { - (*it)->DeleteExportedEvents(); - } - - delete *it; - } - } - - if(error) - { - DoError(to, errorStr.empty() ? TranslateT("Unknown error") : errorStr); - } - - return error; -} - -std::wstring GetFileName(const std::wstring &baseName, std::wstring contactName, std::map& existingContacts, bool replaceContact) -{ - std::wstring str = baseName; - size_t pos = baseName.find(_T("")); - if(replaceContact && pos < baseName.length()) - { - str = baseName.substr(0, pos); - std::wstring baseName1 = contactName; - if(!baseName1.empty()) - { - std::wstring name = baseName1; - int i = 0; - TCHAR buf[32]; - std::map::iterator it = existingContacts.find(name); - while(it != existingContacts.end()) - { - _itot_s(++i, buf, 10); - name = baseName1 + buf; - it = existingContacts.find(name); - } - - str += name; - existingContacts[name] = true; - } - str += baseName.substr(pos + 9); - } - - pos = str.find(_T("")); - if(pos < str.length()) - { - TCHAR time[256]; - SYSTEMTIME st; - GetLocalTime(&st); - _stprintf_s(time, _T("%d-%02d-%02d %02d%02d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute); - std::wstring str1 = str.substr(0, pos); - str1 += time; - str1 += str.substr(pos + 6); - str = str1; - } - - return str; -} - -std::wstring GetDirectoryName(const std::wstring &path) -{ - size_t find = path.find_last_of(L"\\/"); - if(find < path.length()) - { - return path.substr(0, find); - } - - return L""; -} - -void ListDirectory(const std::wstring &basePath, const std::wstring &path, std::list& files) -{ - WIN32_FIND_DATA findFileData; - HANDLE hFind = FindFirstFile((basePath + path + _T("*")).c_str(), &findFileData); - if (hFind == INVALID_HANDLE_VALUE) - return; - do - { - if(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - std::wstring name = findFileData.cFileName; - if(name != L"." && name != L"..") - ListDirectory(basePath, path + findFileData.cFileName + _T("\\"), files); - } - else - { - files.push_back(path + findFileData.cFileName); - } - } - while(FindNextFile(hFind, &findFileData)); - FindClose(hFind); -} - -std::wstring ReplaceStr(const std::wstring& str, wchar_t oldCh, wchar_t newCh) -{ - std::wstring ret; - size_t start = 0; - size_t find; - while((find = str.find_first_of(oldCh, start)) < str.length()) - { - ret += str.substr(start, find - start); - ret += newCh; - start = find + 1; - } - - ret += str.substr(start, str.length() - start); - return ret; -} - -time_t GetNextExportTime(TaskOptions& to) -{ - switch(to.trigerType) - { - case TaskOptions::Daily: - { - tm t; - localtime_s(&t, &to.lastExport); - t.tm_hour = to.dayTime/60; - t.tm_min = to.dayTime%60; - t.tm_sec = 0; - time_t newTime = mktime(&t); - if(newTime <= to.lastExport) - { - newTime += 60 * 60 * 24; - } - - return newTime; - } - case TaskOptions::Weekly: - { - tm t; - localtime_s(&t, &to.lastExport); - t.tm_hour = to.dayTime/60; - t.tm_min = to.dayTime%60; - t.tm_sec = 0; - int dow = (to.dayOfWeek + 1) % 7; - time_t newTime = mktime(&t); - while(dow != t.tm_wday) - { - newTime += 60 * 60 * 24; - localtime_s(&t, &newTime); - newTime = mktime(&t); - } - - if(newTime <= to.lastExport) - { - newTime += 7 * 60 * 60 * 24; - } - - return newTime; - } - case TaskOptions::Monthly: - { - tm t; - localtime_s(&t, &to.lastExport); - t.tm_hour = to.dayTime/60; - t.tm_min = to.dayTime%60; - t.tm_sec = 0; - time_t newTime = mktime(&t); - int lastM = t.tm_mon; - int lastD; - while(to.dayOfMonth != t.tm_mday || newTime <= to.lastExport) - { - lastD = t.tm_mday; - newTime += 60 * 60 * 24; - localtime_s(&t, &newTime); - newTime = mktime(&t); - if(to.dayOfMonth > 28 && t.tm_mon != lastM && (newTime - 60 * 60 * 24) > to.lastExport) - { - lastM = t.tm_mon; - if(to.dayOfMonth > lastD) - { - newTime -= 60 * 60 * 24; - break; - } - } - } - - return newTime; - } - case TaskOptions::DeltaMin: - return to.lastExport + to.deltaTime * 60; - case TaskOptions::DeltaHour: - return to.lastExport + to.deltaTime * 60 * 60; - default: - return to.lastExport; - } -} - -void SchedulerThreadFunc(void*) -{ - if(initTask) - { - WaitForSingleObject(threadEvent, 5 * 1000); - initTask = false; - } - - while(!finishThread) - { - DWORD timeWait; - time_t now = time(NULL); - while(nextExportTime <= now) - { - if(!ExecuteCurrentTask(now)) - return; - } - - time_t dif = nextExportTime - now; - timeWait = (dif > 60 * 60 * 24) ? (60 * 60 * 1000) : (60 * 1000); - - WaitForSingleObject(threadEvent, timeWait); - } -} - -void StartThread(bool init) -{ - StopThread(); - - initTask = false; - bool isExport = GetNextExportTime(init, time(NULL)); - if(isExport) - { - finishThread = false; - threadEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - thread = mir_forkthread(SchedulerThreadFunc, NULL); - } -} - -void StopThread() -{ - if(thread != NULL) - { - finishThread = true; - SetEvent(threadEvent); - WaitForSingleObject(thread, INFINITE); - //CloseHandle(thread); - CloseHandle(threadEvent); - thread = NULL; - threadEvent = NULL; - } -} - -bool GetNextExportTime(bool init, time_t now) -{ - EnterCriticalSection(&Options::instance->criticalSection); - bool isExport = false; - for(std::vector::iterator it = Options::instance->taskOptions.begin(); it != Options::instance->taskOptions.end(); ++it) - { - if(it->forceExecute) - { - nextExportTime = now; - isExport = true; - initTask = init; - break; - } - else if(it->active && it->trigerType != TaskOptions::AtStart && it->trigerType != TaskOptions::AtEnd) - { - time_t t = GetNextExportTime(*it); - if(isExport) - { - if(t < nextExportTime) - nextExportTime = t; - } - else - { - nextExportTime = t; - isExport = true; - initTask = init; - } - } - else if(it->active && it->trigerType == TaskOptions::AtStart && init) - { - it->forceExecute = true; - it->showMBAfterExecute = false; - nextExportTime = now; - isExport = true; - initTask = true; - } - } - - LeaveCriticalSection(&Options::instance->criticalSection); - return isExport; -} - -static void CALLBACK DoTaskFinishInMainAPCFunc(ULONG_PTR dwParam) -{ - TCHAR *item = (TCHAR*) dwParam; - MessageBox(NULL, item, TranslateT("Task finished"), MB_OK | MB_ICONINFORMATION); - delete[] item; -} - -bool ExecuteCurrentTask(time_t now) -{ - EnterCriticalSection(&Options::instance->criticalSection); - TaskOptions to; - bool isExport = false; - for(std::vector::iterator it = Options::instance->taskOptions.begin(); it != Options::instance->taskOptions.end(); ++it) - { - if(it->forceExecute) - { - it->lastExport = time(NULL); - Options::instance->SaveTaskTime(*it); - to = *it; - isExport = true; - break; - } - else if(it->active && it->trigerType != TaskOptions::AtStart && it->trigerType != TaskOptions::AtEnd) - { - time_t t = GetNextExportTime(*it); - if(t <= now) - { - it->lastExport = time(NULL); - Options::instance->SaveTaskTime(*it); - to = *it; - isExport = true; - break; - } - } - } - - LeaveCriticalSection(&Options::instance->criticalSection); - - if(isExport) - { - bool error = DoTask(to); - if(to.forceExecute) - { - EnterCriticalSection(&Options::instance->criticalSection); - for(std::vector::iterator it = Options::instance->taskOptions.begin(); it != Options::instance->taskOptions.end(); ++it) - { - if(it->taskName == to.taskName) - { - it->forceExecute = false; - it->showMBAfterExecute = false; - break; - } - } - - LeaveCriticalSection(&Options::instance->criticalSection); - - if(to.showMBAfterExecute) - { - size_t size = to.taskName.size() + 1024; - TCHAR* name = new TCHAR[size]; - if(error) - { - _stprintf_s(name, size, TranslateT("Task '%s' execution failed"), to.taskName.c_str()); - } - else - { - _stprintf_s(name, size, TranslateT("Task '%s' finished successfully"), to.taskName.c_str()); - } - - QueueUserAPC(DoTaskFinishInMainAPCFunc, g_hMainThread, (ULONG_PTR) name); - } - } - } - - return GetNextExportTime(false, now); -} - -void GetZipFileTime(const TCHAR *file, uLong *dt) -{ - FILETIME ftLocal; - HANDLE hFind; - WIN32_FIND_DATA ff32; - - hFind = FindFirstFile(file, &ff32); - if (hFind != INVALID_HANDLE_VALUE) - { - FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal); - FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0); - FindClose(hFind); - } -} - -/* calculate the CRC32 of a file, - because to encrypt a file, we need known the CRC32 of the file before */ -bool GetFileCrc(const TCHAR* filenameinzip, unsigned char* buf, unsigned long size_buf, unsigned long* result_crc) -{ - unsigned long calculate_crc = 0; - bool error = true; - HANDLE hFile = CreateFile(filenameinzip, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(hFile != INVALID_HANDLE_VALUE) - { - DWORD readed; - do - { - if(!ReadFile(hFile, buf, 1024, &readed, NULL)) - { - error = false; - break; - } - - if (readed > 0) - { - calculate_crc = crc32(calculate_crc, buf, readed); - } - } - while (readed > 0); - CloseHandle(hFile); - } - else - { - error = false; - } - - *result_crc=calculate_crc; - return error; -} - -bool ZipFiles(const std::wstring& dir, std::wstring zipFilePath, const std::string& password) -{ - std::list files; - std::map existingContacts; - ListDirectory(dir, L"", files); - bool error = false; - if(files.size() > 0) - { - zlib_filefunc_def pzlib_filefunc_def; - fill_win32_filefunc(&pzlib_filefunc_def); - zipFilePath = GetFileName(zipFilePath, L"", existingContacts, true); - zipFilePath = ReplaceExt(zipFilePath, L"zip"); - zipFile zf = zipOpen2((LPCSTR)(LPTSTR)zipFilePath.c_str(), APPEND_STATUS_CREATE, NULL, &pzlib_filefunc_def); - if (zf != NULL) - { - unsigned char buf[1024]; - char bufF[MAX_PATH + 20]; - while(files.size() > 0) - { - std::wstring zipDir = *files.begin(); - std::wstring localDir = dir + L"\\" + zipDir; - zip_fileinfo zi = {0}; - GetZipFileTime(localDir.c_str(), &zi.dosDate); - if(zipDir.size() > MAX_PATH + 19) - { - error = true; - break; - } - - BOOL badChar; - WideCharToMultiByte(CP_OEMCP, WC_NO_BEST_FIT_CHARS, zipDir.c_str(), -1, bufF, MAX_PATH + 20, NULL, &badChar); - int flag = 0; - if(badChar) - { - flag = 0x800; // UTF - WideCharToMultiByte(CP_UTF8, 0, zipDir.c_str(), -1, bufF, MAX_PATH + 20, NULL, NULL); - } - - unsigned long calculate_crc = 0; - const char* passwordCh = NULL; - if(password.size() > 0) - { - if(!GetFileCrc(localDir.c_str(), buf, 1024, &calculate_crc)) - { - error = true; - break; - } - - passwordCh = password.c_str(); - } - - int err = zipOpenNewFileInZip4_64 (zf, bufF, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, passwordCh, calculate_crc, 0, flag, 0); - if (err == ZIP_OK) - { - HANDLE hFile = CreateFile(localDir.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(hFile != INVALID_HANDLE_VALUE) - { - DWORD readed; - do - { - err = ZIP_OK; - if(!ReadFile(hFile, buf, 1024, &readed, NULL)) - { - error = true; - break; - } - - if (readed > 0) - { - err = zipWriteInFileInZip(zf, buf, readed); - } - } - while ((err == ZIP_OK) && (readed > 0)); - CloseHandle(hFile); - } - - if(zipCloseFileInZip(zf) != ZIP_OK) - { - error = true; - break; - } - } - else - { - error = true; - break; - } - - files.pop_front(); - } - - zipClose(zf, NULL); - } - else - { - error = true; - } - } - - DeleteDirectory(dir.c_str()); - return error; -} - -bool UnzipFiles(const std::wstring& dir, std::wstring& zipFilePath, const std::string& password) -{ - std::list files; - bool error = false; - zlib_filefunc_def pzlib_filefunc_def; - fill_win32_filefunc(&pzlib_filefunc_def); - std::wstring fileNameInZip; - std::map existingContacts; - zipFilePath = GetFileName(zipFilePath, L"", existingContacts, true); - zipFilePath = ReplaceExt(zipFilePath, L"zip"); - unzFile zf = unzOpen2((LPCSTR)(LPTSTR)zipFilePath.c_str(), &pzlib_filefunc_def); - if (zf != NULL) - { - char buf[8192]; - char bufF[MAX_PATH + 20]; - unz_file_info file_info; - do - { - int err = unzGetCurrentFileInfo(zf, &file_info, bufF, MAX_PATH + 20, buf, 8192, NULL, 0); - if (err == UNZ_OK) - { - UINT cp = CP_OEMCP; - if(file_info.flag & 0x800)// UTF - { - cp = CP_UTF8; - } - - // Get Unicode file name for InfoZip style archives, otherwise assume PKZip/WinZip style - if (file_info.size_file_extra) - { - char *p = buf; - unsigned long size = min(file_info.size_file_extra, 8192); - while (size > 0) - { - unsigned short id = *(unsigned short*)p; - unsigned len = *(unsigned short*)(p + 2); - - if (size < (len + 4)) break; - - if (id == 0x7075 && len > 5 && (len - 5) < MAX_PATH + 20 && *(p + 4) == 1) - { - memcpy(bufF, p + 9, len - 5); - bufF[len - 5] = 0; - cp = CP_UTF8; - break; - } - size -= len + 4; - p += len + 4; - } - } - - int sizeC = (int)strlen(bufF); - int sizeW = MultiByteToWideChar(cp, 0, bufF, sizeC, NULL, 0); - fileNameInZip.resize(sizeW); - MultiByteToWideChar(cp, 0, bufF, sizeC, (wchar_t*)fileNameInZip.c_str(), sizeW); - fileNameInZip = dir + L"\\" + fileNameInZip; - for (size_t i = 0; i < fileNameInZip.length(); ++i) - { - if (fileNameInZip[i] == L'/') - fileNameInZip[i] = L'\\'; - } - - if (file_info.external_fa & FILE_ATTRIBUTE_DIRECTORY) - CreatePath(fileNameInZip.c_str()); - else - { - const char* passwordCh = NULL; - if(password.size() > 0) - { - passwordCh = password.c_str(); - } - - err = unzOpenCurrentFilePassword(zf, passwordCh); - if (err == UNZ_OK) - { - CreatePath(GetDirectoryName(fileNameInZip).c_str()); - HANDLE hFile = CreateFile(fileNameInZip.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); - if(hFile != INVALID_HANDLE_VALUE) - { - DWORD writed; - for (;;) - { - err = unzReadCurrentFile(zf, buf, 8192); - if (err <= 0) break; - - if (!WriteFile(hFile, buf, err, &writed, FALSE)) - { - err = -1; - break; - } - } - - CloseHandle(hFile); - if(err < 0) - { - error = true; - break; - } - } - else - { - unzCloseCurrentFile(zf); - error = true; - break; - } - - if(unzCloseCurrentFile(zf) != ZIP_OK) - { - error = true; - break; - } - } - else - { - error = true; - break; - } - } - } - else - { - error = true; - break; - } - } - while (unzGoToNextFile(zf) == UNZ_OK); - - unzClose(zf); - } - else - { - error = true; - } - - return error; -} - -bool FtpFiles(const std::wstring& dir, const std::wstring& filePath, const std::wstring& ftpName) -{ - std::list files; - std::map existingContacts; - ListDirectory(dir, L"\\", files); - if(files.size() > 0) - { - std::wofstream stream ((dir + _T("\\script.sc")).c_str()); - if(stream.is_open()) - { - std::wstring ftpDir = GetDirectoryName(filePath); - ftpDir = GetFileName(ftpDir, L"", existingContacts, false); - stream << "option batch continue\noption confirm off\nopen \"" - << ftpName << "\"\noption transfer binary\n"; - std::wstring lastCD; - size_t filSize = files.size(); - while(files.size() > 0) - { - std::wstring localDir = *files.begin(); - std::wstring currentCD = ftpDir + GetDirectoryName(ReplaceStr(localDir, L'\\', L'/')); - if(currentCD != lastCD) - { - if(!currentCD.empty() && currentCD != L"/") - stream << "mkdir \"" << currentCD << "\"\n"; - stream << "cd \"" << currentCD << "\"\n"; - lastCD = currentCD; - } - - std::wstring name = GetName(localDir); - stream << "call MDTM " << name << "\n"; - stream << "put \"." << localDir << "\"\n"; - stream << "call MDTM " << name << "\n"; - files.pop_front(); - } - - stream.close(); - std::wstring &log = Options::instance->ftpLogPath; - CreateDirectory(GetDirectoryName(log).c_str(), NULL); - DeleteFile(log.c_str()); - TCHAR cmdLine[MAX_PATH]; - _stprintf_s(cmdLine, _T("\"%s\" /nointeractiveinput /log=\"%s\" /script=script.sc"), Options::instance->ftpExePath.c_str(), log.c_str()); - STARTUPINFO startupInfo = {0}; - PROCESS_INFORMATION processInfo; - startupInfo.cb = sizeof(STARTUPINFO); - if(CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, dir.c_str(), &startupInfo, &processInfo)) - { - WaitForSingleObject(processInfo.hProcess, INFINITE); - CloseHandle(processInfo.hThread); - CloseHandle(processInfo.hProcess); - if(log.empty()) - { - return false; - } - - std::wifstream logStream (log.c_str()); - if(logStream.is_open()) - { - bool isInMDTM = false; - std::list dates; - while(!logStream.eof()) - { - std::wstring lineStr; - std::getline(logStream, lineStr); - if(lineStr.length() > 1) - { - if(lineStr[0] == L'>') - { - if(isInMDTM) - { - if(lineStr.find(L"Script:") < lineStr.length()) - { - dates.push_back(L""); - isInMDTM = false; - } - } - - if(lineStr.find(L"Script: call MDTM") < lineStr.length()) - { - isInMDTM = true; - } - } - else if(isInMDTM && lineStr[0] == L'<') - { - size_t ss = lineStr.find(L"Script: 213 "); - if(ss < lineStr.length()) - { - ss += 12; - if(ss < lineStr.length()) - { - lineStr = lineStr.substr(ss); - if(lineStr.size() == 14) - { - dates.push_back(lineStr); - isInMDTM = false; - } - } - } - } - } - } - - if(dates.size() > 0 && dates.size() == filSize * 2) - { - for(std::list::const_iterator it = dates.begin(); it != dates.end(); ++it) - { - std::wstring date1 = *it++; - if(it->empty() || date1 == *it) - return true; - - } - - return false; - } - } - } - } - } - - return true; -} - -bool FtpGetFiles(const std::wstring& dir, const std::list& files, const std::wstring& ftpName) -{ - std::map existingContacts; - std::wstring script = dir + _T("\\script.sc"); - std::wofstream stream (script.c_str()); - if(stream.is_open()) - { - stream << "option batch continue\noption confirm off\nopen \"" - << ftpName << "\"\noption transfer binary\n"; - std::wstring lastCD; - std::list localFiles; - for(std::list::const_iterator it = files.begin(); it != files.end(); ++it) - { - std::wstring fileName = GetName(*it); - localFiles.push_back(dir + L"\\" + fileName); - std::wstring currentCD = GetDirectoryName(*it); - if(currentCD != lastCD) - { - stream << "cd \"" << currentCD << "\"\n"; - lastCD = currentCD; - } - - stream << "get \"" << fileName << "\"\n"; - } - - stream.close(); - std::wstring &log = Options::instance->ftpLogPath; - CreateDirectory(GetDirectoryName(log).c_str(), NULL); - DeleteFile(log.c_str()); - TCHAR cmdLine[MAX_PATH]; - _stprintf_s(cmdLine, _T("\"%s\" /nointeractiveinput /log=\"%s\" /script=script.sc"), Options::instance->ftpExePath.c_str(), log.c_str()); - STARTUPINFO startupInfo = {0}; - PROCESS_INFORMATION processInfo; - startupInfo.cb = sizeof(STARTUPINFO); - if(CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, dir.c_str(), &startupInfo, &processInfo)) - { - WaitForSingleObject(processInfo.hProcess, INFINITE); - CloseHandle(processInfo.hThread); - CloseHandle(processInfo.hProcess); - } - - DeleteFile(script.c_str()); - for(std::list::const_iterator it = localFiles.begin(); it != localFiles.end(); ++it) - { - DWORD atr = GetFileAttributes(it->c_str()); - if(atr == INVALID_FILE_ATTRIBUTES || atr & FILE_ATTRIBUTE_DIRECTORY) - { - return true; - } - } - - return false; - } - - return true; -} - -void CreatePath(const TCHAR *szDir) -{ - if (!szDir) return; - - DWORD dwAttributes; - TCHAR *pszLastBackslash, szTestDir[ MAX_PATH ]; - - lstrcpyn( szTestDir, szDir, SIZEOF( szTestDir )); - if (( dwAttributes = GetFileAttributes( szTestDir )) != INVALID_FILE_ATTRIBUTES && ( dwAttributes & FILE_ATTRIBUTE_DIRECTORY )) - return; - - pszLastBackslash = _tcsrchr( szTestDir, '\\' ); - if ( pszLastBackslash == NULL ) - return; - - *pszLastBackslash = '\0'; - CreatePath( szTestDir ); - *pszLastBackslash = '\\'; - - CreateDirectory( szTestDir, NULL ); -} - -INT_PTR ExecuteTaskService(WPARAM wParam, LPARAM lParam) -{ - EnterCriticalSection(&Options::instance->criticalSection); - int taskNr = (int)wParam; - if(taskNr < 0 || taskNr >= (int)Options::instance->taskOptions.size()) - { - LeaveCriticalSection(&Options::instance->criticalSection); - return FALSE; - } - - Options::instance->taskOptions[taskNr].forceExecute = true; - Options::instance->taskOptions[taskNr].showMBAfterExecute = true; - LeaveCriticalSection(&Options::instance->criticalSection); - StartThread(false); - return TRUE; -} - -void DoError(const TaskOptions& to, const std::wstring _error) -{ - TCHAR msg[256]; - _stprintf_s(msg, TranslateT("Task '%s' execution failed:"), to.taskName.c_str()); - if(Options::instance->schedulerHistoryAlerts) - { - std::wstring error = msg; - error += L"\n"; - error += _error; - DBEVENTINFO dbei = {0}; - dbei.cbSize = sizeof(DBEVENTINFO); - dbei.szModule = MODULE; - dbei.flags = DBEF_UTF | DBEF_READ; - dbei.timestamp = time(NULL); - // For now I do not convert event data from string to blob, and event type must be message to handle it properly - dbei.eventType = EVENTTYPE_MESSAGE; - int len = (int)error.length() + 1; - dbei.cbBlob = WideCharToMultiByte(CP_UTF8, 0, error.c_str(), len, NULL, 0, NULL, NULL); - char* buf = new char[dbei.cbBlob]; - dbei.cbBlob = WideCharToMultiByte(CP_UTF8, 0, error.c_str(), len, buf, dbei.cbBlob, NULL, NULL); - dbei.pBlob = (PBYTE)buf; - CallService(MS_DB_EVENT_ADD, NULL, (LPARAM) & dbei); - } - - - if(Options::instance->schedulerAlerts) - { - if(CallService(MS_SYSTEM_TERMINATED, 0, 0)) return; - if(ServiceExists(MS_POPUP_ADDPOPUPCLASS)) - { - ShowClassPopupT(MODULE, msg, (wchar_t*)_error.c_str()); - } - else if (ServiceExists( MS_POPUP_ADDPOPUPT )) - { - POPUPDATAT ppd = {0}; - ppd.lchIcon = LoadSkinnedIcon(SKINICON_OTHER_HISTORY); - _tcscpy_s(ppd.lptzContactName, msg); - _tcscpy_s(ppd.lptzText, _error.c_str()); - CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&ppd, 0); - } - } -} diff --git a/plugins/BasicHistory/SearchContext.h b/plugins/BasicHistory/SearchContext.h deleted file mode 100644 index 6b1655d857..0000000000 --- a/plugins/BasicHistory/SearchContext.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once -#include "EventList.h" - -class SearchContext : public EventList -{ -public: - HWND editWindow; - HWND findWindow; - HWND toolbarWindow; - HWND listWindow; - int selected; - - virtual void SelectEventGroup(int sel) = 0; - virtual HANDLE GetNextContact(HANDLE hContact, int adder) = 0; - virtual void SelectContact(HANDLE _hContact) = 0; - - struct MessageData - { - MessageData(const std::wstring& _description, int _startPos, int _endPos, bool _isMe, DWORD _timestamp) - :description(_description) - { - startPos = _startPos; - endPos = _endPos; - isMe = _isMe; - timestamp = _timestamp; - } - - std::wstring description; - int startPos; - int endPos; - bool isMe; - DWORD timestamp; - }; - - std::vector currentGroup; -}; - diff --git a/plugins/BasicHistory/Searcher.cpp b/plugins/BasicHistory/Searcher.cpp deleted file mode 100644 index c93685bcf3..0000000000 --- a/plugins/BasicHistory/Searcher.cpp +++ /dev/null @@ -1,388 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "StdAfx.h" -#include "Searcher.h" -#include "resource.h" - -Searcher::Searcher() - :lastFindSelection(-1), - findBack(false), - matchCase(false), - matchWholeWords(false), - onlyIn(false), - onlyOut(false), - context(NULL) -{ -} - -void Searcher::ChangeFindDirection(bool isBack) -{ - if(isBack != findBack) - { - findBack = isBack; - ClearFind(); - TBBUTTONINFO tbInfo; - tbInfo.cbSize = sizeof(TBBUTTONINFO); - tbInfo.dwMask = TBIF_TEXT | TBIF_IMAGE; - if(isBack) - { - tbInfo.pszText = TranslateT("Find Previous"); - tbInfo.iImage = 1; - } - else - { - tbInfo.pszText = TranslateT("Find Next"); - tbInfo.iImage = 0; - } - SendMessage(context->toolbarWindow, TB_SETBUTTONINFO, (WPARAM)IDM_FIND, (LPARAM)&tbInfo); - } - - Find(); -} - -void Searcher::ClearFind() -{ - if(lastFindSelection != -1) - { - SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_AND,~ECO_NOHIDESEL); - lastFindSelection = -1; - } -} - -inline TCHAR mytoupper(TCHAR a, std::locale* loc) -{ - return std::toupper(a, *loc); -} - -bool Searcher::CompareStr(std::wstring str, TCHAR *strFind) -{ - std::locale loc; - if(!matchCase) - std::transform(str.begin(), str.end(), str.begin(), std::bind2nd(std::ptr_fun(mytoupper), &loc)); - if(!matchWholeWords) - return str.find(strFind) < str.length(); - size_t findid = str.find(strFind); - size_t findLen = _tcslen(strFind); - while(findid < str.length()) - { - if((findid == 0 || std::isspace(str[findid - 1], loc) || std::ispunct(str[findid - 1], loc)) && - (findid + findLen >= str.length() || std::isspace(str[findid + findLen], loc) || std::ispunct(str[findid + findLen], loc))) - return true; - findid = str.find(strFind, findid + 1); - } - - return false; -} - -void Searcher::Find() -{ - FINDTEXTEX ft; - TCHAR str[128]; - int curSel = 0; - bool isStart = false; - bool finished = false; - ft.chrg.cpMin = 0; - ft.chrg.cpMax = -1; - ft.lpstrText = str; - if(context->currentGroup.size() < 1) - { - SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_AND,~ECO_NOHIDESEL); - lastFindSelection = -1; - return; - } - - GetWindowText(context->findWindow, str, 128); - if(!str[0]) - { - TCHAR buf[256]; - mir_sntprintf(buf, 256, TranslateT("\"%s\" not found"), str); - MessageBox(context->hWnd, buf, TranslateT("Search"), MB_OK | MB_ICONINFORMATION); - return; - } - if(!matchCase) - { - std::locale loc; - std::transform(str, str + _tcslen(str), str, std::bind2nd(std::ptr_fun(mytoupper), &loc)); - } - - bool findBack1 = findBack ^ !searchForInMes; - bool findBack2 = findBack ^ !searchForInLG; - int adder1 = findBack1 ? -1 : 1; - int adder2 = findBack2 ? -1 : 1; - WPARAM findStyle = (findBack1 ? 0 : FR_DOWN) | (matchCase ? FR_MATCHCASE : 0) | (matchWholeWords ? FR_WHOLEWORD : 0); - if(lastFindSelection >= 0 && lastFindSelection < (int)context->currentGroup.size()) - { - if(onlyIn && context->currentGroup[lastFindSelection].isMe || onlyOut && !context->currentGroup[lastFindSelection].isMe) - { - curSel = lastFindSelection + adder1; - } - else - { - SendDlgItemMessage(context->hWnd,IDC_EDIT,EM_EXGETSEL,0,(LPARAM)&ft.chrg); - if(findBack1) - { - ft.chrg.cpMin = ft.chrg.cpMin < context->currentGroup[lastFindSelection].endPos ? ft.chrg.cpMin : context->currentGroup[lastFindSelection].endPos; - ft.chrg.cpMax = context->currentGroup[lastFindSelection].startPos; - } - else - { - ft.chrg.cpMin = ft.chrg.cpMax > context->currentGroup[lastFindSelection].startPos ? ft.chrg.cpMax : context->currentGroup[lastFindSelection].startPos; - ft.chrg.cpMax = context->currentGroup[lastFindSelection].endPos; - } - SendMessage(context->editWindow,EM_FINDTEXTEX, findStyle,(LPARAM)&ft); - if(ft.chrgText.cpMin < 0 || ft.chrgText.cpMax < 0) - { - curSel = lastFindSelection + adder1; - } - else - { - if(isFindContactChanged && startFindContact == context->hContact && isFindSelChanged && context->selected == startFindSel && ((!findBack1 && ft.chrg.cpMin >= startFindPos) || (findBack1 && ft.chrg.cpMax <= startFindPos))) - { - finished = true; - } - else - { - curSel = lastFindSelection; - SendMessage(context->editWindow,EM_EXSETSEL,0,(LPARAM)&ft.chrgText); - SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_OR,ECO_NOHIDESEL); - lastFindSelection = curSel; - return; - } - } - } - } - else - { - isStart = true; - SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_OR,ECO_NOHIDESEL); - SendMessage(context->editWindow,EM_EXGETSEL,0,(LPARAM)&ft.chrg); - startFindPos = findBack1 ? ft.chrg.cpMin : (ft.chrg.cpMax >= 0 ? ft.chrg.cpMax : ft.chrg.cpMin); - startFindSel = context->selected; - if(startFindPos < 0) - startFindPos = 0; - isFindSelChanged = false; - startFindContact = context->hContact; - isFindContactChanged = !allUsers; - if(findBack1) - for(curSel = (int)context->currentGroup.size() - 1; curSel >= 0; --curSel) - { - if(context->currentGroup[curSel].startPos < startFindPos) - break; - } - else - for(; curSel < (int)context->currentGroup.size(); ++curSel) - { - if(context->currentGroup[curSel].endPos > startFindPos) - break; - } - } - - if(!finished) - { - for(; curSel < (int)context->currentGroup.size() && curSel >= 0; curSel += adder1) - { - if(onlyIn && context->currentGroup[curSel].isMe || onlyOut && !context->currentGroup[curSel].isMe) - continue; - if(CompareStr(context->currentGroup[curSel].description, str)) - { - if(findBack1) - { - ft.chrg.cpMin = context->currentGroup[curSel].endPos; - ft.chrg.cpMax = context->currentGroup[curSel].startPos; - if(!isFindSelChanged && ft.chrg.cpMin > startFindPos) - ft.chrg.cpMin = startFindPos; - } - else - { - ft.chrg.cpMin = context->currentGroup[curSel].startPos; - ft.chrg.cpMax = context->currentGroup[curSel].endPos; - if(!isFindSelChanged && ft.chrg.cpMin < startFindPos) - ft.chrg.cpMin = startFindPos; - } - SendMessage(context->editWindow,EM_FINDTEXTEX, findStyle,(LPARAM)&ft); - if(!(ft.chrgText.cpMin < 0 || ft.chrgText.cpMax < 0)) - { - if(isFindContactChanged && startFindContact == context->hContact && isFindSelChanged && context->selected == startFindSel && ((!findBack1 && ft.chrg.cpMin >= startFindPos) || (findBack1 && ft.chrg.cpMax <= startFindPos))) - { - finished = true; - break; - } - SendMessage(context->editWindow,EM_EXSETSEL,0,(LPARAM)&ft.chrgText); - SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_OR,ECO_NOHIDESEL); - lastFindSelection = curSel; - return; - } - } - } - } - - if(isFindContactChanged && startFindContact == context->hContact && isFindSelChanged && context->selected == startFindSel) - { - finished = true; - } - - if(!finished) - { - isFindSelChanged = true; - if(onlyGroup) - { - if(IsInSel(context->selected, str)) - { - CHARRANGE ch; - ch.cpMin = ch.cpMax = findBack1 ? MAXLONG : 0; - SendMessage(context->editWindow,EM_EXSETSEL,0,(LPARAM)&ch); - lastFindSelection = findBack1 ? (int)context->currentGroup.size() - 1 : 0; - Find(); - return; - } - } - else - { - for(int sel = context->selected + adder2; ; sel += adder2) - { - if(sel < 0) - { - isFindContactChanged = true; - if(allUsers) - { - HANDLE hNext = context->hContact; - do - { - hNext = context->GetNextContact(hNext, adder2); - } - while(hNext != startFindContact && !context->SearchInContact(hNext, str, this)); - context->SelectContact(hNext); - } - - sel = (int)context->eventList.size() - 1; - } - else if(sel >= (int)context->eventList.size()) - { - isFindContactChanged = true; - if(allUsers) - { - HANDLE hNext = context->hContact; - do - { - hNext = context->GetNextContact(hNext, adder2); - } - while(hNext != startFindContact && !context->SearchInContact(hNext, str, this)); - context->SelectContact(hNext); - } - - sel = 0; - } - if(IsInSel(sel, str)) - { - LVITEM item = {0}; - item.mask = LVIF_STATE; - item.iItem = context->selected; - item.state = 0; - item.stateMask = LVIS_SELECTED; - ListView_SetItem(context->listWindow, &item); - item.iItem = sel; - item.state = LVIS_SELECTED; - ListView_SetItem(context->listWindow, &item); - ListView_EnsureVisible(context->listWindow, sel, FALSE); - CHARRANGE ch; - ch.cpMin = ch.cpMax = findBack1 ? MAXLONG : 0; - SendMessage(context->editWindow,EM_EXSETSEL,0,(LPARAM)&ch); - SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_OR,ECO_NOHIDESEL); - lastFindSelection = findBack1 ? (int)context->currentGroup.size() - 1 : 0; - isFindSelChanged = true; - Find(); - return; - } - if(startFindContact == context->hContact && sel == startFindSel) - break; - } - } - } - - if(startFindContact != context->hContact) - { - context->SelectContact(startFindContact); - } - - if(startFindSel != context->selected) - { - LVITEM item = {0}; - item.mask = LVIF_STATE; - item.iItem = context->selected; - item.state = 0; - item.stateMask = LVIS_SELECTED; - ListView_SetItem(context->listWindow, &item); - item.iItem = startFindSel; - item.state = LVIS_SELECTED; - ListView_SetItem(context->listWindow, &item); - ListView_EnsureVisible(context->listWindow, startFindSel, FALSE); - context->SelectEventGroup(startFindSel); - SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_OR,ECO_NOHIDESEL); - } - ft.chrgText.cpMin = startFindPos; - ft.chrgText.cpMax = startFindPos; - SendMessage(context->editWindow,EM_EXSETSEL,0,(LPARAM)&ft.chrgText); - SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_AND,~ECO_NOHIDESEL); - lastFindSelection = -1; - if(isStart) - { - TCHAR buf[256]; - GetWindowText(context->findWindow, str, 128); - mir_sntprintf(buf, 256, TranslateT("\"%s\" not found"), str); - MessageBox(context->hWnd, buf, TranslateT("Search"), MB_OK | MB_ICONINFORMATION); - } - else - { - MessageBox(context->hWnd, TranslateTS(onlyGroup ? LPGENT("You have reached the end of the group.") : LPGENT("You have reached the end of the history.")), TranslateT("Search"), MB_OK | MB_ICONINFORMATION); - } -} - -bool Searcher::IsInSel(int sel, TCHAR *strFind) -{ - if(sel < 0 || sel >= (int)context->eventList.size()) - return false; - - TCHAR str[MAXSELECTSTR + 8]; // for safety reason - EventList::EventData data; - for(std::deque::iterator it = context->eventList[sel].begin(); it != context->eventList[sel].end(); ++it) - { - EventList::EventIndex hDbEvent = *it; - if(context->GetEventData(hDbEvent, data)) - { - bool isMe = data.isMe; - if(onlyIn && isMe || onlyOut && !isMe) - continue; - context->GetEventMessage(hDbEvent, str); - if(CompareStr(str, strFind)) - { - return true; - } - } - } - - return false; -} - -bool Searcher::Compare(const bool isMe, const std::wstring& message, TCHAR *strFind) -{ - if(onlyIn && isMe || onlyOut && !isMe) - return false; - - return CompareStr(message, strFind); -} diff --git a/plugins/BasicHistory/Searcher.h b/plugins/BasicHistory/Searcher.h deleted file mode 100644 index 2f5aff6e8b..0000000000 --- a/plugins/BasicHistory/Searcher.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once -#include "SearchContext.h" - -class Searcher : ComparatorInterface -{ -private: - SearchContext* context; - int lastFindSelection; - int startFindPos; - int startFindSel; - HANDLE startFindContact; - bool isFindSelChanged; - bool isFindContactChanged; - bool findBack, matchCase, matchWholeWords, onlyIn, onlyOut, onlyGroup, allUsers, searchForInLG, searchForInMes; - - bool CompareStr(std::wstring str, TCHAR *strFind); - bool IsInSel(int sel, TCHAR *strFind); -public: - Searcher(); - virtual bool Compare(const bool isMe, const std::wstring& message, TCHAR *strFind); - void Find(); - void ChangeFindDirection(bool isBack); - void ClearFind(); - void SetContect(SearchContext* _context){ - context = _context; - } - void SetMatchCase(bool val){ - matchCase = val; - ClearFind(); - } - void SetMatchWholeWords(bool val){ - matchWholeWords = val; - ClearFind(); - } - bool IsMatchCase(){ - return matchCase; - } - bool IsMatchWholeWords(){ - return matchWholeWords; - } - bool IsFindBack(){ - return findBack; - } - void SetOnlyIn(bool val){ - onlyIn = val; - if(val && onlyOut) - onlyOut = false; - ClearFind(); - } - void SetOnlyOut(bool val){ - onlyOut = val; - if(val && onlyIn) - onlyIn = false; - ClearFind(); - } - bool IsOnlyIn(){ - return onlyIn; - } - bool IsOnlyOut(){ - return onlyOut; - } - void SetOnlyGroup(bool val){ - onlyGroup = val; - if(onlyGroup) - allUsers = false; - ClearFind(); - } - bool IsOnlyGroup(){ - return onlyGroup; - } - void SetAllUsers(bool val){ - allUsers = val; - if(allUsers) - onlyGroup = false; - ClearFind(); - } - bool IsAllUsers(){ - return allUsers; - } - void SetSearchForInLG(bool val){ - if(searchForInLG != val) - { - searchForInLG = val; - ClearFind(); - } - } - void SetSearchForInMes(bool val){ - if(searchForInMes != val) - { - searchForInMes = val; - ClearFind(); - } - } - bool IsSearchForInLG(){ - return searchForInLG; - } - bool IsSearchForInMes(){ - return searchForInMes; - } -}; - diff --git a/plugins/BasicHistory/TxtExport.cpp b/plugins/BasicHistory/TxtExport.cpp deleted file mode 100644 index a5ca8afddf..0000000000 --- a/plugins/BasicHistory/TxtExport.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#include "StdAfx.h" -#include "TxtExport.h" -#define EXP_FILE (*stream) - -TxtExport::~TxtExport() -{ -} - -void TxtExport::WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding) -{ - TCHAR* start = TranslateT("###"); - EXP_FILE << start << "\n" << start << _T(" ") << TranslateT("History Log") << _T("\n"); - EXP_FILE << start << _T(" ") << myName; - if(proto1.length() || myId.length()) - { - EXP_FILE << _T(" (") << proto1 << _T(": ") << myId << _T(") - "); - } - else - { - EXP_FILE << _T(" - "); - } - - EXP_FILE << name1; - if(proto1.length() || id1.length()) - { - EXP_FILE << _T(" (") << proto1 << _T(": ") << id1 << _T(")\n"); - } - else - { - EXP_FILE << _T("\n"); - } - - EXP_FILE << start << _T(" ") << TranslateT("Filter:") << _T(" ") << filterName << _T("\n") << start << _T("\n"); -} - -void TxtExport::WriteFooter() -{ -} - -void TxtExport::WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText) -{ -} - -void TxtExport::WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei) -{ - EXP_FILE << "\n[" << longDate << "] " << user << ":\n" << message << "\n"; -} diff --git a/plugins/BasicHistory/TxtExport.h b/plugins/BasicHistory/TxtExport.h deleted file mode 100644 index bee2718649..0000000000 --- a/plugins/BasicHistory/TxtExport.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once -#include "IExport.h" - -class TxtExport : - public IExport -{ -public: - virtual const TCHAR* GetExt() - { - return _T("txt"); - } - - virtual void WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding); - virtual void WriteFooter(); - virtual void WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText); - virtual void WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei); - - virtual ~TxtExport(); -}; - diff --git a/plugins/BasicHistory/basichistory-translation.txt b/plugins/BasicHistory/basichistory-translation.txt deleted file mode 100644 index c1be849b57..0000000000 --- a/plugins/BasicHistory/basichistory-translation.txt +++ /dev/null @@ -1,252 +0,0 @@ -; Common strings that belong to many files -;[History] -;[%s Files (*.%s)] -;[* Use negative values to filter younger events] -;[All Contacts] -;[All events] -;[Binary] -;[Compress output files] -;[Dat (mContacts)] -;[Day] -;[Day of week] -;[Default history events] -;[Delete] -;[Delete All User History] -;[Delta time] -;[Error] -;[Export] -;[Export To Plain Html] -;[Export To Rich Html] -;[Export To Txt] -;[Export to] -;[Filter] -;[Filter:] -;[Find Next] -;[Find Previous] -;[Hide Contacts] -;[History Log] -;[Import] -;[Import from] -;[Invalid '%s' value.] -;[Invalid '%s' value.\n%s] -;[Match Case] -;[Match Whole Word] -;[Name] -;[Only Incomming Messages] -;[Only Outgoing Messages] -;[Only Selected Group] -;[Plain Html] -;[Rich Html] -;[Session name] -;[Show Contacts] -;[Some value is invalid] -;[System] -;[Time] -;[Txt] -;[Upload to FTP (WinSCP requred)] - -; ../../plugins/BasicHistory/BasicHistory.cpp -;[Execute history task] -;[Incoming message] -;[Minus in export] -;[Open History] -;[Outgoing message] -;[Plus in export] -;[Statuschange] -;[View &History] - -; ../../plugins/BasicHistory/BasicHistory.rc -;[* Choose encoding from combo box or enter code page number and name separated by semicolon, name is used in Content-Type header.] -;[Action type] -;[Active] -;[Add event] -;[Add filter] -;[Add task] -;[Always show contact list] -;[Cancel] -;[Custom filters] -;[Default Event Filter] -;[Delete event] -;[Delete filter] -;[Delete task] -;[Delta time to group messages:] -;[Display errors using popups] -;[Edit task] -;[Enable Smileys] -;[Events older than*] -;[Execute task for specified contacts] -;[Export imported messages] -;[External CSS file] -;[File encoding*] -;[Limit messages to:] -;[Message History] -;[New messages on top] -;[OK] -;[Password] -;[Path to file**] -;[Save errors to system history] -;[Search forward in list group] -;[Search forward in message window] -;[Settings] -;[Show date in timestamps] -;[Show event icons] -;[Show groups in contact list] -;[Show messages] -;[Show names] -;[Show seconds in timestamps] -;[Show timestamps] -;[Task] -;[Triger type] -;[Truncate message length to:] -;[WinSCP log path] -;[WinSCP path] -;[hours] - -; ../../plugins/BasicHistory/EventList.cpp -;[Authorisation request by %s (%s%d): %s] -;[History for %s] -;[Invalid Message] -;[Me] - -; ../../plugins/BasicHistory/ExportManager.cpp -;[*.%s] -;[File do not contain selected contact] -;[File is corrupted] - -; ../../plugins/BasicHistory/HistoryWindow.cpp -;[&Copy link] -;[&Open in existing window] -;[Are You sure?] -;[Copy] -;[Delete Group] -;[Do you want delete all imported messages for this contact?\nNote that next scheduler task import this messages again.] -;[Do you want save imported messages to local profile?] -;[Filters] -;[Fonts & Colors] -;[Hotkeys] -;[Icons] -;[Number of history items to delete: %d.\nAre you sure you want to do this?] -;[Open in &new window] -;[Options] -;[Reply &Quoted] -;[Save window position as default] -;[Save window position for all contacts] -;[Send Message] -;[This operation will PERMANENTLY REMOVE all history for this contact.\nAre you sure you want to do this?] - -; ../../plugins/BasicHistory/Options.cpp -;[** Use to insert date, to insert extension, to insert contact name] -;[** Use to insert extension, to insert contact name] -;[<< Incoming messages] -;[<< Incoming name] -;[<< Incoming timestamp] -;[>> Outgoing messages] -;[>> Outgoing name] -;[>> Outgoing timestamp] -;[Advanced] -;[All Files (*.*)] -;[At Finish] -;[At Start] -;[Authorization request] -;[Browse CSS file] -;[Browse WinSCP file] -;[Contact list background] -;[Contacts recieved] -;[Daily] -;[Delta time (hours)] -;[Delta time (minutes)] -;[Download from FTP (WinSCP requred)] -;[Enter filter name] -;[Event already exists] -;[Events older than] -;[Export To Binary] -;[Export To Dat (mContacts)] -;[Export and Delete] -;[File do not exist. Enter correct file path.] -;[File transfer] -;[Filter name exists] -;[Find] -;[Find window] -;[Find window background] -;[Friday] -;[Group list] -;[Group list background] -;[Hour] -;[Import From Binary] -;[Import From Dat (mContacts)] -;[Import and Marge] -;[Incoming background] -;[Incoming events] -;[Input files are compressed] -;[Invalid codepage] -;[Invalid event number] -;[Invalid file] -;[Link] -;[Message] -;[Messages] -;[Minute] -;[Monday] -;[Monthly] -;[Open global history] -;[Outgoing background] -;[Outgoing events] -;[SMS message] -;[SMTP Simple Email] -;[Saturday] -;[Save WinSCP log file] -;[Scheduler] -;[Searching] -;[Show/Hide Contacts] -;[Status change] -;[Sunday] -;[Switch All Contacts] -;[Switch Match Case] -;[Switch Match Whole Word] -;[Switch Only Incomming Messages] -;[Switch Only Outgoing Messages] -;[Switch Only Selected Group] -;[Thursday] -;[Tuesday] -;[Wednesday] -;[Weekly] -;[Window background] -;[You were added] -;[You've entered invalid codepage. Select codepage from combo box or enter correct number.] - -; ../../plugins/BasicHistory/PlainHtmlExport.cpp -;[Conversation started at %s] - -; ../../plugins/BasicHistory/RichHtmlExport.cpp -;[Close all] -;[Menu] -;[Open all] -;[_files] - -; ../../plugins/BasicHistory/Scheduler.cpp -;[At least one contact should be selected.] -;[Cannot compress file(s).] -;[Cannot export history for contact: %s.] -;[Cannot get FTP file(s).] -;[Cannot send FTP file(s).] -;[Cannot unzip file(s).] -;[Contacts] -;[FTP path cannot contain in import task.] -;[FTP path must contains '/' instead '\\' and starts from '/'.] -;[History task] -;[Incorrect file format: %s.] -;[Path to file] -;[Path to output file] -;[Task '%s' execution failed] -;[Task '%s' execution failed:] -;[Task '%s' finished successfully] -;[Task finished] -;[To create session open WinSCP, click New Session, enter data and save with specific name. Remember if FTP server using password you should save it in WinSCP.] -;[Unknown contact in file: %s.] -;[Unknown error] -;[Upload to FTP] - -; ../../plugins/BasicHistory/Searcher.cpp -;[Search] -;[You have reached the end of the group.] -;[You have reached the end of the history.] -;[\"%s\" not found] diff --git a/plugins/BasicHistory/codecvt_CodePage.h b/plugins/BasicHistory/codecvt_CodePage.h deleted file mode 100644 index 37b6b7d26f..0000000000 --- a/plugins/BasicHistory/codecvt_CodePage.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -Basic History plugin -Copyright (C) 2011-2012 Krzysztof Kral - -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 version 2 -of the License. - -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, see . -*/ - -#pragma once - -template -class codecvt_CodePage : public std::codecvt<_Elem, char, mbstate_t> -{ -private: - UINT codePage; -public: - typedef std::codecvt<_Elem, char, mbstate_t> _Mybase; - typedef typename _Mybase::result result; - typedef char _Byte; - typedef _Elem intern_type; - typedef _Byte extern_type; - typedef mbstate_t state_type; - - explicit codecvt_CodePage(UINT _codePage) - : _Mybase(0), - codePage(_codePage) - { // construct with ref count - } - - virtual ~codecvt_CodePage() - { // destroy the object - } - -protected: - virtual result do_in(mbstate_t& _State, const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1, _Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const - { // convert bytes [_First1, _Last1) to [_First2, _Last) - return (_Mybase::error); // not implemented - } - - virtual result do_out(mbstate_t& _State, const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1, _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const - { // convert [_First1, _Last1) to bytes [_First2, _Last) - _Mid1 = _First1; - _Mid2 = _First2; - - int conv = WideCharToMultiByte(codePage, 0, _First1, _Last1 - _First1, _First2, _Last2 - _First2, NULL, NULL); - if(conv == 0) - { - if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) - return (_Mybase::partial); - else - return (_Mybase::error); - } - else - { - _Mid1 = _Last1; - _Mid2 = _First2 + conv; - } - - return (_Mybase::ok); - } - - virtual result do_unshift(mbstate_t&, - _Byte *_First2, _Byte *, _Byte *& _Mid2) const - { // generate bytes to return to default shift state - _Mid2 = _First2; - return (_Mybase::ok); - } - - virtual int do_length(const mbstate_t& _State, const _Byte *_First1, const _Byte *_Last1, size_t _Count) const _THROW0() - { // return min(_Count, converted length of bytes [_First1, _Last1)) - return (int)_Count; // not implemented - } - - virtual bool do_always_noconv() const _THROW0() - { // return true if conversions never change input - return (false); - } - - virtual int do_max_length() const _THROW0() - { // return maximum length required for a conversion - return 6; - } - - virtual int do_encoding() const _THROW0() - { // return length of code sequence (from codecvt) - return 0; // -1 => state dependent, 0 => varying length - } -}; diff --git a/plugins/BasicHistory/dllmain.cpp b/plugins/BasicHistory/dllmain.cpp deleted file mode 100644 index ad89773ec8..0000000000 --- a/plugins/BasicHistory/dllmain.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// dllmain.cpp : Defines the entry point for the DLL application. -#include "stdafx.h" - -HINSTANCE hInst; - -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - hInst = hModule; - return TRUE; -} - diff --git a/plugins/BasicHistory/history.css b/plugins/BasicHistory/history.css deleted file mode 100644 index 43a584597d..0000000000 --- a/plugins/BasicHistory/history.css +++ /dev/null @@ -1,34 +0,0 @@ -h3 { color: #666666; text-align: center; font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 16pt; } -h4 { text-align: center; font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14pt; } -h6 { font-weight: normal; color: #000000; text-align: center; font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 8pt; } -.mes { border-top-width: 1px; border-right-width: 1px; border-bottom-width: 0px;border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #666666; border-bottom-color: #666666; border-left-color: #666666; border-right-color: #666666; padding: 4px; color: #000000; font: normal normal normal 8pt normal Tahoma, Tahoma, Verdana, Arial, sans-serif; text-decoration: none; } -.text { clear: both; } -.nick { float: left; font: normal normal bold 8pt normal Tahoma, Tahoma, Verdana, Arial, sans-serif; text-decoration: none; } -.date { float: left; padding-left:5px; padding-right:5px; font: normal normal bold 8pt normal Tahoma, Tahoma, Verdana, Arial, sans-serif; text-decoration: none; } -.eventimg { float: left; } -.nick#inc { color: #C83F6B; } -.nick#out { color: #0860BD; } -.date#inc { color: #000000; } -.date#out { color: #000000; } -.url { color: #0000FF; } -.mes#event0 { background-color: #DBDBDB; } -.mes#event1 { background-color: #EEEEEE; } -.mes#event2 { background-color: #CCD9F4; } -.mes#session { background-color: #FFFDD7; } -.mes#bottom { border-right-width: 0px; border-left-width: 0px; } -.mes .eventimg {padding-left:16px; } -.mes#session .eventimg {padding-left:0px; } -.mes .text {padding-left:37px; display:table; } -.mes#session .text {padding-left:0px; clear: none; line-height: 16px; } -.mes#session .date {line-height: 16px; } -.group { display: none; margin: 0px; } -.sessionimage { vertical-align:middle; } -.smiley { vertical-align:middle; } -#menubar { position:absolute; left:10px; top:10px; visibility:hidden; border: 1px solid #000000; background-color:#dddddd; padding: 3px 3px 3px 3px; } -.mainmenu { text-decoration:none; color:#6666AA; background-color: transparent; } -.mainmenusel { text-decoration:none; color:#6666AA; background-color: #BBBBBB; } -.floatmenu { position: absolute; background-color: #dddddd; visibility: hidden; top: 36px; left: 10px; } -.floatmenu table { border: 1px solid #000000; } -.menuitem { text-decoration:none; color:#0860BD; } -.menuitemunsel { background-color: transparent; } -.menuitemsel { background-color: #BBBBBB; } \ No newline at end of file diff --git a/plugins/BasicHistory/history.js b/plugins/BasicHistory/history.js deleted file mode 100644 index 4d2156ac24..0000000000 --- a/plugins/BasicHistory/history.js +++ /dev/null @@ -1,95 +0,0 @@ - -function toggleFolder(id, imageNode) -{ - var folder = document.getElementById(id); - if (imageNode.previousSibling != null) - { - imageNode = imageNode.previousSibling; - } - var l = imageNode.src.length; - if (folder == null) - { - } - else if (folder.style.display == "block") - { - if (imageNode != null) - { - if (imageNode.src.substring(l-9,l) == "mnode.ico") - { - imageNode.src = imageNode.src.substring(0, l-9) + "pnode.ico"; - } - } - folder.style.display = "none"; - } - else - { - if (imageNode != null) - { - if (imageNode.src.substring(l-9,l) == "pnode.ico") - { - imageNode.src = imageNode.src.substring(0, l-9) + "mnode.ico"; - } - } - folder.style.display = "block"; - } -} - -var timer; - -function ShowMenu(isShow) -{ - if(timer) - clearTimeout(timer); - - var menu = document.getElementById("L1"); - if(isShow == 1) - menu.style.visibility = "visible"; - else - menu.style.visibility = "hidden"; -} - -function HideMenu() -{ - timer = setTimeout("ShowMenu(0)", 500); -} - -function OpenAll(isOpen) -{ - var idMod = 0; - while(gr = document.getElementById("group" + idMod)) - { - var imageNode = gr.previousSibling; - if(imageNode.tagName == null) - imageNode = imageNode.previousSibling; - imageNode = imageNode.getElementsByTagName("span")[0].getElementsByTagName("img")[0]; - var l = imageNode.src.length; - if(gr.style.display == "block") - { - if(!isOpen) - { - if (imageNode != null) - { - if (imageNode.src.substring(l-9,l) == "mnode.ico") - { - imageNode.src = imageNode.src.substring(0, l-9) + "pnode.ico"; - } - } - gr.style.display = "none"; - } - } - else if(isOpen) - { - if (imageNode != null) - { - if (imageNode.src.substring(l-9,l) == "pnode.ico") - { - imageNode.src = imageNode.src.substring(0, l-9) + "mnode.ico"; - } - } - gr.style.display = "block"; - } - ++idMod; - } - - ShowMenu(0); -} diff --git a/plugins/BasicHistory/icons/FindNext.ico b/plugins/BasicHistory/icons/FindNext.ico deleted file mode 100644 index dd1c62f113..0000000000 Binary files a/plugins/BasicHistory/icons/FindNext.ico and /dev/null differ diff --git a/plugins/BasicHistory/icons/FindPrev.ico b/plugins/BasicHistory/icons/FindPrev.ico deleted file mode 100644 index ba8c3ba5df..0000000000 Binary files a/plugins/BasicHistory/icons/FindPrev.ico and /dev/null differ diff --git a/plugins/BasicHistory/icons/Incom.ico b/plugins/BasicHistory/icons/Incom.ico deleted file mode 100644 index 9c618335c5..0000000000 Binary files a/plugins/BasicHistory/icons/Incom.ico and /dev/null differ diff --git a/plugins/BasicHistory/icons/Outg.ico b/plugins/BasicHistory/icons/Outg.ico deleted file mode 100644 index 8bfeef6344..0000000000 Binary files a/plugins/BasicHistory/icons/Outg.ico and /dev/null differ diff --git a/plugins/BasicHistory/icons/Status change.ico b/plugins/BasicHistory/icons/Status change.ico deleted file mode 100644 index b9b270228a..0000000000 Binary files a/plugins/BasicHistory/icons/Status change.ico and /dev/null differ diff --git a/plugins/BasicHistory/icons/minus.ico b/plugins/BasicHistory/icons/minus.ico deleted file mode 100644 index 39d1f72f79..0000000000 Binary files a/plugins/BasicHistory/icons/minus.ico and /dev/null differ diff --git a/plugins/BasicHistory/icons/mnode.ico b/plugins/BasicHistory/icons/mnode.ico deleted file mode 100644 index d332fbda16..0000000000 Binary files a/plugins/BasicHistory/icons/mnode.ico and /dev/null differ diff --git a/plugins/BasicHistory/icons/plus.ico b/plugins/BasicHistory/icons/plus.ico deleted file mode 100644 index 1230b5de32..0000000000 Binary files a/plugins/BasicHistory/icons/plus.ico and /dev/null differ diff --git a/plugins/BasicHistory/icons/pnode.ico b/plugins/BasicHistory/icons/pnode.ico deleted file mode 100644 index 811dfd0f84..0000000000 Binary files a/plugins/BasicHistory/icons/pnode.ico and /dev/null differ diff --git a/plugins/BasicHistory/res/BasicHistory.rc b/plugins/BasicHistory/res/BasicHistory.rc new file mode 100644 index 0000000000..ff34263736 --- /dev/null +++ b/plugins/BasicHistory/res/BasicHistory.rc @@ -0,0 +1,263 @@ +#include "..\src\resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +//#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +#include +#include +#include +#include +#include +#include + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1250) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_HISTORY DIALOGEX 0, 0, 496, 366 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Message History" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "",IDC_LIST,WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS | LVS_SINGLESEL | LVS_SHAREIMAGELISTS ,102,27,387,73 + CONTROL "",IDC_SPLITTER,WC_STATIC,SS_ENHMETAFILE,102,100,413,2 + CONTROL "", IDC_EDIT, RICHEDIT_CLASS, WS_VSCROLL | WS_TABSTOP | WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | ES_DISABLENOSCROLL, 102,102,387,252 + CONTROL "", IDC_SHOWHIDE,"MButtonClass", WS_TABSTOP,7,7,16,14 + EDITTEXT IDC_FIND_TEXT,25,8,380,12,ES_AUTOHSCROLL + CONTROL "", IDC_TOOLBAR,TOOLBARCLASSNAME, WS_TABSTOP | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | CCS_NOPARENTALIGN | CCS_NODIVIDER | CCS_NORESIZE,413,7,76,20 + CONTROL "", IDC_LIST_CONTACTS, CLISTCONTROL_CLASS, WS_TABSTOP | CLS_USEGROUPS | CLS_NOHIDEOFFLINE | CLS_HIDEEMPTYGROUPS,7,27,93,327,WS_EX_CLIENTEDGE + CONTROL "",IDC_SPLITTERV,WC_STATIC,SS_ENHMETAFILE,100,27,2,338 +END + +IDD_OPT_MAIN DIALOGEX 0, 0, 304, 225 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Settings",IDC_STATIC,4,5,298,220 + CONTROL "Always show contact list",IDC_SHOWCONTACTS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,23,270,10 + CONTROL "Show groups in contact list",IDC_SHOWCONTACTGROUPS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,34,270,10 + COMBOBOX IDC_DEFFILTER,172,45,122,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Default Event Filter",IDC_STATIC,12,48,145,8 + GROUPBOX "Custom filters",IDC_STATIC,12,67,282,86 + LISTBOX IDC_LIST_FILTERS,20,81,133,30, WS_TABSTOP | LBS_NOINTEGRALHEIGHT | WS_BORDER | WS_VSCROLL + LISTBOX IDC_LIST_EVENTS,20,113,133,30, WS_TABSTOP | LBS_NOINTEGRALHEIGHT | WS_BORDER | WS_VSCROLL + EDITTEXT IDC_FILTER_NAME,160,81,130,12,WS_TABSTOP|ES_AUTOHSCROLL + PUSHBUTTON "Add filter",IDC_ADD_FILTER,160,97,63,14, WS_TABSTOP + PUSHBUTTON "Delete filter",IDC_DELETE_FILTER,227,97,63,14, WS_TABSTOP + COMBOBOX IDC_EVENT,160,113,130,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add event",IDC_ADD_EVENT,160,129,63,14, WS_TABSTOP + PUSHBUTTON "Delete event",IDC_DELETE_EVENT,227,129,63,14, WS_TABSTOP + EDITTEXT IDC_WINSCP,107,160,165,12, ES_AUTOHSCROLL | WS_TABSTOP + PUSHBUTTON "...",IDC_WINSCP_BROWSE,274,160,20,12, WS_TABSTOP + LTEXT "WinSCP path",IDC_STATIC,12,163,94,8 + EDITTEXT IDC_WINSCPLOG,107,178,165,12, ES_AUTOHSCROLL | WS_TABSTOP + PUSHBUTTON "...",IDC_WINSCPLOG_BROWSE,274,178,20,12, WS_TABSTOP + LTEXT "WinSCP log path",IDC_STATIC,12,181,94,8 +END + +IDD_OPT_GROUPLIST DIALOGEX 0, 0, 304, 225 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Settings",IDC_STATIC,4,5,298,220 + CONTROL "New messages on top",IDC_NEWONTOP, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,23,270,10 + CONTROL "Show event icons",IDC_SHOWEVENTS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,37,270,10 + CONTROL "Show timestamps",IDC_SHOWTIME, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,51,270,10 + CONTROL "Show names",IDC_SHOWNAME, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,65,270,10 + CONTROL "Show messages",IDC_SHOWMESSAGE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,79,270,10 + EDITTEXT IDC_MESSAGELEN,172,95,30,12,WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER + LTEXT "Truncate message length to:",IDC_MESSAGELEN_DESC,24,97,145,8 + EDITTEXT IDC_GROUPTIME,172,113,30,12,WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER + LTEXT "Delta time to group messages:",IDC_STATIC,12,115,157,8 + LTEXT "hours",IDC_STATIC,205,115,80,8 + EDITTEXT IDC_LIMITMESSAGES,172,131,30,12,WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER + LTEXT "Limit messages to:",IDC_STATIC,12,133,157,8 +END + +IDD_OPT_MESSAGES DIALOGEX 0, 0, 304, 225 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Settings",IDC_STATIC,4,5,298,220 + CONTROL "New messages on top",IDC_NEWONTOP, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,23,270,10 + CONTROL "Show date in timestamps",IDC_SHOWDATE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,37,270,10 + CONTROL "Show seconds in timestamps",IDC_SHOWSECOND, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,51,270,10 + CONTROL "Show names",IDC_SHOWNAME, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,65,270,10 + CONTROL "Show event icons",IDC_SHOWEVENTS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,79,270,10 + CONTROL "Enable Smileys",IDC_SHOWSMILEYS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,93,270,10 +END + +IDD_OPT_SEARCHING DIALOGEX 0, 0, 304, 225 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Settings",IDC_STATIC,4,5,298,220 + CONTROL "Search forward in list group",IDC_FORLIST, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,23,270,10 + CONTROL "Search forward in message window",IDC_FORMES, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,37,270,10 + CONTROL "Match Case",IDC_MATCHCASE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,51,270,10 + CONTROL "Match Whole Word",IDC_MATCHWHOLE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,65,270,10 + CONTROL "Only Incomming Messages",IDC_ONLYIN, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,79,270,10 + CONTROL "Only Outgoing Messages",IDC_ONLYOUT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,93,270,10 + CONTROL "Only Selected Group",IDC_ONLYGROUP, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,107,270,10 + CONTROL "All Contacts",IDC_ALLCONTACTS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,121,270,10 +END + +IDD_OPT_EXPORT DIALOGEX 0, 0, 304, 225 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Export To Txt",IDC_STATIC,4,5,298,37 + COMBOBOX IDC_TXTENC,142,20,152,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "File encoding*",IDC_STATIC,12,23,115,8 + GROUPBOX "Export To Plain Html",IDC_STATIC,4,47,298,50 + COMBOBOX IDC_HTML1ENC,142,62,152,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "File encoding*",IDC_STATIC,12,65,115,8 + CONTROL "Show date in timestamps",IDC_HTML1DATE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,80,270,10 + GROUPBOX "Export To Rich Html",IDC_STATIC,4,102,298,80 + COMBOBOX IDC_HTML2ENC,142,117,152,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "File encoding*",IDC_STATIC,12,120,115,8 + CONTROL "Show date in timestamps",IDC_HTML2DATE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,135,270,10 + CONTROL "Enable Smileys",IDC_HTML2SHOWSMILEYS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,149,270,10 + CONTROL "External CSS file",IDC_HTML2EXTCSS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,163,115,10 + EDITTEXT IDC_HTML2EXTCSSFILE,142,162,130,12, ES_AUTOHSCROLL | WS_TABSTOP + PUSHBUTTON "...",IDC_CSS_BROWSE,274,162,20,12, WS_TABSTOP + LTEXT "* Choose encoding from combo box or enter code page number and name separated by semicolon, name is used in Content-Type header.",IDC_STATIC,12,188,270,24 +END + +IDD_OPT_SCHEDULER DIALOGEX 0, 0, 304, 225 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Settings",IDC_STATIC,4,5,298,220 + LISTBOX IDC_LIST_TASKS,12,23,208,174, WS_TABSTOP | LBS_NOINTEGRALHEIGHT | WS_BORDER | WS_VSCROLL + PUSHBUTTON "Add task",IDC_ADD_TASK,231,23,63,14, WS_TABSTOP + PUSHBUTTON "Edit task",IDC_EDIT_TASK,231,39,63,14, WS_TABSTOP + PUSHBUTTON "Delete task",IDC_DELETE_TASK,231,55,63,14, WS_TABSTOP + CONTROL "Display errors using popups",IDC_SCHEDULER_ALERTS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,200,270,10 + CONTROL "Save errors to system history",IDC_SCHEDULER_HISTORY_ALERTS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,211,270,10 +END + +IDD_DLG_TASK DIALOGEX 0, 0, 359, 281 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Task" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_TASK_NAME,85,10,109,12,WS_TABSTOP|ES_AUTOHSCROLL + LTEXT "Name",IDC_STATIC,10,13,73,8 + CONTROL "Active",IDC_TASK_ACTIVE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,28,180,10 + COMBOBOX IDC_TASK_TYPE,85,40,109,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Action type",IDC_STATIC,10,43,73,8 + COMBOBOX IDC_TASK_FILTER,85,55,109,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Filter",IDC_TASK_FILTER_LABEL,10,58,73,8 + EDITTEXT IDC_EVENT_TIME,85,70,50,12,WS_TABSTOP | ES_AUTOHSCROLL + COMBOBOX IDC_EVENT_UNIT,140,70,54,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Events older than*",IDC_EVENT_LABEL,10,73,73,8 + COMBOBOX IDC_TRIGER_TYPE,85,85,109,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Triger type",IDC_STATIC,10,88,73,8 + CONTROL "", IDC_TRIGER_TIME, DATETIMEPICK_CLASS, WS_TABSTOP | DTS_TIMEFORMAT | DTS_UPDOWN, 85,99,109,15 + LTEXT "Time",IDC_TRIGER_TIME_LABEL,10,103,73,8 + EDITTEXT IDC_TRIGER_DELTA_TIME,85,100,109,12,WS_TABSTOP | ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Delta time",IDC_TRIGER_DELTA_TIME_LABEL,10,103,73,8 + COMBOBOX IDC_TRIGER_WEEK,85,115,109,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Day of week",IDC_TRIGER_WEEK_LABEL,10,118,73,8 + EDITTEXT IDC_TRIGER_DAY,85,115,109,12,WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER + LTEXT "Day",IDC_TRIGER_DAY_LABEL,10,118,73,8 + COMBOBOX IDC_EXPORT_TYPE,85,130,109,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_IMPORT_TYPE,85,130,109,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Export to",IDC_EXPORT_TYPE_LABEL,10,133,73,8 + CONTROL "Compress output files",IDC_COMPRESS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,148,180,10 + EDITTEXT IDC_PASSWORD,85,160,109,12, ES_AUTOHSCROLL | ES_PASSWORD | WS_TABSTOP + LTEXT "Password",IDC_PASSWORD_LABEL,10,163,73,8 + CONTROL "Upload to FTP (WinSCP requred)",IDC_UPLOAD, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,178,180,10 + EDITTEXT IDC_FTP,85,190,109,12,ES_AUTOHSCROLL | WS_TABSTOP + LTEXT "Session name",IDC_FTP_LABEL,10,193,73,8 + EDITTEXT IDC_EXPORT_PATH,85,205,109,12, ES_AUTOHSCROLL | WS_TABSTOP + LTEXT "Path to file**",IDC_EXPORT_PATH_LABEL,10,208,73,8 + CONTROL "Export imported messages",IDC_EXPIMP, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,223,180,10 + LTEXT "* Use negative values to filter younger events",IDC_TASK_STAR,10,236,184,40 + CONTROL "", IDC_LIST_CONTACTSEX, CLISTCONTROL_CLASS, WS_TABSTOP | CLS_GREYALTERNATE | CLS_GROUPCHECKBOXES | CLS_MULTICOLUMN | CLS_USEGROUPS | CLS_NOHIDEOFFLINE | CLS_CHECKBOXES, + 200,25,149,233,WS_EX_CLIENTEDGE + LTEXT "Execute task for specified contacts",IDC_STATIC,200,13,149,8 + DEFPUSHBUTTON "OK",IDOK,245,261,50,14 + PUSHBUTTON "Cancel",IDCANCEL,299,261,50,14 +END + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_INM ICON "Incom.ico" +IDI_OUTM ICON "Outg.ico" +IDI_SHOW ICON "plus.ico" +IDI_HIDE ICON "minus.ico" +IDI_FINDNEXT ICON "FindNext.ico" +IDI_FINDPREV ICON "FindPrev.ico" + +IDI_STATUS ICON "Status change.ico" + +IDR_CSS CUSTOMRES "history.css" +IDR_JS CUSTOMRES "history.js" +IDI_PLUSEX ICON "pnode.ico" +IDI_MINUSEX ICON "mnode.ico" + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + diff --git a/plugins/BasicHistory/res/FindNext.ico b/plugins/BasicHistory/res/FindNext.ico new file mode 100644 index 0000000000..dd1c62f113 Binary files /dev/null and b/plugins/BasicHistory/res/FindNext.ico differ diff --git a/plugins/BasicHistory/res/FindPrev.ico b/plugins/BasicHistory/res/FindPrev.ico new file mode 100644 index 0000000000..ba8c3ba5df Binary files /dev/null and b/plugins/BasicHistory/res/FindPrev.ico differ diff --git a/plugins/BasicHistory/res/Incom.ico b/plugins/BasicHistory/res/Incom.ico new file mode 100644 index 0000000000..9c618335c5 Binary files /dev/null and b/plugins/BasicHistory/res/Incom.ico differ diff --git a/plugins/BasicHistory/res/Outg.ico b/plugins/BasicHistory/res/Outg.ico new file mode 100644 index 0000000000..8bfeef6344 Binary files /dev/null and b/plugins/BasicHistory/res/Outg.ico differ diff --git a/plugins/BasicHistory/res/Status change.ico b/plugins/BasicHistory/res/Status change.ico new file mode 100644 index 0000000000..b9b270228a Binary files /dev/null and b/plugins/BasicHistory/res/Status change.ico differ diff --git a/plugins/BasicHistory/res/history.css b/plugins/BasicHistory/res/history.css new file mode 100644 index 0000000000..43a584597d --- /dev/null +++ b/plugins/BasicHistory/res/history.css @@ -0,0 +1,34 @@ +h3 { color: #666666; text-align: center; font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 16pt; } +h4 { text-align: center; font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14pt; } +h6 { font-weight: normal; color: #000000; text-align: center; font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 8pt; } +.mes { border-top-width: 1px; border-right-width: 1px; border-bottom-width: 0px;border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #666666; border-bottom-color: #666666; border-left-color: #666666; border-right-color: #666666; padding: 4px; color: #000000; font: normal normal normal 8pt normal Tahoma, Tahoma, Verdana, Arial, sans-serif; text-decoration: none; } +.text { clear: both; } +.nick { float: left; font: normal normal bold 8pt normal Tahoma, Tahoma, Verdana, Arial, sans-serif; text-decoration: none; } +.date { float: left; padding-left:5px; padding-right:5px; font: normal normal bold 8pt normal Tahoma, Tahoma, Verdana, Arial, sans-serif; text-decoration: none; } +.eventimg { float: left; } +.nick#inc { color: #C83F6B; } +.nick#out { color: #0860BD; } +.date#inc { color: #000000; } +.date#out { color: #000000; } +.url { color: #0000FF; } +.mes#event0 { background-color: #DBDBDB; } +.mes#event1 { background-color: #EEEEEE; } +.mes#event2 { background-color: #CCD9F4; } +.mes#session { background-color: #FFFDD7; } +.mes#bottom { border-right-width: 0px; border-left-width: 0px; } +.mes .eventimg {padding-left:16px; } +.mes#session .eventimg {padding-left:0px; } +.mes .text {padding-left:37px; display:table; } +.mes#session .text {padding-left:0px; clear: none; line-height: 16px; } +.mes#session .date {line-height: 16px; } +.group { display: none; margin: 0px; } +.sessionimage { vertical-align:middle; } +.smiley { vertical-align:middle; } +#menubar { position:absolute; left:10px; top:10px; visibility:hidden; border: 1px solid #000000; background-color:#dddddd; padding: 3px 3px 3px 3px; } +.mainmenu { text-decoration:none; color:#6666AA; background-color: transparent; } +.mainmenusel { text-decoration:none; color:#6666AA; background-color: #BBBBBB; } +.floatmenu { position: absolute; background-color: #dddddd; visibility: hidden; top: 36px; left: 10px; } +.floatmenu table { border: 1px solid #000000; } +.menuitem { text-decoration:none; color:#0860BD; } +.menuitemunsel { background-color: transparent; } +.menuitemsel { background-color: #BBBBBB; } \ No newline at end of file diff --git a/plugins/BasicHistory/res/history.js b/plugins/BasicHistory/res/history.js new file mode 100644 index 0000000000..4d2156ac24 --- /dev/null +++ b/plugins/BasicHistory/res/history.js @@ -0,0 +1,95 @@ + +function toggleFolder(id, imageNode) +{ + var folder = document.getElementById(id); + if (imageNode.previousSibling != null) + { + imageNode = imageNode.previousSibling; + } + var l = imageNode.src.length; + if (folder == null) + { + } + else if (folder.style.display == "block") + { + if (imageNode != null) + { + if (imageNode.src.substring(l-9,l) == "mnode.ico") + { + imageNode.src = imageNode.src.substring(0, l-9) + "pnode.ico"; + } + } + folder.style.display = "none"; + } + else + { + if (imageNode != null) + { + if (imageNode.src.substring(l-9,l) == "pnode.ico") + { + imageNode.src = imageNode.src.substring(0, l-9) + "mnode.ico"; + } + } + folder.style.display = "block"; + } +} + +var timer; + +function ShowMenu(isShow) +{ + if(timer) + clearTimeout(timer); + + var menu = document.getElementById("L1"); + if(isShow == 1) + menu.style.visibility = "visible"; + else + menu.style.visibility = "hidden"; +} + +function HideMenu() +{ + timer = setTimeout("ShowMenu(0)", 500); +} + +function OpenAll(isOpen) +{ + var idMod = 0; + while(gr = document.getElementById("group" + idMod)) + { + var imageNode = gr.previousSibling; + if(imageNode.tagName == null) + imageNode = imageNode.previousSibling; + imageNode = imageNode.getElementsByTagName("span")[0].getElementsByTagName("img")[0]; + var l = imageNode.src.length; + if(gr.style.display == "block") + { + if(!isOpen) + { + if (imageNode != null) + { + if (imageNode.src.substring(l-9,l) == "mnode.ico") + { + imageNode.src = imageNode.src.substring(0, l-9) + "pnode.ico"; + } + } + gr.style.display = "none"; + } + } + else if(isOpen) + { + if (imageNode != null) + { + if (imageNode.src.substring(l-9,l) == "pnode.ico") + { + imageNode.src = imageNode.src.substring(0, l-9) + "mnode.ico"; + } + } + gr.style.display = "block"; + } + ++idMod; + } + + ShowMenu(0); +} diff --git a/plugins/BasicHistory/res/minus.ico b/plugins/BasicHistory/res/minus.ico new file mode 100644 index 0000000000..39d1f72f79 Binary files /dev/null and b/plugins/BasicHistory/res/minus.ico differ diff --git a/plugins/BasicHistory/res/mnode.ico b/plugins/BasicHistory/res/mnode.ico new file mode 100644 index 0000000000..d332fbda16 Binary files /dev/null and b/plugins/BasicHistory/res/mnode.ico differ diff --git a/plugins/BasicHistory/res/plus.ico b/plugins/BasicHistory/res/plus.ico new file mode 100644 index 0000000000..1230b5de32 Binary files /dev/null and b/plugins/BasicHistory/res/plus.ico differ diff --git a/plugins/BasicHistory/res/pnode.ico b/plugins/BasicHistory/res/pnode.ico new file mode 100644 index 0000000000..811dfd0f84 Binary files /dev/null and b/plugins/BasicHistory/res/pnode.ico differ diff --git a/plugins/BasicHistory/res/version.rc b/plugins/BasicHistory/res/version.rc new file mode 100644 index 0000000000..76cbd98061 --- /dev/null +++ b/plugins/BasicHistory/res/version.rc @@ -0,0 +1,37 @@ + +#include +#include "..\src\version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION __FILEVERSION_STRING + PRODUCTVERSION __FILEVERSION_STRING + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Author", "Krzysztof Kral" + VALUE "CompanyName", "Krzysztof Kral" + VALUE "FileDescription", __DESCRIPTION + VALUE "FileVersion", __VERSION_STRING + VALUE "InternalName", __INTERNAL_NAME + VALUE "LegalCopyright", __COPYRIGHT + VALUE "OriginalFilename", __FILENAME + VALUE "ProductName", __PLUGIN_NAME + VALUE "ProductVersion", __VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/plugins/BasicHistory/resource.h b/plugins/BasicHistory/resource.h deleted file mode 100644 index 71484f2343..0000000000 --- a/plugins/BasicHistory/resource.h +++ /dev/null @@ -1,157 +0,0 @@ - -#define IDD_HISTORY 101 -#define IDD_OPT_MAIN 102 -#define IDD_OPT_GROUPLIST 103 -#define IDD_OPT_MESSAGES 104 -#define IDD_OPT_SEARCHING 105 -#define IDD_OPT_EXPORT 106 -#define IDD_OPT_SCHEDULER 107 -#define IDD_DLG_TASK 108 -#define IDC_EDIT 1001 -#define IDC_LIST 1002 -#define IDC_DELETEHISTORY 1004 -#define IDC_SPLITTER 1005 -#define IDC_FIND_TEXT 1006 -#define IDC_LIST_CONTACTS 1007 -#define IDC_SPLITTERV 1008 -#define IDC_SHOWHIDE 1009 -#define IDC_TOOLBAR 1010 -#define IDC_SHOWCONTACTS 1011 -#define IDC_NEWONTOP 1012 -#define IDC_SHOWEVENTS 1013 -#define IDC_SHOWTIME 1014 -#define IDC_SHOWNAME 1015 -#define IDC_SHOWMESSAGE 1016 -#define IDC_MESSAGELEN 1017 -#define IDC_MESSAGELEN_DESC 1018 -#define IDC_GROUPTIME 1019 -#define IDC_LIMITMESSAGES 1020 -#define IDC_SHOWDATE 1021 -#define IDC_SHOWSECOND 1022 -#define IDC_SHOWSMILEYS 1023 -#define IDC_FORLIST 1024 -#define IDC_FORMES 1025 -#define IDC_MATCHCASE 1026 -#define IDC_MATCHWHOLE 1027 -#define IDC_ONLYIN 1028 -#define IDC_ONLYOUT 1029 -#define IDC_ONLYGROUP 1030 -#define IDC_DEFFILTER 1031 -#define IDC_LIST_FILTERS 1032 -#define IDC_LIST_EVENTS 1033 -#define IDC_ADD_FILTER 1034 -#define IDC_DELETE_FILTER 1035 -#define IDC_FILTER_NAME 1036 -#define IDC_EVENT 1037 -#define IDC_ADD_EVENT 1038 -#define IDC_DELETE_EVENT 1039 -#define IDC_SHOWCONTACTGROUPS 1040 -#define IDC_TXTENC 1041 -#define IDC_HTML1ENC 1042 -#define IDC_HTML1DATE 1043 -#define IDC_HTML2ENC 1044 -#define IDC_HTML2DATE 1045 -#define IDC_HTML2SHOWSMILEYS 1046 -#define IDC_HTML2EXTCSS 1047 -#define IDC_HTML2EXTCSSFILE 1048 -#define IDC_LIST_TASKS 1049 -#define IDC_ADD_TASK 1050 -#define IDC_EDIT_TASK 1051 -#define IDC_DELETE_TASK 1052 -#define IDC_TASK_TYPE 1053 -#define IDC_TASK_FILTER 1054 -#define IDC_LIST_CONTACTSEX 1055 -#define IDC_EVENT_TIME 1056 -#define IDC_EVENT_UNIT 1057 -#define IDC_TRIGER_TYPE 1058 -#define IDC_EXPORT_TYPE 1059 -#define IDC_EXPORT_TYPE_LABEL 1060 -#define IDC_COMPRESS 1061 -#define IDC_EXPORT_PATH 1062 -#define IDC_EXPORT_PATH_LABEL 1063 -#define IDC_TASK_STAR 1064 -#define IDC_FTP 1065 -#define IDC_UPLOAD 1066 -#define IDC_FTP_LABEL 1067 -#define IDC_TRIGER_TIME 1068 -#define IDC_TRIGER_TIME_LABEL 1069 -#define IDC_TRIGER_WEEK 1070 -#define IDC_TRIGER_WEEK_LABEL 1071 -#define IDC_TRIGER_DAY 1072 -#define IDC_TRIGER_DAY_LABEL 1073 -#define IDC_TRIGER_DELTA_TIME 1074 -#define IDC_TRIGER_DELTA_TIME_LABEL 1075 -#define IDC_WINSCP 1076 -#define IDC_WINSCPLOG 1077 -#define IDC_TASK_NAME 1078 -#define IDC_TASK_ACTIVE 1079 -#define IDC_TASK_FILTER_LABEL 1080 -#define IDC_EVENT_LABEL 1081 -#define IDC_IMPORT_TYPE 1082 -#define IDC_PASSWORD 1083 -#define IDC_PASSWORD_LABEL 1084 -#define IDC_EXPIMP 1085 -#define IDC_WINSCP_BROWSE 1086 -#define IDC_WINSCPLOG_BROWSE 1087 -#define IDC_CSS_BROWSE 1088 -#define IDC_SCHEDULER_ALERTS 1089 -#define IDC_SCHEDULER_HISTORY_ALERTS 1090 -#define IDC_ALLCONTACTS 1091 -#define IDI_INM 20000 -#define IDI_OUTM 20001 -#define IDI_SHOW 20002 -#define IDI_HIDE 20003 -#define IDI_FINDNEXT 20004 -#define IDI_FINDPREV 20005 -#define IDI_STATUS 20008 -#define IDR_CSS 20009 -#define IDR_JS 20010 -#define IDI_PLUSEX 20011 -#define IDI_MINUSEX 20012 -#define IDM_FIND 40001 -#define IDM_CONFIG 40002 -#define IDM_FINDNEXT 40003 -#define IDM_FINDPREV 40004 -#define IDM_MATCHCASE 40005 -#define IDM_MATCHWHOLE 40006 -#define IDM_OPTIONS 40007 -#define IDM_FONTS 40008 -#define IDM_ICONS 40009 -#define IDM_HOTKEYS 40010 -#define IDM_SAVEPOS 40011 -#define IDM_SAVEPOSALL 40012 -#define IDM_ONLYIN 40013 -#define IDM_ONLYOUT 40014 -#define IDM_DELETE 40015 -#define IDM_DELETEGROUP 40016 -#define IDM_DELETEUSER 40017 -#define IDM_MESSAGE 40018 -#define IDM_COPY 40019 -#define IDM_OPENNEW 40020 -#define IDM_OPENEXISTING 40021 -#define IDM_COPYLINK 40022 -#define IDM_ONLYGROUP 40023 -#define IDM_QUOTE 40024 -#define IDM_FILTERDEF 40025 -#define IDM_FILTERALL 40026 -#define IDM_EXPORTRHTML 40027 -#define IDM_EXPORTPHTML 40028 -#define IDM_EXPORTTXT 40029 -#define IDM_EXPORTBINARY 40030 -#define IDM_IMPORTBINARY 40031 -#define IDM_EXPORTDAT 40032 -#define IDM_IMPORTDAT 40033 -#define IDM_ALLUSERS 40034 - -#define CUSTOMRES 300 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 106 -#define _APS_NEXT_COMMAND_VALUE 40024 -#define _APS_NEXT_CONTROL_VALUE 1030 -#define _APS_NEXT_SYMED_VALUE 106 -#endif -#endif diff --git a/plugins/BasicHistory/src/BasicHistory.cpp b/plugins/BasicHistory/src/BasicHistory.cpp new file mode 100644 index 0000000000..e28278e68b --- /dev/null +++ b/plugins/BasicHistory/src/BasicHistory.cpp @@ -0,0 +1,425 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "stdafx.h" +#include "version.h" +#include "HistoryWindow.h" +#include "resource.h" +#include "Options.h" + +// {E25367A2-51AE-4044-BE28-131BC18B71A4} +#define MIID_BASICHISTORY { 0xe25367a2, 0x51ae, 0x4044, { 0xbe, 0x28, 0x13, 0x1b, 0xc1, 0x8b, 0x71, 0xa4 } } + +#define MS_HISTORY_DELETEALLCONTACTHISTORY "BasicHistory/DeleteAllContactHistory" +#define MS_HISTORY_EXECUTE_TASK "BasicHistory/ExecuteTask" + +HCURSOR hCurSplitNS, hCurSplitWE; +HANDLE g_hMainThread=NULL; + +extern HINSTANCE hInst; + +HANDLE hModulesLoaded, hOptionsInit, hPrebuildContactMenu, hServiceShowContactHistory, hServiceDeleteAllContactHistory, hServiceExecuteTask, hPreShutdownHistoryModule, hHistoryContactDelete, hFontsChanged,hToolBarLoaded, hSysOK; +HANDLE *hEventIcons = NULL; +int iconsNum; +HANDLE hPlusIcon, hMinusIcon, hFindNextIcon, hFindPrevIcon; +HANDLE hPlusExIcon, hMinusExIcon; +HANDLE hToolbarButton; +HGENMENU hContactMenu, hDeleteContactMenu; +HGENMENU hTaskMainMenu; +std::vector taskMenus; +bool g_SmileyAddAvail = false; +char* metaContactProto = NULL; +const IID IID_ITextDocument={0x8CC497C0, 0xA1DF, 0x11ce, {0x80, 0x98, 0x00, 0xAA, 0x00, 0x47, 0xBE, 0x5D}}; + +#define MODULE "BasicHistory" + +PLUGININFOEX pluginInfo = +{ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESCRIPTION, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE, + MIID_BASICHISTORY +}; + +TIME_API tmi = {0}; +int hLangpack = 0; + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +static const MUUID interfaces[] = {MIID_UIHISTORY, MIID_LAST}; +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +void InitScheduler(); +void DeinitScheduler(); +int DoLastTask(WPARAM, LPARAM); +INT_PTR ExecuteTaskService(WPARAM wParam, LPARAM lParam); + +int PrebuildContactMenu(WPARAM wParam, LPARAM lParam) +{ + int count = EventList::GetContactMessageNumber((HANDLE)wParam); + bool isInList = HistoryWindow::IsInList(GetForegroundWindow()); + CLISTMENUITEM mi = {0}; + mi.cbSize = sizeof(mi); + mi.flags = CMIM_FLAGS; + + if (!count) mi.flags |= CMIF_HIDDEN; + else mi.flags &= ~CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hContactMenu, (LPARAM)&mi); + + mi.flags = CMIM_FLAGS; + if (!count || !isInList) mi.flags |= CMIF_HIDDEN; + else mi.flags &= ~CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hDeleteContactMenu, (LPARAM)&mi); + + return 0; +} + +int ToolbarModuleLoaded(WPARAM wParam,LPARAM lParam) +{ + if(ServiceExists(MS_TB_ADDBUTTON)) + { + TBButton tbb = {0}; + tbb.cbSize = sizeof(tbb); + tbb.pszButtonID = "open_history"; + tbb.pszButtonName = LPGEN("Open History"); + tbb.pszServiceName = MS_HISTORY_SHOWCONTACTHISTORY; + tbb.lParam = 0; + tbb.pszTooltipUp = LPGEN("Open History"); + tbb.pszTooltipDn = LPGEN("Open History"); + tbb.defPos = 200; + tbb.tbbFlags = TBBF_SHOWTOOLTIP; + tbb.hPrimaryIconHandle = LoadSkinnedIconHandle(SKINICON_OTHER_HISTORY); + tbb.hSecondaryIconHandle = LoadSkinnedIconHandle(SKINICON_OTHER_HISTORY); + hToolbarButton = (HANDLE) CallService(MS_TB_ADDBUTTON,0, (LPARAM)&tbb); + } + return 0; +} + +void InitMenuItems() +{ + CLISTMENUITEM mi = { 0 }; + mi.cbSize = sizeof(mi); + mi.position = 1000090000; + mi.flags = CMIF_ICONFROMICOLIB; + mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_HISTORY); + mi.pszName = LPGEN("View &History"); + mi.pszService = MS_HISTORY_SHOWCONTACTHISTORY; + hContactMenu = Menu_AddContactMenuItem(&mi); + + mi.position = 500060000; + mi.pszService = MS_HISTORY_SHOWCONTACTHISTORY; + Menu_AddMainMenuItem(&mi); + + mi.position = 1000090001; + mi.flags = CMIF_ICONFROMICOLIB; + mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_DELETE); + mi.pszName = LPGEN("Delete All User History"); + mi.pszService = MS_HISTORY_DELETEALLCONTACTHISTORY; + hDeleteContactMenu = Menu_AddContactMenuItem(&mi); + + hPrebuildContactMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu); +} + +void InitTaskMenuItems() +{ + if(Options::instance->taskOptions.size() > 0) + { + CLISTMENUITEM mi = { 0 }; + mi.cbSize = sizeof(mi); + if(hTaskMainMenu == NULL) + { + mi.position = 500060005; + mi.flags = CMIF_ROOTPOPUP | CMIF_ICONFROMICOLIB; + mi.icolibItem = LoadSkinnedIconHandle(SKINICON_OTHER_HISTORY); + mi.pszName = LPGEN("Execute history task"); + hTaskMainMenu = Menu_AddMainMenuItem(&mi); + } + + std::vector::iterator taskIt = Options::instance->taskOptions.begin(); + std::vector::iterator it = taskMenus.begin(); + for(; it != taskMenus.end() && taskIt != Options::instance->taskOptions.end(); ++it, ++taskIt) + { + memset(&mi, 0, sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.flags = CMIM_FLAGS | CMIM_NAME | CMIF_CHILDPOPUP | CMIF_ROOTHANDLE | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED; + mi.hParentMenu = hTaskMainMenu; + mi.ptszName = (TCHAR*)taskIt->taskName.c_str(); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HGENMENU)*it, (LPARAM)&mi); + } + + for(; it != taskMenus.end(); ++it) + { + memset(&mi, 0, sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.flags = CMIM_FLAGS | CMIF_CHILDPOPUP | CMIF_ROOTHANDLE | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED | CMIF_HIDDEN; + mi.hParentMenu = hTaskMainMenu; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HGENMENU)*it, (LPARAM)&mi); + } + + int pos = (int)taskMenus.size(); + for(; taskIt != Options::instance->taskOptions.end(); ++taskIt) + { + memset(&mi, 0, sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.flags = CMIF_CHILDPOPUP | CMIF_ROOTHANDLE | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED; + mi.pszService = MS_HISTORY_EXECUTE_TASK; + mi.hParentMenu = hTaskMainMenu; + mi.popupPosition = pos++; + mi.ptszName = (TCHAR*)taskIt->taskName.c_str(); + HGENMENU menu = Menu_AddMainMenuItem(&mi); + taskMenus.push_back(menu); + } + } + else if(hTaskMainMenu != NULL) + { + CLISTMENUITEM mi = { 0 }; + mi.cbSize = sizeof(mi); + mi.flags = CMIM_FLAGS | CMIF_ROOTPOPUP | CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hTaskMainMenu, (LPARAM)&mi); + } +} + +void InitIcolib() +{ + TCHAR stzFile[MAX_PATH]; + + SKINICONDESC sid = {0}; + sid.cbSize = sizeof(sid); + sid.cx = sid.cy = 16; + sid.ptszDefaultFile = stzFile; + sid.ptszSection = LPGENT("History"); + sid.flags = SIDF_ALL_TCHAR; + + GetModuleFileName(hInst, stzFile, MAX_PATH); + + iconsNum = 3; + hEventIcons = new HANDLE[iconsNum]; + sid.pszName = "BasicHistory_in"; + sid.ptszDescription = LPGENT("Incoming message"); + sid.iDefaultIndex = -IDI_INM; + hEventIcons[0] = Skin_AddIcon(&sid); + + sid.pszName = "BasicHistory_out"; + sid.ptszDescription = LPGENT("Outgoing message"); + sid.iDefaultIndex = -IDI_OUTM; + hEventIcons[1] = Skin_AddIcon(&sid); + + sid.pszName = "BasicHistory_status"; + sid.ptszDescription = LPGENT("Statuschange"); + sid.iDefaultIndex = -IDI_STATUS; + hEventIcons[2] = Skin_AddIcon(&sid); + + sid.pszName = "BasicHistory_show"; + sid.ptszDescription = LPGENT("Show Contacts"); + sid.iDefaultIndex = -IDI_SHOW; + hPlusIcon = Skin_AddIcon(&sid); + + sid.pszName = "BasicHistory_hide"; + sid.ptszDescription = LPGENT("Hide Contacts"); + sid.iDefaultIndex = -IDI_HIDE; + hMinusIcon = Skin_AddIcon(&sid); + + sid.pszName = "BasicHistory_findnext"; + sid.ptszDescription = LPGENT("Find Next"); + sid.iDefaultIndex = -IDI_FINDNEXT; + hFindNextIcon = Skin_AddIcon(&sid); + + sid.pszName = "BasicHistory_findprev"; + sid.ptszDescription = LPGENT("Find Previous"); + sid.iDefaultIndex = -IDI_FINDPREV; + hFindPrevIcon = Skin_AddIcon(&sid); + + sid.pszName = "BasicHistory_plusex"; + sid.ptszDescription = LPGENT("Plus in export"); + sid.iDefaultIndex = -IDI_PLUSEX; + hPlusExIcon = Skin_AddIcon(&sid); + + sid.pszName = "BasicHistory_minusex"; + sid.ptszDescription = LPGENT("Minus in export"); + sid.iDefaultIndex = -IDI_MINUSEX; + hMinusExIcon = Skin_AddIcon(&sid); +} + +void InitUpdater() +{ + if (ServiceExists(MS_UPDATE_REGISTER)) + { + Update update = {0}; + char szVersion[16]; + update.cbSize = sizeof(Update); + update.szComponentName = pluginInfo.shortName; + update.pbVersion = (BYTE *)CreateVersionStringPluginEx(&pluginInfo, szVersion); + update.cpbVersion = (int)strlen((char *)update.pbVersion); + +#ifdef _WIN64 + update.szUpdateURL = "http://programista.free.of.pl/miranda/BasicHistory64.zip"; + update.szVersionURL = "http://programista.free.of.pl/miranda/pluginversion.php?plugin=basichistory&x64=yes"; + update.szBetaUpdateURL = "http://programista.free.of.pl/miranda/BasicHistoryBeta64.zip"; + update.szBetaVersionURL = "http://programista.free.of.pl/miranda/pluginversion.php?plugin=basichistory&beta=yes&x64=yes"; + update.szBetaChangelogURL = "http://programista.free.of.pl/miranda/BasicHistoryChangelog.txt"; +#else + update.szUpdateURL = "http://programista.free.of.pl/miranda/BasicHistory.zip"; + update.szVersionURL = "http://programista.free.of.pl/miranda/pluginversion.php?plugin=basichistory"; + update.szBetaUpdateURL = "http://programista.free.of.pl/miranda/BasicHistoryBeta.zip"; + update.szBetaVersionURL = "http://programista.free.of.pl/miranda/pluginversion.php?plugin=basichistory&beta=yes"; + update.szBetaChangelogURL = "http://programista.free.of.pl/miranda/BasicHistoryChangelog.txt"; + +#endif + update.pbBetaVersionPrefix = update.pbVersionPrefix = (BYTE *)"Basic History "; + update.cpbBetaVersionPrefix = update.cpbVersionPrefix = (int)strlen((char *)update.pbVersionPrefix); + CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); + } +} + +INT_PTR ShowContactHistory(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + HistoryWindow::Open(hContact); + return 0; +} + +int PreShutdownHistoryModule(WPARAM, LPARAM) +{ + HistoryWindow::Deinit(); + DeinitScheduler(); + return 0; +} + +int HistoryContactDelete(WPARAM wParam, LPARAM) +{ + HistoryWindow::Close((HANDLE)wParam); + return 0; +} + +int ModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + InitMenuItems(); + InitUpdater(); + + TCHAR ftpExe[MAX_PATH]; + if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, ftpExe))) + { + _tcscat_s(ftpExe, _T("\\WinSCP\\WinSCP.exe")); + DWORD atr = GetFileAttributes(ftpExe); + if(atr == INVALID_FILE_ATTRIBUTES || atr & FILE_ATTRIBUTE_DIRECTORY) + { +#ifdef _WIN64 + if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILESX86, NULL, SHGFP_TYPE_CURRENT, ftpExe))) + { + _tcscat_s(ftpExe, _T("\\WinSCP\\WinSCP.exe")); + atr = GetFileAttributes(ftpExe); + if(!(atr == INVALID_FILE_ATTRIBUTES || atr & FILE_ATTRIBUTE_DIRECTORY)) + { + Options::instance->ftpExePathDef = ftpExe; + } + } +#endif + } + else + Options::instance->ftpExePathDef = ftpExe; + } + + TCHAR* log = _T("%miranda_logpath%\\BasicHistory\\ftplog.txt"); + TCHAR* logAbsolute = Utils_ReplaceVarsT(log); + Options::instance->ftpLogPath = logAbsolute; + mir_free(logAbsolute); + Options::instance->Load(); + InitTaskMenuItems(); + + hPreShutdownHistoryModule = HookEvent(ME_SYSTEM_PRESHUTDOWN,PreShutdownHistoryModule); + hHistoryContactDelete = HookEvent(ME_DB_CONTACT_DELETED,HistoryContactDelete); + hFontsChanged = HookEvent(ME_FONT_RELOAD, HistoryWindow::FontsChanged); + hSysOK = HookEvent(ME_SYSTEM_OKTOEXIT, DoLastTask); + if (ServiceExists(MS_SMILEYADD_REPLACESMILEYS)) + { + g_SmileyAddAvail = true; + } + if (ServiceExists(MS_MC_GETPROTOCOLNAME)) + { + metaContactProto = (char*)CallService(MS_MC_GETPROTOCOLNAME, 0, 0); + } + + InitScheduler(); + return 0; +} + +extern "C" int __declspec(dllexport) Load(void) +{ + hTaskMainMenu = NULL; + DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),GetCurrentProcess(),&g_hMainThread,0,FALSE,DUPLICATE_SAME_ACCESS); + mir_getTMI(&tmi); + mir_getLP(&pluginInfo); + hCurSplitNS = LoadCursor(NULL, IDC_SIZENS); + hCurSplitWE = LoadCursor(NULL, IDC_SIZEWE); + hServiceShowContactHistory = CreateServiceFunction(MS_HISTORY_SHOWCONTACTHISTORY, ShowContactHistory); + hServiceDeleteAllContactHistory = CreateServiceFunction(MS_HISTORY_DELETEALLCONTACTHISTORY, HistoryWindow::DeleteAllUserHistory); + hServiceExecuteTask = CreateServiceFunction(MS_HISTORY_EXECUTE_TASK, ExecuteTaskService); + Options::instance = new Options(); + hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); + hOptionsInit = HookEvent(ME_OPT_INITIALISE, Options::InitOptions); + hToolBarLoaded = HookEvent(ME_TB_MODULELOADED,ToolbarModuleLoaded); + EventList::Init(); + InitIcolib(); + return 0; +} + +extern "C" int __declspec(dllexport) Unload(void) +{ + if(g_hMainThread) CloseHandle(g_hMainThread); + g_hMainThread=NULL; + UnhookEvent(hModulesLoaded); + UnhookEvent(hPrebuildContactMenu); + UnhookEvent(hPreShutdownHistoryModule); + UnhookEvent(hHistoryContactDelete); + UnhookEvent(hOptionsInit); + UnhookEvent(hFontsChanged); + UnhookEvent(hToolBarLoaded); + UnhookEvent(hSysOK); + DestroyServiceFunction(hServiceShowContactHistory); + DestroyServiceFunction(hServiceDeleteAllContactHistory); + DestroyServiceFunction(hServiceExecuteTask); + HistoryWindow::Deinit(); + DestroyCursor(hCurSplitNS); + DestroyCursor(hCurSplitWE); + EventList::Deinit(); + if(Options::instance != NULL) + { + Options::instance->Unload(); + delete Options::instance; + Options::instance = NULL; + } + + if(hEventIcons != NULL) + { + delete [] hEventIcons; + } + + return 0; +} diff --git a/plugins/BasicHistory/src/BinaryExport.cpp b/plugins/BasicHistory/src/BinaryExport.cpp new file mode 100644 index 0000000000..f57343cff0 --- /dev/null +++ b/plugins/BasicHistory/src/BinaryExport.cpp @@ -0,0 +1,231 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "StdAfx.h" +#include "BinaryExport.h" + +#define EXP_FILE (*((std::ofstream*)IExport::stream)) +#define IMP_FILE (*((std::ifstream*)IImport::stream)) + +std::wstring GetProtocolName(HANDLE hContact); +std::wstring GetContactId(HANDLE hContact); + +#pragma pack(push, 1) + +struct BinaryFileHeader +{ + unsigned char signature[4]; + unsigned char version; + unsigned char extraFlags; + unsigned short int reserved; + unsigned int codepage; + unsigned short int dataStart; +}; + +struct BinaryFileMessageHeader +{ + DWORD timestamp; + WORD eventType; + WORD flags; +}; + +#pragma pack(pop) + +BinaryExport::~BinaryExport() +{ +} + +void BinaryExport::WriteString(const std::wstring &str) +{ + int conv = WideCharToMultiByte(codepage, 0, str.c_str(), (int)str.length() + 1, NULL, 0, NULL, NULL); + char* buf = new char[conv]; + conv = WideCharToMultiByte(codepage, 0, str.c_str(), (int)str.length() + 1, buf, conv, NULL, NULL); + EXP_FILE.write(buf, conv); + delete[] buf; +} + +bool BinaryExport::ReadString(std::wstring &str) +{ + std::string buf; + int size = 1024; + int pos = 0; + int totalSize = 0; + while(1) + { + buf.resize(size); + if(IMP_FILE.peek() == 0) + { + IMP_FILE.get(); + break; + } + + IMP_FILE.get(((char*)buf.c_str()) + pos, size - pos, 0); + if(!IMP_FILE.good()) + return false; + + int readed = IMP_FILE.gcount(); + totalSize += readed; + char end; + IMP_FILE.get(end); + if(!IMP_FILE.good()) + return false; + if(end == 0) + break; + if(size - pos - 1 != readed) + return false; + buf[size - 1] = end; + ++totalSize; + size += 1024; + pos += 1024; + } + + if(totalSize == 0) + return true; + int sizeW = MultiByteToWideChar(codepage, 0, (char*)buf.c_str(), totalSize, NULL, 0); + str.resize(sizeW); + MultiByteToWideChar(codepage, 0, (char*)buf.c_str(), totalSize, (wchar_t*)str.c_str(), sizeW); + return true; +} + +void BinaryExport::WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding) +{ + BinaryFileHeader header; + memset(&header, 0, sizeof(BinaryFileHeader)); + memcpy(header.signature, "BHBF", 4); + header.codepage = codepage = CP_UTF8; + EXP_FILE.write((char*)&header, sizeof(BinaryFileHeader)); + WriteString(filterName); + WriteString(myName); + WriteString(myId); + WriteString(name1); + WriteString(proto1); + WriteString(id1); + size_t pos = EXP_FILE.tellp(); + header.dataStart = (unsigned short)pos; + EXP_FILE.seekp(offsetof(BinaryFileHeader, dataStart), std::ios_base::beg); + EXP_FILE.write((char*)&(header.dataStart), sizeof(header.dataStart)); + EXP_FILE.seekp(pos, std::ios_base::beg); + lTime = 0; +} + +void BinaryExport::WriteFooter() +{ +} + +void BinaryExport::WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText) +{ +} + +void BinaryExport::WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei) +{ + if(dbei.timestamp >= lTime) + { + BinaryFileMessageHeader header; + header.eventType = dbei.eventType; + header.flags = dbei.flags & (~(0x800)); + header.timestamp = dbei.timestamp; + EXP_FILE.write((char*)&header, sizeof(BinaryFileMessageHeader)); + WriteString(message); + lTime = dbei.timestamp; + } +} + +bool ReadHeader(BinaryFileHeader& header, std::istream* stream) +{ + stream->read((char*)&header, sizeof(BinaryFileHeader)); + if(!stream->good()) + return false; + if(memcmp(header.signature, "BHBF", 4) != 0) + return false; + if(header.version != 0 || header.codepage == 12000 || header.codepage == 12001) + return false; + + return true; +} + +int BinaryExport::IsContactInFile(const std::vector& contacts) +{ + BinaryFileHeader header; + if(!ReadHeader(header, IImport::stream)) + return -2; + codepage = header.codepage; + std::wstring filterName; + std::wstring myName; + std::wstring myId; + std::wstring name1; + std::wstring proto1; + std::wstring id1; + if(!ReadString(filterName)) + return -2; + if(!ReadString(myName)) + return -2; + if(!ReadString(myId)) + return -2; + if(!ReadString(name1)) + return -2; + if(!ReadString(proto1)) + return -2; + if(!ReadString(id1)) + return -2; + + size_t pos = IMP_FILE.tellg(); + if(header.dataStart < pos) + return -2; + + IMP_FILE.seekg(0, std::ios_base::beg); + for(int i = 0; i < (int)contacts.size(); ++i) + { + std::wstring pn = GetProtocolName(contacts[i]); + std::wstring id = GetContactId(contacts[i]); + if(pn == proto1 && id == id1) + { + return i; + } + } + + return -1; +} + +bool BinaryExport::GetEventList(std::vector& eventList) +{ + BinaryFileHeader header; + if(!ReadHeader(header, IImport::stream)) + return false; + codepage = header.codepage; + IMP_FILE.seekg(header.dataStart, std::ios_base::beg); + BinaryFileMessageHeader messageHeader; + while(1) + { + IMP_FILE.read((char*)&messageHeader, sizeof(BinaryFileMessageHeader)); + if(IMP_FILE.eof()) + break; + if(!IMP_FILE.good()) + return false; + + IImport::ExternalMessage exMsg; + exMsg.eventType = messageHeader.eventType; + exMsg.flags = messageHeader.flags; + exMsg.timestamp = messageHeader.timestamp; + if(!ReadString(exMsg.message)) + return false; + + eventList.push_back(exMsg); + } + + return true; +} diff --git a/plugins/BasicHistory/src/BinaryExport.h b/plugins/BasicHistory/src/BinaryExport.h new file mode 100644 index 0000000000..386625226f --- /dev/null +++ b/plugins/BasicHistory/src/BinaryExport.h @@ -0,0 +1,47 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once +#include "IExport.h" +#include "IImport.h" + +class BinaryExport : + public IExport, + public IImport +{ +public: + virtual const TCHAR* GetExt() + { + return _T("bin"); + } + + virtual void WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding); + virtual void WriteFooter(); + virtual void WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText); + virtual void WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei); + virtual int IsContactInFile(const std::vector& contacts); + virtual bool GetEventList(std::vector& eventList); + + virtual ~BinaryExport(); +private: + unsigned int codepage; + inline void WriteString(const std::wstring &str); + inline bool ReadString(std::wstring &str); + DWORD lTime; +}; + diff --git a/plugins/BasicHistory/src/DatExport.cpp b/plugins/BasicHistory/src/DatExport.cpp new file mode 100644 index 0000000000..bd74546393 --- /dev/null +++ b/plugins/BasicHistory/src/DatExport.cpp @@ -0,0 +1,214 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "StdAfx.h" +#include "DatExport.h" +#include "EventList.h" + +#define EXP_FILE (*((std::ofstream*)IExport::stream)) +#define IMP_FILE (*((std::ifstream*)IImport::stream)) + +std::wstring GetProtocolName(HANDLE hContact); +std::wstring GetContactId(HANDLE hContact); + +#pragma pack(push, 1) + +struct MCHeader +{ + unsigned char signature[2]; + unsigned int version; + unsigned int dataSize; +}; + +#pragma pack(pop) + +typedef struct { + int cbSize; //size of the structure in bytes + DWORD szModule; //pointer to name of the module that 'owns' this + //event, ie the one that is in control of the data format + DWORD timestamp; //seconds since 00:00, 01/01/1970. Gives us times until + //2106 unless you use the standard C library which is + //signed and can only do until 2038. In GMT. + DWORD flags; //the omnipresent flags + WORD eventType; //module-defined event type field + DWORD cbBlob; //size of pBlob in bytes + DWORD pBlob; //pointer to buffer containing module-defined event data +} DBEVENTINFO86; + + +DatExport::~DatExport() +{ +} + + +int DatExport::WriteString(const std::wstring &str) +{ + int conv = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.length() + 1, NULL, 0, NULL, NULL); + if(conv > (int)memBuf.size()) + { + memBuf.resize(conv); + } + + conv = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.length() + 1, (char*)memBuf.c_str(), conv, NULL, NULL); + return conv; +} + +void DatExport::WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding) +{ + MCHeader header; + memset(&header, 0, sizeof(MCHeader)); + memcpy(header.signature, "HB", 2); + header.version = -1; + header.dataSize = 0; + dataSize = 0; + EXP_FILE.write((char*)&header, sizeof(MCHeader)); +} + +void DatExport::WriteFooter() +{ + size_t pos = EXP_FILE.tellp(); + EXP_FILE.seekp(offsetof(MCHeader, dataSize), std::ios_base::beg); + EXP_FILE.write((char*)&dataSize, sizeof(dataSize)); + EXP_FILE.seekp(pos, std::ios_base::beg); + memBuf.resize(0); +#ifdef _WIN64 + memBuf.shrink_to_fit(); +#endif +} + +void DatExport::WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText) +{ +} + +void DatExport::WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei) +{ + DBEVENTINFO86 header; + header.cbSize = sizeof(DBEVENTINFO86); + header.eventType = dbei.eventType; + header.flags = dbei.flags & (~(0x800)); + header.timestamp = dbei.timestamp; + header.szModule = 0; + header.pBlob = 0; + if(dbei.flags & 0x800) + { + //Imported + header.flags |= DBEF_UTF; + header.cbBlob = WriteString(message); + EXP_FILE.write((char*)&header, header.cbSize); + EXP_FILE.write(memBuf.c_str(), header.cbBlob); + } + else + { + //Internal + header.cbBlob = dbei.cbBlob; + EXP_FILE.write((char*)&header, header.cbSize); + EXP_FILE.write((char*)dbei.pBlob, header.cbBlob); + } + + dataSize += header.cbSize + header.cbBlob; +} + +bool ReadHeader(MCHeader& header, std::istream* stream) +{ + stream->read((char*)&header, sizeof(MCHeader)); + if(!stream->good()) + return false; + if(memcmp(header.signature, "HB", 2) != 0) + return false; + + return true; +} + +int DatExport::IsContactInFile(const std::vector& contacts) +{ + MCHeader header; + if(!ReadHeader(header, IImport::stream)) + return -2; + + if(contacts.size() == 1) + { + hContact = contacts[0]; + } + + IMP_FILE.seekg(0, std::ios_base::beg); + return -3; +} + +bool DatExport::GetEventList(std::vector& eventList) +{ + MCHeader header; + if(!ReadHeader(header, IImport::stream)) + return false; + dataSize = header.dataSize; + DBEVENTINFO86 messageHeader; + DBEVENTINFO info = {0}; + info.cbSize = sizeof(DBEVENTINFO); + info.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + TCHAR _str[MAXSELECTSTR + 8]; // for safety reason + std::multimap sortedEvents; + while(dataSize > 0) + { + messageHeader.cbSize = 0; + IMP_FILE.read((char*)&messageHeader, sizeof(DBEVENTINFO86)); + if(!IMP_FILE.good()) + return false; + + if(messageHeader.cbSize < sizeof(DBEVENTINFO86)) + return false; + + if(messageHeader.cbSize > sizeof(DBEVENTINFO86)) + { + IMP_FILE.seekg(messageHeader.cbSize - sizeof(DBEVENTINFO86), std::ios_base::cur); + } + + IImport::ExternalMessage exMsg; + exMsg.eventType = messageHeader.eventType; + exMsg.flags = messageHeader.flags; + exMsg.timestamp = messageHeader.timestamp; + if(messageHeader.cbBlob > memBuf.size()) + { + memBuf.resize(messageHeader.cbBlob); + } + + IMP_FILE.read((char*)memBuf.c_str(), messageHeader.cbBlob); + if(!IMP_FILE.good()) + return false; + + info.eventType = messageHeader.eventType; + info.flags = messageHeader.flags; + info.timestamp = messageHeader.timestamp; + info.cbBlob = messageHeader.cbBlob; + info.pBlob = (PBYTE)memBuf.c_str(); + EventList::GetObjectDescription(&info, _str, MAXSELECTSTR); + exMsg.message = _str; + sortedEvents.insert(std::pair(messageHeader.timestamp, exMsg)); + dataSize -= messageHeader.cbSize + messageHeader.cbBlob; + } + + memBuf.resize(0); +#ifdef _WIN64 + memBuf.shrink_to_fit(); +#endif + + for(std::multimap::iterator it = sortedEvents.begin(); it != sortedEvents.end(); ++it) + { + eventList.push_back(it->second); + } + + return true; +} diff --git a/plugins/BasicHistory/src/DatExport.h b/plugins/BasicHistory/src/DatExport.h new file mode 100644 index 0000000000..980a12d148 --- /dev/null +++ b/plugins/BasicHistory/src/DatExport.h @@ -0,0 +1,53 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once +#include "IExport.h" +#include "IImport.h" + +class DatExport : + public IExport, + public IImport +{ +public: + virtual const TCHAR* GetExt() + { + return _T("dat"); + } + + virtual void WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding); + virtual void WriteFooter(); + virtual void WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText); + virtual void WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei); + virtual int IsContactInFile(const std::vector& contacts); + virtual bool GetEventList(std::vector& eventList); + + DatExport() + { + hContact = NULL; + } + + virtual ~DatExport(); +private: + int dataSize; + HANDLE hContact; + std::string memBuf; + inline int WriteString(const std::wstring &str); + //inline bool ReadString(std::wstring &str, int size); +}; + diff --git a/plugins/BasicHistory/src/EventList.cpp b/plugins/BasicHistory/src/EventList.cpp new file mode 100644 index 0000000000..8ac9e2eb37 --- /dev/null +++ b/plugins/BasicHistory/src/EventList.cpp @@ -0,0 +1,907 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "StdAfx.h" +#include "EventList.h" +#include "Options.h" +#include "ExportManager.h" +#include + +extern int iconsNum; + +bool DeleteDirectory(LPCTSTR lpszDir, bool noRecycleBin = true); +std::wstring GetName(const std::wstring &path); + +EventList::EventList() + :hWnd(NULL), + isWnd(false), + hContact(NULL), + deltaTime(0), + isFlat(false), + useImportedMessages(true) +{ + memset(&gdbei, 0, sizeof(DBEVENTINFO)); + gdbei.cbSize = sizeof(DBEVENTINFO); + goldBlobSize = 0; +} + +EventList::EventList(HANDLE _hContact, int filter) + :hWnd(NULL), + isWnd(false), + hContact(_hContact), + deltaTime(0), + isFlat(false), + useImportedMessages(true) +{ + memset(&gdbei, 0, sizeof(DBEVENTINFO)); + gdbei.cbSize = sizeof(DBEVENTINFO); + goldBlobSize = 0; + SetDefFilter(filter); +} + + +EventList::~EventList() +{ + mir_free(gdbei.pBlob); + eventList.clear(); +} + +bool EventList::CanShowHistory(DBEVENTINFO* dbei) +{ + if(deltaTime != 0) + { + if(deltaTime > 0) + { + if(now - deltaTime < dbei->timestamp) + return false; + } + else + { + if(now + deltaTime > dbei->timestamp) + return false; + } + } + + if(hContact == NULL || defFilter == 1) + return true; + + else if(defFilter < 1) + { + switch( dbei->eventType ) + { + case EVENTTYPE_MESSAGE: + case EVENTTYPE_URL: + case EVENTTYPE_FILE: + return true; + + default: + { + DBEVENTTYPEDESCR* et = ( DBEVENTTYPEDESCR* )CallService( MS_DB_EVENT_GETTYPE, ( WPARAM )dbei->szModule, ( LPARAM )dbei->eventType ); + if ( et && ( et->flags & DETF_HISTORY )) + { + return true; + } + } + } + + return false; + } + else + { + if(filterMap.find(dbei->eventType) != filterMap.end()) + { + if(onlyInFilter) + { + return !(dbei->flags & DBEF_SENT); + } + else if(onlyOutFilter) + { + return (dbei->flags & DBEF_SENT) != 0; + } + return true; + } + return false; + } +} + +bool EventList::CanShowHistory(const IImport::ExternalMessage& message) +{ + if(deltaTime != 0) + { + if(deltaTime > 0) + { + if(now - deltaTime < message.timestamp) + return false; + } + else + { + if(now + deltaTime > message.timestamp) + return false; + } + } + + if(hContact == NULL || defFilter == 1) + return true; + + else if(defFilter < 1) + { + switch(message.eventType ) + { + case EVENTTYPE_MESSAGE: + case EVENTTYPE_URL: + case EVENTTYPE_FILE: + return true; + } + + return false; + } + else + { + if(filterMap.find(message.eventType) != filterMap.end()) + { + if(onlyInFilter) + { + return !(message.flags & DBEF_SENT); + } + else if(onlyOutFilter) + { + return (message.flags & DBEF_SENT) != 0; + } + return true; + } + return false; + } +} + +void EventList::InitFilters() +{ + filterMap.clear(); + onlyInFilter = false; + onlyOutFilter = false; + if(defFilter >= 2) + { + defFilter = 0; + for(int i = 0; i < (int)Options::instance->customFilters.size(); ++i) + { + if(filterName == Options::instance->customFilters[i].name) + { + defFilter = i + 2; + if(Options::instance->customFilters[i].onlyIncomming && !Options::instance->customFilters[i].onlyOutgoing) + { + onlyInFilter = true; + } + else if(Options::instance->customFilters[i].onlyOutgoing && !Options::instance->customFilters[i].onlyIncomming) + { + onlyOutFilter = true; + } + + for(std::vector::iterator it = Options::instance->customFilters[i].events.begin(); it != Options::instance->customFilters[i].events.end(); ++it) + { + filterMap[*it] = true; + } + + break; + } + } + } + else + filterName = L""; +} + +void EventList::SetDefFilter(int filter) +{ + defFilter = filter; + if(filter >= 2 && filter - 2 < (int)Options::instance->customFilters.size()) + { + filterName = Options::instance->customFilters[filter - 2].name; + } + else if(filter == 1) + { + filterName = TranslateT("All events"); + } + else + { + filterName = TranslateT("Default history events"); + } +} + +int EventList::GetFilterNr() +{ + return defFilter; +} + +std::wstring EventList::GetFilterName() +{ + return filterName; +} + +void EventList::GetTempList(std::list& tempList, bool noFilter, bool noExt, HANDLE _hContact) +{ + HANDLE hDbEvent; + bool isWndLocal = isWnd; + EventTempIndex ti; + EventIndex ei; + EventData data; + ti.isExternal = false; + ei.isExternal = false; + hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRST,(WPARAM)_hContact,0); + while ( hDbEvent != NULL ) + { + if (isWndLocal && !IsWindow( hWnd )) + break; + ei.hEvent = hDbEvent; + if(GetEventData(ei, data)) + { + if(noFilter || CanShowHistory(&gdbei)) + { + ti.hEvent = hDbEvent; + ti.timestamp = data.timestamp; + tempList.push_back(ti); + } + } + hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0); + } + + if(!noExt) + { + std::list::iterator itL = tempList.begin(); + ti.isExternal = true; + for(int i = 0; i < (int)importedMessages.size(); ++i) + { + if(noFilter || CanShowHistory(importedMessages[i])) + { + DWORD ts = importedMessages[i].timestamp; + while(itL != tempList.end() && itL->timestamp < ts)++itL; + if(itL == tempList.end() || itL->timestamp > ts) + { + ti.exIdx = i; + ti.timestamp = ts; + tempList.insert(itL, ti); + } + } + } + } +} + +void EventList::RefreshEventList() +{ + InitNames(); + InitFilters(); + + if(useImportedMessages) + { + std::vector messages; + + EnterCriticalSection(&criticalSection); + std::map::iterator it = contactFileMap.find(hContact); + if(it != contactFileMap.end()) + { + ExportManager imp(hWnd, hContact, 1); + imp.SetAutoImport(it->second.file); + if(!imp.Import(it->second.type, messages, NULL)) + { + messages.clear(); + } + } + + LeaveCriticalSection(&criticalSection); + + ImportMessages(messages); + } + + std::list tempList; + GetTempList(tempList, false, false, hContact); + std::list revTempList; + std::list& nrTempList = tempList; + bool isNewOnTop = Options::instance->groupNewOnTop; + if(isNewOnTop) + { + revTempList.insert(revTempList.begin(), tempList.rbegin(), tempList.rend()); + nrTempList = revTempList; + } + + eventList.clear(); + eventList.push_back(std::deque()); + DWORD lastTime = MAXDWORD; + DWORD groupTime = Options::instance->groupTime * 60 * 60; + int maxMess = Options::instance->groupMessagesNumber; + int limitator = 0; + EventIndex ei; + for(std::list::iterator itL = nrTempList.begin(); itL != nrTempList.end(); ++itL) + { + DWORD tm = isNewOnTop ? lastTime - itL->timestamp : itL->timestamp - lastTime; + if(isFlat || tm < groupTime && limitator < maxMess) + { + lastTime = itL->timestamp; + ei.isExternal = itL->isExternal; + ei.hEvent = itL->hEvent; + if(isNewOnTop) + eventList.back().push_front(ei); + else + eventList.back().push_back(ei); + ++limitator; + } + else + { + limitator = 0; + lastTime = itL->timestamp; + if(!eventList.back().empty()) + { + ei = eventList.back().front(); + AddGroup(ei); + eventList.push_back(std::deque()); + } + ei.isExternal = itL->isExternal; + ei.hEvent = itL->hEvent; + eventList.back().push_front(ei); + } + } + + if(!eventList.back().empty()) + { + ei = eventList.back().front(); + AddGroup(ei); + } +} + +bool EventList::SearchInContact(HANDLE hContact, TCHAR *strFind, ComparatorInterface* compFun) +{ + InitFilters(); + + if(useImportedMessages) + { + std::vector messages; + + EnterCriticalSection(&criticalSection); + std::map::iterator it = contactFileMap.find(hContact); + if(it != contactFileMap.end()) + { + ExportManager imp(hWnd, hContact, 1); + imp.SetAutoImport(it->second.file); + if(!imp.Import(it->second.type, messages, NULL)) + { + messages.clear(); + } + } + + LeaveCriticalSection(&criticalSection); + for(int i = 0; i < (int)importedMessages.size(); ++i) + { + if(compFun->Compare((importedMessages[i].flags & DBEF_SENT) != 0, importedMessages[i].message, strFind)) + { + return true; + } + } + } + + std::list tempList; + GetTempList(tempList, false, true, hContact); + + EventIndex ei; + EventData ed; + TCHAR str[MAXSELECTSTR + 8]; // for safety reason + for(std::list::iterator itL = tempList.begin(); itL != tempList.end(); ++itL) + { + ei.isExternal = itL->isExternal; + ei.hEvent = itL->hEvent; + if(GetEventData(ei, ed)) + { + GetEventMessage(ei, str); + if(compFun->Compare(ed.isMe, str, strFind)) + { + return true; + } + } + } + + return false; +} + +void EventList::InitNames() +{ + TCHAR str[200]; + if(hContact) + { + _tcscpy_s(contactName, 256, (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR )); + mir_sntprintf(str,200,TranslateT("History for %s"),contactName); + } + else + { + _tcscpy_s(contactName, 256, TranslateT("System")); + mir_sntprintf(str,200,TranslateT("History")); + } + + if(isWnd) + { + SetWindowText(hWnd,str); + } + + _tcscpy_s(myName, GetMyName().c_str()); +} + +void EventList::AddGroup(const EventIndex& ev) +{ + EventData data; + GetEventData(ev, data); + TCHAR eventText[256]; + int i; + eventText[0] = 0; + tmi.printTimeStamp(NULL, data.timestamp, _T("d t"), eventText, 64, 0); + std::wstring time = eventText; + std::wstring user; + if(data.isMe) + user = myName; + else + user = contactName; + GetEventMessage(ev, eventText, 256); + for(i = 0; eventText[i] != 0 && eventText[i] != _T('\r') && eventText[i] != _T('\n'); ++i); + eventText[i] = 0; + if(i > Options::instance->groupMessageLen) + { + eventText[Options::instance->groupMessageLen - 3] = '.'; + eventText[Options::instance->groupMessageLen - 2] = '.'; + eventText[Options::instance->groupMessageLen - 1] = '.'; + eventText[Options::instance->groupMessageLen] = 0; + } + + int ico = 0; + GetEventIcon(data.isMe, data.eventType, ico); + AddGroup(data.isMe, time, user, eventText, ico); +} + +std::wstring EventList::GetContactName() +{ + if(hContact) + { + return (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR ); + } + else + { + return TranslateT("System"); + } +} + +void GetInfo(CONTACTINFO& ci, std::wstring& str) +{ + if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) + { + if (ci.type == CNFT_ASCIIZ) + { + str = ci.pszVal; + mir_free(ci.pszVal); + + } + else if (ci.type == CNFT_DWORD) + { + TCHAR buf[20]; + _ltot_s(ci.dVal, buf, 10 ); + str = buf; + } + else if (ci.type == CNFT_WORD) + { + TCHAR buf[20]; + _ltot_s(ci.wVal, buf, 10 ); + str = buf; + } + } +} + +std::wstring EventList::GetMyName() +{ + std::wstring myName; + CONTACTINFO ci; + ZeroMemory(&ci, sizeof(ci)); + ci.cbSize = sizeof(ci); + ci.szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + ci.hContact = 0; + ci.dwFlag = CNF_DISPLAY | CNF_TCHAR; + GetInfo(ci, myName); + if(myName.empty()) + { + return TranslateT("Me"); + } + + return myName; +} + +inline std::wstring GetProtocolName(HANDLE hContact) +{ + char* ac = (char *)CallService(MS_PROTO_GETCONTACTBASEACCOUNT, (WPARAM)hContact, 0); + std::wstring proto1; + if(ac != NULL) + { + PROTOACCOUNT* acnt = ProtoGetAccount(ac); + if(acnt != NULL && acnt->szModuleName != NULL) + { + wchar_t* proto = mir_a2u(acnt->szProtoName); + proto1 = proto; + mir_free(proto); + } + } + + return proto1; +} + +std::wstring EventList::GetProtocolName() +{ + return ::GetProtocolName(hContact); +} + +std::string EventList::GetBaseProtocol() +{ + char* proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + return proto == NULL ? "" : proto; +} + +std::wstring EventList::GetMyId() +{ + std::wstring myId; + CONTACTINFO ci; + ZeroMemory(&ci, sizeof(ci)); + ci.cbSize = sizeof(ci); + ci.szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + ci.hContact = 0; + ci.dwFlag = CNF_DISPLAYUID | CNF_TCHAR; + GetInfo(ci, myId); + return myId; +} + +inline std::wstring GetContactId(HANDLE hContact) +{ + std::wstring id; + CONTACTINFO ci; + ZeroMemory(&ci, sizeof(ci)); + ci.cbSize = sizeof(ci); + ci.szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + ci.hContact = hContact; + ci.dwFlag = CNF_DISPLAYUID | CNF_TCHAR; + GetInfo(ci, id); + return id; +} + +std::wstring EventList::GetContactId() +{ + return ::GetContactId(hContact); +} + +static void GetMessageDescription( DBEVENTINFO *dbei, TCHAR* buf, int cbBuf ) +{ + TCHAR* msg = DbGetEventTextT( dbei, CP_ACP ); + _tcsncpy_s(buf, cbBuf, msg ? msg : TranslateT("Invalid Message"), cbBuf - 1 ); + buf[ cbBuf-1 ] = 0; + mir_free( msg ); +} + +static void GetAuthRequestDescription( DBEVENTINFO *dbei, TCHAR* buf, int cbBuf ) +{ + std::wstring allName; + buf[0] = 0; + size_t pos = sizeof( DWORD ) + sizeof( HANDLE ); + if(pos >= dbei->cbBlob) + return; + DWORD uin = *((DWORD*)dbei->pBlob); + HANDLE hContact = *((HANDLE*)(dbei->pBlob + sizeof( DWORD ))); + char* nick, *firstName, *lastName, *jid, *reason; + nick = ( char* )( dbei->pBlob + sizeof( DWORD )+ sizeof( HANDLE )); + pos += strnlen_s(nick, dbei->cbBlob - pos) + 1; + if(pos >= dbei->cbBlob) + return; + firstName = ( char* )dbei->pBlob + pos; + pos += strnlen_s(firstName, dbei->cbBlob - pos) + 1; + if(pos >= dbei->cbBlob) + return; + lastName = ( char* )dbei->pBlob + pos; + pos += strnlen_s(lastName, dbei->cbBlob - pos) + 1; + if(pos >= dbei->cbBlob) + return; + jid = (char*)dbei->pBlob + pos; + pos += strnlen_s(jid, dbei->cbBlob - pos) + 1; + if(pos >= dbei->cbBlob) + return; + reason = (char*)dbei->pBlob + pos; + TCHAR *newNick, *newFirstName, *newLastName, *newJid, *newReason; + if(dbei->flags & DBEF_UTF) + { + newNick = mir_utf8decodeT( nick ); + newFirstName = mir_utf8decodeT( firstName ); + newLastName = mir_utf8decodeT( lastName ); + newJid = mir_utf8decodeT( jid ); + newReason = mir_utf8decodeT( reason ); + } + else + { + newNick = mir_a2t( nick ); + newFirstName = mir_a2t( firstName ); + newLastName = mir_a2t( lastName ); + newJid = mir_a2t( jid ); + newReason = mir_a2t( reason ); + } + + if(newFirstName[0] != 0) + { + allName += newFirstName; + if(newLastName[0] != 0) + allName += _T(" "); + } + + if(newLastName[0] != 0) + allName += newLastName; + if(!allName.empty()) + allName += _T(", "); + if(newJid[0] != 0) + { + allName += newJid; + allName += _T(", "); + } + + _sntprintf_s(buf, cbBuf, _TRUNCATE, TranslateT("Authorisation request by %s (%s%d): %s"), + (newNick[0] == 0 ? (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR) : newNick), + allName.c_str(), uin, newReason); + mir_free( newNick ); + mir_free( newFirstName ); + mir_free( newLastName ); + mir_free( newJid ); + mir_free( newReason ); +} + +void EventList::GetObjectDescription( DBEVENTINFO *dbei, TCHAR* str, int cbStr ) +{ + switch( dbei->eventType ) + { + case EVENTTYPE_AUTHREQUEST: + GetAuthRequestDescription( dbei, str, cbStr ); + break; + + default: + GetMessageDescription( dbei, str, cbStr ); + } +} + +bool EventList::GetEventIcon(bool isMe, int eventType, int &id) +{ + switch(eventType) + { + case EVENTTYPE_MESSAGE: + id = isMe ? 1 : 0; + return true; + case EVENTTYPE_STATUSCHANGE: + id = 2; + return true; + case EVENTTYPE_FILE: + id = iconsNum; + return true; + case EVENTTYPE_URL: + id = iconsNum + 1; + return true; + case EVENTTYPE_AUTHREQUEST: + id = iconsNum + 2; + return true; + default: + id = isMe ? 1 : 0; + return false; + } +} + +void EventList::ImportMessages(const std::vector& messages) +{ + DWORD lastTime = 0; + importedMessages.clear(); + for(int i = 0; i < (int)messages.size(); ++i) + { + if(messages[i].timestamp >= lastTime) + { + importedMessages.push_back(messages[i]); + lastTime = messages[i].timestamp; + } + else + { + assert(FALSE); + } + } +} + +void EventList::MargeMessages(const std::vector& messages) +{ + ImportMessages(messages); + std::list tempList; + GetTempList(tempList, true, false, hContact); + DBEVENTINFO dbei = {0}; + dbei.cbSize = sizeof(DBEVENTINFO); + dbei.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + CallService(MS_DB_SETSAFETYMODE, (WPARAM)FALSE, 0); + for(std::list::iterator it = tempList.begin(); it != tempList.end(); ++it) + { + if(it->isExternal) + { + IImport::ExternalMessage& msg = importedMessages[it->exIdx]; + dbei.flags = msg.flags & (~(DBEF_FIRST)); + dbei.flags |= DBEF_READ; + dbei.timestamp = msg.timestamp; + // For now I do not convert event data from string to blob, and event type must be message to handle it properly + dbei.eventType = EVENTTYPE_MESSAGE; + UINT cp = dbei.flags & DBEF_UTF ? CP_UTF8 : CP_ACP; + dbei.cbBlob = WideCharToMultiByte(cp, 0, msg.message.c_str(), (int)msg.message.length() + 1, NULL, 0, NULL, NULL); + char* buf = new char[dbei.cbBlob]; + dbei.cbBlob = WideCharToMultiByte(cp, 0, msg.message.c_str(), (int)msg.message.length() + 1, buf, dbei.cbBlob, NULL, NULL); + dbei.pBlob = (PBYTE)buf; + CallService(MS_DB_EVENT_ADD, (WPARAM) hContact, (LPARAM) & dbei); + delete buf; + } + } + + CallService(MS_DB_SETSAFETYMODE, (WPARAM)TRUE, 0); + std::vector emessages; + ImportMessages(emessages); +} + +bool EventList::GetEventData(const EventIndex& ev, EventData& data) +{ + if(!ev.isExternal) + { + DWORD newBlobSize=CallService(MS_DB_EVENT_GETBLOBSIZE,(WPARAM)ev.hEvent,0); + if(newBlobSize>goldBlobSize) + { + gdbei.pBlob=(PBYTE)mir_realloc(gdbei.pBlob,newBlobSize); + goldBlobSize=newBlobSize; + } + + gdbei.cbBlob = goldBlobSize; + if (CallService(MS_DB_EVENT_GET,(WPARAM)ev.hEvent,(LPARAM)&gdbei) == 0) + { + data.isMe = (gdbei.flags & DBEF_SENT) != 0; + data.eventType = gdbei.eventType; + data.timestamp = gdbei.timestamp; + return true; + } + } + else + { + if(ev.exIdx >= 0 && ev.exIdx < (int)importedMessages.size()) + { + IImport::ExternalMessage& em = importedMessages[ev.exIdx]; + data.isMe = (em.flags & DBEF_SENT) != 0; + data.eventType = em.eventType; + data.timestamp = em.timestamp; + return true; + } + } + + return false; +} + +void EventList::GetExtEventDBei(const EventIndex& ev) +{ + IImport::ExternalMessage& em = importedMessages[ev.exIdx]; + gdbei.flags = (em.flags & (~(DBEF_FIRST))) | 0x800; + gdbei.eventType = em.eventType; + gdbei.timestamp = em.timestamp; +} + +HICON EventList::GetEventCoreIcon(const EventIndex& ev) +{ + if(ev.isExternal) + return NULL; + HICON ico; + ico = (HICON)CallService(MS_DB_EVENT_GETICON, LR_SHARED, (LPARAM)&gdbei); + HICON icoMsg = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE); + if(icoMsg == ico) + { + return NULL; + } + + return ico; +} + +void EventList::RebuildGroup(int selected) +{ + std::deque newGroup; + for(size_t i = 0; i < eventList[selected].size(); ++i) + { + EventIndex& ev = eventList[selected][i]; + if(!ev.isExternal) + { + if(CallService(MS_DB_EVENT_GETBLOBSIZE,(WPARAM)(HANDLE)ev.hEvent,0) >= 0) + { + // If event exist, we add it to new group + newGroup.push_back(eventList[selected][i]); + } + } + else + { + newGroup.push_back(eventList[selected][i]); + } + } + eventList[selected].clear(); + eventList[selected].insert(eventList[selected].begin(), newGroup.begin(), newGroup.end()); +} + +CRITICAL_SECTION EventList::criticalSection; +std::map EventList::contactFileMap; +std::wstring EventList::contactFileDir; + +void EventList::AddImporter(HANDLE hContact, IImport::ImportType type, const std::wstring& file) +{ + EnterCriticalSection(&criticalSection); + TCHAR buf[32]; + _stprintf_s(buf, _T("%016llx"), (unsigned long long int)hContact); + std::wstring internalFile = contactFileDir; + ImportDiscData data; + data.file = contactFileDir + buf; + data.type = type; + CopyFile(file.c_str(), data.file.c_str(), FALSE); + contactFileMap[hContact] = data; + LeaveCriticalSection(&criticalSection); +} + +void EventList::Init() +{ + InitializeCriticalSection(&EventList::criticalSection); + TCHAR temp[MAX_PATH]; + temp[0] = 0; + GetTempPath(MAX_PATH, temp); + contactFileDir = temp; + contactFileDir += L"BasicHistoryImportDir\\"; + DeleteDirectory(contactFileDir.c_str()); + CreateDirectory(contactFileDir.c_str(), NULL); +} + +void EventList::Deinit() +{ + DeleteCriticalSection(&EventList::criticalSection); +} + +int EventList::GetContactMessageNumber(HANDLE hContact) +{ + int count = CallService(MS_DB_EVENT_GETCOUNT,(WPARAM)hContact,0); + EnterCriticalSection(&criticalSection); + std::map::iterator it = contactFileMap.find(hContact); + if(it != contactFileMap.end()) + { + ++count; + } + + LeaveCriticalSection(&criticalSection); + return count; +} + +bool EventList::IsImportedHistory(HANDLE hContact) +{ + bool count = false; + EnterCriticalSection(&criticalSection); + std::map::iterator it = contactFileMap.find(hContact); + if(it != contactFileMap.end()) + { + count = true; + } + + LeaveCriticalSection(&criticalSection); + return count; +} + +void EventList::DeleteImporter(HANDLE hContact) +{ + EnterCriticalSection(&criticalSection); + std::map::iterator it = contactFileMap.find(hContact); + if(it != contactFileMap.end()) + { + DeleteFile(it->second.file.c_str()); + contactFileMap.erase(it); + } + + LeaveCriticalSection(&criticalSection); +} diff --git a/plugins/BasicHistory/src/EventList.h b/plugins/BasicHistory/src/EventList.h new file mode 100644 index 0000000000..36628ff278 --- /dev/null +++ b/plugins/BasicHistory/src/EventList.h @@ -0,0 +1,161 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once +#include "IImport.h" + +#define MAXSELECTSTR 8184 + +class ComparatorInterface +{ +public: + virtual bool Compare(const bool isMe, const std::wstring& message, TCHAR *strFind) = 0; +}; + +class EventList +{ +public: + struct EventData + { + bool isMe; + WORD eventType; + DWORD timestamp; + }; + struct EventIndex + { + union + { + HANDLE hEvent; + int exIdx; + }; + bool isExternal; + }; +private: + std::map filterMap; + bool onlyInFilter; + bool onlyOutFilter; + int defFilter; + std::wstring filterName; + std::vector importedMessages; + DWORD goldBlobSize; + static CRITICAL_SECTION criticalSection; + + struct EventTempIndex + { + union + { + HANDLE hEvent; + int exIdx; + }; + bool isExternal; + DWORD timestamp; + }; + + struct ImportDiscData + { + IImport::ImportType type; + std::wstring file; + }; + + static std::map contactFileMap; + static std::wstring contactFileDir; + + bool CanShowHistory(DBEVENTINFO* dbei); + bool CanShowHistory(const IImport::ExternalMessage& message); + void InitFilters(); + void InitNames(); + void AddGroup(const EventIndex& ev); + void GetTempList(std::list& tempList, bool noFilter, bool noExt, HANDLE _hContact); + void ImportMessages(const std::vector& messages); +protected: + TCHAR contactName[256]; + TCHAR myName[256]; + bool isWnd; + int deltaTime; + DWORD now; + bool isFlat; + DBEVENTINFO gdbei; + + virtual void AddGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText, int ico) = 0; + bool GetEventIcon(bool isMe, int eventType, int &id); + void DeleteEvent(const EventIndex& ev) + { + if(!ev.isExternal) + CallService(MS_DB_EVENT_DELETE,(WPARAM)hContact,(LPARAM)(HANDLE)ev.hEvent); + } + + void RebuildGroup(int selected); +public: + EventList(); + EventList(HANDLE _hContact, int filter); + ~EventList(); + + HWND hWnd; + HANDLE hContact; + std::vector > eventList; + bool useImportedMessages; + + static void Init(); + static void Deinit(); + void SetDefFilter(int filter); + int GetFilterNr(); + std::wstring GetFilterName(); + void RefreshEventList(); + bool SearchInContact(HANDLE hContact, TCHAR *strFind, ComparatorInterface* compFun); + std::wstring GetContactName(); + std::wstring GetMyName(); + std::wstring GetProtocolName(); + std::wstring GetMyId(); + std::wstring GetContactId(); + std::string GetBaseProtocol(); + void MargeMessages(const std::vector& messages); + static void AddImporter(HANDLE hContact, IImport::ImportType type, const std::wstring& file); + static int GetContactMessageNumber(HANDLE hContact); + static bool IsImportedHistory(HANDLE hContact); + static void DeleteImporter(HANDLE hContact); + static void GetObjectDescription( DBEVENTINFO *dbei, TCHAR* str, int cbStr ); + bool GetEventData(const EventIndex& ev, EventData& data); + void GetExtEventDBei(const EventIndex& ev); + HICON GetEventCoreIcon(const EventIndex& ev); + void GetEventMessage(const EventIndex& ev, TCHAR* message) // must be allocated with MAXSELECTSTR len + { + if(!ev.isExternal) + GetObjectDescription(&gdbei, message, MAXSELECTSTR); + else + _tcscpy_s(message, MAXSELECTSTR, importedMessages[ev.exIdx].message.c_str()); + } + void GetEventMessage(const EventIndex& ev, TCHAR* message, int strLen) + { + if(!ev.isExternal) + GetObjectDescription(&gdbei, message, strLen); + else + { + std::wstring& meg = importedMessages[ev.exIdx].message; + if((int)meg.size() >= strLen) + { + memcpy_s(message, strLen * sizeof(TCHAR), meg.c_str(), (strLen - 1) * sizeof(TCHAR)); + message[strLen - 1] = 0; + } + else + { + _tcscpy_s(message, strLen, meg.c_str()); + } + } + } +}; + diff --git a/plugins/BasicHistory/src/ExportManager.cpp b/plugins/BasicHistory/src/ExportManager.cpp new file mode 100644 index 0000000000..897561ef26 --- /dev/null +++ b/plugins/BasicHistory/src/ExportManager.cpp @@ -0,0 +1,391 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "StdAfx.h" +#include "ExportManager.h" +#include "TxtExport.h" +#include "PlainHtmlExport.h" +#include "RichHtmlExport.h" +#include "BinaryExport.h" +#include "DatExport.h" +#include "Options.h" +#include "codecvt_CodePage.h" + +ExportManager::ExportManager(HWND _hwnd, HANDLE _hContact, int filter) + :EventList(_hContact, filter), + hwnd(_hwnd), + oldOnTop(false) +{ +} + +std::wstring GetFile(const TCHAR* ext, HWND hwnd, bool open) +{ + TCHAR filter[512]; + std::locale loc; + TCHAR extUpper[32]; + _tcscpy_s(extUpper, ext); + extUpper[0] = std::toupper(ext[0], loc); + _stprintf_s(filter, TranslateT("%s Files (*.%s)"), extUpper, ext); + size_t len = _tcslen(filter) + 1; + _stprintf_s(filter + len, 512 - len, TranslateT("*.%s"), ext); + len += _tcslen(filter + len); + filter[++len] = 0; + TCHAR stzFilePath[1024]; + _tcscpy_s(stzFilePath, TranslateT("History")); + _tcscat_s(stzFilePath, _T(".")); + _tcscat_s(stzFilePath, ext); + len = _tcslen(stzFilePath) + 1; + stzFilePath[len] = 0; + OPENFILENAME ofn = {0}; + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = filter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = stzFilePath; + ofn.lpstrTitle = open ? TranslateT("Import") : TranslateT("Export"); + ofn.nMaxFile = 1024; + ofn.lpstrDefExt = ext; + if(open) + { + ofn.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + if(GetOpenFileName(&ofn)) + { + return stzFilePath; + } + } + else + { + ofn.Flags = OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR; + if(GetSaveFileName(&ofn)) + { + return stzFilePath; + } + } + + return L""; +} + +std::wstring ReplaceExt(const std::wstring& file, const TCHAR* ext) +{ + size_t pos = file.find(_T("")); + if(pos < file.length()) + { + std::wstring fileName = file.substr(0, pos); + fileName += ext; + fileName += file.substr(pos + 5); + return fileName; + } + + return file; +} + +bool ExportManager::Export(IExport::ExportType type) +{ + exp = NULL; + UINT cp; + std::wstring encoding; + bool isBin = false; + switch(type) + { + case IExport::Txt: + exp = new TxtExport(); + cp = Options::instance->codepageTxt; + encoding = Options::instance->encodingTxt; + isFlat = true; + break; + case IExport::PlainHtml: + exp = new PlainHtmlExport(); + cp = Options::instance->codepageHtml1; + encoding = Options::instance->encodingHtml1; + break; + case IExport::RichHtml: + exp = new RichHtmlExport(); + cp = Options::instance->codepageHtml2; + encoding = Options::instance->encodingHtml2; + break; + case IExport::Binary: + exp = new BinaryExport(); + cp = CP_UTF8; + encoding = L"UTF8"; + isFlat = true; + oldOnTop = true; + isBin = true; + break; + case IExport::Dat: + exp = new DatExport(); + cp = CP_UTF8; + encoding = L"UTF8"; + isFlat = true; + oldOnTop = true; + isBin = true; + break; + default: + return false; + } + + std::wstring fileName; + if(file.empty()) + fileName = GetFile(exp->GetExt(), hwnd, false); + else + { + fileName = ReplaceExt(file, exp->GetExt()); + } + + if(fileName.empty()) + return false; + + std::wofstream* stream; + if(!isBin) + { + stream = new std::wofstream (fileName.c_str()); + if(!stream->is_open()) + return false; + + std::locale filelocale(std::locale(), new codecvt_CodePage(cp)); + stream->imbue(filelocale); + exp->SetStream(stream); + } + else + { + std::ofstream* cstream = new std::ofstream (fileName.c_str(), std::ios_base::binary); + if(!cstream->is_open()) + return false; + + stream = (std::wofstream*)cstream; + exp->SetStream(stream); + } + + exp->WriteHeader(fileName, GetFilterName(), GetMyName(), GetMyId(), GetContactName(), GetProtocolName(), GetContactId(), GetBaseProtocol(), encoding); + + RefreshEventList(); + + exp->WriteFooter(); + if(!isBin) + { + stream->close(); + delete stream; + } + else + { + std::ofstream* cstream = (std::ofstream*)stream; + cstream->close(); + delete cstream; + } + + delete exp; + return true; +} + +const TCHAR* ExportManager::GetExt(IImport::ImportType type) +{ + IImport* imp = NULL; + switch(type) + { + case IImport::Binary: + imp = new BinaryExport(); + break; + case IImport::Dat: + imp = new DatExport(); + break; + default: + return L""; + } + + const TCHAR* ext = imp->GetExt(); + delete imp; + return ext; +} + +int ExportManager::Import(IImport::ImportType type, const std::vector& contacts) +{ + IImport* imp = NULL; + switch(type) + { + case IImport::Binary: + imp = new BinaryExport(); + break; + case IImport::Dat: + imp = new DatExport(); + break; + default: + return -2; + } + + std::wstring fileName; + if(file.empty()) + return -2; + else + { + fileName = ReplaceExt(file, imp->GetExt()); + } + + if(fileName.empty()) + return -2; + + std::ifstream* stream = new std::ifstream (fileName.c_str(), std::ios_base::binary); + if(!stream->is_open()) + return -2; + + imp->SetStream(stream); + int t = imp->IsContactInFile(contacts); + stream->close(); + delete stream; + delete imp; + return t; +} + +bool ExportManager::Import(IImport::ImportType type, std::vector& eventList, std::wstring* err) +{ + IImport* imp = NULL; + switch(type) + { + case IImport::Binary: + imp = new BinaryExport(); + break; + case IImport::Dat: + imp = new DatExport(); + break; + default: + return false; + } + + std::wstring fileName; + if(file.empty()) + file = fileName = GetFile(imp->GetExt(), hwnd, true); + else + { + fileName = ReplaceExt(file, imp->GetExt()); + } + + std::ifstream* stream = new std::ifstream (fileName.c_str(), std::ios_base::binary); + if(!stream->is_open()) + return false; + + imp->SetStream(stream); + std::vector v; + v.push_back(hContact); + bool ret = true; + int contInFile = imp->IsContactInFile(v); + if(contInFile != 0 && contInFile != -3) + { + ret = false; + if(err != NULL) + *err = TranslateT("File do not contain selected contact"); + } + else + { + ret = imp->GetEventList(eventList); + if(!ret && err != NULL) + *err = TranslateT("File is corrupted"); + } + stream->close(); + delete stream; + delete imp; + return ret; +} + +void ExportManager::AddGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText, int ico) +{ + if(exp == NULL) + return; + exp->WriteGroup(isMe, time, user, eventText); + TCHAR str[MAXSELECTSTR + 8]; // for safety reason + str[0] = 0; + tm lastTime; + bool isFirst = true; + bool lastMe = false; + EventData data; + std::deque revDeq; + std::deque& deq = eventList.back(); + if(!oldOnTop && Options::instance->messagesNewOnTop) + { + revDeq.insert(revDeq.begin(), deq.rbegin(), deq.rend()); + deq = revDeq; + } + for(std::deque::iterator it = deq.begin(); it != deq.end(); ++it) + { + EventIndex hDbEvent = *it; + if(GetEventData(hDbEvent, data)) + { + lastMe = data.isMe; + + TCHAR* formatDate = Options::instance->messagesShowSec ? _T("d s") : _T("d t"); + TCHAR* longFormatDate = Options::instance->messagesShowSec ? _T("d s") : _T("d t"); + if(!Options::instance->messagesShowDate) + { + if(isFirst) + { + isFirst = false; + formatDate = Options::instance->messagesShowSec ? _T("s") : _T("t"); + time_t tt = data.timestamp; + localtime_s(&lastTime, &tt); + } + else + { + time_t tt = data.timestamp; + tm t; + localtime_s(&t, &tt); + if(lastTime.tm_yday == t.tm_yday && lastTime.tm_year == t.tm_year) + formatDate = Options::instance->messagesShowSec ? _T("s") : _T("t"); + } + } + + tmi.printTimeStamp(NULL, data.timestamp, longFormatDate, str , MAXSELECTSTR, 0); + std::wstring longDate = str; + tmi.printTimeStamp(NULL, data.timestamp, formatDate, str , MAXSELECTSTR, 0); + std::wstring shortDate = str; + + std::wstring user; + if(lastMe) + user = myName; + else + user = contactName; + + GetEventMessage(hDbEvent, str); + std::wstring strMessage = str; + if(strMessage.length() + 1 >= MAXSELECTSTR) + continue; + + if(hDbEvent.isExternal) + { + GetExtEventDBei(hDbEvent); + } + + exp->WriteMessage(lastMe, longDate, shortDate, user, strMessage, gdbei); + } + } +} + +void ExportManager::DeleteExportedEvents() +{ + for(size_t j = 0; j < eventList.size(); ++j) + { + for(size_t i = 0; i < eventList[j].size(); ++i) + { + DeleteEvent(eventList[j][i]); + } + } +} + +void ExportManager::SetDeleteWithoutExportEvents(int _deltaTime, DWORD _now) +{ + exp = NULL; + deltaTime = _deltaTime; + now = _now; + RefreshEventList(); +} diff --git a/plugins/BasicHistory/src/ExportManager.h b/plugins/BasicHistory/src/ExportManager.h new file mode 100644 index 0000000000..d99ff077a6 --- /dev/null +++ b/plugins/BasicHistory/src/ExportManager.h @@ -0,0 +1,59 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once +#include "EventList.h" +#include "IExport.h" +#include "IImport.h" +class ExportManager : public EventList +{ +private: + IExport* exp; + std::wstring file; + HWND hwnd; + bool oldOnTop; +protected: + virtual void AddGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText, int ico); +public: + ExportManager(HWND _hwnd, HANDLE _hContact, int filter); + + void SetAutoExport(const std::wstring _file, int _deltaTime, DWORD _now) + { + file = _file; + deltaTime = _deltaTime; + now = _now; + } + + void SetAutoImport(const std::wstring _file) + { + file = _file; + } + + std::wstring GetFileName() + { + return file; + } + + bool Export(IExport::ExportType type); + void SetDeleteWithoutExportEvents(int _deltaTime, DWORD _now); + void DeleteExportedEvents(); + int Import(IImport::ImportType type, const std::vector& contacts); + bool Import(IImport::ImportType type, std::vector& eventList, std::wstring* err = NULL); + static const TCHAR* GetExt(IImport::ImportType type); +}; + diff --git a/plugins/BasicHistory/src/HistoryWindow.cpp b/plugins/BasicHistory/src/HistoryWindow.cpp new file mode 100644 index 0000000000..d5c3948cb7 --- /dev/null +++ b/plugins/BasicHistory/src/HistoryWindow.cpp @@ -0,0 +1,2572 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "StdAfx.h" +#include "HistoryWindow.h" +#include "resource.h" +#include "Options.h" +#include "HotkeyHelper.h" +#include "ImageDataObject.h" +#include "ExportManager.h" + +#define MODULE "BasicHistory" +extern HINSTANCE hInst; +extern HCURSOR hCurSplitNS, hCurSplitWE; +extern HANDLE *hEventIcons; +extern int iconsNum; +extern HANDLE hPlusIcon, hMinusIcon, hFindNextIcon, hFindPrevIcon; +extern bool g_SmileyAddAvail; +extern char* metaContactProto; +#define DM_HREBUILD (WM_USER+11) +#define DM_SPLITTERMOVED (WM_USER+15) + +#define MIN_PANELHEIGHT 40 + +void ResetCList(HWND hWnd); + +HistoryWindow::HistoryWindow(HANDLE _hContact) : + isDestroyed(true), + OldSplitterProc(0), + splitterY(0), + splitterOrgY(0), + splitterX(0), + splitterOrgX(0), + plusIco(NULL), + minusIco(NULL), + findNextIco(NULL), + findPrevIco(NULL), + configIco(NULL), + deleteIco(NULL), + isContactList(false), + isLoading(false), + isGroupImages(false), + allIconNumber(0), + eventIcoms(NULL), + bkBrush(NULL), + bkFindBrush(NULL), + hSystem(NULL), + splitterXhWnd(NULL), + splitterYhWnd(NULL) +{ + searcher.SetContect(this); + hContact = _hContact; + selected = -1; + searcher.SetMatchCase(Options::instance->searchMatchCase); + searcher.SetMatchWholeWords(Options::instance->searchMatchWhole); + searcher.SetOnlyIn(Options::instance->searchOnlyIn); + searcher.SetOnlyOut(Options::instance->searchOnlyOut); + searcher.SetOnlyGroup(Options::instance->searchOnlyGroup); + searcher.SetAllUsers(Options::instance->searchAllContacts); + searcher.SetSearchForInLG(Options::instance->searchForInList); + searcher.SetSearchForInMes(Options::instance->searchForInMess); +} + + +HistoryWindow::~HistoryWindow() +{ + if(eventIcoms != NULL) + { + for(int i = 0; i < iconsNum; ++i) + { + if(eventIcoms[i] != NULL) + { + CallService(MS_SKIN2_RELEASEICON, (LPARAM)eventIcoms[i], 0); + } + } + + delete[] eventIcoms; + } + + if(plusIco != NULL) + { + CallService(MS_SKIN2_RELEASEICON, (LPARAM)plusIco, 0); + } + if(minusIco != NULL) + { + CallService(MS_SKIN2_RELEASEICON, (LPARAM)minusIco, 0); + } + if(findNextIco != NULL) + { + CallService(MS_SKIN2_RELEASEICON, (LPARAM)findNextIco, 0); + } + if(findPrevIco != NULL) + { + CallService(MS_SKIN2_RELEASEICON, (LPARAM)findPrevIco, 0); + } + if(himlSmall != NULL) + { + ImageList_Destroy(himlSmall); + } + if(himlNone != NULL) + { + ImageList_Destroy(himlNone); + } + if(bkBrush != NULL) + { + DeleteObject(bkBrush); + } + if(bkFindBrush != NULL) + { + DeleteObject(bkFindBrush); + } +} + +std::map HistoryWindow::windows; +std::vector HistoryWindow::freeWindows; + +void HistoryWindow::Deinit() +{ + bool destroyed = true; + std::vector keys; + for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) + { + if(!it->second->isDestroyed) + { + keys.push_back(it->first); + } + } + for(std::vector::iterator it = keys.begin(); it != keys.end(); ++it) + { + std::map::iterator it1 = windows.find(*it); + if(it1 != windows.end()) + { + DestroyWindow(it1->second->hWnd); + it1 = windows.find(*it); + destroyed &= it1 == windows.end(); + } + } + + std::vector keys1; + for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) + { + if(!(*it)->isDestroyed) + { + keys1.push_back(*it); + } + } + for(std::vector::iterator it = keys1.begin(); it != keys1.end(); ++it) + { + DestroyWindow((*it)->hWnd); + } + for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) + { + if(!(*it)->isDestroyed) + { + destroyed = false; + break; + } + } + + if(destroyed) + { + for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) + { + delete it->second; + } + + windows.clear(); + + for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) + { + delete *it; + } + + freeWindows.clear(); + } +} + +void HistoryWindow::Open(HANDLE hContact) +{ + if(hContact == NULL) + { + HistoryWindow *hw = new HistoryWindow(hContact); + freeWindows.push_back(hw); + hw->Show(); + } + else + { + std::map::iterator it = windows.find(hContact); + if(it != windows.end()) + { + it->second->Focus(); + } + else + { + windows[hContact] = new HistoryWindow(hContact); + windows[hContact]->Show(); + } + } +} + +void HistoryWindow::Close(HANDLE hContact) +{ + std::map::iterator it = windows.find(hContact); + if(it != windows.end()) + { + if(it->second->isDestroyed) + { + delete it->second; + windows.erase(it); + } + else + { + DestroyWindow(it->second->hWnd); + } + } +} + +void HistoryWindow::Close(HistoryWindow* historyWindow) +{ + if(!historyWindow->isDestroyed) + { + DestroyWindow(historyWindow->hWnd); + return; + } + std::map::iterator it = windows.find(historyWindow->hContact); + if(it != windows.end() && it->second == historyWindow) + { + delete it->second; + windows.erase(it); + } + else + { + for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) + { + if(*it == historyWindow) + { + freeWindows.erase(it); + delete historyWindow; + return; + } + } + } +} + +void HistoryWindow::RebuildEvents(HANDLE hContact) +{ + if(hContact != NULL) + { + std::map::iterator it = windows.find(hContact); + if(it != windows.end() && !it->second->isDestroyed) + { + SendMessage(it->second->hWnd,DM_HREBUILD,0,0); + } + } + + for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) + { + if((*it)->hContact == hContact && !(*it)->isDestroyed) + { + SendMessage((*it)->hWnd,DM_HREBUILD,0,0); + } + } +} + +void HistoryWindow::ChangeToFreeWindow(HistoryWindow* historyWindow) +{ + std::map::iterator it = windows.find(historyWindow->hContact); + if(it != windows.end() && it->second == historyWindow) + { + windows.erase(it); + freeWindows.push_back(historyWindow); + } +} + +void HistoryWindow::Show() +{ + CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_HISTORY),NULL,HistoryWindow::DlgProcHistory,(LPARAM)this); +} + +void HistoryWindow::Focus() +{ + if(IsIconic(hWnd)) + { + ShowWindow(hWnd, SW_RESTORE); + } + else + { + SetForegroundWindow(hWnd); + SetFocus(hWnd); + } + SendMessage(hWnd,DM_HREBUILD,0,0); +} + +int HistoryWindow::FontsChanged(WPARAM wParam, LPARAM lParam) +{ + for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) + { + if(!it->second->isDestroyed) + { + it->second->FontsChanged(); + } + } + + for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) + { + if(!(*it)->isDestroyed) + { + (*it)->FontsChanged(); + } + } + + return 0; +} + +void HistoryWindow::FontsChanged() +{ + if(bkBrush != NULL) + { + DeleteObject(bkBrush); + } + if(bkFindBrush != NULL) + { + DeleteObject(bkFindBrush); + } + + bkBrush = CreateSolidBrush(Options::instance->GetColor(Options::WindowBackground)); + bkFindBrush = CreateSolidBrush(Options::instance->GetColor(Options::FindBackground)); + + ResetCList(hWnd); + COLORREF bkColor = Options::instance->GetColor(Options::GroupListBackground); + ListView_SetBkColor(listWindow, bkColor); + ListView_SetTextBkColor(listWindow, bkColor); + LOGFONT font; + ListView_SetTextColor(listWindow, Options::instance->GetFont(Options::GroupList, &font)); + InvalidateRect(listWindow, NULL, TRUE); + InvalidateRect(hWnd, NULL, TRUE); + SelectEventGroup(selected); +} + +void OptionsGroupChanged() +{ + HistoryWindow::OptionsGroupChanged(); +} + +void HistoryWindow::OptionsGroupChanged() +{ + for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) + { + if(!it->second->isDestroyed) + { + it->second->GroupImagesChanged(); + SendMessage(it->second->hWnd,DM_HREBUILD,0,0); + } + } + + for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) + { + if(!(*it)->isDestroyed) + { + (*it)->GroupImagesChanged(); + SendMessage((*it)->hWnd,DM_HREBUILD,0,0); + } + } +} + +void OptionsMainChanged() +{ + HistoryWindow::OptionsMainChanged(); +} + +void HistoryWindow::OptionsMainChanged() +{ + for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) + { + if(!it->second->isDestroyed) + { + it->second->ReloadMainOptions(); + } + } + + for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) + { + if(!(*it)->isDestroyed) + { + (*it)->ReloadMainOptions(); + } + } +} + +void HistoryWindow::ReloadMainOptions() +{ + SendDlgItemMessage(hWnd, IDC_LIST_CONTACTS, CLM_SETUSEGROUPS, Options::instance->showContactGroups, 0); + SendMessage(hWnd,DM_HREBUILD,0,0); +} + +void OptionsMessageChanged() +{ + HistoryWindow::FontsChanged(0, 0); +} + +void OptionsSearchingChanged() +{ + HistoryWindow::OptionsSearchingChanged(); +} + +void HistoryWindow::OptionsSearchingChanged() +{ + for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) + { + if(!it->second->isDestroyed) + { + it->second->searcher.SetSearchForInLG(Options::instance->searchForInList); + it->second->searcher.SetSearchForInMes(Options::instance->searchForInMess); + } + } + + for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) + { + if(!(*it)->isDestroyed) + { + (*it)->searcher.SetSearchForInLG(Options::instance->searchForInList); + (*it)->searcher.SetSearchForInMes(Options::instance->searchForInMess); + } + } +} + +INT_PTR HistoryWindow::DeleteAllUserHistory(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + HWND hWnd = NULL; + int start = 0; + int end = 0; + int count = EventList::GetContactMessageNumber(hContact); + if(!count) + return FALSE; + + for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) + { + if(!it->second->isDestroyed) + { + if(it->second->hContact == hContact) + { + if(hWnd == NULL) + { + hWnd = it->second->hWnd; + } + else if(GetForegroundWindow() == it->second->hWnd) + { + hWnd = it->second->hWnd; + } + } + } + } + + for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) + { + if(!(*it)->isDestroyed) + { + if((*it)->hContact == hContact) + { + if(hWnd == NULL) + { + hWnd = (*it)->hWnd; + } + else if(GetForegroundWindow() == (*it)->hWnd) + { + hWnd = (*it)->hWnd; + } + } + } + } + + TCHAR *message = TranslateT("This operation will PERMANENTLY REMOVE all history for this contact.\nAre you sure you want to do this?"); + if(MessageBox(hWnd, message, TranslateT("Are You sure?"), MB_OKCANCEL | MB_ICONERROR) != IDOK) + return FALSE; + + std::deque toRemove; + HANDLE hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRST,(WPARAM)hContact,0); + while ( hDbEvent != NULL ) + { + toRemove.push_back(hDbEvent); + hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0); + } + + for(std::deque::iterator it = toRemove.begin(); it != toRemove.end(); ++it) + { + CallService(MS_DB_EVENT_DELETE,(WPARAM)hContact,(LPARAM)(HANDLE)*it); + } + + if(EventList::IsImportedHistory(hContact)) + { + TCHAR *message = TranslateT("Do you want delete all imported messages for this contact?\nNote that next scheduler task import this messages again."); + if(MessageBox(hWnd, message, TranslateT("Are You sure?"), MB_YESNO | MB_ICONERROR) == IDYES) + { + EventList::DeleteImporter(hContact); + } + } + + RebuildEvents(hContact); + return TRUE; +} + +bool HistoryWindow::IsInList(HWND hWnd) +{ + for(std::map::iterator it = windows.begin(); it != windows.end(); ++it) + { + if(!it->second->isDestroyed) + { + if(it->second->hWnd == hWnd) + { + return true; + } + } + } + + for(std::vector::iterator it = freeWindows.begin(); it != freeWindows.end(); ++it) + { + if(!(*it)->isDestroyed) + { + if((*it)->hWnd == hWnd) + { + return true; + } + } + } + + return false; +} + +void ClickLink(HWND hwnd, ENLINK *penLink) +{ + TCHAR buf[1024]; + if(penLink->msg != WM_LBUTTONUP) + return; + if(penLink->chrg.cpMin >= 0 && penLink->chrg.cpMax > penLink->chrg.cpMin) + { + // selection + int len = penLink->chrg.cpMax - penLink->chrg.cpMin; + if(len < 1023) + { + TEXTRANGE tr; + CHARRANGE sel; + + SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM) & sel); + if (sel.cpMin != sel.cpMax) + return; + tr.chrg = penLink->chrg; + tr.lpstrText = buf; + SendMessage(hwnd, EM_GETTEXTRANGE, 0, (LPARAM) & tr); + CallService(MS_UTILS_OPENURL, (penLink->nmhdr.code == IDM_OPENNEW ? OUF_NEWWINDOW : 0) | OUF_TCHAR, (LPARAM) tr.lpstrText); + } + } +} + +void ConvertSize(HWND hwndSrc, HWND hwndDest, RECT& rc) +{ + POINT pt; + pt.x = rc.left; + pt.y = rc.top; + ClientToScreen(hwndSrc, &pt); + ScreenToClient(hwndDest, &pt); + rc.left = pt.x; + rc.top = pt.y; + + pt.x = rc.right; + pt.y = rc.bottom; + ClientToScreen(hwndSrc, &pt); + ScreenToClient(hwndDest, &pt); + rc.right = pt.x; + rc.bottom = pt.y; +} + +void OpenOptions(char* group, char* page, char* tab = NULL) +{ + OPENOPTIONSDIALOG op; + op.cbSize = sizeof(OPENOPTIONSDIALOG); + op.pszGroup = group; + op.pszPage = page; + op.pszTab = tab; + CallService(MS_OPT_OPENOPTIONS, 0, (LPARAM)&op); +} + +#define DlgReturn(ret){\ + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (ret));\ + return (ret);\ +} + +class ShowMessageData +{ +public: + ShowMessageData(HANDLE _hContact) + :hContact(_hContact) + { + } + + ShowMessageData(HANDLE _hContact, const std::wstring &_str) + :hContact(_hContact), + str(_str) + { + } + + HANDLE hContact; + std::wstring str; +}; + +void __stdcall ShowMessageWindow(void* arg) +{ + ShowMessageData* dt = (ShowMessageData*)arg; + if(dt->str.empty()) + CallService(MS_MSG_SENDMESSAGE, (WPARAM)dt->hContact, 0); + else + CallService(MS_MSG_SENDMESSAGET, (WPARAM)dt->hContact, (LPARAM)dt->str.c_str()); + delete dt; +} + +INT_PTR CALLBACK HistoryWindow::DlgProcHistory(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_GETMINMAXINFO: + ((MINMAXINFO*)lParam)->ptMinTrackSize.x=500; + ((MINMAXINFO*)lParam)->ptMinTrackSize.y=380; + + case WM_SIZE: + { + UTILRESIZEDIALOG urd={0}; + urd.cbSize=sizeof(urd); + urd.hwndDlg=hwndDlg; + urd.hInstance=hInst; + urd.lpTemplate=MAKEINTRESOURCEA(IDD_HISTORY); + urd.lParam=(LPARAM)NULL; + urd.pfnResizer=HistoryWindow::HistoryDlgResizer; + CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd); + ListView_SetColumnWidth(GetDlgItem(hwndDlg,IDC_LIST), 0, LVSCW_AUTOSIZE_USEHEADER); + DlgReturn(TRUE); + } + case WM_COMMAND: + switch ( LOWORD( wParam )) { + case IDOK: + case IDCANCEL: + DestroyWindow(hwndDlg); + DlgReturn(TRUE); + + case IDM_FIND: + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + historyWindow->searcher.Find(); + DlgReturn(TRUE); + } + + case IDM_CONFIG: + { + OPENOPTIONSDIALOG opd = {0}; + opd.cbSize = sizeof(OPENOPTIONSDIALOG); + opd.pszPage = LPGEN("History"); + CallService(MS_OPT_OPENOPTIONS, 0, (LPARAM)&opd); + DlgReturn(TRUE); + } + + case IDM_DELETE: + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + historyWindow->Delete(0); + DlgReturn(TRUE); + } + + case IDC_FIND_TEXT: + if(HIWORD(wParam) == EN_CHANGE) + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + historyWindow->searcher.ClearFind(); + } + + DlgReturn(TRUE); + + case IDC_SHOWHIDE: + { + if(HIWORD( wParam ) == BN_CLICKED) + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + if(Button_GetCheck(GetDlgItem(hwndDlg,IDC_SHOWHIDE)) & BST_CHECKED) + { + SendDlgItemMessage( hwndDlg, IDC_SHOWHIDE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)historyWindow->minusIco); + SendDlgItemMessage( hwndDlg, IDC_SHOWHIDE, BUTTONADDTOOLTIP, (WPARAM)LPGENT("Hide Contacts"), BATF_TCHAR); + historyWindow->isContactList = true; + ShowWindow(GetDlgItem(hwndDlg,IDC_LIST_CONTACTS), SW_SHOW); + ShowWindow(historyWindow->splitterYhWnd, SW_SHOW); + } + else + { + SendDlgItemMessage( hwndDlg, IDC_SHOWHIDE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)historyWindow->plusIco); + SendDlgItemMessage( hwndDlg, IDC_SHOWHIDE, BUTTONADDTOOLTIP, (WPARAM)LPGENT("Show Contacts"), BATF_TCHAR); + historyWindow->isContactList = false; + ShowWindow(GetDlgItem(hwndDlg,IDC_LIST_CONTACTS), SW_HIDE); + ShowWindow(historyWindow->splitterYhWnd, SW_HIDE); + } + + SendMessage(hwndDlg, WM_SIZE, 0, 0); + } + + DlgReturn(TRUE); + } + } + break; + case WM_NOTIFY: + { + LPNMHDR pNmhdr; + + pNmhdr = (LPNMHDR)lParam; + switch(pNmhdr->idFrom) + { + case IDC_LIST_CONTACTS: + if(pNmhdr->code == CLN_LISTREBUILT)// || pNmhdr->code == CLN_CONTACTMOVED || pNmhdr->code == CLN_NEWCONTACT) + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + if(historyWindow != NULL) + { + historyWindow->ReloadContacts(); + } + + DlgReturn(TRUE); + } + else if(pNmhdr->code == CLN_MYSELCHANGED) + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + if(historyWindow->ContactChanged()) + { + MSGFILTER* msgFilter = (MSGFILTER *) lParam; + if(msgFilter->msg == WM_LBUTTONDOWN) + { + SendMessage(pNmhdr->hwndFrom, WM_LBUTTONUP, msgFilter->wParam, msgFilter->lParam); + } + } + + DlgReturn(TRUE); + } + else if(pNmhdr->code == CLN_OPTIONSCHANGED) + { + ResetCList(hwndDlg); + return FALSE; + } + + //fall through + //case IDC_LIST_CONTACTS: + case IDC_SHOWHIDE: + case IDC_FIND_TEXT: + case IDC_EDIT: + if ( pNmhdr->code == EN_LINK ) + { + ClickLink(GetDlgItem(hwndDlg, IDC_EDIT), (ENLINK *) lParam); + return FALSE; + } + else if( pNmhdr->code == EN_SELCHANGE) + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + historyWindow->searcher.ClearFind(); + } + else if(pNmhdr->code == EN_MSGFILTER) + { + MSGFILTER* msgFilter = (MSGFILTER *) lParam; + if (msgFilter->msg == WM_KEYDOWN || msgFilter->msg == WM_SYSKEYDOWN) + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + if(historyWindow->DoHotkey(msgFilter->msg, msgFilter->lParam, msgFilter->wParam, pNmhdr->idFrom)) + DlgReturn(TRUE); + } + else if (msgFilter->msg == WM_RBUTTONDOWN || msgFilter->msg == WM_RBUTTONDBLCLK || msgFilter->msg == WM_NCRBUTTONUP || msgFilter->msg == WM_NCRBUTTONDBLCLK || msgFilter->msg == WM_NCRBUTTONDOWN) + { + DlgReturn(TRUE); + } + else if (msgFilter->msg == WM_RBUTTONUP) + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + POINT clicked; + LPNMITEMACTIVATE nmlv = (LPNMITEMACTIVATE)lParam; + HWND window = historyWindow->editWindow; + POINTL p; + POINT scrool; + LVHITTESTINFO info = {0}; + p.x = clicked.x = info.pt.x = GET_X_LPARAM(msgFilter->lParam); + p.y = clicked.y = info.pt.y = GET_Y_LPARAM(msgFilter->lParam); + ClientToScreen(window, &clicked); + SetFocus(window); + int selChar = SendMessage(window, EM_CHARFROMPOS, 0, (LPARAM)&p); + CHARRANGE chrg; + SendMessage(window,EM_EXGETSEL,0,(LPARAM)&chrg); + SendMessage(window,EM_GETSCROLLPOS,0,(LPARAM)&scrool); + if(selChar < chrg.cpMin || selChar > chrg.cpMax) + { + chrg.cpMin = chrg.cpMax = selChar; + } + + if(chrg.cpMin == chrg.cpMax) + { + CHARRANGE chrgNew; + chrgNew.cpMin = chrg.cpMin; + chrgNew.cpMax = chrg.cpMax + 1; + SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrgNew); + } + CHARFORMAT2 chf; + memset(&chf, 0, sizeof(CHARFORMAT2)); + chf.cbSize = sizeof(CHARFORMAT2); + chf.dwMask = CFM_LINK; + SendMessage(window, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&chf); + if(chrg.cpMin == chrg.cpMax) + SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrg); + + HMENU hPopupMenu = CreatePopupMenu(); + if(hPopupMenu != NULL) + { + if(chf.dwEffects & CFE_LINK) + { + AppendMenu(hPopupMenu, MF_STRING, IDM_OPENNEW, TranslateT("Open in &new window")); + AppendMenu(hPopupMenu, MF_STRING, IDM_OPENEXISTING, TranslateT("&Open in existing window")); + AppendMenu(hPopupMenu, MF_STRING, IDM_COPYLINK, TranslateT("&Copy link")); + } + else + { + AppendMenu(hPopupMenu, MF_STRING, IDM_COPY, TranslateT("Copy")); + AppendMenu(hPopupMenu, MF_STRING, IDM_DELETE, TranslateT("Delete")); + AppendMenu(hPopupMenu, MFT_SEPARATOR, 0, NULL); + AppendMenu(hPopupMenu, MF_STRING, IDM_MESSAGE, TranslateT("Send Message")); + AppendMenu(hPopupMenu, MF_STRING, IDM_QUOTE, TranslateT("Reply &Quoted")); + AppendMenu(hPopupMenu, MF_STRING, IDM_DELETEGROUP, TranslateT("Delete Group")); + AppendMenu(hPopupMenu, MF_STRING, IDM_DELETEUSER, TranslateT("Delete All User History")); + } + + int selected = TrackPopupMenu(hPopupMenu, TPM_RETURNCMD, clicked.x, clicked.y, 0, hwndDlg, 0); + switch (selected) + { + case IDM_COPY: + { + if(chrg.cpMax == chrg.cpMin && historyWindow->currentGroup.size() > 0) + { + size_t start = 0; + while(start < historyWindow->currentGroup.size() && chrg.cpMin >= historyWindow->currentGroup[start].endPos) ++start; + if(start < historyWindow->currentGroup.size()) + { + CHARRANGE chrgNew; + chrgNew.cpMin = 0; + if(start > 0) + chrgNew.cpMin = historyWindow->currentGroup[start - 1].endPos; + chrgNew.cpMax = historyWindow->currentGroup[start].endPos; + SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrgNew); + SendMessage(window,WM_COPY,0,0); + SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrg); + } + } + else + { + SendMessage(window,WM_COPY,0,0); + } + } + break; + case IDM_MESSAGE: + //CallService(MS_MSG_SENDMESSAGE, (WPARAM)historyWindow->hContact, 0); + CallFunctionAsync(ShowMessageWindow, new ShowMessageData(historyWindow->hContact)); + break; + case IDM_QUOTE: + { + if(historyWindow->currentGroup.size() > 0) + { + std::wstring quote; + if(chrg.cpMax == chrg.cpMin) + { + size_t start = 0; + while(start < historyWindow->currentGroup.size() && chrg.cpMin >= historyWindow->currentGroup[start].endPos) ++start; + if(start < historyWindow->currentGroup.size()) + { + historyWindow->FormatQuote(quote, historyWindow->currentGroup[start], historyWindow->currentGroup[start].description); + } + } + else + { + size_t start = 0; + while(start < historyWindow->currentGroup.size() && chrg.cpMin >= historyWindow->currentGroup[start].endPos) ++start; + size_t end = 0; + while(end < historyWindow->currentGroup.size() && chrg.cpMax > historyWindow->currentGroup[end].endPos) ++end; + if(end >= historyWindow->currentGroup.size()) + end = historyWindow->currentGroup.size() - 1; + if(start == end && start < historyWindow->currentGroup.size()) + { + int iStart = historyWindow->currentGroup[start].startPos; + if(chrg.cpMin > iStart) + iStart = chrg.cpMin; + int iEnd = historyWindow->currentGroup[start].endPos; + if(chrg.cpMax < iEnd) + iEnd = chrg.cpMax; + if(iEnd > iStart) + { + TEXTRANGE tr; + tr.chrg.cpMin = iStart; + tr.chrg.cpMax = iEnd; + tr.lpstrText = new TCHAR[iEnd - iStart + 1]; + SendMessage(historyWindow->editWindow, EM_GETTEXTRANGE, 0, (LPARAM) & tr); + historyWindow->FormatQuote(quote, historyWindow->currentGroup[start], tr.lpstrText); + delete [] tr.lpstrText; + } + } + else + { + while(start <= end) + { + historyWindow->FormatQuote(quote, historyWindow->currentGroup[start], historyWindow->currentGroup[start].description); + ++start; + } + } + } + + if(!quote.empty()) + { + CallFunctionAsync(ShowMessageWindow, new ShowMessageData(historyWindow->hContact, quote)); + } + } + } + break; + case IDM_DELETE: + historyWindow->Delete(0); + break; + case IDM_DELETEGROUP: + historyWindow->Delete(1); + break; + case IDM_DELETEUSER: + historyWindow->Delete(2); + break; + case IDM_OPENNEW: + case IDM_OPENEXISTING: + case IDM_COPYLINK: + { + int start = chrg.cpMin, end = chrg.cpMin; + CHARRANGE chrgNew; + chrgNew.cpMin = start-1; + chrgNew.cpMax = start; + do + { + memset(&chf, 0, sizeof(CHARFORMAT2)); + chf.cbSize = sizeof(CHARFORMAT2); + chf.dwMask = CFM_LINK; + int sel = SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrgNew); + if(sel != chrgNew.cpMax) + break; + SendMessage(window, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&chf); + --chrgNew.cpMin; + --chrgNew.cpMax; + --start; + } while(start >= 0 && chf.dwEffects & CFE_LINK); + + ++start; + chrgNew.cpMin = end; + chrgNew.cpMax = end + 1; + do + { + memset(&chf, 0, sizeof(CHARFORMAT2)); + chf.cbSize = sizeof(CHARFORMAT2); + chf.dwMask = CFM_LINK; + int sel = SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrgNew); + if(sel != chrgNew.cpMax) + break; + SendMessage(window, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&chf); + ++chrgNew.cpMin; + ++chrgNew.cpMax; + ++end; + } while(chf.dwEffects & CFE_LINK); + + --end; + if(selected == IDM_COPYLINK) + { + chrgNew.cpMin = start; + chrgNew.cpMax = end; + SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrgNew); + SendMessage(window,WM_COPY,0,0); + SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrg); + } + else + { + ENLINK link; + link.chrg.cpMin = start; + link.chrg.cpMax = end; + link.msg = WM_LBUTTONUP; + link.nmhdr.code = selected; + SendMessage(window,EM_EXSETSEL,0,(LPARAM)&chrg); + ClickLink(window, &link); + } + } + break; + } + + DestroyMenu(hPopupMenu); + } + SendMessage(window,EM_SETSCROLLPOS,0,(LPARAM)&scrool); + DlgReturn(TRUE); + } + } + break; + case IDC_LIST: + if( pNmhdr->code == LVN_ITEMCHANGED) + { + NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam; + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + if((nmlv->uChanged & LVIF_STATE) && (nmlv->uNewState & LVIS_SELECTED) && historyWindow->selected != nmlv->iItem && nmlv->iItem >= 0) + { + historyWindow->SelectEventGroup(nmlv->iItem); + DlgReturn(TRUE); + } + } + else if( pNmhdr->code == LVN_KEYDOWN) + { + LPNMLVKEYDOWN nmlv = (LPNMLVKEYDOWN)lParam; + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + if(historyWindow->DoHotkey(WM_KEYDOWN, 0, nmlv->wVKey, IDC_LIST)) + DlgReturn(TRUE); + } + else if(pNmhdr->code == NM_RCLICK) + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + POINT clicked; + LPNMITEMACTIVATE nmlv = (LPNMITEMACTIVATE)lParam; + HWND window = historyWindow->listWindow; + LVHITTESTINFO info = {0}; + clicked.x = info.pt.x = nmlv->ptAction.x; + clicked.y = info.pt.y = nmlv->ptAction.y; + ClientToScreen(window, &clicked); + int newSel = SendMessage(window, LVM_SUBITEMHITTEST, 0, (LPARAM)&info); + int curSel = historyWindow->selected; + + if(newSel >= 0) + { + HMENU hPopupMenu = CreatePopupMenu(); + if(hPopupMenu != NULL) + { + AppendMenu(hPopupMenu, MF_STRING, IDM_COPY, TranslateT("Copy")); + AppendMenu(hPopupMenu, MF_STRING, IDM_DELETEGROUP, TranslateT("Delete Group")); + AppendMenu(hPopupMenu, MFT_SEPARATOR, 0, NULL); + AppendMenu(hPopupMenu, MF_STRING, IDM_MESSAGE, TranslateT("Send Message")); + AppendMenu(hPopupMenu, MF_STRING, IDM_DELETEUSER, TranslateT("Delete All User History")); + + int selected = TrackPopupMenu(hPopupMenu, TPM_RETURNCMD, clicked.x, clicked.y, 0, hwndDlg, 0); + switch (selected) + { + case IDM_COPY: + { + CHARRANGE chrg; + SendMessage(historyWindow->editWindow,EM_EXGETSEL,0,(LPARAM)&chrg); + CHARRANGE chrgNew; + chrgNew.cpMin = 0; + chrgNew.cpMax = -1; + SendMessage(historyWindow->editWindow,EM_EXSETSEL,0,(LPARAM)&chrgNew); + SendMessage(historyWindow->editWindow,WM_COPY,0,0); + SendMessage(historyWindow->editWindow,EM_EXSETSEL,0,(LPARAM)&chrg); + } + break; + case IDM_MESSAGE: + CallService(MS_MSG_SENDMESSAGE, (WPARAM)historyWindow->hContact, 0); + break; + case IDM_DELETEGROUP: + historyWindow->Delete(1); + break; + case IDM_DELETEUSER: + historyWindow->Delete(2); + break; + } + + DestroyMenu(hPopupMenu); + } + } + + DlgReturn(TRUE); + } + + break; + case IDC_TOOLBAR: + if( pNmhdr->code == TBN_DROPDOWN) + { + LPNMTOOLBAR lpnmTB= (LPNMTOOLBAR)lParam; + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + if(lpnmTB->iItem == IDM_FIND) + { + historyWindow->FindToolbarClicked(lpnmTB); + } + else if(lpnmTB->iItem == IDM_CONFIG) + { + historyWindow->ConfigToolbarClicked(lpnmTB); + } + else if(lpnmTB->iItem == IDM_DELETE) + { + historyWindow->DeleteToolbarClicked(lpnmTB); + } + + DlgReturn(TBDDRET_DEFAULT); + } + else if( pNmhdr->code == NM_KEYDOWN) + { + LPNMKEY nmlv = (LPNMKEY)lParam; + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + if(historyWindow->DoHotkey(WM_KEYDOWN, 0, nmlv->nVKey, IDC_TOOLBAR)) + DlgReturn(TRUE); + } + break; + } + break; + } + case WM_CTLCOLORDLG: + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + DlgReturn((LONG_PTR)historyWindow->bkBrush); + } + case WM_CTLCOLORSTATIC: + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + HWND curhWnd = (HWND)lParam; + if(historyWindow->splitterXhWnd == curhWnd || historyWindow->splitterYhWnd == curhWnd) + { + DlgReturn((LONG_PTR)historyWindow->bkBrush); + } + + break; + } + case WM_CTLCOLOREDIT: + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + HWND curhWnd = (HWND)lParam; + if(historyWindow->findWindow == curhWnd) + { + HDC edithdc = (HDC)wParam; + LOGFONT font; + SetTextColor(edithdc, Options::instance->GetFont(Options::Find, &font)); + SetBkColor(edithdc, Options::instance->GetColor(Options::FindBackground)); + DlgReturn((LONG_PTR)historyWindow->bkFindBrush); + } + + break; + } + case DM_SPLITTERMOVED: + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + historyWindow->SplitterMoved((HWND)lParam, wParam, true); + break; + } + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + HistoryWindow* historyWindow = (HistoryWindow*)lParam; + historyWindow->hWnd = hwndDlg; + historyWindow->isWnd = true; + SetWindowLongPtr(hwndDlg,GWLP_USERDATA,(LONG_PTR)lParam); + historyWindow->Initialise(); + } + DlgReturn(TRUE); + + case DM_HREBUILD: + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + if(!historyWindow->isLoading) + { + historyWindow->isLoading = true; + historyWindow->ReloadContacts(); + mir_forkthread(HistoryWindow::FillHistoryThread, historyWindow); + } + } + DlgReturn(TRUE); + + case WM_DESTROY: + { + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); + historyWindow->Destroy(); + } + DlgReturn(TRUE); + } + return FALSE; +} + +void HistoryWindow::Initialise() +{ + splitterXhWnd = GetDlgItem(hWnd, IDC_SPLITTER); + splitterYhWnd = GetDlgItem(hWnd, IDC_SPLITTERV); + OldSplitterProc = (WNDPROC)SetWindowLongPtr(splitterXhWnd, GWLP_WNDPROC, (LONG_PTR) SplitterSubclassProc); + SetWindowLongPtr(splitterYhWnd, GWLP_WNDPROC, (LONG_PTR) SplitterSubclassProc); + + editWindow = GetDlgItem(hWnd, IDC_EDIT); + findWindow = GetDlgItem(hWnd, IDC_FIND_TEXT); + toolbarWindow = GetDlgItem(hWnd, IDC_TOOLBAR); + listWindow = GetDlgItem(hWnd, IDC_LIST); + + RECT rc; + POINT pt; + GetWindowRect(splitterXhWnd, &rc); + pt.y = (rc.top + rc.bottom) / 2; + pt.x = 0; + ScreenToClient(hWnd, &pt); + splitterOrgY = pt.y; + splitterY = pt.y; + GetWindowRect(splitterYhWnd, &rc); + pt.y = 0; + pt.x = (rc.left + rc.right) / 2; + ScreenToClient(hWnd, &pt); + splitterOrgX = pt.x; + splitterX = pt.x; + GetWindowRect(GetDlgItem(hWnd, IDC_LIST_CONTACTS), &rc); + pt.y = rc.top; + pt.x = rc.left; + ScreenToClient(hWnd, &pt); + listOryginalPos = pt.x; + + plusIco = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 1, (LPARAM)hPlusIcon); + minusIco = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 1, (LPARAM)hMinusIcon); + SendDlgItemMessage( hWnd, IDC_SHOWHIDE, BUTTONSETASPUSHBTN, TRUE, 0 ); + SendDlgItemMessage( hWnd, IDC_SHOWHIDE, BUTTONSETASFLATBTN, TRUE, 0 ); + if(hContact == NULL || Options::instance->showContacts) + { + SendDlgItemMessage( hWnd, IDC_SHOWHIDE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)minusIco); + SendDlgItemMessage( hWnd, IDC_SHOWHIDE, BUTTONADDTOOLTIP, (WPARAM)LPGENT("Hide Contacts"), BATF_TCHAR); + Button_SetCheck(GetDlgItem(hWnd,IDC_SHOWHIDE), BST_CHECKED); + isContactList = true; + } + else + { + SendDlgItemMessage( hWnd, IDC_SHOWHIDE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)plusIco); + SendDlgItemMessage( hWnd, IDC_SHOWHIDE, BUTTONADDTOOLTIP, (WPARAM)LPGENT("Show Contacts"), BATF_TCHAR); + Button_SetCheck(GetDlgItem(hWnd,IDC_SHOWHIDE), BST_UNCHECKED); + ShowWindow(GetDlgItem(hWnd,IDC_LIST_CONTACTS), SW_HIDE); + ShowWindow(splitterYhWnd, SW_HIDE); + isContactList = false; + } + RegisterHotkeyControl(GetDlgItem(hWnd, IDC_SHOWHIDE)); + RegisterHotkeyControl(GetDlgItem(hWnd, IDC_LIST_CONTACTS)); + + ResetCList(hWnd); + + RestorePos(); + SendMessage(hWnd, WM_SETICON, ICON_BIG, ( LPARAM )LoadSkinnedIconBig( SKINICON_OTHER_HISTORY )); + SendMessage(hWnd, WM_SETICON, ICON_SMALL, ( LPARAM )LoadSkinnedIcon( SKINICON_OTHER_HISTORY )); + SendMessage(editWindow,EM_AUTOURLDETECT,TRUE,0); + SendMessage(editWindow,EM_SETEVENTMASK,0,ENM_LINK | ENM_SELCHANGE | ENM_KEYEVENTS | ENM_MOUSEEVENTS); + SendMessage(editWindow,EM_SETEDITSTYLE,SES_EXTENDBACKCOLOR,SES_EXTENDBACKCOLOR); + + himlSmall = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 2, 2); + himlNone = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 2, 2); + ImageList_SetIconSize(himlNone, 0, 16); + if(himlSmall) + { + allIconNumber = iconsNum + 3; + eventIcoms = new HICON[allIconNumber]; + for(int i = 0; i < iconsNum; ++i) + { + eventIcoms[i] = hEventIcons[i] == NULL ? NULL : (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hEventIcons[i]); + ImageList_AddIcon(himlSmall, eventIcoms[i]); + } + + int id = iconsNum; + eventIcoms[id] = LoadSkinnedIcon(SKINICON_EVENT_FILE); + ImageList_AddIcon(himlSmall, eventIcoms[id]); + + eventIcoms[++id] = LoadSkinnedIcon(SKINICON_EVENT_URL); + ImageList_AddIcon(himlSmall, eventIcoms[id]); + + eventIcoms[++id] = LoadSkinnedIcon(SKINICON_OTHER_WINDOWS); + ImageList_AddIcon(himlSmall, eventIcoms[id]); + + if((isGroupImages = Options::instance->groupShowEvents) != false) + ListView_SetImageList(listWindow, himlSmall, LVSIL_SMALL); + } + + bkBrush = CreateSolidBrush(Options::instance->GetColor(Options::WindowBackground)); + bkFindBrush = CreateSolidBrush(Options::instance->GetColor(Options::FindBackground)); + + LVCOLUMN col = {0}; + col.mask = LVCF_WIDTH | LVCF_TEXT; + col.cx = 470; + col.pszText = _T(""); + ListView_InsertColumn(listWindow, 0, &col); + ListView_SetColumnWidth(listWindow, 0, LVSCW_AUTOSIZE_USEHEADER); + ListView_SetExtendedListViewStyleEx(listWindow, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); + COLORREF bkColor = Options::instance->GetColor(Options::GroupListBackground); + ListView_SetBkColor(listWindow, bkColor); + ListView_SetTextBkColor(listWindow, bkColor); + LOGFONT font; + ListView_SetTextColor(listWindow, Options::instance->GetFont(Options::GroupList, &font)); + + Edit_LimitText(findWindow, 100); + RegisterHotkeyControl(findWindow); + + HIMAGELIST himlButtons = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 3, 3); + if(himlButtons) + { + findNextIco = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hFindNextIcon); + ImageList_AddIcon(himlButtons, findNextIco); + findPrevIco = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hFindPrevIcon); + ImageList_AddIcon(himlButtons, findPrevIco); + configIco = LoadSkinnedIcon(SKINICON_OTHER_OPTIONS); + ImageList_AddIcon(himlButtons, configIco); + deleteIco = LoadSkinnedIcon(SKINICON_OTHER_DELETE); + ImageList_AddIcon(himlButtons, deleteIco); + + // Set the image list. + SendMessage(toolbarWindow, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)himlButtons); + + // Load the button images. + SendMessage(toolbarWindow, TB_LOADIMAGES, (WPARAM)IDB_STD_SMALL_COLOR, (LPARAM)HINST_COMMCTRL); + } + + TBBUTTON tbButtons[] = + { + { 0, IDM_FIND, TBSTATE_ENABLED, BTNS_DROPDOWN, {0}, 0, (INT_PTR)TranslateT("Find Next") }, + { 3, IDM_DELETE, TBSTATE_ENABLED, BTNS_DROPDOWN, {0}, 0, (INT_PTR)TranslateT("Delete")}, + { 2, IDM_CONFIG, TBSTATE_ENABLED, BTNS_DROPDOWN, {0}, 0, (INT_PTR)TranslateT("Options")}, + }; + SendMessage(toolbarWindow, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); + SendMessage(toolbarWindow, TB_ADDBUTTONS, (WPARAM)SIZEOF(tbButtons), (LPARAM)&tbButtons); + SendMessage(toolbarWindow, TB_SETBUTTONSIZE, 0, MAKELPARAM(16, 16)); + SendMessage(toolbarWindow, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS); + SendMessage(toolbarWindow, TB_SETMAXTEXTROWS, 0, 0); + + SetDefFilter(Options::instance->defFilter); + + SendMessage(hWnd, DM_SETDEFID, IDM_FIND, 0); + SendMessage(hWnd, WM_SIZE, 0, 0); + SendMessage(hWnd,DM_HREBUILD,0,0); + isDestroyed = false; +} + +void HistoryWindow::Destroy() +{ + HICON hIcon = (HICON)SendMessage(hWnd, WM_SETICON, ICON_BIG, 0); + CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0); + + hIcon = (HICON)SendMessage(hWnd, WM_SETICON, ICON_SMALL, 0); + CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0); + + UnregisterHotkeyControl(GetDlgItem(hWnd, IDC_SHOWHIDE)); + UnregisterHotkeyControl(GetDlgItem(hWnd, IDC_LIST_CONTACTS)); + UnregisterHotkeyControl(findWindow); + + isDestroyed = true; + HistoryWindow::Close(this); +} + +void HistoryWindow::SplitterMoved(HWND splitter, LONG pos, bool screenPos) +{ + POINT pt; + RECT rc1; + RECT rc2; + POINT pt1; + POINT pt2; + + if(splitter == splitterXhWnd) + { + GetWindowRect(listWindow, &rc1); + GetWindowRect(editWindow, &rc2); + pt.x = 0; + pt.y = pos; + pt1.x = rc1.left; + pt1.y = rc1.top; + pt2.x = rc2.right; + pt2.y = rc2.bottom; + if(screenPos) + ScreenToClient(hWnd, &pt); + ScreenToClient(hWnd, &pt1); + ScreenToClient(hWnd, &pt2); + if ((pt.y >= pt1.y + MIN_PANELHEIGHT) && (pt.y < pt2.y - MIN_PANELHEIGHT)) + { + splitterY = pt.y; + if(!screenPos) + SendMessage(hWnd, WM_SIZE, 0, 0); + //if(M->isAero()) + // InvalidateRect(GetParent(hwndDlg), NULL, FALSE); + } + } + else + { + GetWindowRect(GetDlgItem(hWnd, IDC_LIST_CONTACTS), &rc1); + GetWindowRect(listWindow, &rc2); + pt.x = pos; + pt.y = 0; + pt1.x = rc1.left; + pt1.y = rc1.top; + pt2.x = rc2.right; + pt2.y = rc2.bottom; + if(screenPos) + ScreenToClient(hWnd, &pt); + ScreenToClient(hWnd, &pt1); + ScreenToClient(hWnd, &pt2); + if ((pt.x >= pt1.x + MIN_PANELHEIGHT) && (pt.x < pt2.x - MIN_PANELHEIGHT)) + { + splitterX = pt.x; + if(!screenPos) + SendMessage(hWnd, WM_SIZE, 0, 0); + //if(M->isAero()) + // InvalidateRect(GetParent(hwndDlg), NULL, FALSE); + } + } +} + +int HistoryWindow::HistoryDlgResizer(HWND hwnd, LPARAM, UTILRESIZECONTROL *urc) +{ + HistoryWindow* historyWindow =(HistoryWindow*)GetWindowLongPtr(hwnd,GWLP_USERDATA); + switch(urc->wId) { + case IDC_LIST: + { + urc->rcItem.bottom += historyWindow->splitterY - historyWindow->splitterOrgY; + urc->rcItem.left += historyWindow->splitterX - historyWindow->splitterOrgX; + if(!historyWindow->isContactList) + urc->rcItem.left = historyWindow->listOryginalPos; + return RD_ANCHORX_WIDTH|RD_ANCHORY_TOP; + } + case IDC_LIST_CONTACTS: + { + urc->rcItem.right += historyWindow->splitterX - historyWindow->splitterOrgX; + return RD_ANCHORX_LEFT|RD_ANCHORY_HEIGHT; + } + case IDC_SPLITTER: + { + urc->rcItem.top += historyWindow->splitterY - historyWindow->splitterOrgY; + urc->rcItem.bottom += historyWindow->splitterY - historyWindow->splitterOrgY; + urc->rcItem.left += historyWindow->splitterX - historyWindow->splitterOrgX; + if(!historyWindow->isContactList) + urc->rcItem.left = 0; + return RD_ANCHORX_WIDTH|RD_ANCHORY_TOP; + } + case IDC_SPLITTERV: + { + urc->rcItem.left += historyWindow->splitterX - historyWindow->splitterOrgX; + urc->rcItem.right += historyWindow->splitterX - historyWindow->splitterOrgX; + return RD_ANCHORX_LEFT|RD_ANCHORY_HEIGHT; + } + case IDC_EDIT: + { + urc->rcItem.top += historyWindow->splitterY - historyWindow->splitterOrgY; + urc->rcItem.left += historyWindow->splitterX - historyWindow->splitterOrgX; + if(!historyWindow->isContactList) + urc->rcItem.left = historyWindow->listOryginalPos; + return RD_ANCHORX_WIDTH|RD_ANCHORY_HEIGHT; + } + case IDC_FIND_TEXT: + return RD_ANCHORX_WIDTH|RD_ANCHORY_TOP; + case IDC_SHOWHIDE: + return RD_ANCHORX_LEFT|RD_ANCHORY_TOP; + case IDC_TOOLBAR: + return RD_ANCHORX_RIGHT|RD_ANCHORY_TOP; + } + return RD_ANCHORX_LEFT|RD_ANCHORY_TOP; +} + +void HistoryWindow::FillHistoryThread(void* param) +{ + HistoryWindow *hInfo = ( HistoryWindow* )param; + HWND hwndList = hInfo->listWindow; + ListView_DeleteAllItems(hwndList); + hInfo->SelectEventGroup(-1); + hInfo->EnableWindows(FALSE); + bool isNewOnTop = Options::instance->groupNewOnTop; + + hInfo->RefreshEventList(); + + LVITEM item = {0}; + item.mask = LVIF_STATE; + item.iItem = 0; + item.state = LVIS_SELECTED; + item.stateMask = LVIS_SELECTED; + if(!isNewOnTop) + { + item.iItem = ListView_GetItemCount(hwndList) - 1; + if(item.iItem < 0) + item.iItem = 0; + } + + ListView_SetItem(hwndList, &item); + ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE_USEHEADER); + ListView_EnsureVisible(hwndList, item.iItem, FALSE); + hInfo->EnableWindows(TRUE); + SetFocus(hwndList); +} + +void HistoryWindow::AddGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText, int ico) +{ + TCHAR msg[256]; + msg[0] = 0; + if(Options::instance->groupShowTime) + { + _tcscpy_s(msg, time.c_str()); + } + if(Options::instance->groupShowName) + { + if(msg[0] != 0) + _tcscat_s(msg, _T(" ")); + _tcscat_s(msg, user.c_str()); + } + + if(Options::instance->groupShowMessage) + { + if(msg[0] != 0) + _tcscat_s(msg, _T(" ")); + _tcscat_s(msg, eventText.c_str()); + } + + LVITEM item = {0}; + item.mask = LVIF_TEXT | LVIF_IMAGE; + item.iItem = MAXINT; + item.pszText = msg; + item.iImage = ico; + ListView_InsertItem(listWindow, &item); +} + +void HistoryWindow::ReplaceIcons(HWND hwndDlg, int selStart, BOOL isSent) +{ + if(g_SmileyAddAvail) + { + CHARRANGE sel; + SMADD_RICHEDIT3 smadd = {0}; + + sel.cpMin = selStart; + sel.cpMax = -1; + + smadd.cbSize = sizeof(smadd); + smadd.hwndRichEditControl = hwndDlg; + smadd.Protocolname = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + smadd.hContact = hContact; + smadd.flags = isSent ? SAFLRE_OUTGOING : 0; + if (selStart > 0) + smadd.rangeToReplace = &sel; + CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&smadd); + } +} + +void SetFontFromOptions(ITextFont *TextFont, int caps, Options::Fonts fontId) +{ + COLORREF fontColor; + LOGFONT font; + fontColor = Options::instance->GetFont(fontId, &font); + BSTR bstrFont = SysAllocString(font.lfFaceName); + TextFont->SetName(bstrFont); + SysFreeString(bstrFont); + TextFont->SetForeColor(fontColor); + TextFont->SetWeight(font.lfWeight); + font.lfHeight = (font.lfHeight * 72) / caps; + TextFont->SetSize(font.lfHeight < 0 ? -font.lfHeight : font.lfHeight); + TextFont->SetItalic(font.lfItalic ? tomTrue : tomFalse); + TextFont->SetItalic(font.lfUnderline ? tomTrue : tomFalse); + TextFont->SetItalic(font.lfStrikeOut ? tomTrue : tomFalse); +} + +void HistoryWindow::SelectEventGroup(int sel) +{ + SendMessage(editWindow, WM_SETTEXT, 0, (LPARAM)_T("")); + currentGroup.clear(); + selected = sel; + if(sel < 0 || sel >= (int)eventList.size()) + return; + + TCHAR _str[MAXSELECTSTR + 8]; // for safety reason + TCHAR *str = _str + sizeof(int)/sizeof(TCHAR); + BSTR pStr = str; + unsigned int *strLen = (unsigned int*)_str; + str[0] = 0; + tm lastTime; + bool isFirst = true; + bool lastMe = false; + long startAt, endAt; + long cnt; + std::wstring strStl; + IRichEditOle* RichEditOle; + EventData data; + if (SendMessage(editWindow, EM_GETOLEINTERFACE, 0, (LPARAM)&RichEditOle) == 0) + return; + ITextDocument* TextDocument; + if (RichEditOle->QueryInterface(IID_ITextDocument, (void**)&TextDocument) != S_OK) + { + RichEditOle->Release(); + return; + } + ITextSelection* TextSelection; + ITextFont *TextFont; + SendMessage(editWindow, EM_SETREADONLY, FALSE, 0); + TextDocument->Freeze(&cnt); + TextDocument->GetSelection(&TextSelection); + HDC hDC = GetDC(NULL); + int caps = GetDeviceCaps(hDC, LOGPIXELSY); + std::deque revDeq; + std::deque& deq = eventList[sel]; + if(Options::instance->messagesNewOnTop) + { + revDeq.insert(revDeq.begin(), deq.rbegin(), deq.rend()); + deq = revDeq; + } + COLORREF backColor = GetSysColor(COLOR_WINDOW); + for(std::deque::iterator it = deq.begin(); it != deq.end(); ++it) + { + EventIndex hDbEvent = *it; + if(GetEventData(hDbEvent, data)) + { + bool isUser = Options::instance->messagesShowName && (isFirst || (!lastMe && data.isMe) || (lastMe && !data.isMe)); + lastMe = data.isMe; + backColor = Options::instance->GetColor(lastMe ? Options::OutBackground : Options::InBackground); + if(Options::instance->messagesShowEvents) + { + str[0] = _T('>'); + str[1] = 0; + *strLen = 1 * sizeof(TCHAR); + TextSelection->SetStart(MAXLONG); + TextSelection->GetFont(&TextFont); + TextFont->SetBackColor(backColor); + TextSelection->SetText(pStr); + TextFont->Release(); + int imId; + HICON ico; + if(GetEventIcon(lastMe, data.eventType, imId)) + { + ico = eventIcoms[imId]; + } + else + { + ico = GetEventCoreIcon(hDbEvent); + if(ico == NULL) + { + ico = eventIcoms[imId]; + } + } + + ImageDataObject::InsertIcon(RichEditOle, ico, backColor, 16, 16); + } + + TCHAR* formatDate = Options::instance->messagesShowSec ? (isUser ? _T("d s ") : _T("d s\n")) : (isUser ? _T("d t ") : _T("d t\n")); + if(!Options::instance->messagesShowDate) + { + if(isFirst) + { + isFirst = false; + formatDate = Options::instance->messagesShowSec ? (isUser ? _T("s ") : _T("s\n")) : (isUser ? _T("t ") : _T("t\n")); + time_t tt = data.timestamp; + localtime_s(&lastTime, &tt); + } + else + { + time_t tt = data.timestamp; + tm t; + localtime_s(&t, &tt); + if(lastTime.tm_yday == t.tm_yday && lastTime.tm_year == t.tm_year) + formatDate = Options::instance->messagesShowSec ? (isUser ? _T("s ") : _T("s\n")) : (isUser ? _T("t ") : _T("t\n")); + } + } + + tmi.printTimeStamp(NULL, data.timestamp, formatDate, str , MAXSELECTSTR, 0); + *strLen = (unsigned int)_tcslen(str) * sizeof(TCHAR); + TextSelection->SetStart(MAXLONG); + TextSelection->GetFont(&TextFont); + SetFontFromOptions(TextFont, caps, lastMe ? Options::OutTimestamp : Options::InTimestamp); + TextFont->SetBackColor(backColor); + TextSelection->SetText(pStr); + TextFont->Release(); + + if(isUser) + { + if(lastMe) + mir_sntprintf( str, MAXSELECTSTR, _T("%s\n"), myName ); + else + mir_sntprintf( str, MAXSELECTSTR, _T("%s\n"), contactName ); + *strLen = (unsigned int)_tcslen(str) * sizeof(TCHAR); + TextSelection->SetStart(MAXLONG); + TextSelection->GetFont(&TextFont); + SetFontFromOptions(TextFont, caps, lastMe ? Options::OutName : Options::InName); + TextSelection->SetText(pStr); + TextFont->Release(); + } + + GetEventMessage(hDbEvent, str); + strStl = str; + size_t i = strStl.length(); + if(i + 1 >= MAXSELECTSTR) + continue; + str[i++] = _T('\n'); + str[i] = 0; + *strLen = (unsigned int)i * sizeof(TCHAR); + TextSelection->SetStart(MAXLONG); + TextSelection->GetFont(&TextFont); + SetFontFromOptions(TextFont, caps, lastMe ? Options::OutMessages : Options::InMessages); + TextFont->SetBackColor(backColor); + TextSelection->GetStart(&startAt); + TextSelection->SetText(pStr); + TextFont->Release(); + + if(Options::instance->messagesUseSmileys) + ReplaceIcons(editWindow, startAt, lastMe); + TextSelection->SetStart(MAXLONG); + TextSelection->GetStart(&endAt); + currentGroup.push_back(MessageData(strStl, startAt, endAt, lastMe, data.timestamp)); + } + } + + TextSelection->SetRange(0, 0); + TextSelection->Release(); + TextDocument->Unfreeze(&cnt); + TextDocument->Release(); + RichEditOle->Release(); + SendMessage(editWindow, EM_SETREADONLY, TRUE, 0); + SendMessage(editWindow,EM_SETBKGNDCOLOR,0, backColor); + if (cnt == 0) + { + UpdateWindow(editWindow); + } +} + +LRESULT CALLBACK HistoryWindow::SplitterSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hwndParent = GetParent(hwnd); + HistoryWindow *dat = (HistoryWindow*)GetWindowLongPtr(hwndParent, GWLP_USERDATA); + if(dat == NULL || dat->isDestroyed) + return FALSE; + + switch (msg) { + case WM_NCHITTEST: + return HTCLIENT; + case WM_SETCURSOR: { + RECT rc; + GetClientRect(hwnd, &rc); + SetCursor(rc.right > rc.bottom ? hCurSplitNS : hCurSplitWE); + return TRUE; + } + case WM_LBUTTONDOWN: { + SetCapture(hwnd); + return 0; + } + case WM_MOUSEMOVE: + if (GetCapture() == hwnd) { + RECT rc; + GetClientRect(hwnd, &rc); + SendMessage(hwndParent, DM_SPLITTERMOVED, rc.right > rc.bottom ? (short) HIWORD(GetMessagePos()) + rc.bottom / 2 : (short) LOWORD(GetMessagePos()) + rc.right / 2, (LPARAM) hwnd); + } + return 0; + case WM_ERASEBKGND: + return(1); + case WM_LBUTTONUP: { + HWND hwndCapture = GetCapture(); + + ReleaseCapture(); + SendMessage(hwndParent, WM_SIZE, 0, 0); + RedrawWindow(hwndParent, NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW); + return 0; + } + } + return CallWindowProc(dat->OldSplitterProc, hwnd, msg, wParam, lParam); +} + +void HistoryWindow::EnableWindows(BOOL enable) +{ + EnableWindow(GetDlgItem(hWnd,IDC_LIST_CONTACTS), enable); + EnableWindow(listWindow, enable); + EnableWindow(findWindow, enable); + EnableWindow(toolbarWindow, enable); + isLoading = !enable; +} + +void HistoryWindow::ReloadContacts() +{ + HWND contactList = GetDlgItem(hWnd,IDC_LIST_CONTACTS); + if(EventList::GetContactMessageNumber(NULL)) + { + if(hSystem == NULL) + { + CLCINFOITEM cii = { 0 }; + cii.cbSize = sizeof(cii); + cii.flags = CLCIIF_GROUPFONT | CLCIIF_BELOWCONTACTS; + cii.pszText = TranslateT("System"); + hSystem = (HANDLE) SendMessage(contactList, CLM_ADDINFOITEM, 0, (LPARAM) & cii); + } + } + else + { + if(hSystem != NULL) + { + SendMessage(contactList, CLM_DELETEITEM, (WPARAM)hSystem, 0); + hSystem = NULL; + } + } + + HANDLE _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while(_hContact) + { + if(EventList::GetContactMessageNumber(_hContact) && (metaContactProto == NULL || DBGetContactSettingByte(_hContact, metaContactProto, "IsSubcontact", 0) == 0)) + { + HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); + if(hItem == NULL) + { + SendMessage(contactList, CLM_ADDCONTACT, (WPARAM)_hContact, 0); + } + } + else + { + HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); + if(hItem != NULL) + { + SendMessage(contactList, CLM_DELETEITEM, (WPARAM)_hContact, 0); + } + } + + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); + } + + if(hContact != NULL) + { + HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)hContact, 0); + if(hItem != NULL) + { + SendMessage(contactList, CLM_ENSUREVISIBLE, (WPARAM)hItem, 0); + SendMessage(contactList, CLM_SELECTITEM, (WPARAM)hItem, 0); + } + } + else if(hSystem != NULL) + { + SendMessage(contactList, CLM_ENSUREVISIBLE, (WPARAM)hSystem, 0); + SendMessage(contactList, CLM_SELECTITEM, (WPARAM)hSystem, 0); + } +} + +bool HistoryWindow::DoHotkey(UINT msg, LPARAM lParam, WPARAM wParam, int window) +{ + MSG message; + message.hwnd = hWnd; + message.message = msg; + message.lParam = lParam; + message.wParam = wParam; + LRESULT mim_hotkey_check = CallService(MS_HOTKEY_CHECK, (WPARAM)&message, (LPARAM)("History")); + switch(mim_hotkey_check) + { + case HISTORY_HK_FIND: + SetFocus(findWindow); + Edit_SetSel(findWindow, 0, -1); + break; + case HISTORY_HK_FINDNEXT: + searcher.ChangeFindDirection(false); + break; + case HISTORY_HK_FINDPREV: + searcher.ChangeFindDirection(true); + break; + case HISTORY_HK_MATCHCASE: + searcher.SetMatchCase(!searcher.IsMatchCase()); + break; + case HISTORY_HK_MATCHWHOLE: + searcher.SetMatchWholeWords(!searcher.IsMatchWholeWords()); + break; + case HISTORY_HK_SHOWCONTACTS: + Button_SetCheck(GetDlgItem(hWnd, IDC_SHOWHIDE), Button_GetCheck(GetDlgItem(hWnd, IDC_SHOWHIDE)) & BST_CHECKED ? BST_UNCHECKED : BST_CHECKED); + SendMessage(hWnd, WM_COMMAND, MAKELONG(IDC_SHOWHIDE, BN_CLICKED), NULL); + break; + case HISTORY_HK_ONLYIN: + searcher.SetOnlyIn(!searcher.IsOnlyIn()); + break; + case HISTORY_HK_ONLYOUT: + searcher.SetOnlyOut(!searcher.IsOnlyOut()); + break; + case HISTORY_HK_ONLYGROUP: + searcher.SetOnlyGroup(!searcher.IsOnlyGroup()); + break; + case HISTORY_HK_ALLCONTACTS: + searcher.SetAllUsers(!searcher.IsAllUsers()); + break; + case HISTORY_HK_EXRHTML: + { + ExportManager exp(hWnd, hContact, GetFilterNr()); + exp.Export(IExport::RichHtml); + } + break; + case HISTORY_HK_EXPHTML: + { + ExportManager exp(hWnd, hContact, GetFilterNr()); + exp.Export(IExport::PlainHtml); + } + break; + case HISTORY_HK_EXTXT: + { + ExportManager exp(hWnd, hContact, GetFilterNr()); + exp.Export(IExport::Txt); + } + break; + case HISTORY_HK_EXBIN: + { + ExportManager exp(hWnd, hContact, GetFilterNr()); + exp.Export(IExport::Binary); + } + break; + case HISTORY_HK_EXDAT: + { + ExportManager exp(hWnd, hContact, GetFilterNr()); + exp.Export(IExport::Dat); + } + break; + case HISTORY_HK_IMPBIN: + { + DoImport(IImport::Binary); + } + break; + case HISTORY_HK_IMPDAT: + { + DoImport(IImport::Dat); + } + break; + case HISTORY_HK_DELETE: + { + int what = window == IDC_EDIT ? 0 : (window == IDC_LIST ? 1 : (window == IDC_LIST_CONTACTS ? 2 : -1)); + Delete(what); + return what != -1; + } + break; + default: + return false; + } + + return true; +} + +void HistoryWindow::RestorePos() +{ + HANDLE contactToLoad = hContact; + if(hContact == NULL) + { + Utils_RestoreWindowPosition(hWnd,NULL,MODULE,"history_"); + contactToLoad = NULL; + } + else if(Utils_RestoreWindowPosition(hWnd,hContact,MODULE,"history_") != 0) + { + Utils_RestoreWindowPosition(hWnd,NULL,MODULE,"history_"); + contactToLoad = NULL; + } + if(DBGetContactSettingByte(contactToLoad, MODULE, "history_ismax", 0)) + { + ShowWindow(hWnd, SW_SHOWMAXIMIZED); + } + + LONG pos = DBGetContactSettingDword(contactToLoad, MODULE, "history_splitterv", 0); + if(pos > 0) + { + SplitterMoved(splitterYhWnd, pos, false); + } + + pos = DBGetContactSettingDword(contactToLoad, MODULE, "history_splitter", 0); + if(pos > 0) + { + SplitterMoved(splitterXhWnd, pos, false); + } +} + +void HistoryWindow::SavePos(bool all) +{ + HANDLE contactToSave = hContact; + if(all) + { + HANDLE _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while(_hContact) + { + DBDeleteContactSetting(_hContact, MODULE, "history_x"); + DBDeleteContactSetting(_hContact, MODULE, "history_y"); + DBDeleteContactSetting(_hContact, MODULE, "history_width"); + DBDeleteContactSetting(_hContact, MODULE, "history_height"); + DBDeleteContactSetting(_hContact, MODULE, "history_ismax"); + DBDeleteContactSetting(_hContact, MODULE, "history_splitterv"); + DBDeleteContactSetting(_hContact, MODULE, "history_splitter"); + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); + } + + contactToSave = NULL; + } + + Utils_SaveWindowPosition(hWnd,contactToSave,MODULE,"history_"); + WINDOWPLACEMENT wp; + wp.length=sizeof(wp); + GetWindowPlacement(hWnd,&wp); + DBWriteContactSettingByte(contactToSave, MODULE, "history_ismax", wp.showCmd == SW_MAXIMIZE ? 1 : 0); + DBWriteContactSettingDword(contactToSave, MODULE, "history_splitterv", splitterX); + DBWriteContactSettingDword(contactToSave, MODULE, "history_splitter", splitterY); +} + +#define DEF_FILTERS_START 50000 +void HistoryWindow::FindToolbarClicked(LPNMTOOLBAR lpnmTB) +{ + RECT rc; + SendMessage(lpnmTB->hdr.hwndFrom, TB_GETRECT, (WPARAM)lpnmTB->iItem, (LPARAM)&rc); + MapWindowPoints(lpnmTB->hdr.hwndFrom, HWND_DESKTOP, (LPPOINT)&rc, 2); + HMENU hPopupMenu = CreatePopupMenu(); + if(hPopupMenu != NULL) + { + AppendMenu(hPopupMenu, MF_STRING, IDM_FINDNEXT, TranslateT("Find Next")); + AppendMenu(hPopupMenu, MF_STRING, IDM_FINDPREV, TranslateT("Find Previous")); + AppendMenu(hPopupMenu, MFT_SEPARATOR, 0, NULL); + AppendMenu(hPopupMenu, searcher.IsMatchCase() ? MF_STRING | MF_CHECKED : MF_STRING, IDM_MATCHCASE, TranslateT("Match Case")); + AppendMenu(hPopupMenu, searcher.IsMatchWholeWords() ? MF_STRING | MF_CHECKED : MF_STRING, IDM_MATCHWHOLE, TranslateT("Match Whole Word")); + AppendMenu(hPopupMenu, searcher.IsOnlyIn() ? MF_STRING | MF_CHECKED : MF_STRING, IDM_ONLYIN, TranslateT("Only Incomming Messages")); + AppendMenu(hPopupMenu, searcher.IsOnlyOut() ? MF_STRING | MF_CHECKED : MF_STRING, IDM_ONLYOUT, TranslateT("Only Outgoing Messages")); + AppendMenu(hPopupMenu, searcher.IsOnlyGroup() ? MF_STRING | MF_CHECKED : MF_STRING, IDM_ONLYGROUP, TranslateT("Only Selected Group")); + AppendMenu(hPopupMenu, searcher.IsAllUsers() ? MF_STRING | MF_CHECKED : MF_STRING, IDM_ALLUSERS, TranslateT("All Contacts")); + AppendMenu(hPopupMenu, MFT_SEPARATOR, 0, NULL); + HMENU hFilterMenu = CreatePopupMenu(); + int filter = GetFilterNr(); + AppendMenu(hFilterMenu, filter == 0 ? MF_STRING | MF_CHECKED : MF_STRING, IDM_FILTERDEF, TranslateT("Default history events")); + AppendMenu(hFilterMenu, filter == 1 ? MF_STRING | MF_CHECKED : MF_STRING, IDM_FILTERALL, TranslateT("All events")); + for(size_t i = 0 ; i < Options::instance->customFilters.size(); ++i) + { + UINT flags = MF_STRING; + if(filter - 2 == i) + flags |= MF_CHECKED; + + AppendMenu(hFilterMenu, flags, DEF_FILTERS_START + i, Options::instance->customFilters[i].name.c_str()); + } + AppendMenu(hPopupMenu, MF_STRING | MF_POPUP, (UINT_PTR)hFilterMenu, TranslateT("Filters")); + if(searcher.IsFindBack()) + SetMenuDefaultItem(hPopupMenu, IDM_FINDPREV, FALSE); + else + SetMenuDefaultItem(hPopupMenu, IDM_FINDNEXT, FALSE); + + int selected = TrackPopupMenu(hPopupMenu, TPM_RETURNCMD, rc.left, rc.bottom, 0, hWnd, 0); + switch (selected) + { + case IDM_FINDNEXT: + searcher.ChangeFindDirection(false); + break; + case IDM_FINDPREV: + searcher.ChangeFindDirection(true); + break; + case IDM_MATCHCASE: + searcher.SetMatchCase(!searcher.IsMatchCase()); + break; + case IDM_MATCHWHOLE: + searcher.SetMatchWholeWords(!searcher.IsMatchWholeWords()); + break; + case IDM_ONLYIN: + searcher.SetOnlyIn(!searcher.IsOnlyIn()); + break; + case IDM_ONLYOUT: + searcher.SetOnlyOut(!searcher.IsOnlyOut()); + break; + case IDM_ONLYGROUP: + searcher.SetOnlyGroup(!searcher.IsOnlyGroup()); + break; + case IDM_ALLUSERS: + searcher.SetAllUsers(!searcher.IsAllUsers()); + break; + case IDM_FILTERDEF: + SetDefFilter(0); + SendMessage(hWnd,DM_HREBUILD,0,0); + break; + case IDM_FILTERALL: + SetDefFilter(1); + SendMessage(hWnd,DM_HREBUILD,0,0); + break; + default: + if(selected >= DEF_FILTERS_START) + { + SetDefFilter(selected - DEF_FILTERS_START + 2); + SendMessage(hWnd,DM_HREBUILD,0,0); + } + break; + } + + DestroyMenu(hFilterMenu); + DestroyMenu(hPopupMenu); + } +} + +void HistoryWindow::ConfigToolbarClicked(LPNMTOOLBAR lpnmTB) +{ + RECT rc; + SendMessage(lpnmTB->hdr.hwndFrom, TB_GETRECT, (WPARAM)lpnmTB->iItem, (LPARAM)&rc); + MapWindowPoints(lpnmTB->hdr.hwndFrom, HWND_DESKTOP, (LPPOINT)&rc, 2); + HMENU hPopupMenu = CreatePopupMenu(); + if(hPopupMenu != NULL) + { + AppendMenu(hPopupMenu, MF_STRING, IDM_OPTIONS, TranslateT("Options")); + AppendMenu(hPopupMenu, MF_STRING, IDM_FONTS, TranslateT("Fonts & Colors")); + AppendMenu(hPopupMenu, MF_STRING, IDM_ICONS, TranslateT("Icons")); + AppendMenu(hPopupMenu, MF_STRING, IDM_HOTKEYS, TranslateT("Hotkeys")); + AppendMenu(hPopupMenu, MFT_SEPARATOR, 0, NULL); + + HMENU hExportMenu = CreatePopupMenu(); + AppendMenu(hExportMenu, MF_STRING, IDM_EXPORTRHTML, TranslateT("Rich Html")); + AppendMenu(hExportMenu, MF_STRING, IDM_EXPORTPHTML, TranslateT("Plain Html")); + AppendMenu(hExportMenu, MF_STRING, IDM_EXPORTTXT, TranslateT("Txt")); + AppendMenu(hExportMenu, MF_STRING, IDM_EXPORTBINARY, TranslateT("Binary")); + AppendMenu(hExportMenu, MF_STRING, IDM_EXPORTDAT, TranslateT("Dat (mContacts)")); + + HMENU hImportMenu = CreatePopupMenu(); + AppendMenu(hImportMenu, MF_STRING, IDM_IMPORTBINARY, TranslateT("Binary")); + AppendMenu(hImportMenu, MF_STRING, IDM_IMPORTDAT, TranslateT("Dat (mContacts)")); + + AppendMenu(hPopupMenu, MF_STRING | MF_POPUP, (UINT_PTR)hExportMenu, TranslateT("Export")); + AppendMenu(hPopupMenu, MF_STRING | MF_POPUP, (UINT_PTR)hImportMenu, TranslateT("Import")); + + AppendMenu(hPopupMenu, MFT_SEPARATOR, 0, NULL); + AppendMenu(hPopupMenu, MF_STRING, IDM_SAVEPOS, TranslateT("Save window position as default")); + AppendMenu(hPopupMenu, MF_STRING, IDM_SAVEPOSALL, TranslateT("Save window position for all contacts")); + SetMenuDefaultItem(hPopupMenu, IDM_OPTIONS, FALSE); + + int selected = TrackPopupMenu(hPopupMenu, TPM_RETURNCMD, rc.left, rc.bottom, 0, hWnd, 0); + switch (selected) + { + case IDM_OPTIONS: + SendMessage(hWnd, WM_COMMAND, IDM_CONFIG, 0); + break; + case IDM_FONTS: + OpenOptions("Customize", "Fonts & Colors"); + break; + case IDM_ICONS: + OpenOptions("Customize", "Icons"); + break; + case IDM_HOTKEYS: + OpenOptions("Customize", "Hotkeys"); + break; + case IDM_SAVEPOS: + SavePos(false); + break; + case IDM_SAVEPOSALL: + SavePos(true); + break; + case IDM_EXPORTRHTML: + { + ExportManager exp(hWnd, hContact, GetFilterNr()); + exp.Export(IExport::RichHtml); + } + + break; + case IDM_EXPORTPHTML: + { + ExportManager exp(hWnd, hContact, GetFilterNr()); + exp.Export(IExport::PlainHtml); + } + + break; + case IDM_EXPORTTXT: + { + ExportManager exp(hWnd, hContact, GetFilterNr()); + exp.Export(IExport::Txt); + } + + break; + case IDM_EXPORTBINARY: + { + ExportManager exp(hWnd, hContact, GetFilterNr()); + exp.Export(IExport::Binary); + } + + break; + case IDM_EXPORTDAT: + { + ExportManager exp(hWnd, hContact, GetFilterNr()); + exp.Export(IExport::Dat); + } + + break; + case IDM_IMPORTBINARY: + { + DoImport(IImport::Binary); + } + + break; + case IDM_IMPORTDAT: + { + DoImport(IImport::Dat); + } + + break; + } + + DestroyMenu(hExportMenu); + DestroyMenu(hImportMenu); + DestroyMenu(hPopupMenu); + } +} + +void HistoryWindow::DoImport(IImport::ImportType type) +{ + ExportManager exp(hWnd, hContact, GetFilterNr()); + std::vector messages; + std::wstring err; + if(exp.Import(type, messages, &err)) + { + int act = MessageBox(hWnd, TranslateT("Do you want save imported messages to local profile?"), TranslateT("Import"), MB_ICONQUESTION | MB_YESNOCANCEL | MB_DEFBUTTON2); + if(act == IDYES) + { + MargeMessages(messages); + HistoryWindow::RebuildEvents(hContact); + } + else if(act == IDNO) + { + EventList::AddImporter(hContact, type, exp.GetFileName()); + HistoryWindow::RebuildEvents(hContact); + } + } + else if(!err.empty()) + { + MessageBox(hWnd, err.c_str(), TranslateT("Error"), MB_ICONERROR); + } +} + +void HistoryWindow::DeleteToolbarClicked(LPNMTOOLBAR lpnmTB) +{ + RECT rc; + SendMessage(lpnmTB->hdr.hwndFrom, TB_GETRECT, (WPARAM)lpnmTB->iItem, (LPARAM)&rc); + MapWindowPoints(lpnmTB->hdr.hwndFrom, HWND_DESKTOP, (LPPOINT)&rc, 2); + HMENU hPopupMenu = CreatePopupMenu(); + if(hPopupMenu != NULL) + { + AppendMenu(hPopupMenu, MF_STRING, IDM_DELETE, TranslateT("Delete")); + AppendMenu(hPopupMenu, MF_STRING, IDM_DELETEGROUP, TranslateT("Delete Group")); + AppendMenu(hPopupMenu, MF_STRING, IDM_DELETEUSER, TranslateT("Delete All User History")); + SetMenuDefaultItem(hPopupMenu, IDM_DELETE, FALSE); + + int selected = TrackPopupMenu(hPopupMenu, TPM_RETURNCMD, rc.left, rc.bottom, 0, hWnd, 0); + switch (selected) + { + case IDM_DELETE: + Delete(0); + break; + case IDM_DELETEGROUP: + Delete(1); + break; + case IDM_DELETEUSER: + Delete(2); + break; + } + + DestroyMenu(hPopupMenu); + } +} + +void HistoryWindow::Delete(int what) +{ + int toDelete = 1; + size_t start = 0; + size_t end = 0; + if(selected < 0 || selected >= (int)eventList.size() || what > 2 || what < 0) + return; + if(what == 0) + { + CHARRANGE chrg; + SendMessage(editWindow,EM_EXGETSEL,0,(LPARAM)&chrg); + if(chrg.cpMin == 0 && chrg.cpMax == -1) + { + toDelete = (int)currentGroup.size(); + } + else + { + while(start < currentGroup.size() && chrg.cpMin >= currentGroup[start].endPos) ++start; + end = start; + while(end < currentGroup.size() && chrg.cpMax > currentGroup[end].endPos) ++end; + if(start >= currentGroup.size()) + return; + if(end < currentGroup.size()) + ++end; + toDelete = (int)(end - start); + } + } + else if(what == 1) + { + end = currentGroup.size(); + toDelete = (int)end; + } + else + { + if(eventList.size() == 0) + return; + toDelete = 1; + } + + if(toDelete == 0) + return; + TCHAR message[256]; + if(what == 2) + _tcscpy_s(message, TranslateT("This operation will PERMANENTLY REMOVE all history for this contact.\nAre you sure you want to do this?")); + else + _stprintf_s(message, TranslateT("Number of history items to delete: %d.\nAre you sure you want to do this?"), toDelete); + if(MessageBox(hWnd, message, TranslateT("Are You sure?"), MB_OKCANCEL | MB_ICONERROR) != IDOK) + return; + + bool areImpMessages = false; + bool rebuild = false; + if(what == 2) + { + for(size_t j = 0; j < eventList.size(); ++j) + { + for(size_t i = 0; i < eventList[j].size(); ++i) + { + DeleteEvent(eventList[j][i]); + } + } + + areImpMessages = EventList::IsImportedHistory(hContact); + rebuild = true; + } + else + { + for(size_t i = start; i < end; ++i) + { + EventIndex& ev = eventList[selected][i]; + DeleteEvent(ev); + areImpMessages |= ev.isExternal; + } + + if(start == 0 && end == currentGroup.size()) + { + rebuild = true; + } + else + { + rebuild = false; + } + } + + if(areImpMessages) + { + TCHAR *message = TranslateT("Do you want delete all imported messages for this contact?\nNote that next scheduler task import this messages again."); + if(MessageBox(hWnd, message, TranslateT("Are You sure?"), MB_YESNO | MB_ICONERROR) == IDYES) + { + EventList::DeleteImporter(hContact); + rebuild = true; + } + } + + if(rebuild) + { + RebuildEvents(hContact); + } + else + { + RebuildGroup(selected); + SelectEventGroup(selected); + } +} + +bool HistoryWindow::ContactChanged(bool sync) +{ + if(!isLoading) + { + HANDLE hItem = (HANDLE)SendDlgItemMessage(hWnd, IDC_LIST_CONTACTS, CLM_GETSELECTION, 0, 0); + if(hItem != NULL) + { + int typeOf = SendDlgItemMessage(hWnd, IDC_LIST_CONTACTS, CLM_GETITEMTYPE,(WPARAM)hItem,0); + if(typeOf == CLCIT_CONTACT) + { + if(hContact != hItem) + { + ChangeToFreeWindow(this); + isLoading = true; + hContact = hItem; + ReloadContacts(); + if(sync) + FillHistoryThread(this); + else + mir_forkthread(HistoryWindow::FillHistoryThread, this); + return true; + } + } + else if(typeOf == CLCIT_INFO && hSystem == hItem) + { + if(hContact != NULL) + { + ChangeToFreeWindow(this); + isLoading = true; + hContact = NULL; + ReloadContacts(); + if(sync) + FillHistoryThread(this); + else + mir_forkthread(HistoryWindow::FillHistoryThread, this); + return true; + } + } + } + } + + return false; +} + +void HistoryWindow::GroupImagesChanged() +{ + if(isGroupImages != Options::instance->groupShowEvents) + { + isGroupImages = Options::instance->groupShowEvents; + if(isGroupImages) + { + ListView_SetImageList(listWindow, himlSmall, LVSIL_SMALL); + } + else + { + ListView_SetImageList(listWindow, himlNone, LVSIL_SMALL); + } + } +} + +void HistoryWindow::FormatQuote(std::wstring& quote, const MessageData& md, const std::wstring& msg) +{ + if(md.isMe) + quote += myName; + else + quote += contactName; + TCHAR str[32]; + tmi.printTimeStamp(NULL, md.timestamp, _T("d t"), str , 32, 0); + quote += _T(", "); + quote += str; + quote += _T("\n"); + int f = 0; + do + { + int nf = (int)msg.find_first_of(_T("\r\n"), f); + if(nf >= 0 && nf < (int)msg.length()) + { + if(nf - f >= 0 ) + { + quote += _T(">"); + quote += msg.substr(f, nf - f); + quote += _T("\n"); + } + + f = nf + 1; + if(msg[nf] == _T('\r') && f < (int)msg.length() && msg[f] == _T('\n')) + ++f; + } + else if(msg.length() - f > 0) + { + quote += _T(">"); + quote += msg.substr(f, msg.length() - f); + quote += _T("\n"); + f = -1; + } + else + f = -1; + } + while(f > 0 && f < (int)msg.length()); +} + +HANDLE HistoryWindow::GetNextContact(HANDLE hContact, int adder) +{ + HWND contactList = GetDlgItem(hWnd,IDC_LIST_CONTACTS); + bool find = false; + HANDLE _hContact; + if(adder > 0) + { + if(hContact != NULL) + { + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + while(_hContact) + { + HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); + if(hItem != NULL) + { + find = true; + break; + } + + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); + } + + if(!find && EventList::GetContactMessageNumber(NULL)) + { + _hContact = NULL; + find = true; + } + } + + if(!find) + { + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while(_hContact && _hContact != hContact) + { + HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); + if(hItem != NULL) + { + find = true; + break; + } + + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); + } + } + } + else + { + HANDLE lastContact = NULL; + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while(_hContact && _hContact != hContact) + { + HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); + if(hItem != NULL) + { + lastContact = _hContact; + } + + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); + } + + if(hContact != NULL) + { + if(lastContact == NULL && !EventList::GetContactMessageNumber(NULL)) + { + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + while(_hContact) + { + HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); + if(hItem != NULL) + { + lastContact = _hContact; + } + + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); + } + } + + if(lastContact != NULL || EventList::GetContactMessageNumber(NULL)) + { + _hContact = lastContact; + find = true; + } + } + else if(lastContact != NULL) + { + _hContact = lastContact; + find = true; + } + } + + if(find) + { + return _hContact; + } + else + { + return hContact; + } +} + +void HistoryWindow::SelectContact(HANDLE _hContact) +{ + if(hContact != _hContact) + { + HWND contactList = GetDlgItem(hWnd,IDC_LIST_CONTACTS); + if(_hContact != NULL) + { + HANDLE hItem = (HANDLE)SendMessage(contactList, CLM_FINDCONTACT, (WPARAM)_hContact, 0); + if(hItem != NULL) + { + SendMessage(contactList, CLM_ENSUREVISIBLE, (WPARAM)hItem, 0); + SendMessage(contactList, CLM_SELECTITEM, (WPARAM)hItem, 0); + } + } + else + { + SendMessage(contactList, CLM_ENSUREVISIBLE, (WPARAM)hSystem, 0); + SendMessage(contactList, CLM_SELECTITEM, (WPARAM)hSystem, 0); + } + + while(isLoading) + Sleep(100); + ContactChanged(true); + } +} + +void ResetCList(HWND hWnd) +{ + COLORREF bkCLColor = Options::instance->GetColor(Options::ContactListBackground); + SendDlgItemMessage(hWnd, IDC_LIST_CONTACTS, CLM_SETBKBITMAP, 0, (LPARAM)(HBITMAP) NULL); + SendDlgItemMessage(hWnd, IDC_LIST_CONTACTS, CLM_SETBKCOLOR, bkCLColor, 0); + SendDlgItemMessage(hWnd, IDC_LIST_CONTACTS, CLM_SETUSEGROUPS, Options::instance->showContactGroups, 0); +} diff --git a/plugins/BasicHistory/src/HistoryWindow.h b/plugins/BasicHistory/src/HistoryWindow.h new file mode 100644 index 0000000000..8a31d9194a --- /dev/null +++ b/plugins/BasicHistory/src/HistoryWindow.h @@ -0,0 +1,95 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once +#include "Searcher.h" + +class HistoryWindow : public SearchContext +{ +private: + HistoryWindow(HANDLE _hContact); + void Initialise(); + void Destroy(); + void SplitterMoved(HWND splitter, LONG pos, bool screenPos); + static INT_PTR CALLBACK DlgProcHistory(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + static LRESULT CALLBACK SplitterSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + static int HistoryDlgResizer(HWND, LPARAM, UTILRESIZECONTROL *urc); + static void FillHistoryThread(void* param); + static void Close(HistoryWindow* historyWindow); + static void ChangeToFreeWindow(HistoryWindow* historyWindow); + void ReplaceIcons(HWND hwndDlg, int selStart, BOOL isSent); + void EnableWindows(BOOL enable); + void ReloadContacts(); + bool DoHotkey(UINT msg, LPARAM lParam, WPARAM wParam, int window); + void RestorePos(); + void SavePos(bool all); + void FindToolbarClicked(LPNMTOOLBAR lpnmTB); + void ConfigToolbarClicked(LPNMTOOLBAR lpnmTB); + void DeleteToolbarClicked(LPNMTOOLBAR lpnmTB); + void Delete(int what); + bool ContactChanged(bool sync = false); + void GroupImagesChanged(); + void FormatQuote(std::wstring& quote, const MessageData& md, const std::wstring& msg); + void FontsChanged(); + void ReloadMainOptions(); + void DoImport(IImport::ImportType type); + + static std::map windows; + static std::vector freeWindows; + bool isDestroyed; + LONG splitterY; + LONG splitterOrgY; + LONG splitterX; + LONG splitterOrgX; + HICON *eventIcoms; + int allIconNumber; + HICON plusIco, minusIco, findNextIco, findPrevIco, configIco, deleteIco; + WNDPROC OldSplitterProc; + bool isContactList; + LONG listOryginalPos; + bool isLoading; + Searcher searcher; + bool isGroupImages; + HIMAGELIST himlSmall, himlNone; + HBRUSH bkBrush; + HBRUSH bkFindBrush; + HANDLE hSystem; + HWND splitterXhWnd, splitterYhWnd; +protected: + virtual void AddGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText, int ico); +public: + ~HistoryWindow(); + static void Deinit(); + static void Open(HANDLE hContact); + static void Close(HANDLE hContact); + static void RebuildEvents(HANDLE hContact); + static bool IsInList(HWND hWnd); + static int FontsChanged(WPARAM wParam, LPARAM lParam); + static INT_PTR DeleteAllUserHistory(WPARAM wParam, LPARAM lParam); + static void OptionsMainChanged(); + static void OptionsGroupChanged(); + static void OptionsSearchingChanged(); + void Show(); + void Focus(); + + // SearchContext interface + virtual void SelectEventGroup(int sel); + virtual HANDLE GetNextContact(HANDLE hContact, int adder); + virtual void SelectContact(HANDLE _hContact); +}; + diff --git a/plugins/BasicHistory/src/HotkeyHelper.cpp b/plugins/BasicHistory/src/HotkeyHelper.cpp new file mode 100644 index 0000000000..eeb537456a --- /dev/null +++ b/plugins/BasicHistory/src/HotkeyHelper.cpp @@ -0,0 +1,105 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "StdAfx.h" +#include "HotkeyHelper.h" + +LRESULT CALLBACK HotkeySubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +void RegisterHotkeyControl(HWND control) +{ + WNDPROC oldProc = (WNDPROC)SetWindowLongPtr(control, GWLP_WNDPROC, (LONG_PTR) HotkeySubclassProc); + SetWindowLongPtr(control, GWLP_USERDATA, (LONG_PTR) oldProc); +} + +void UnregisterHotkeyControl(HWND control) +{ + WNDPROC oldProc = (WNDPROC)GetWindowLongPtr(control, GWLP_USERDATA); + if(oldProc != NULL) + { + SetWindowLongPtr(control, GWLP_WNDPROC, (LONG_PTR) oldProc); + SetWindowLongPtr(control, GWLP_USERDATA, NULL); + } +} + +static bool isPresed = false; + +LRESULT CALLBACK HotkeySubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA); + + switch (msg) { + case WM_CHAR: + case WM_SYSCHAR: + case WM_UNICHAR: + case WM_DEADCHAR: + case WM_SYSDEADCHAR: + if(isPresed) + return 0; + break; + case WM_KEYUP: + case WM_SYSKEYUP: + if(isPresed) + { + isPresed = false; + return 0; + } + break; + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + isPresed = false; + HWND hwndParent = GetParent(hwnd); + MSGFILTER filter; + filter.msg = msg; + filter.lParam = lParam; + filter.wParam = wParam; + filter.nmhdr.hwndFrom = hwnd; + filter.nmhdr.code = EN_MSGFILTER; + filter.nmhdr.idFrom = GetDlgCtrlID(hwnd); + if(SendMessage(hwndParent, WM_NOTIFY, NULL, (LPARAM)&filter)) + { + isPresed = true; + return 0; + } + + LRESULT res = CallWindowProc(oldProc, hwnd, msg, wParam, lParam); + filter.nmhdr.code = CLN_MYSELCHANGED; + SendMessage(hwndParent, WM_NOTIFY, NULL, (LPARAM)&filter); + return res; + } + break; + case WM_LBUTTONDOWN: + { + HWND hwndParent = GetParent(hwnd); + MSGFILTER filter; + filter.msg = msg; + filter.lParam = lParam; + filter.wParam = wParam; + filter.nmhdr.hwndFrom = hwnd; + filter.nmhdr.code = CLN_MYSELCHANGED; + filter.nmhdr.idFrom = GetDlgCtrlID(hwnd); + + LRESULT res = CallWindowProc(oldProc, hwnd, msg, wParam, lParam); + SendMessage(hwndParent, WM_NOTIFY, NULL, (LPARAM)&filter); + return res; + } + break; + } + return CallWindowProc(oldProc, hwnd, msg, wParam, lParam); +} \ No newline at end of file diff --git a/plugins/BasicHistory/src/HotkeyHelper.h b/plugins/BasicHistory/src/HotkeyHelper.h new file mode 100644 index 0000000000..f31b1c6666 --- /dev/null +++ b/plugins/BasicHistory/src/HotkeyHelper.h @@ -0,0 +1,24 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#define CLN_MYSELCHANGED (CLN_FIRST-50) + +void RegisterHotkeyControl(HWND control); +void UnregisterHotkeyControl(HWND control); diff --git a/plugins/BasicHistory/src/IExport.h b/plugins/BasicHistory/src/IExport.h new file mode 100644 index 0000000000..d024a084e4 --- /dev/null +++ b/plugins/BasicHistory/src/IExport.h @@ -0,0 +1,49 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once +class IExport +{ +protected: + std::wostream* stream; +public: + enum ExportType + { + RichHtml, + PlainHtml, + Txt, + Binary, + Dat + }; + + void SetStream(std::wostream *str) + { + stream = str; + } + + virtual const TCHAR* GetExt() = 0; + virtual void WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding) = 0; + virtual void WriteFooter() = 0; + virtual void WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText) = 0; + virtual void WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei) = 0; + + virtual ~IExport() + { + } +}; + diff --git a/plugins/BasicHistory/src/IImport.h b/plugins/BasicHistory/src/IImport.h new file mode 100644 index 0000000000..aef3b35179 --- /dev/null +++ b/plugins/BasicHistory/src/IImport.h @@ -0,0 +1,53 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +class IImport +{ +protected: + std::istream* stream; +public: + enum ImportType + { + Binary, + Dat + }; + + struct ExternalMessage + { + DWORD timestamp; + WORD eventType; + WORD flags; + std::wstring message; + }; + + void SetStream(std::istream *str) + { + stream = str; + } + + virtual const TCHAR* GetExt() = 0; + virtual int IsContactInFile(const std::vector& contacts) = 0; + virtual bool GetEventList(std::vector& eventList) = 0; + + virtual ~IImport() + { + } +}; + diff --git a/plugins/BasicHistory/src/ImageDataObject.cpp b/plugins/BasicHistory/src/ImageDataObject.cpp new file mode 100644 index 0000000000..15cb67f6ce --- /dev/null +++ b/plugins/BasicHistory/src/ImageDataObject.cpp @@ -0,0 +1,171 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +//code taken partly from public example on the internet, source unknown. + +#include "StdAfx.h" +#include "ImageDataObject.h" + +HBITMAP CacheIconToBMP(HICON hIcon, COLORREF backgroundColor, int sizeX, int sizeY) +{ + RECT rc; + HBRUSH hBkgBrush = CreateSolidBrush(backgroundColor); + rc.top = rc.left = 0; + rc.right = sizeY; + rc.bottom = sizeX; + HDC hdc = GetDC(0); + HBITMAP hBmp = CreateCompatibleBitmap(hdc, sizeY, sizeX); + HDC hdcMem = CreateCompatibleDC(hdc); + HBITMAP hoBmp = (HBITMAP)SelectObject(hdcMem, hBmp); + FillRect(hdcMem, &rc, hBkgBrush); + DrawIconEx(hdcMem, 0, 0, hIcon, sizeY, sizeX, 0, NULL, DI_NORMAL); + SelectObject(hdcMem, hoBmp); + DeleteDC(hdcMem); + ReleaseDC(NULL, hdc); + DeleteObject(hBkgBrush); + return hBmp; +} + +// returns true on success, false on failure +bool ImageDataObject::InsertIcon(IRichEditOle* pRichEditOle, HICON hIcon, + COLORREF backgroundColor, int sizeX, int sizeY) +{ + bool result; + HBITMAP hBmp = CacheIconToBMP(hIcon, backgroundColor, sizeX, sizeY); + result = InsertBitmap(pRichEditOle, hBmp); + DeleteObject(hBmp); + return result; +} + +// returns true on success, false on failure +bool ImageDataObject::InsertBitmap(IRichEditOle* pRichEditOle, HBITMAP hBitmap) +{ + SCODE sc; + BITMAP bminfo; + + // Get the image data object + // + ImageDataObject *pods = new ImageDataObject; + + GetObject(hBitmap, sizeof(bminfo), &bminfo); + pods->SetBitmap(hBitmap); + + // Get the RichEdit container site + // + IOleClientSite *pOleClientSite; + pRichEditOle->GetClientSite(&pOleClientSite); + + // Initialize a Storage Object + // + IStorage *pStorage; + + LPLOCKBYTES lpLockBytes = NULL; + sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes); + if (sc != S_OK) { + pOleClientSite->Release(); + return false; + } + sc = ::StgCreateDocfileOnILockBytes(lpLockBytes, + STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage); + if (sc != S_OK) { + lpLockBytes = NULL; + pOleClientSite->Release(); + return false; + } + // The final ole object which will be inserted in the richedit control + // + IOleObject *pOleObject; + pOleObject = pods->GetOleObject(pOleClientSite, pStorage); + if (pOleObject == NULL) { + pStorage->Release(); + pOleClientSite->Release(); + return false; + } + + // all items are "contained" -- this makes our reference to this object + // weak -- which is needed for links to embedding silent update. + OleSetContainedObject(pOleObject, TRUE); + + // Now Add the object to the RichEdit + // + REOBJECT reobject; + ZeroMemory(&reobject, sizeof(REOBJECT)); + reobject.cbStruct = sizeof(REOBJECT); + + CLSID clsid; + sc = pOleObject->GetUserClassID(&clsid); + if (sc != S_OK) { + pOleObject->Release(); + pStorage->Release(); + pOleClientSite->Release(); + return false; + } + + reobject.clsid = clsid; + reobject.cp = REO_CP_SELECTION ; + reobject.dvaspect = DVASPECT_CONTENT; + reobject.poleobj = pOleObject; + reobject.polesite = pOleClientSite; + reobject.pstg = pStorage; + reobject.dwFlags = bminfo.bmHeight <= 12 ? 0 : REO_BELOWBASELINE; + + // Insert the bitmap at the current location in the richedit control + // + sc = pRichEditOle->InsertObject(&reobject); + + // Release all unnecessary interfaces + // + pOleObject->Release(); + pOleClientSite->Release(); + lpLockBytes->Release(); + pStorage->Release(); + if (sc != S_OK) + return false; + else + return true; +} + + +void ImageDataObject::SetBitmap(HBITMAP hBitmap) +{ + STGMEDIUM stgm; + stgm.tymed = TYMED_GDI; // Storage medium = HBITMAP handle + stgm.hBitmap = hBitmap; + stgm.pUnkForRelease = NULL; // Use ReleaseStgMedium + + FORMATETC fm; + fm.cfFormat = CF_BITMAP; // Clipboard format = CF_BITMAP + fm.ptd = NULL; // Target Device = Screen + fm.dwAspect = DVASPECT_CONTENT; // Level of detail = Full content + fm.lindex = -1; // Index = Not applicaple + fm.tymed = TYMED_GDI; // Storage medium = HBITMAP handle + + this->SetData(&fm, &stgm, TRUE); +} + + +IOleObject *ImageDataObject::GetOleObject(IOleClientSite *pOleClientSite, IStorage *pStorage) +{ + SCODE sc; + IOleObject *pOleObject; + sc = ::OleCreateStaticFromData(this, IID_IOleObject, OLERENDER_FORMAT, + &m_format, pOleClientSite, pStorage, (void **) & pOleObject); + if (sc != S_OK) + pOleObject = NULL; + return pOleObject; +} diff --git a/plugins/BasicHistory/src/ImageDataObject.h b/plugins/BasicHistory/src/ImageDataObject.h new file mode 100644 index 0000000000..309c220e36 --- /dev/null +++ b/plugins/BasicHistory/src/ImageDataObject.h @@ -0,0 +1,133 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +//code taken partly from public example on the internet, source unknown. + +#pragma once + +class ImageDataObject : IDataObject +{ +public: + // returns true on success, false on failure + static bool InsertBitmap(IRichEditOle* pRichEditOle, HBITMAP hBitmap); + // returns true on success, false on failure + static bool InsertIcon(IRichEditOle* pRichEditOle, HICON hIcon, + COLORREF backgroundColor, int sizeX = 0, int sizeY = 0); + +private: + ULONG m_ulRefCnt; + BOOL m_bRelease; + + STGMEDIUM m_stgmed; + FORMATETC m_format; + + // ULONG m_nIndex; // current enumerator index + +public: + ImageDataObject() : m_ulRefCnt(0) + { + m_bRelease = FALSE; + } + + ~ImageDataObject() + { + if (m_bRelease) + ::ReleaseStgMedium(&m_stgmed); + } + + // IUnknown interface + STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) + { + if (iid == IID_IUnknown || iid == IID_IDataObject) + { + *ppvObject = this; + AddRef(); + return S_OK; + } + else + return E_NOINTERFACE; + } + + STDMETHOD_(ULONG, AddRef)(void) + { + m_ulRefCnt++; + return m_ulRefCnt; + } + + STDMETHOD_(ULONG, Release)(void) + { + m_ulRefCnt--; + if (m_ulRefCnt == 0) + delete this; + return m_ulRefCnt; + } + + // IDataObject Interface + STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium) { + HANDLE hDst; + hDst = ::OleDuplicateData(m_stgmed.hBitmap, CF_BITMAP, 0); + if (hDst == NULL) + return E_HANDLE; + + pmedium->tymed = TYMED_GDI; + pmedium->hBitmap = (HBITMAP)hDst; + pmedium->pUnkForRelease = NULL; + return S_OK; + } + + STDMETHOD(GetDataHere)(FORMATETC* pformatetc, STGMEDIUM* pmedium ) { + return E_NOTIMPL; + } + + STDMETHOD(QueryGetData)(FORMATETC* pformatetc ) { + return E_NOTIMPL; + } + + STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* pformatectIn ,FORMATETC* pformatetcOut ) { + return E_NOTIMPL; + } + + STDMETHOD(SetData)(FORMATETC* pformatetc , STGMEDIUM* pmedium , BOOL fRelease ) { + m_format = *pformatetc; + m_stgmed = *pmedium; + + return S_OK; + } + + STDMETHOD(EnumFormatEtc)(DWORD dwDirection , IEnumFORMATETC** ppenumFormatEtc ) { + return E_NOTIMPL; + } + + STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, + DWORD *pdwConnection) { + return E_NOTIMPL; + } + + STDMETHOD(DUnadvise)(DWORD dwConnection) { + return E_NOTIMPL; + } + + STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise) { + return E_NOTIMPL; + } + + // Other + void SetBitmap(HBITMAP hBitmap); + IOleObject *GetOleObject(IOleClientSite *pOleClientSite, IStorage *pStorage); +}; + diff --git a/plugins/BasicHistory/src/Options.cpp b/plugins/BasicHistory/src/Options.cpp new file mode 100644 index 0000000000..218e721f03 --- /dev/null +++ b/plugins/BasicHistory/src/Options.cpp @@ -0,0 +1,2170 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "StdAfx.h" +#include "Options.h" +#include "resource.h" + +extern HINSTANCE hInst; +extern bool g_SmileyAddAvail; +extern bool bPopupsEnabled; + +#define MODULE "BasicHistory" + +Options *Options::instance; + +struct EventNamesType +{ + int id; + TCHAR* name; +} EventNames[] = +{ + EVENTTYPE_MESSAGE, LPGENT("Message"), + EVENTTYPE_FILE, LPGENT("File transfer"), + EVENTTYPE_URL, LPGENT("Link"), + EVENTTYPE_STATUSCHANGE, LPGENT("Status change"), + EVENTTYPE_AUTHREQUEST, LPGENT("Authorization request"), + EVENTTYPE_ADDED, LPGENT("You were added"), + EVENTTYPE_CONTACTS, LPGENT("Contacts recieved"), + EVENTTYPE_SMTPSIMPLE, LPGENT("SMTP Simple Email"), + ICQEVENTTYPE_SMS, LPGENT("SMS message") +}; + +struct TCpTable { + UINT cpId; + TCHAR *cpName; +} +cpTable[] = { + { CP_UTF8, _T("UTF-8") }, + { 1250, _T("windows-1250") }, + { 1251, _T("windows-1251") }, + { 1252, _T("windows-1252") }, + { 1253, _T("windows-1253") }, + { 1254, _T("windows-1254") }, + { 1255, _T("windows-1255") }, + { 1256, _T("windows-1256") }, + { 1257, _T("windows-1257") }, + { 1258, _T("windows-1258") }, + { 28591, _T("iso-8859-1") }, + { 28592, _T("iso-8859-2") }, + { 28593, _T("iso-8859-3") }, + { 28594, _T("iso-8859-4") }, + { 28595, _T("iso-8859-5") }, + { 28596, _T("iso-8859-6") }, + { 28597, _T("iso-8859-7") }, + { 28598, _T("iso-8859-8") }, + { 28599, _T("iso-8859-9") }, + { 28603, _T("iso-8859-13") }, + { 28605, _T("iso-8859-15") }, +}; + +Options::Options() +{ + showContacts = false; + showContactGroups = true; + groupNewOnTop = true; + groupShowEvents = true; + groupShowTime = true; + groupShowName = false; + groupShowMessage = true; + groupMessageLen = 43; + groupTime = 5; + groupMessagesNumber = 100; + messagesNewOnTop = false; + messagesShowDate = false; + messagesShowSec = false; + messagesShowName = true; + messagesShowEvents = false; + messagesUseSmileys = true; + searchForInList = true; + searchForInMess = true; + searchMatchCase = false; + searchMatchWhole = false; + searchOnlyIn = false; + searchOnlyOut = false; + searchOnlyGroup = false; + searchAllContacts = false; + schedulerAlerts = true; + schedulerHistoryAlerts = true; + defFilter = 0; + codepageTxt = CP_UTF8; + codepageHtml1 = CP_UTF8; + codepageHtml2 = CP_UTF8; + encodingTxt = _T("UTF-8"); + encodingHtml1 = _T("UTF-8"); + encodingHtml2 = _T("UTF-8"); + exportHtml1ShowDate = true; + exportHtml2ShowDate = false; + exportHtml2UseSmileys = true; +} + +Options::~Options() +{ +} + +int Options::InitOptions(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = {0}; + + odp.cbSize = sizeof(odp); + odp.position = 100000000; + odp.hInstance = hInst; + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; + odp.ptszTitle = LPGENT("History"); + + odp.ptszTab = LPGENT("Group list"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_GROUPLIST); + odp.pfnDlgProc = Options::DlgProcOptsGroupList; + Options_AddPage(wParam, &odp); + + odp.ptszTab = LPGENT("Messages"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MESSAGES); + odp.pfnDlgProc = Options::DlgProcOptsMessages; + Options_AddPage(wParam, &odp); + + odp.ptszTab = LPGENT("Searching"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_SEARCHING); + odp.pfnDlgProc = Options::DlgProcOptsSearching; + Options_AddPage(wParam, &odp); + + odp.ptszTab = LPGENT("Export"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_EXPORT); + odp.pfnDlgProc = Options::DlgProcOptsExport; + Options_AddPage(wParam, &odp); + + odp.ptszTab = LPGENT("Scheduler"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_SCHEDULER); + odp.pfnDlgProc = Options::DlgProcOptsScheduler; + Options_AddPage(wParam, &odp); + + odp.ptszTab = LPGENT("Advanced"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MAIN); + odp.pfnDlgProc = Options::DlgProcOptsMain; + Options_AddPage(wParam, &odp); + + return 0; +} + +struct FontOptionsList { + TCHAR* szDescr; + COLORREF defColour; + TCHAR* szDefFace; + BYTE defStyle; + char defSize; + TCHAR* szBackgroundName; + DWORD flags; +}; + +struct ColorOptionsList { + TCHAR* tszName; + COLORREF def; +}; + +struct HotkeyOptionsList { + const char *pszName; + const TCHAR *ptszDescription; + const TCHAR *ptszSection; + const char *pszService; + WORD DefHotKey; + LPARAM lParam; +}; + +static FontOptionsList g_FontOptionsList[] = { + {LPGENT(">> Outgoing timestamp"), RGB(0, 0, 0), _T("MS Shell Dlg 2"), DBFONTF_BOLD, -11, LPGENT("Outgoing background"), FIDF_ALLOWEFFECTS}, + {LPGENT("<< Incoming timestamp"), RGB(0, 0, 0), _T("MS Shell Dlg 2"), DBFONTF_BOLD, -11, LPGENT("Incoming background"), FIDF_ALLOWEFFECTS}, + {LPGENT(">> Outgoing name"), RGB(100,100,100), _T("MS Shell Dlg 2"), DBFONTF_BOLD, -11, LPGENT("Outgoing background"), FIDF_ALLOWEFFECTS}, + {LPGENT("<< Incoming name"), RGB(90,160,90), _T("MS Shell Dlg 2"), DBFONTF_BOLD, -11, LPGENT("Incoming background"), FIDF_ALLOWEFFECTS}, + {LPGENT(">> Outgoing messages"), RGB(0, 0, 0), _T("MS Shell Dlg 2"), 0, -11, LPGENT("Outgoing background"), FIDF_ALLOWEFFECTS}, + {LPGENT("<< Incoming messages"), RGB(0, 0, 0), _T("MS Shell Dlg 2"), 0, -11, LPGENT("Incoming background"), FIDF_ALLOWEFFECTS}, + {LPGENT("Group list"), RGB(0, 0, 0), _T("MS Shell Dlg 2"), 0, -11, LPGENT("Group list background"), FIDF_DISABLESTYLES}, + {LPGENT("Find window"), RGB(0, 0, 0), _T("MS Shell Dlg 2"), 0, -11, LPGENT("Find window background"), FIDF_DISABLESTYLES}, +}; + +static ColorOptionsList g_ColorOptionsList[] = { + LPGENT("Outgoing background"), RGB(245,245,255), + LPGENT("Incoming background"), RGB(245,255,245), + LPGENT("Group list background"), GetSysColor(COLOR_3DFACE), + LPGENT("Window background"), GetSysColor(COLOR_3DFACE), + LPGENT("Contact list background"), GetSysColor(COLOR_3DFACE), + LPGENT("Find window background"), GetSysColor(COLOR_WINDOW), +}; + +static HotkeyOptionsList g_HotkeyOptionsList[] = { + { "basichistory_hot_showall", LPGENT("Open global history"), LPGENT("History"), MS_HISTORY_SHOWCONTACTHISTORY, HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, 'H') | HKF_MIRANDA_LOCAL, 0 }, + { "basichistory_hot_find", LPGENT("Find"), LPGENT("History"), 0, HOTKEYCODE(HOTKEYF_CONTROL, 'F'), HISTORY_HK_FIND }, + { "basichistory_hot_findnext", LPGENT("Find Next"), LPGENT("History"), 0, VK_F3, HISTORY_HK_FINDNEXT }, + { "basichistory_hot_findprev", LPGENT("Find Previous"), LPGENT("History"), 0, VK_F2, HISTORY_HK_FINDPREV }, + { "basichistory_hot_matchcase", LPGENT("Switch Match Case"), LPGENT("History"), 0, 0, HISTORY_HK_MATCHCASE }, + { "basichistory_hot_matchwhole", LPGENT("Switch Match Whole Word"), LPGENT("History"), 0, 0, HISTORY_HK_MATCHWHOLE }, + { "basichistory_hot_showcontacts", LPGENT("Show/Hide Contacts"), LPGENT("History"), 0, 0, HISTORY_HK_SHOWCONTACTS }, + { "basichistory_hot_onlyin", LPGENT("Switch Only Incomming Messages"), LPGENT("History"), 0, 0, HISTORY_HK_ONLYIN }, + { "basichistory_hot_onlyout", LPGENT("Switch Only Outgoing Messages"), LPGENT("History"), 0, 0, HISTORY_HK_ONLYOUT }, + { "basichistory_hot_onlygroup", LPGENT("Switch Only Selected Group"), LPGENT("History"), 0, 0, HISTORY_HK_ONLYGROUP }, + { "basichistory_hot_allcontacts", LPGENT("Switch All Contacts"), LPGENT("History"), 0, 0, HISTORY_HK_ALLCONTACTS }, + { "basichistory_hot_delete", LPGENT("Delete"), LPGENT("History"), 0, VK_DELETE, HISTORY_HK_DELETE }, + { "basichistory_hot_exrhtml", LPGENT("Export To Rich Html"), LPGENT("History"), 0, 0, HISTORY_HK_EXRHTML }, + { "basichistory_hot_exphtml", LPGENT("Export To Plain Html"), LPGENT("History"), 0, 0, HISTORY_HK_EXPHTML }, + { "basichistory_hot_extxt", LPGENT("Export To Txt"), LPGENT("History"), 0, 0, HISTORY_HK_EXTXT }, + { "basichistory_hot_exbin", LPGENT("Export To Binary"), LPGENT("History"), 0, 0, HISTORY_HK_EXBIN }, + { "basichistory_hot_impbin", LPGENT("Import From Binary"), LPGENT("History"), 0, 0, HISTORY_HK_IMPBIN }, + { "basichistory_hot_exdat", LPGENT("Export To Dat (mContacts)"), LPGENT("History"), 0, 0, HISTORY_HK_EXDAT }, + { "basichistory_hot_impdat", LPGENT("Import From Dat (mContacts)"), LPGENT("History"), 0, 0, HISTORY_HK_IMPDAT }, +}; + +const int g_fontsSize = SIZEOF(g_FontOptionsList); + +const int g_colorsSize = SIZEOF(g_ColorOptionsList); + +const int g_hotkeysSize = SIZEOF(g_HotkeyOptionsList); + +void Options::Unload() +{ + DeleteCriticalSection(&criticalSection); +} + +void Options::Load(void) +{ + InitializeCriticalSection(&criticalSection); + FontIDT fid = {0}; + ColourIDT cid = {0}; + HOTKEYDESC hid = {0}; + fid.cbSize = sizeof(FontIDT); + cid.cbSize = sizeof(ColourIDT); + hid.cbSize = sizeof(HOTKEYDESC); + strncpy_s(fid.dbSettingsGroup, "BasicHistory_Fonts", SIZEOF(fid.dbSettingsGroup)); + _tcsncpy_s(fid.backgroundGroup, _T("History"), SIZEOF(fid.backgroundGroup)); + _tcsncpy_s(fid.group, LPGENT("History"), SIZEOF(fid.group)); + for(int i = 0; i < g_fontsSize; ++i) + { + fid.order = i; + _tcsncpy_s(fid.deffontsettings.szFace, g_FontOptionsList[i].szDefFace, LF_FACESIZE); + fid.deffontsettings.size = g_FontOptionsList[i].defSize; + fid.deffontsettings.colour = g_FontOptionsList[i].defColour; + fid.deffontsettings.style = g_FontOptionsList[i].defStyle; + fid.deffontsettings.charset = DEFAULT_CHARSET; + sprintf_s(fid.prefix, SIZEOF(fid.prefix), "Font%d", i); + _tcsncpy_s(fid.name, g_FontOptionsList[i].szDescr, SIZEOF(fid.name)); + _tcsncpy_s(fid.backgroundName, g_FontOptionsList[i].szBackgroundName, SIZEOF(fid.name)); + fid.flags = FIDF_DEFAULTVALID | FIDF_CLASSGENERAL | g_FontOptionsList[i].flags; + FontRegisterT(&fid); + } + + strncpy_s(cid.dbSettingsGroup, "BasicHistory_Fonts", SIZEOF(fid.dbSettingsGroup)); + _tcsncpy_s(cid.group, LPGENT("History"), SIZEOF(fid.group)); + for(int i = 0; i < g_colorsSize; ++i) + { + _tcsncpy_s(cid.name, g_ColorOptionsList[i].tszName, SIZEOF(cid.name)); + sprintf_s(cid.setting, SIZEOF(cid.setting), "Color%d", i); + cid.order = i; + cid.defcolour = g_ColorOptionsList[i].def; + ColourRegisterT(&cid); + } + + hid.dwFlags = HKD_TCHAR; + for(int i = 0; i < g_hotkeysSize; ++i) + { + hid.pszName = g_HotkeyOptionsList[i].pszName; + hid.ptszDescription = g_HotkeyOptionsList[i].ptszDescription; + hid.ptszSection = g_HotkeyOptionsList[i].ptszSection; + hid.pszService = g_HotkeyOptionsList[i].pszService; + hid.DefHotKey = g_HotkeyOptionsList[i].DefHotKey; + hid.lParam = g_HotkeyOptionsList[i].lParam; + Hotkey_Register(&hid); + } + + showContacts = DBGetContactSettingByte(0, MODULE, "showContacts", 0) ? true : false; + showContactGroups = DBGetContactSettingByte(0, MODULE, "showContactGroups", 1) ? true : false; + groupNewOnTop = DBGetContactSettingByte(0, MODULE, "groupNewOnTop", 1) ? true : false; + groupShowEvents = DBGetContactSettingByte(0, MODULE, "groupShowEvents", 1) ? true : false; + groupShowTime = DBGetContactSettingByte(0, MODULE, "groupShowTime", 1) ? true : false; + groupShowName = DBGetContactSettingByte(0, MODULE, "groupShowName", 0) ? true : false; + groupShowMessage = DBGetContactSettingByte(0, MODULE, "groupShowMessage", 1) ? true : false; + groupMessageLen = DBGetContactSettingDword(0, MODULE, "groupMessageLen", 43); + if(groupMessageLen < 5) groupMessageLen = 5; + groupTime = DBGetContactSettingDword(0, MODULE, "groupTime", 5); + if(groupTime < 1) groupTime = 1; + groupMessagesNumber = DBGetContactSettingDword(0, MODULE, "groupMessagesNumber", 100); + if(groupMessagesNumber < 1) groupMessagesNumber = 1; + messagesNewOnTop = DBGetContactSettingByte(0, MODULE, "messagesNewOnTop", 0) ? true : false; + messagesShowDate = DBGetContactSettingByte(0, MODULE, "messagesShowDate", 0) ? true : false; + messagesShowSec = DBGetContactSettingByte(0, MODULE, "messagesShowSec", 0) ? true : false; + messagesShowName = DBGetContactSettingByte(0, MODULE, "messagesShowName", 1) ? true : false; + messagesShowEvents = DBGetContactSettingByte(0, MODULE, "messagesShowEvents", 0) ? true : false; + messagesUseSmileys = DBGetContactSettingByte(0, MODULE, "messagesUseSmileys", 1) ? true : false; + searchForInList = DBGetContactSettingByte(0, MODULE, "searchForInList", 1) ? true : false; + searchForInMess = DBGetContactSettingByte(0, MODULE, "searchForInMess", 1) ? true : false; + searchMatchCase = DBGetContactSettingByte(0, MODULE, "searchMatchCase", 0) ? true : false; + searchMatchWhole = DBGetContactSettingByte(0, MODULE, "searchMatchWhole", 0) ? true : false; + searchOnlyIn = DBGetContactSettingByte(0, MODULE, "searchOnlyIn", 0) ? true : false; + searchOnlyOut = DBGetContactSettingByte(0, MODULE, "searchOnlyOut", 0) ? true : false; + searchOnlyGroup = DBGetContactSettingByte(0, MODULE, "searchOnlyGroup", 0) ? true : false; + searchAllContacts = DBGetContactSettingByte(0, MODULE, "searchAllContacts", 0) ? true : false; + schedulerAlerts = DBGetContactSettingByte(0, MODULE, "schedulerAlerts", 1) ? true : false; + schedulerHistoryAlerts = DBGetContactSettingByte(0, MODULE, "schedulerHistoryAlerts", 1) ? true : false; + + defFilter = DBGetContactSettingByte(0, MODULE, "defFilter", defFilter); + int filtersCount = DBGetContactSettingDword(0, MODULE, "customFiltersCount", 0); + for(int i = 0; i < filtersCount; ++i) + { + char buf[256]; + FilterOptions fo; + sprintf_s(buf, "filterName_%d", i); + DBVARIANT nameV; + if(!DBGetContactSettingWString(0, MODULE, buf, &nameV)) + { + fo.name = nameV.pwszVal; + DBFreeVariant(&nameV); + } + else break; + sprintf_s(buf, "filterInOut_%d", i); + int inOut = DBGetContactSettingByte(0, MODULE, buf, 0); + if(inOut == 1) + fo.onlyIncomming = true; + else if(inOut == 2) + fo.onlyOutgoing = true; + sprintf_s(buf, "filterEvents_%d", i); + DBVARIANT eventsV; + if(!DBGetContactSettingString(0, MODULE, buf, &eventsV)) + { + int k = 0; + char* id = eventsV.pszVal; + while(eventsV.pszVal[k]) + { + if(eventsV.pszVal[k] == ';') + { + eventsV.pszVal[k] = 0; + fo.events.push_back(strtol(id, NULL, 16)); + id = eventsV.pszVal + k + 1; + } + + ++k; + } + DBFreeVariant(&eventsV); + } + else break; + + customFilters.insert(customFilters.end(), fo); + } + + if(defFilter > 1) + { + defFilter = 0; + + DBVARIANT defFilterStrV; + if(!DBGetContactSettingWString(0, MODULE, "defFilterStr", &defFilterStrV)) + { + std::wstring filterName = defFilterStrV.pwszVal; + for(int i = 0; i < (int)customFilters.size(); ++i) + { + if(filterName == customFilters[i].name) + { + defFilter = i + 2; + break; + } + } + DBFreeVariant(&defFilterStrV); + } + } + + codepageTxt = DBGetContactSettingDword(0, MODULE, "codepageTxt", CP_UTF8); + codepageHtml1 = DBGetContactSettingDword(0, MODULE, "codepageHtml1", CP_UTF8); + codepageHtml2 = DBGetContactSettingDword(0, MODULE, "codepageHtml2", CP_UTF8); + DBVARIANT encodingV; + if(!DBGetContactSettingWString(0, MODULE, "encodingTxt", &encodingV)) + { + encodingTxt = encodingV.pwszVal; + DBFreeVariant(&encodingV); + } + else + { + encodingTxt = _T("UTF-8"); + } + if(!DBGetContactSettingWString(0, MODULE, "encodingHtml1", &encodingV)) + { + encodingHtml1 = encodingV.pwszVal; + DBFreeVariant(&encodingV); + } + else + { + encodingHtml1 = _T("UTF-8"); + } + if(!DBGetContactSettingWString(0, MODULE, "encodingHtml2", &encodingV)) + { + encodingHtml2 = encodingV.pwszVal; + DBFreeVariant(&encodingV); + } + else + { + encodingHtml2 = _T("UTF-8"); + } + + exportHtml1ShowDate = DBGetContactSettingByte(0, MODULE, "exportHtml1ShowDate", 1) ? true : false; + exportHtml2ShowDate = DBGetContactSettingByte(0, MODULE, "exportHtml2ShowDate", 0) ? true : false; + exportHtml2UseSmileys = DBGetContactSettingByte(0, MODULE, "exportHtml2UseSmileys", 1) ? true : false; + if(!DBGetContactSettingWString(0, MODULE, "extCssHtml2", &encodingV)) + { + extCssHtml2 = encodingV.pwszVal; + DBFreeVariant(&encodingV); + } + else + { + extCssHtml2 = _T(""); + } + + if(!DBGetContactSettingWString(0, MODULE, "ftpLogPath", &encodingV)) + { + ftpLogPath = encodingV.pwszVal; + DBFreeVariant(&encodingV); + } + + if(!DBGetContactSettingWString(0, MODULE, "ftpExePath", &encodingV)) + { + ftpExePath = encodingV.pwszVal; + DBFreeVariant(&encodingV); + } + else + { + ftpExePath = ftpExePathDef; + } + + LoadTasks(); +} + +COLORREF Options::GetFont(Fonts fontId, PLOGFONT font) +{ + FontIDT fid = {0}; + fid.cbSize = sizeof(FontIDT); + _tcsncpy_s(fid.group, LPGENT("History"), SIZEOF(fid.group)); + _tcsncpy_s(fid.name, g_FontOptionsList[fontId].szDescr, SIZEOF(fid.name)); + return (COLORREF)CallService(MS_FONT_GETT, (WPARAM)&fid, (LPARAM)font); +} + +COLORREF Options::GetColor(Colors colorId) +{ + ColourIDT cid = {0}; + cid.cbSize = sizeof(ColourIDT); + _tcsncpy_s(cid.group, LPGENT("History"), SIZEOF(cid.group)); + _tcsncpy_s(cid.name, g_ColorOptionsList[colorId].tszName, SIZEOF(cid.name)); + return (COLORREF)CallService(MS_COLOUR_GETT, (WPARAM)&cid, NULL); +} + +void Options::Save() +{ + DBWriteContactSettingByte(0, MODULE, "showContacts", showContacts ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "showContactGroups", showContactGroups ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "groupNewOnTop", groupNewOnTop ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "groupShowEvents", groupShowEvents ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "groupShowTime", groupShowTime ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "groupShowName", groupShowName ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "groupShowMessage", groupShowMessage ? 1 : 0); + if(groupMessageLen < 5) groupMessageLen = 5; + DBWriteContactSettingDword(0, MODULE, "groupMessageLen", groupMessageLen); + if(groupTime < 1) groupTime = 1; + DBWriteContactSettingDword(0, MODULE, "groupTime", groupTime); + if(groupMessagesNumber < 1) groupMessagesNumber = 1; + DBWriteContactSettingDword(0, MODULE, "groupMessagesNumber", groupMessagesNumber); + DBWriteContactSettingByte(0, MODULE, "messagesNewOnTop", messagesNewOnTop ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "messagesShowDate", messagesShowDate ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "messagesShowSec", messagesShowSec ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "messagesShowName", messagesShowName ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "messagesShowEvents", messagesShowEvents ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "messagesUseSmileys", messagesUseSmileys ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "searchForInList", searchForInList ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "searchForInMess", searchForInMess ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "searchMatchCase", searchMatchCase ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "searchMatchWhole", searchMatchWhole ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "searchOnlyIn", searchOnlyIn ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "searchOnlyOut", searchOnlyOut ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "searchOnlyGroup", searchOnlyGroup ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "searchAllContacts", searchAllContacts ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "schedulerAlerts", schedulerAlerts ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "schedulerHistoryAlerts", schedulerHistoryAlerts ? 1 : 0); + if(defFilter < 0 || defFilter - 2 >= (int)customFilters.size()) defFilter = 0; + DBWriteContactSettingByte(0, MODULE, "defFilter", defFilter < 2 ? defFilter : 2); + if(defFilter >= 2) + DBWriteContactSettingWString(0, MODULE, "defFilterStr", customFilters[defFilter - 2].name.c_str()); + DBWriteContactSettingDword(0, MODULE, "customFiltersCount", (DWORD)customFilters.size()); + for(int i = 0 ; i < (int)customFilters.size(); ++i) + { + char buf[256]; + sprintf_s(buf, "filterName_%d", i); + DBWriteContactSettingWString(0, MODULE, buf, customFilters[i].name.c_str()); + sprintf_s(buf, "filterInOut_%d", i); + DBWriteContactSettingByte(0, MODULE, buf, customFilters[i].onlyIncomming ? 1 : (customFilters[i].onlyOutgoing ? 2 : 0)); + std::string events; + for(std::vector::iterator it = customFilters[i].events.begin(); it != customFilters[i].events.end(); ++it) + { + _itoa_s(*it, buf, 16); + events += buf; + events += ";"; + } + + sprintf_s(buf, "filterEvents_%d", i); + DBWriteContactSettingString(0, MODULE, buf, events.c_str()); + } + + DBWriteContactSettingDword(0, MODULE, "codepageTxt", codepageTxt); + DBWriteContactSettingDword(0, MODULE, "codepageHtml1", codepageHtml1); + DBWriteContactSettingDword(0, MODULE, "codepageHtml2", codepageHtml2); + DBWriteContactSettingWString(0, MODULE, "encodingTxt", encodingTxt.c_str()); + DBWriteContactSettingWString(0, MODULE, "encodingHtml1", encodingHtml1.c_str()); + DBWriteContactSettingWString(0, MODULE, "encodingHtml2", encodingHtml2.c_str()); + DBWriteContactSettingByte(0, MODULE, "exportHtml1ShowDate", exportHtml1ShowDate ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "exportHtml2ShowDate", exportHtml2ShowDate ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "exportHtml2UseSmileys", exportHtml2UseSmileys ? 1 : 0); + DBWriteContactSettingWString(0, MODULE, "extCssHtml2", extCssHtml2.c_str()); + DBWriteContactSettingWString(0, MODULE, "ftpLogPath", ftpLogPath.c_str()); + if(ftpExePath != ftpExePathDef) + { + DBWriteContactSettingWString(0, MODULE, "ftpExePath", ftpExePath.c_str()); + } + else + { + DBDeleteContactSetting(0, MODULE, "ftpExePath"); + } +} + +void Options::SaveTasks(std::list* tasks) +{ + EnterCriticalSection(&criticalSection); + int oldTaskNr = (int)taskOptions.size(); + taskOptions.clear(); + int i = 0; + char buf[256]; + for(std::list::iterator it = tasks->begin(); it != tasks->end(); ++it) + { + sprintf_s(buf, "Task_compress_%d", i); + DBWriteContactSettingByte(0, MODULE, buf, it->compress); + sprintf_s(buf, "Task_useFtp_%d", i); + DBWriteContactSettingByte(0, MODULE, buf, it->useFtp); + sprintf_s(buf, "Task_isSystem_%d", i); + DBWriteContactSettingByte(0, MODULE, buf, it->isSystem); + sprintf_s(buf, "Task_active_%d", i); + DBWriteContactSettingByte(0, MODULE, buf, it->active); + sprintf_s(buf, "Task_exportImported_%d", i); + DBWriteContactSettingByte(0, MODULE, buf, it->exportImported); + sprintf_s(buf, "Task_type_%d", i); + DBWriteContactSettingByte(0, MODULE, buf, it->type); + sprintf_s(buf, "Task_eventUnit_%d", i); + DBWriteContactSettingByte(0, MODULE, buf, it->eventUnit); + sprintf_s(buf, "Task_trigerType_%d", i); + DBWriteContactSettingByte(0, MODULE, buf, it->trigerType); + sprintf_s(buf, "Task_exportType_%d", i); + DBWriteContactSettingByte(0, MODULE, buf, it->exportType); + sprintf_s(buf, "Task_importType_%d", i); + DBWriteContactSettingByte(0, MODULE, buf, it->importType); + sprintf_s(buf, "Task_eventDeltaTime_%d", i); + DBWriteContactSettingDword(0, MODULE, buf, it->eventDeltaTime); + sprintf_s(buf, "Task_filterId_%d", i); + DBWriteContactSettingDword(0, MODULE, buf, it->filterId); + sprintf_s(buf, "Task_dayTime_%d", i); + DBWriteContactSettingDword(0, MODULE, buf, it->dayTime); + sprintf_s(buf, "Task_dayOfWeek_%d", i); + DBWriteContactSettingDword(0, MODULE, buf, it->dayOfWeek); + sprintf_s(buf, "Task_dayOfMonth_%d", i); + DBWriteContactSettingDword(0, MODULE, buf, it->dayOfMonth); + sprintf_s(buf, "Task_deltaTime_%d", i); + DBWriteContactSettingDword(0, MODULE, buf, it->deltaTime); + sprintf_s(buf, "Task_lastExport_low_%d", i); + DBWriteContactSettingDword(0, MODULE, buf, (int)it->lastExport); + sprintf_s(buf, "Task_lastExport_hi_%d", i); + DBWriteContactSettingDword(0, MODULE, buf, ((unsigned long long int)it->lastExport) >> 32); + sprintf_s(buf, "Task_ftpName_%d", i); + DBWriteContactSettingWString(0, MODULE, buf, it->ftpName.c_str()); + sprintf_s(buf, "Task_filterName_%d", i); + DBWriteContactSettingWString(0, MODULE, buf, it->filterName.c_str()); + sprintf_s(buf, "Task_filePath_%d", i); + DBWriteContactSettingWString(0, MODULE, buf, it->filePath.c_str()); + sprintf_s(buf, "Task_taskName_%d", i); + DBWriteContactSettingWString(0, MODULE, buf, it->taskName.c_str()); + sprintf_s(buf, "Task_zipPassword_%d", i); + DBWriteContactSettingString(0, MODULE, buf, it->zipPassword.c_str()); + + HANDLE _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + sprintf_s(buf, "IsInTask_%d", i); + while(_hContact) + { + DBDeleteContactSetting(_hContact, MODULE, buf); + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); + } + + for(size_t j = 0; j < it->contacts.size(); ++j) + { + DBWriteContactSettingByte(it->contacts[j], MODULE, buf, 1); + } + + it->orderNr = i++; + taskOptions.push_back(*it); + } + + DBWriteContactSettingDword(0, MODULE, "Task_count", i); + + for(i = (int)tasks->size(); i < oldTaskNr; ++i) + { + sprintf_s(buf, "Task_compress_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_useFtp_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_isSystem_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_active_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_type_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_eventUnit_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_trigerType_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_exportType_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_eventDeltaTime_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_filterId_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_dayTime_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_dayOfWeek_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_dayOfMonth_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_deltaTime_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_lastExport_low_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_lastExport_hi_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_ftpName_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_filterName_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_filePath_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + sprintf_s(buf, "Task_taskName_%d", i); + DBDeleteContactSetting(NULL, MODULE, buf); + + HANDLE _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + sprintf_s(buf, "IsInTask_%d", i); + while(_hContact) + { + DBDeleteContactSetting(_hContact, MODULE, buf); + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); + } + } + + LeaveCriticalSection(&criticalSection); +} + +void Options::SaveTaskTime(TaskOptions& to) +{ + int i = to.orderNr; + char buf[256]; + sprintf_s(buf, "Task_lastExport_low_%d", i); + DBWriteContactSettingDword(0, MODULE, buf, (int)to.lastExport); + sprintf_s(buf, "Task_lastExport_hi_%d", i); + DBWriteContactSettingDword(0, MODULE, buf, ((unsigned long long int)to.lastExport) >> 32); +} + +void Options::LoadTasks() +{ + int taskCount = DBGetContactSettingDword(0, MODULE, "Task_count", 0); + char buf[256]; + for(int i = 0; i < taskCount; ++i) + { + TaskOptions to; + sprintf_s(buf, "Task_compress_%d", i); + to.compress = DBGetContactSettingByte(0, MODULE, buf, to.compress) != 0; + sprintf_s(buf, "Task_useFtp_%d", i); + to.useFtp = DBGetContactSettingByte(0, MODULE, buf, to.useFtp) != 0; + sprintf_s(buf, "Task_isSystem_%d", i); + to.isSystem = DBGetContactSettingByte(0, MODULE, buf, to.isSystem) != 0; + sprintf_s(buf, "Task_active_%d", i); + to.active = DBGetContactSettingByte(0, MODULE, buf, to.active) != 0; + sprintf_s(buf, "Task_exportImported_%d", i); + to.exportImported = DBGetContactSettingByte(0, MODULE, buf, to.exportImported) != 0; + sprintf_s(buf, "Task_type_%d", i); + to.type = (TaskOptions::TaskType)DBGetContactSettingByte(0, MODULE, buf, to.type); + sprintf_s(buf, "Task_eventUnit_%d", i); + to.eventUnit = (TaskOptions::EventUnit)DBGetContactSettingByte(0, MODULE, buf, to.eventUnit); + sprintf_s(buf, "Task_trigerType_%d", i); + to.trigerType = (TaskOptions::TrigerType)DBGetContactSettingByte(0, MODULE, buf, to.trigerType); + sprintf_s(buf, "Task_exportType_%d", i); + to.exportType = (IExport::ExportType)DBGetContactSettingByte(0, MODULE, buf, to.exportType); + sprintf_s(buf, "Task_importType_%d", i); + to.importType = (IImport::ImportType)DBGetContactSettingByte(0, MODULE, buf, to.importType); + sprintf_s(buf, "Task_eventDeltaTime_%d", i); + to.eventDeltaTime = DBGetContactSettingDword(0, MODULE, buf, to.eventDeltaTime); + sprintf_s(buf, "Task_filterId_%d", i); + to.filterId = DBGetContactSettingDword(0, MODULE, buf, to.filterId); + sprintf_s(buf, "Task_dayTime_%d", i); + to.dayTime = DBGetContactSettingDword(0, MODULE, buf, to.dayTime); + sprintf_s(buf, "Task_dayOfWeek_%d", i); + to.dayOfWeek = DBGetContactSettingDword(0, MODULE, buf, to.dayOfWeek); + sprintf_s(buf, "Task_dayOfMonth_%d", i); + to.dayOfMonth = DBGetContactSettingDword(0, MODULE, buf, to.dayOfMonth); + sprintf_s(buf, "Task_deltaTime_%d", i); + to.deltaTime = DBGetContactSettingDword(0, MODULE, buf, to.deltaTime); + unsigned long long int le = to.lastExport; + sprintf_s(buf, "Task_lastExport_low_%d", i); + to.lastExport = DBGetContactSettingDword(0, MODULE, buf, (int)le) & 0xffffffff; + sprintf_s(buf, "Task_lastExport_hi_%d", i); + to.lastExport |= ((unsigned long long int)DBGetContactSettingDword(0, MODULE, buf, le >> 32)) << 32; + sprintf_s(buf, "Task_ftpName_%d", i); + DBVARIANT var; + if(!DBGetContactSettingWString(0, MODULE, buf, &var)) + { + to.ftpName = var.ptszVal; + DBFreeVariant(&var); + } + sprintf_s(buf, "Task_filterName_%d", i); + if(!DBGetContactSettingWString(0, MODULE, buf, &var)) + { + to.filterName = var.ptszVal; + DBFreeVariant(&var); + } + sprintf_s(buf, "Task_filePath_%d", i); + if(!DBGetContactSettingWString(0, MODULE, buf, &var)) + { + to.filePath = var.ptszVal; + DBFreeVariant(&var); + } + sprintf_s(buf, "Task_taskName_%d", i); + if(!DBGetContactSettingWString(0, MODULE, buf, &var)) + { + to.taskName = var.ptszVal; + DBFreeVariant(&var); + } + sprintf_s(buf, "Task_zipPassword_%d", i); + if(!DBGetContactSettingString(0, MODULE, buf, &var)) + { + to.zipPassword = var.pszVal; + DBFreeVariant(&var); + } + + HANDLE _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + sprintf_s(buf, "IsInTask_%d", i); + while(_hContact) + { + if(DBGetContactSettingByte(_hContact, MODULE, buf, 0) == 1) + { + to.contacts.push_back(_hContact); + } + + _hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)_hContact, 0); + } + + to.orderNr = i; + taskOptions.push_back(to); + } +} + +void OptionsMainChanged(); +void OptionsGroupChanged(); +void OptionsMessageChanged(); +void OptionsSearchingChanged(); +void OptionsSchedulerChanged(); +void InitTaskMenuItems(); + +void SetEventCB(HWND hwndCB, int eventId) +{ + int cpCount = SIZEOF(EventNames); + int selCpIdx = -1; + for(int i = 0; i < cpCount; ++i) + { + if(EventNames[i].id == eventId) + selCpIdx = i; + } + + if(selCpIdx == -1) + { + TCHAR buf[24]; + _stprintf_s(buf, 24, _T("%d"), eventId); + ComboBox_SetText(hwndCB, buf); + } + else + { + ComboBox_SetCurSel(hwndCB, selCpIdx); + } +} + +int GetEventCB(HWND hwndCB, bool errorReport, int &eventId) +{ + int selCpIdx = ComboBox_GetCurSel(hwndCB); + if(selCpIdx < 0) + { + TCHAR text[24]; + ComboBox_GetText(hwndCB, text, 24); + TCHAR * stopOn = NULL; + long cp = _tcstol(text, &stopOn, 10); + if(errorReport && (stopOn == text || *stopOn != '\0' || cp < 0)) + { + MessageBox(GetParent(hwndCB), TranslateT("Invalid event number"), TranslateT("Error"), MB_OK | MB_ICONERROR); + SetFocus(hwndCB); + return -1; + } + + eventId = cp; + } + else if(selCpIdx > 1) + eventId = EventNames[selCpIdx - 2].id; + else + return selCpIdx + 1; + + return 0; +} + +void ClearLB(HWND hwndLB) +{ + while(ListBox_GetCount(hwndLB) > 0) + ListBox_DeleteString(hwndLB, 0); +} + +void ReloadEventLB(HWND hwndLB, const FilterOptions &sel) +{ + while(ListBox_GetCount(hwndLB) > 0) + ListBox_DeleteString(hwndLB, 0); + if(sel.onlyIncomming && !sel.onlyOutgoing) + { + ListBox_AddString(hwndLB, TranslateT("Incoming events")); + } + else if(sel.onlyOutgoing && !sel.onlyIncomming) + { + ListBox_AddString(hwndLB, TranslateT("Outgoing events")); + } + + for(std::vector::const_iterator it = sel.events.begin(); it != sel.events.end(); ++it) + { + int cpCount = SIZEOF(EventNames); + int selCpIdx = -1; + for(int i = 0; i < cpCount; ++i) + { + if(EventNames[i].id == *it) + selCpIdx = i; + } + if(selCpIdx == -1) + { + TCHAR buf[24]; + _stprintf_s(buf, 24, _T("%d"), *it); + ListBox_AddString(hwndLB, buf); + } + else + { + ListBox_AddString(hwndLB, TranslateTS(EventNames[selCpIdx].name)); + } + } +} + +bool CheckFile(HWND hwndEdit) +{ + TCHAR buf[MAX_PATH]; + Edit_GetText(hwndEdit, buf, MAX_PATH); + DWORD atr = GetFileAttributes(buf); + if(atr == INVALID_FILE_ATTRIBUTES || atr & FILE_ATTRIBUTE_DIRECTORY) + { + MessageBox(GetParent(hwndEdit), TranslateT("File do not exist. Enter correct file path."), TranslateT("Invalid file"), MB_OK | MB_ICONERROR); + SetFocus(hwndEdit); + return false; + } + + return true; +} + +bool OpenFileDlg(HWND hwndDlg, HWND hwndEdit, const TCHAR* defName, const TCHAR* ext, const TCHAR* title, bool open) +{ + TCHAR filter[1024]; + std::locale loc; + TCHAR extUpper[32]; + _tcscpy_s(extUpper, ext); + extUpper[0] = std::toupper(ext[0], loc); + _stprintf_s(filter, TranslateT("%s Files (*.%s)"), extUpper, ext); + size_t len = _tcslen(filter) + 1; + _stprintf_s(filter + len, 1024 - len, _T("*.%s"), ext); + len += _tcslen(filter + len) + 1; + _tcscpy_s(filter + len, 1024 - len, TranslateT("All Files (*.*)")); + len += _tcslen(filter + len) + 1; + _tcscpy_s(filter + len, 1024 - len, _T("*.*")); + len += _tcslen(filter + len) + 1; + filter[len] = 0; + TCHAR stzFilePath[1024]; + + Edit_GetText(hwndEdit, stzFilePath, 1023); + if(stzFilePath[0] == 0) + { + _tcscpy_s(stzFilePath, defName); + len = _tcslen(stzFilePath) + 1; + stzFilePath[len] = 0; + } + else + { + len = _tcslen(stzFilePath) + 1; + stzFilePath[len] = 0; + } + + OPENFILENAME ofn = {0}; + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwndDlg; + ofn.lpstrFilter = filter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = stzFilePath; + ofn.lpstrTitle = title; + ofn.nMaxFile = 1024; + ofn.lpstrDefExt = ext; + if(open) + { + ofn.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + if(GetOpenFileName(&ofn)) + { + Edit_SetText(hwndEdit, stzFilePath); + return true; + } + } + else + { + ofn.Flags = OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_NOCHANGEDIR; + if(GetSaveFileName(&ofn)) + { + Edit_SetText(hwndEdit, stzFilePath); + return true; + } + } + + return false; +} + +INT_PTR CALLBACK Options::DlgProcOptsMain(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)FALSE); + CheckDlgButton(hwndDlg, IDC_SHOWCONTACTS, instance->showContacts ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_SHOWCONTACTGROUPS, instance->showContactGroups ? 1 : 0); + HWND events = GetDlgItem(hwndDlg, IDC_EVENT); + HWND defFilter = GetDlgItem(hwndDlg, IDC_DEFFILTER); + HWND listFilter = GetDlgItem(hwndDlg, IDC_LIST_FILTERS); + HWND ftp = GetDlgItem(hwndDlg, IDC_WINSCP); + HWND ftpLog = GetDlgItem(hwndDlg, IDC_WINSCPLOG); + ComboBox_AddString(events, TranslateT("Incoming events")); + ComboBox_AddString(events, TranslateT("Outgoing events")); + for(int i = 0 ; i < SIZEOF(EventNames); ++i) + { + ComboBox_AddString(events, TranslateTS(EventNames[i].name)); + } + + ComboBox_AddString(defFilter, TranslateT("Default history events")); + ComboBox_AddString(defFilter, TranslateT("All events")); + Edit_LimitText(GetDlgItem(hwndDlg, IDC_FILTER_NAME), 20); + ComboBox_LimitText(events, 20); + + instance->customFiltersTemp.clear(); + instance->customFiltersTemp.insert(instance->customFiltersTemp.begin(), instance->customFilters.begin(), instance->customFilters.end()); + for(std::vector::iterator it = instance->customFiltersTemp.begin(); it != instance->customFiltersTemp.end(); ++it) + { + ComboBox_AddString(defFilter, it->name.c_str()); + ListBox_AddString(listFilter, it->name.c_str()); + } + ComboBox_SetCurSel(defFilter, instance->defFilter); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_FILTER), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_EVENT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_EVENT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), FALSE); + + Edit_LimitText(ftp, MAX_PATH); + Edit_LimitText(ftpLog, MAX_PATH); + Edit_SetText(ftp, instance->ftpExePath.c_str()); + Edit_SetText(ftpLog, instance->ftpLogPath.c_str()); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)TRUE); + return TRUE; + } + case WM_COMMAND: + { + BOOL init = (BOOL)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (HIWORD(wParam) == BN_CLICKED) + { + HWND listFilter = GetDlgItem(hwndDlg, IDC_LIST_FILTERS); + HWND listEvents = GetDlgItem(hwndDlg, IDC_LIST_EVENTS); + HWND nameFilter = GetDlgItem(hwndDlg, IDC_FILTER_NAME); + HWND defFilter = GetDlgItem(hwndDlg, IDC_DEFFILTER); + HWND eventCB = GetDlgItem(hwndDlg, IDC_EVENT); + switch(LOWORD(wParam)) + { + case IDC_ADD_FILTER: + { + TCHAR name[24]; + Edit_GetText(nameFilter, name, 24); + if(name[0] == 0) + { + MessageBox(hwndDlg, TranslateT("Enter filter name"), TranslateT("Error"), MB_ICONERROR); + return TRUE; + } + + FilterOptions fo(name); + for(std::vector::iterator it = instance->customFiltersTemp.begin(); it != instance->customFiltersTemp.end(); ++it) + { + if(it->name == fo.name) + { + MessageBox(hwndDlg, TranslateT("Filter name exists"), TranslateT("Error"), MB_ICONERROR); + return TRUE; + } + } + + instance->customFiltersTemp.insert(instance->customFiltersTemp.end(), fo); + int i = ListBox_AddString(listFilter, name); + ListBox_SetCurSel(listFilter, i); + ComboBox_AddString(defFilter, name); + name[0] = 0; + Edit_SetText(nameFilter, name); + ReloadEventLB(listEvents, instance->customFiltersTemp[i]); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_FILTER), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_EVENT), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_EVENT), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), FALSE); + } + break; + case IDC_DELETE_FILTER: + { + int sel = ListBox_GetCurSel(listFilter); + if(sel < 0) + return TRUE; + for(size_t i = sel; i < instance->customFiltersTemp.size() - 1; ++i) + { + instance->customFiltersTemp[i] = instance->customFiltersTemp[i + 1]; + } + + instance->customFiltersTemp.resize(instance->customFiltersTemp.size() - 1); + ListBox_DeleteString(listFilter, sel); + ComboBox_DeleteString(defFilter, sel + 2); + if(ComboBox_GetCurSel(defFilter) < 0) + { + ComboBox_SetCurSel(defFilter, 0); + } + + ClearLB(listEvents); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_FILTER), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_EVENT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_EVENT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), FALSE); + } + break; + case IDC_ADD_EVENT: + { + int sel = ListBox_GetCurSel(listFilter); + if(sel < 0) + return TRUE; + int eventId; + int selCB = GetEventCB(eventCB, true, eventId); + if(selCB < 0) + return TRUE; + if(selCB == 1) + { + if(instance->customFiltersTemp[sel].onlyIncomming) + { + MessageBox(hwndDlg, TranslateT("Event already exists"), TranslateT("Error"), MB_ICONERROR); + return TRUE; + } + + if(instance->customFiltersTemp[sel].onlyOutgoing) + instance->customFiltersTemp[sel].onlyOutgoing = false; + else + instance->customFiltersTemp[sel].onlyIncomming = true; + } + else if(selCB == 2) + { + if(instance->customFiltersTemp[sel].onlyOutgoing) + { + MessageBox(hwndDlg, TranslateT("Event already exists"), TranslateT("Error"), MB_ICONERROR); + return TRUE; + } + + if(instance->customFiltersTemp[sel].onlyIncomming) + instance->customFiltersTemp[sel].onlyIncomming = false; + else + instance->customFiltersTemp[sel].onlyOutgoing = true; + } + else + { + if(std::find(instance->customFiltersTemp[sel].events.begin(), instance->customFiltersTemp[sel].events.end(), eventId) != instance->customFiltersTemp[sel].events.end()) + { + MessageBox(hwndDlg, TranslateT("Event already exists"), TranslateT("Error"), MB_ICONERROR); + return TRUE; + } + + instance->customFiltersTemp[sel].events.push_back(eventId); + } + + ReloadEventLB(listEvents, instance->customFiltersTemp[sel]); + ComboBox_SetCurSel(eventCB, -1); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), FALSE); + } + break; + case IDC_DELETE_EVENT: + { + int sel = ListBox_GetCurSel(listFilter); + if(sel < 0) + return TRUE; + int eventSel = ListBox_GetCurSel(listEvents); + if(eventSel < 0) + return TRUE; + int stId = 0; + if(instance->customFiltersTemp[sel].onlyIncomming || instance->customFiltersTemp[sel].onlyOutgoing) + ++stId; + if(eventSel >= stId) + { + --eventSel; + for(int i = eventSel; i < (int)instance->customFiltersTemp[sel].events.size() - 1; ++i) + { + instance->customFiltersTemp[sel].events[i] = instance->customFiltersTemp[sel].events[i + 1]; + } + + instance->customFiltersTemp[sel].events.resize(instance->customFiltersTemp[sel].events.size() - 1); + } + else + { + instance->customFiltersTemp[sel].onlyIncomming = false; + instance->customFiltersTemp[sel].onlyOutgoing = false; + } + + ReloadEventLB(listEvents, instance->customFiltersTemp[sel]); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), FALSE); + } + break; + case IDC_WINSCP_BROWSE: + if(!OpenFileDlg(hwndDlg, GetDlgItem(hwndDlg, IDC_WINSCP), _T("WinSCP.exe"), _T("exe"), TranslateT("Browse WinSCP file"), true)) + { + return TRUE; + } + + break; + case IDC_WINSCPLOG_BROWSE: + if(!OpenFileDlg(hwndDlg, GetDlgItem(hwndDlg, IDC_WINSCPLOG), _T("ftplog.txt"), _T("txt"), TranslateT("Save WinSCP log file"), false)) + { + return TRUE; + } + + break; + } + } + else if(HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_LIST_FILTERS) + { + HWND listFilter = GetDlgItem(hwndDlg, IDC_LIST_FILTERS); + HWND listEvents = GetDlgItem(hwndDlg, IDC_LIST_EVENTS); + int sel = ListBox_GetCurSel(listFilter); + if(sel < 0) + ClearLB(listEvents); + else + ReloadEventLB(listEvents, instance->customFiltersTemp[sel]); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_FILTER), sel >= 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_EVENT), sel >= 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_EVENT), sel >= 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), FALSE); + } + else if(HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_LIST_EVENTS) + { + HWND listEvents = GetDlgItem(hwndDlg, IDC_LIST_EVENTS); + int sel = ListBox_GetCurSel(listEvents); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_EVENT), sel >= 0); + } + + if (init && (HIWORD(wParam) == BN_CLICKED || (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_DEFFILTER) || (HIWORD(wParam) == EN_CHANGE && LOWORD(wParam) != IDC_FILTER_NAME))) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + return TRUE; + } + case WM_NOTIFY: + { + if(((LPNMHDR)lParam)->code == PSN_APPLY) + { + HWND ftp = GetDlgItem(hwndDlg, IDC_WINSCP); + TCHAR buf[MAX_PATH]; + Edit_GetText(ftp, buf, MAX_PATH); + if(buf[0] != 0 && !CheckFile(ftp)) + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); + return TRUE; + } + + instance->ftpExePath = buf; + Edit_GetText(GetDlgItem(hwndDlg, IDC_WINSCPLOG), buf, MAX_PATH); + instance->ftpLogPath = buf; + + instance->showContacts = IsDlgButtonChecked(hwndDlg, IDC_SHOWCONTACTS) ? true : false; + instance->showContactGroups = IsDlgButtonChecked(hwndDlg, IDC_SHOWCONTACTGROUPS) ? true : false; + instance->defFilter = ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_DEFFILTER)); + instance->customFilters.clear(); + instance->customFilters.insert(instance->customFilters.begin(), instance->customFiltersTemp.begin(), instance->customFiltersTemp.end()); + Options::instance->Save(); + OptionsMainChanged(); + } + return TRUE; + } + } + + return FALSE; +} + +class OptsData +{ +public: + OptsData() + { + init = false; + } + + bool init; +}; + +INT_PTR CALLBACK Options::DlgProcOptsGroupList(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + OptsData* optsData = new OptsData(); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)optsData); + + CheckDlgButton(hwndDlg, IDC_NEWONTOP, instance->groupNewOnTop ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_SHOWEVENTS, instance->groupShowEvents ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_SHOWTIME, instance->groupShowTime ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_SHOWNAME, instance->groupShowName ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_SHOWMESSAGE, instance->groupShowMessage ? 1 : 0); + Edit_LimitText(GetDlgItem(hwndDlg, IDC_MESSAGELEN), 4); + SetDlgItemInt(hwndDlg, IDC_MESSAGELEN, instance->groupMessageLen, FALSE); + SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_SHOWMESSAGE, BN_CLICKED), NULL); + Edit_LimitText(GetDlgItem(hwndDlg, IDC_GROUPTIME), 2); + Edit_LimitText(GetDlgItem(hwndDlg, IDC_LIMITMESSAGES), 3); + SetDlgItemInt(hwndDlg, IDC_GROUPTIME, instance->groupTime, FALSE); + SetDlgItemInt(hwndDlg, IDC_LIMITMESSAGES, instance->groupMessagesNumber, FALSE); + + optsData->init = true; + return TRUE; + } + case WM_COMMAND: + { + OptsData* optsData = (OptsData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_SHOWMESSAGE) + { + if(IsDlgButtonChecked(hwndDlg, IDC_SHOWMESSAGE)) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_MESSAGELEN), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_MESSAGELEN_DESC), TRUE); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_MESSAGELEN), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_MESSAGELEN_DESC), FALSE); + } + } + if (optsData->init && (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == EN_CHANGE)) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + return TRUE; + } + case WM_NOTIFY: + { + if(((LPNMHDR)lParam)->code == PSN_APPLY) + { + instance->groupNewOnTop = IsDlgButtonChecked(hwndDlg, IDC_NEWONTOP) ? true : false; + instance->groupShowEvents = IsDlgButtonChecked(hwndDlg, IDC_SHOWEVENTS) ? true : false; + instance->groupShowTime = IsDlgButtonChecked(hwndDlg, IDC_SHOWTIME) ? true : false; + instance->groupShowName = IsDlgButtonChecked(hwndDlg, IDC_SHOWNAME) ? true : false; + instance->groupShowMessage = IsDlgButtonChecked(hwndDlg, IDC_SHOWMESSAGE) ? true : false; + BOOL success; + instance->groupMessageLen = GetDlgItemInt(hwndDlg, IDC_MESSAGELEN, &success, FALSE); + instance->groupTime = GetDlgItemInt(hwndDlg, IDC_GROUPTIME, &success, FALSE); + instance->groupMessagesNumber = GetDlgItemInt(hwndDlg, IDC_LIMITMESSAGES, &success, FALSE); + + Options::instance->Save(); + OptionsGroupChanged(); + } + return TRUE; + } + } + + return FALSE; +} + +INT_PTR CALLBACK Options::DlgProcOptsMessages(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + + CheckDlgButton(hwndDlg, IDC_NEWONTOP, instance->messagesNewOnTop ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_SHOWDATE, instance->messagesShowDate ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_SHOWSECOND, instance->messagesShowSec ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_SHOWNAME, instance->messagesShowName ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_SHOWEVENTS, instance->messagesShowEvents ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_SHOWSMILEYS, instance->messagesUseSmileys ? 1 : 0); + if(!g_SmileyAddAvail) + EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWSMILEYS), FALSE); + return TRUE; + } + case WM_COMMAND: + { + if (HIWORD(wParam) == BN_CLICKED) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + return TRUE; + } + case WM_NOTIFY: + { + if(((LPNMHDR)lParam)->code == PSN_APPLY) + { + instance->messagesNewOnTop = IsDlgButtonChecked(hwndDlg, IDC_NEWONTOP) ? true : false; + instance->messagesShowDate = IsDlgButtonChecked(hwndDlg, IDC_SHOWDATE) ? true : false; + instance->messagesShowSec = IsDlgButtonChecked(hwndDlg, IDC_SHOWSECOND) ? true : false; + instance->messagesShowName = IsDlgButtonChecked(hwndDlg, IDC_SHOWNAME) ? true : false; + instance->messagesShowEvents = IsDlgButtonChecked(hwndDlg, IDC_SHOWEVENTS) ? true : false; + instance->messagesUseSmileys = IsDlgButtonChecked(hwndDlg, IDC_SHOWSMILEYS) ? true : false; + + Options::instance->Save(); + OptionsMessageChanged(); + } + return TRUE; + } + } + + return FALSE; +} + +INT_PTR CALLBACK Options::DlgProcOptsSearching(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + + CheckDlgButton(hwndDlg, IDC_FORLIST, instance->searchForInList ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_FORMES, instance->searchForInMess ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_MATCHCASE, instance->searchMatchCase ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_MATCHWHOLE, instance->searchMatchWhole ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_ONLYIN, instance->searchOnlyIn ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_ONLYOUT, instance->searchOnlyOut ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_ONLYGROUP, instance->searchOnlyGroup ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_ALLCONTACTS, instance->searchAllContacts ? 1 : 0); + return TRUE; + } + case WM_COMMAND: + { + if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ONLYIN) + { + if(IsDlgButtonChecked(hwndDlg, IDC_ONLYIN) && IsDlgButtonChecked(hwndDlg, IDC_ONLYOUT)) + { + CheckDlgButton(hwndDlg, IDC_ONLYOUT, 0); + } + } + else if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ONLYOUT) + { + if(IsDlgButtonChecked(hwndDlg, IDC_ONLYOUT) && IsDlgButtonChecked(hwndDlg, IDC_ONLYIN)) + { + CheckDlgButton(hwndDlg, IDC_ONLYIN, 0); + } + } + + if (HIWORD(wParam) == BN_CLICKED) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + return TRUE; + } + case WM_NOTIFY: + { + if(((LPNMHDR)lParam)->code == PSN_APPLY) + { + instance->searchForInList = IsDlgButtonChecked(hwndDlg, IDC_FORLIST) ? true : false; + instance->searchForInMess = IsDlgButtonChecked(hwndDlg, IDC_FORMES) ? true : false; + instance->searchMatchCase = IsDlgButtonChecked(hwndDlg, IDC_MATCHCASE) ? true : false; + instance->searchMatchWhole = IsDlgButtonChecked(hwndDlg, IDC_MATCHWHOLE) ? true : false; + instance->searchOnlyIn = IsDlgButtonChecked(hwndDlg, IDC_ONLYIN) ? true : false; + instance->searchOnlyOut = IsDlgButtonChecked(hwndDlg, IDC_ONLYOUT) ? true : false; + instance->searchOnlyGroup = IsDlgButtonChecked(hwndDlg, IDC_ONLYGROUP) ? true : false; + instance->searchAllContacts = IsDlgButtonChecked(hwndDlg, IDC_ALLCONTACTS) ? true : false; + + Options::instance->Save(); + OptionsSearchingChanged(); + } + return TRUE; + } + } + + return FALSE; +} + +void InitCodepageCB(HWND hwndCB, unsigned int codepage, const std::wstring& name) +{ + int cpCount = sizeof(cpTable) / sizeof(cpTable[0]); + int selCpIdx = -1; + ComboBox_LimitText(hwndCB, 256); + for(int i = 0; i < cpCount; ++i) + { + ComboBox_AddString(hwndCB, TranslateTS(cpTable[i].cpName)); + if(cpTable[i].cpId == codepage && name == cpTable[i].cpName) + selCpIdx = i; + } + + if(selCpIdx == -1) + { + TCHAR buf[300]; + _stprintf_s(buf, 300, _T("%d;%s"), codepage, name.c_str()); + ComboBox_SetText(hwndCB, buf); + } + else + { + ComboBox_SetCurSel(hwndCB, selCpIdx); + } + + ComboBox_LimitText(hwndCB, 127); +} + +unsigned int GetCodepageCB(HWND hwndCB, bool errorReport, unsigned int defCp, const std::wstring& defName, std::wstring& name) +{ + int selCpIdx = ComboBox_GetCurSel(hwndCB); + if(selCpIdx < 0) + { + TCHAR text[128]; + ComboBox_GetText(hwndCB, text, 128); + std::wstring str = text; + name = _T(""); + size_t pos = str.find_first_of(_T(';')); + if(pos < str.length()) + { + text[pos] = 0; + name = str.substr(pos + 1); + } + + TCHAR * stopOn = NULL; + long cp = _tcstol(text, &stopOn, 10); + if((pos >= str.length() || name.empty() || stopOn == text || *stopOn != '\0' || cp < 0 || cp > 0xffff)) + { + if(errorReport) + { + MessageBox(GetParent(hwndCB), TranslateT("You've entered invalid codepage. Select codepage from combo box or enter correct number."), TranslateT("Invalid codepage"), MB_OK | MB_ICONERROR); + SetFocus(hwndCB); + } + + name = defName; + return -1; + } + + return cp; + } + else + { + name = cpTable[selCpIdx].cpName; + return cpTable[selCpIdx].cpId; + } +} + +INT_PTR CALLBACK Options::DlgProcOptsExport(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)FALSE); + InitCodepageCB(GetDlgItem(hwndDlg, IDC_TXTENC), instance->codepageTxt, instance->encodingTxt); + InitCodepageCB(GetDlgItem(hwndDlg, IDC_HTML1ENC), instance->codepageHtml1, instance->encodingHtml1); + InitCodepageCB(GetDlgItem(hwndDlg, IDC_HTML2ENC), instance->codepageHtml2, instance->encodingHtml2); + CheckDlgButton(hwndDlg, IDC_HTML1DATE, instance->exportHtml1ShowDate ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_HTML2DATE, instance->exportHtml2ShowDate ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_HTML2SHOWSMILEYS, instance->exportHtml2UseSmileys ? 1 : 0); + Edit_LimitText(GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE), MAX_PATH); + if(instance->extCssHtml2.empty()) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_CSS_BROWSE), FALSE); + } + else + { + CheckDlgButton(hwndDlg, IDC_HTML2EXTCSS, TRUE); + Edit_SetText(GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE), instance->extCssHtml2.c_str()); + } + + if(!g_SmileyAddAvail) + EnableWindow(GetDlgItem(hwndDlg, IDC_HTML2SHOWSMILEYS), FALSE); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)TRUE); + return TRUE; + } + case WM_COMMAND: + { + BOOL init = (BOOL)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_HTML2EXTCSS) + { + BOOL en = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_HTML2EXTCSS); + EnableWindow(GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE), en); + EnableWindow(GetDlgItem(hwndDlg, IDC_CSS_BROWSE), en); + } + else if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_CSS_BROWSE) + { + if(!OpenFileDlg(hwndDlg, GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE), _T(""), _T("css"), TranslateT("Browse CSS file"), true)) + { + return TRUE; + } + } + + if (init && (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)==CBN_EDITCHANGE || HIWORD(wParam) == EN_CHANGE)) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + return TRUE; + } + case WM_NOTIFY: + { + if(((LPNMHDR)lParam)->code == PSN_APPLY) + { + std::wstring newName1, newName2, newName3; + unsigned int cp1 = GetCodepageCB(GetDlgItem(hwndDlg, IDC_TXTENC), true, instance->codepageTxt, instance->encodingTxt, newName1); + if(cp1 == -1) + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); + return TRUE; + } + unsigned int cp2 = GetCodepageCB(GetDlgItem(hwndDlg, IDC_HTML1ENC), true, instance->codepageHtml1, instance->encodingHtml1, newName2); + if(cp2 == -1) + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); + return TRUE; + } + unsigned int cp3 = GetCodepageCB(GetDlgItem(hwndDlg, IDC_HTML2ENC), true, instance->codepageHtml2, instance->encodingHtml2, newName3); + if(cp3 == -1) + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); + return TRUE; + } + if(IsDlgButtonChecked(hwndDlg, IDC_HTML2EXTCSS)) + { + if(!CheckFile(GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE))) + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); + return TRUE; + } + + TCHAR buf[MAX_PATH]; + Edit_GetText(GetDlgItem(hwndDlg, IDC_HTML2EXTCSSFILE), buf, MAX_PATH); + instance->extCssHtml2 = buf; + } + else + { + instance->extCssHtml2 = _T(""); + } + + instance->codepageTxt = cp1; + instance->encodingTxt = newName1; + instance->codepageHtml1 = cp2; + instance->encodingHtml1 = newName2; + instance->codepageHtml2 = cp3; + instance->encodingHtml2 = newName3; + instance->exportHtml1ShowDate = IsDlgButtonChecked(hwndDlg, IDC_HTML1DATE) ? true : false; + instance->exportHtml2ShowDate = IsDlgButtonChecked(hwndDlg, IDC_HTML2DATE) ? true : false; + instance->exportHtml2UseSmileys = IsDlgButtonChecked(hwndDlg, IDC_HTML2SHOWSMILEYS) ? true : false; + + Options::instance->Save(); + } + return TRUE; + } + } + + return FALSE; +} + + +struct DlgTaskOpt +{ + std::list* tasks; + TaskOptions* to; +}; + +INT_PTR CALLBACK Options::DlgProcOptsScheduler(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + std::list* tasks = new std::list(Options::instance->taskOptions.begin(), Options::instance->taskOptions.end()); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)tasks); + HWND listTasks = GetDlgItem(hwndDlg, IDC_LIST_TASKS); + for(std::list::iterator it = tasks->begin(); it != tasks->end(); ++it) + { + ListBox_AddString(listTasks, it->taskName.c_str()); + } + + if(!bPopupsEnabled) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_SCHEDULER_ALERTS), FALSE); + } + + CheckDlgButton(hwndDlg, IDC_SCHEDULER_ALERTS, instance->schedulerAlerts ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_SCHEDULER_HISTORY_ALERTS, instance->schedulerHistoryAlerts ? 1 : 0); + + EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_TASK), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_TASK), FALSE); + return TRUE; + } + case WM_COMMAND: + { + if(HIWORD(wParam) == BN_CLICKED) + { + std::list* tasks = (std::list*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + HWND listTasks = GetDlgItem(hwndDlg, IDC_LIST_TASKS); + int sel = ListBox_GetCurSel(listTasks); + TaskOptions toAdd; + TaskOptions* to = &toAdd; + switch(LOWORD(wParam)) + { + case IDC_EDIT_TASK: + if(sel >= 0) + { + std::list::iterator it = tasks->begin(); + while(sel-- > 0 && it != tasks->end()) + ++it; + if(it == tasks->end()) + break; + to = &(*it); + } + else + break; + case IDC_ADD_TASK: + { + DlgTaskOpt top; + top.tasks = tasks; + top.to = to; + if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_DLG_TASK), hwndDlg, DlgProcOptsTask, (LPARAM)&top) == IDOK) + { + if(LOWORD(wParam) == IDC_ADD_TASK) + { + tasks->push_back(*to); + ListBox_AddString(listTasks, to->taskName.c_str()); + ListBox_SetCurSel(listTasks, tasks->size() - 1); + } + else + { + sel = ListBox_GetCurSel(listTasks); + ListBox_DeleteString(listTasks, sel); + ListBox_InsertString(listTasks, sel, to->taskName.c_str()); + ListBox_SetCurSel(listTasks, sel); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_TASK), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_TASK), TRUE); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + + break; + case IDC_DELETE_TASK: + if(sel >= 0) + { + ListBox_DeleteString(listTasks, sel); + std::list::iterator it = tasks->begin(); + while(sel-- > 0 && it != tasks->end()) + ++it; + if(it != tasks->end()) + tasks->erase(it); + EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_TASK), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_TASK), FALSE); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + + break; + default: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + else if(HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_LIST_TASKS) + { + HWND listTasks = GetDlgItem(hwndDlg, IDC_LIST_TASKS); + int sel = ListBox_GetCurSel(listTasks); + if(sel < 0) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_TASK), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_TASK), FALSE); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_TASK), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_TASK), TRUE); + } + } + return TRUE; + } + case WM_NOTIFY: + { + if(((LPNMHDR)lParam)->code == PSN_APPLY) + { + std::list* tasks = (std::list*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + instance->schedulerAlerts = IsDlgButtonChecked(hwndDlg, IDC_SCHEDULER_ALERTS) ? true : false; + instance->schedulerHistoryAlerts = IsDlgButtonChecked(hwndDlg, IDC_SCHEDULER_HISTORY_ALERTS) ? true : false; + Options::instance->SaveTasks(tasks); + OptionsSchedulerChanged(); + InitTaskMenuItems(); + } + return TRUE; + } + case WM_DESTROY: + { + std::list* tasks = (std::list*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + delete tasks; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, NULL); + break; + } + } + + return FALSE; +} + +void ResetListOptions(HWND hwnd) +{ + SendMessage(hwnd, CLM_SETGREYOUTFLAGS, 0, 0); + SendMessage(hwnd, CLM_SETLEFTMARGIN, 2, 0); + SendMessage(hwnd, CLM_SETBKBITMAP, 0, (LPARAM)(HBITMAP) NULL); + SendMessage(hwnd, CLM_SETBKCOLOR, GetSysColor(COLOR_WINDOW), 0); + SendMessage(hwnd, CLM_SETINDENT, 10, 0); + for (int i = 0; i <= FONTID_MAX; i++) + SendMessage(hwnd, CLM_SETTEXTCOLOR, i, GetSysColor(COLOR_WINDOWTEXT)); +} + +void RebuildList(HWND hwnd, HANDLE hSystem, TaskOptions* to) +{ + HANDLE hItem; + if(to->isSystem && hSystem) + { + SendMessage(hwnd, CLM_SETCHECKMARK, (WPARAM) hSystem, 1); + } + + for(size_t i = 0; i < to->contacts.size(); ++i) + { + hItem = (HANDLE) SendMessage(hwnd, CLM_FINDCONTACT, (WPARAM) to->contacts[i], 0); + if (hItem) + SendMessage(hwnd, CLM_SETCHECKMARK, (WPARAM) hItem, 1); + } +} + +void SaveList(HWND hwnd, HANDLE hSystem, TaskOptions* to) +{ + HANDLE hContact, hItem; + + to->contacts.clear(); + if (hSystem) + to->isSystem = SendMessage(hwnd, CLM_GETCHECKMARK, (WPARAM) hSystem, 0) != 0; + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + do + { + hItem = (HANDLE) SendMessage(hwnd, CLM_FINDCONTACT, (WPARAM) hContact, 0); + if (hItem && SendMessage(hwnd, CLM_GETCHECKMARK, (WPARAM) hItem, 0)) + to->contacts.push_back(hContact); + } + while (hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0)); +} + +bool IsValidTask(TaskOptions& to, std::list* top = NULL, std::wstring* err = NULL, std::wstring* errDescr = NULL); + +#ifndef LOCALE_SSHORTTIME +#define LOCALE_SSHORTTIME 0x00000079 +#endif + +INT_PTR CALLBACK Options::DlgProcOptsTask(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static HANDLE hSystem; + switch(msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + DlgTaskOpt* top = (DlgTaskOpt*)lParam; + TaskOptions* to = top->to; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); + HWND comboType = GetDlgItem(hwndDlg, IDC_TASK_TYPE); + HWND filter = GetDlgItem(hwndDlg, IDC_TASK_FILTER); + HWND eventUnit = GetDlgItem(hwndDlg, IDC_EVENT_UNIT); + HWND trigerType = GetDlgItem(hwndDlg, IDC_TRIGER_TYPE); + HWND exportType = GetDlgItem(hwndDlg, IDC_EXPORT_TYPE); + HWND importType = GetDlgItem(hwndDlg, IDC_IMPORT_TYPE); + HWND compress = GetDlgItem(hwndDlg, IDC_COMPRESS); + HWND exportPath = GetDlgItem(hwndDlg, IDC_EXPORT_PATH); + HWND ftpFile = GetDlgItem(hwndDlg, IDC_FTP); + HWND ftpFileButton = GetDlgItem(hwndDlg, IDC_UPLOAD); + HWND contactList = GetDlgItem(hwndDlg, IDC_LIST_CONTACTSEX); + HWND weekList = GetDlgItem(hwndDlg, IDC_TRIGER_WEEK); + HWND day = GetDlgItem(hwndDlg, IDC_TRIGER_DAY); + HWND deltaTime = GetDlgItem(hwndDlg, IDC_TRIGER_DELTA_TIME); + HWND time = GetDlgItem(hwndDlg, IDC_TRIGER_TIME); + HWND name = GetDlgItem(hwndDlg, IDC_TASK_NAME); + HWND active = GetDlgItem(hwndDlg, IDC_TASK_ACTIVE); + HWND star = GetDlgItem(hwndDlg, IDC_TASK_STAR); + HWND password = GetDlgItem(hwndDlg, IDC_PASSWORD); + HWND expImp = GetDlgItem(hwndDlg, IDC_EXPIMP); + + Edit_LimitText(name, 16); + Edit_SetText(name, to->taskName.c_str()); + + Button_SetCheck(active, to->active); + + Button_SetCheck(expImp, to->exportImported); + + ComboBox_AddString(comboType, TranslateT("Export")); + ComboBox_AddString(comboType, TranslateT("Delete")); + ComboBox_AddString(comboType, TranslateT("Export and Delete")); + ComboBox_AddString(comboType, TranslateT("Import")); + ComboBox_AddString(comboType, TranslateT("Import and Marge")); + ComboBox_SetCurSel(comboType, to->type); + + Edit_LimitText(GetDlgItem(hwndDlg, IDC_EVENT_TIME), 6); + SetDlgItemInt(hwndDlg, IDC_EVENT_TIME, to->eventDeltaTime, TRUE); + ComboBox_AddString(eventUnit, TranslateT("Minute")); + ComboBox_AddString(eventUnit, TranslateT("Hour")); + ComboBox_AddString(eventUnit, TranslateT("Day")); + ComboBox_SetCurSel(eventUnit, to->eventUnit); + + ComboBox_AddString(filter, TranslateT("Default history events")); + ComboBox_AddString(filter, TranslateT("All events")); + int selFilter = to->filterId; + if(selFilter > 1) + selFilter = 0; + int i = 1; + for(std::vector::iterator it = instance->customFilters.begin(); it != instance->customFilters.end(); ++it) + { + ++i; + ComboBox_AddString(filter, it->name.c_str()); + if(to->filterId > 1 && it->name == to->filterName) + { + selFilter = i; + } + } + ComboBox_SetCurSel(filter, selFilter); + + ComboBox_AddString(trigerType, TranslateT("At Start")); + ComboBox_AddString(trigerType, TranslateT("At Finish")); + ComboBox_AddString(trigerType, TranslateT("Daily")); + ComboBox_AddString(trigerType, TranslateT("Weekly")); + ComboBox_AddString(trigerType, TranslateT("Monthly")); + ComboBox_AddString(trigerType, TranslateT("Delta time (minutes)")); + ComboBox_AddString(trigerType, TranslateT("Delta time (hours)")); + ComboBox_SetCurSel(trigerType, to->trigerType); + + ComboBox_AddString(exportType, TranslateT("Rich Html")); + ComboBox_AddString(exportType, TranslateT("Plain Html")); + ComboBox_AddString(exportType, TranslateT("Txt")); + ComboBox_AddString(exportType, TranslateT("Binary")); + ComboBox_AddString(exportType, TranslateT("Dat (mContacts)")); + ComboBox_SetCurSel(exportType, to->exportType); + + ComboBox_AddString(importType, TranslateT("Binary")); + ComboBox_AddString(importType, TranslateT("Dat (mContacts)")); + ComboBox_SetCurSel(importType, to->importType); + + Button_SetCheck(compress, to->compress); + Edit_LimitText(password, 99); + SetWindowTextA(password, to->zipPassword.c_str()); + + Edit_LimitText(exportPath, MAX_PATH); + Edit_SetText(exportPath, to->filePath.c_str()); + + if(!FTPAvail()) + { + EnableWindow(ftpFile, FALSE); + EnableWindow(ftpFileButton, FALSE); + to->useFtp = false; + } + + Button_SetCheck(ftpFileButton, to->useFtp); + Edit_SetText(ftpFile, to->ftpName.c_str()); + + ComboBox_AddString(weekList, TranslateT("Monday")); + ComboBox_AddString(weekList, TranslateT("Tuesday")); + ComboBox_AddString(weekList, TranslateT("Wednesday")); + ComboBox_AddString(weekList, TranslateT("Thursday")); + ComboBox_AddString(weekList, TranslateT("Friday")); + ComboBox_AddString(weekList, TranslateT("Saturday")); + ComboBox_AddString(weekList, TranslateT("Sunday")); + ComboBox_SetCurSel(weekList, to->dayOfWeek); + + Edit_LimitText(day, 2); + SetDlgItemInt(hwndDlg, IDC_TRIGER_DAY, to->dayOfMonth, FALSE); + + Edit_LimitText(deltaTime, 4); + SetDlgItemInt(hwndDlg, IDC_TRIGER_DELTA_TIME, to->deltaTime, FALSE); + + TCHAR timeFormat[10]; + if(GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SSHORTTIME, timeFormat, 10) == 0) + { + TCHAR sep = _T(':'); + if(GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIME, timeFormat, 10) > 0) + sep = timeFormat[0]; + _stprintf_s(timeFormat, _T("HH%cmm"), sep); + } + + SYSTEMTIME st; + GetSystemTime (&st); + st.wHour = to->dayTime/60; + st.wMinute = to->dayTime%60; + st.wSecond = 0; + st.wMilliseconds = 0; + DateTime_SetFormat(time, timeFormat); + DateTime_SetSystemtime(time, GDT_VALID, &st); + + CLCINFOITEM cii = { 0 }; + cii.cbSize = sizeof(cii); + cii.flags = CLCIIF_GROUPFONT | CLCIIF_CHECKBOX | CLCIIF_BELOWCONTACTS; + cii.pszText = TranslateT("System"); + hSystem = (HANDLE) SendMessage(contactList, CLM_ADDINFOITEM, 0, (LPARAM) & cii); + SendMessage(contactList, CLM_AUTOREBUILD, 0, 0); + ResetListOptions(contactList); + RebuildList(contactList, hSystem, to); + + SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_TASK_TYPE, CBN_SELCHANGE), NULL); + SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_TRIGER_TYPE, CBN_SELCHANGE), NULL); + SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_COMPRESS, BN_CLICKED), NULL); + SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_UPLOAD, BN_CLICKED), NULL); + SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_COMPRESS, BN_CLICKED), NULL); + return TRUE; + } + case WM_COMMAND: + { + if (HIWORD(wParam) == BN_CLICKED) + { + if (LOWORD(wParam) == IDOK) + { + DlgTaskOpt* top = (DlgTaskOpt*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + TaskOptions* to = top->to; + TaskOptions toCp(*to); + toCp.taskName.resize(17); + int nameLen = Edit_GetText(GetDlgItem(hwndDlg, IDC_TASK_NAME), (wchar_t*)toCp.taskName.c_str(), 17); + toCp.taskName.resize(nameLen); + toCp.active = Button_GetCheck(GetDlgItem(hwndDlg, IDC_TASK_ACTIVE)) != 0; + toCp.exportImported = Button_GetCheck(GetDlgItem(hwndDlg, IDC_EXPIMP)) != 0; + toCp.type = (enum TaskOptions::TaskType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_TASK_TYPE)); + toCp.filterId = ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_TASK_FILTER)); + if(toCp.filterId > 1) + toCp.filterName = instance->customFilters[toCp.filterId - 2].name; + BOOL isOK = FALSE; + toCp.eventDeltaTime = GetDlgItemInt(hwndDlg, IDC_EVENT_TIME, &isOK, TRUE); + if(!isOK) + { + TCHAR msg[256]; + _stprintf_s(msg, TranslateT("Invalid '%s' value."), TranslateT("Events older than")); + MessageBox(hwndDlg, msg, TranslateT("Error"), MB_ICONERROR); + break; + } + toCp.eventUnit = (enum TaskOptions::EventUnit)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_EVENT_UNIT)); + toCp.trigerType = (enum TaskOptions::TrigerType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_TRIGER_TYPE)); + toCp.exportType = (enum IExport::ExportType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_EXPORT_TYPE)); + toCp.importType = (enum IImport::ImportType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_IMPORT_TYPE)); + toCp.compress = Button_GetCheck(GetDlgItem(hwndDlg, IDC_COMPRESS)) != 0; + char bufC[100]; + GetWindowTextA(GetDlgItem(hwndDlg, IDC_PASSWORD), bufC, 100); + toCp.zipPassword = bufC; + HWND exportPath = GetDlgItem(hwndDlg, IDC_EXPORT_PATH); + int exLen = Edit_GetTextLength(exportPath); + toCp.filePath.resize(exLen + 1); + Edit_GetText(exportPath, (wchar_t*)toCp.filePath.c_str(), exLen + 1); + toCp.filePath.resize(exLen); + toCp.useFtp = Button_GetCheck(GetDlgItem(hwndDlg, IDC_UPLOAD)) != 0; + HWND ftpFile = GetDlgItem(hwndDlg, IDC_FTP); + exLen = Edit_GetTextLength(ftpFile); + toCp.ftpName.resize(exLen + 1); + Edit_GetText(ftpFile, (wchar_t*)toCp.ftpName.c_str(), exLen + 1); + toCp.ftpName.resize(exLen); + SYSTEMTIME st; + DateTime_GetSystemtime(GetDlgItem(hwndDlg, IDC_TRIGER_TIME), &st); + toCp.dayTime = st.wHour * 60 + st.wMinute; + toCp.dayOfWeek = ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_TRIGER_WEEK)); + toCp.dayOfMonth = GetDlgItemInt(hwndDlg, IDC_TRIGER_DAY, &isOK, FALSE); + if(!isOK) + { + if(toCp.trigerType == TaskOptions::Monthly) + { + TCHAR msg[256]; + _stprintf_s(msg, TranslateT("Invalid '%s' value."), TranslateT("Day")); + MessageBox(hwndDlg, msg, TranslateT("Error"), MB_ICONERROR); + break; + } + else + toCp.dayOfMonth = to->dayOfMonth; + } + toCp.deltaTime = GetDlgItemInt(hwndDlg, IDC_TRIGER_DELTA_TIME, &isOK, FALSE); + if(!isOK) + { + if(toCp.trigerType == TaskOptions::DeltaMin || toCp.trigerType == TaskOptions::DeltaHour) + { + TCHAR msg[256]; + _stprintf_s(msg, TranslateT("Invalid '%s' value."), TranslateT("Delta time")); + MessageBox(hwndDlg, msg, TranslateT("Error"), MB_ICONERROR); + break; + } + else + toCp.deltaTime = to->deltaTime; + } + SaveList(GetDlgItem(hwndDlg, IDC_LIST_CONTACTSEX), hSystem, &toCp); + std::wstring err; + std::wstring errDescr; + std::wstring lastName = to->taskName; + to->taskName = L""; + if(!IsValidTask(toCp, top->tasks, &err, &errDescr)) + { + to->taskName = lastName; + TCHAR msg[256]; + if(err.empty()) + _tcscpy_s(msg, TranslateT("Some value is invalid")); + else if(errDescr.empty()) + { + _stprintf_s(msg, TranslateT("Invalid '%s' value."), err.c_str()); + } + else + { + _stprintf_s(msg, TranslateT("Invalid '%s' value.\n%s"), err.c_str(), errDescr.c_str()); + } + + MessageBox(hwndDlg, msg, TranslateT("Error"), MB_ICONERROR); + break; + } + + toCp.lastExport = time(NULL); + + *to = toCp; + EndDialog(hwndDlg, IDOK); + } + else if (LOWORD(wParam) == IDCANCEL) + { + EndDialog(hwndDlg, IDCANCEL); + } + else if (LOWORD(wParam) == IDC_UPLOAD) + { + if(Button_GetCheck(GetDlgItem(hwndDlg, IDC_UPLOAD)) == 0) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_FTP), FALSE); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_FTP), TRUE); + } + } + else if(LOWORD(wParam) == IDC_COMPRESS) + { + if(Button_GetCheck(GetDlgItem(hwndDlg, IDC_COMPRESS)) == 0) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_PASSWORD), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_PASSWORD_LABEL), FALSE); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_PASSWORD), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_PASSWORD_LABEL), TRUE); + } + } + } + else if (HIWORD(wParam) == CBN_SELCHANGE) + { + if(LOWORD(wParam) == IDC_TASK_TYPE) + { + TaskOptions::TaskType sel = (enum TaskOptions::TaskType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_TASK_TYPE)); + int show = sel == TaskOptions::Delete ? SW_HIDE : SW_SHOW; + int showFilter = (sel == TaskOptions::Import || sel == TaskOptions::ImportAndMarge) ? SW_HIDE : SW_SHOW; + int showImport = (sel == TaskOptions::Import || sel == TaskOptions::ImportAndMarge) ? SW_SHOW : SW_HIDE; + ShowWindow(GetDlgItem(hwndDlg, IDC_EXPORT_TYPE), show); + ShowWindow(GetDlgItem(hwndDlg, IDC_EXPORT_TYPE_LABEL), show); + ShowWindow(GetDlgItem(hwndDlg, IDC_COMPRESS), show); + ShowWindow(GetDlgItem(hwndDlg, IDC_PASSWORD), show); + ShowWindow(GetDlgItem(hwndDlg, IDC_PASSWORD_LABEL), show); + ShowWindow(GetDlgItem(hwndDlg, IDC_EXPORT_PATH), show); + ShowWindow(GetDlgItem(hwndDlg, IDC_EXPORT_PATH_LABEL), show); + ShowWindow(GetDlgItem(hwndDlg, IDC_FTP), show); + ShowWindow(GetDlgItem(hwndDlg, IDC_UPLOAD), show); + ShowWindow(GetDlgItem(hwndDlg, IDC_FTP_LABEL), show); + ShowWindow(GetDlgItem(hwndDlg, IDC_EXPIMP), show); + ShowWindow(GetDlgItem(hwndDlg, IDC_TASK_FILTER), showFilter); + ShowWindow(GetDlgItem(hwndDlg, IDC_TASK_FILTER_LABEL), showFilter); + ShowWindow(GetDlgItem(hwndDlg, IDC_EVENT_TIME), showFilter); + ShowWindow(GetDlgItem(hwndDlg, IDC_EVENT_UNIT), showFilter); + ShowWindow(GetDlgItem(hwndDlg, IDC_EVENT_LABEL), showFilter); + if(show != showFilter) + { + ShowWindow(GetDlgItem(hwndDlg, IDC_EXPORT_TYPE), SW_HIDE); + ShowWindow(GetDlgItem(hwndDlg, IDC_EXPIMP), SW_HIDE); + } + + ShowWindow(GetDlgItem(hwndDlg, IDC_IMPORT_TYPE), showImport); + std::wstring str; + TCHAR* compressText = TranslateT("Compress output files"); + TCHAR* uploadText = TranslateT("Upload to FTP (WinSCP requred)"); + TCHAR* typeText = TranslateT("Export to"); + if(showFilter == SW_HIDE) + { + str = TranslateT("** Use to insert extension, to insert contact name"); + compressText = TranslateT("Input files are compressed"); + uploadText = TranslateT("Download from FTP (WinSCP requred)"); + typeText = TranslateT("Import from"); + } + else if(show == SW_HIDE) + { + str = TranslateT("* Use negative values to filter younger events"); + } + else + { + str = TranslateT("* Use negative values to filter younger events"); + str += _T("\n"); + str += TranslateT("** Use to insert date, to insert extension, to insert contact name"); + } + + Static_SetText(GetDlgItem(hwndDlg, IDC_TASK_STAR), str.c_str()); + Button_SetText(GetDlgItem(hwndDlg, IDC_COMPRESS), compressText); + Button_SetText(GetDlgItem(hwndDlg, IDC_UPLOAD), uploadText); + Static_SetText(GetDlgItem(hwndDlg, IDC_EXPORT_TYPE_LABEL), typeText); + } + else if(LOWORD(wParam) == IDC_TRIGER_TYPE) + { + TaskOptions::TrigerType sel = (enum TaskOptions::TrigerType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_TRIGER_TYPE)); + int showT = (sel == TaskOptions::Daily || sel == TaskOptions::Weekly || sel == TaskOptions::Monthly) ? SW_SHOW : SW_HIDE; + int showW = sel == TaskOptions::Weekly ? SW_SHOW : SW_HIDE; + int showM = sel == TaskOptions::Monthly ? SW_SHOW : SW_HIDE; + int showDT = (sel == TaskOptions::DeltaMin || sel == TaskOptions::DeltaHour) ? SW_SHOW : SW_HIDE; + ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_TIME), showT); + ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_TIME_LABEL), showT); + ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_WEEK), showW); + ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_WEEK_LABEL), showW); + ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_DAY), showM); + ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_DAY_LABEL), showM); + ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_DELTA_TIME), showDT); + ShowWindow(GetDlgItem(hwndDlg, IDC_TRIGER_DELTA_TIME_LABEL), showDT); + } + } + return TRUE; + } + case WM_NOTIFY: + { + NMHDR* nmhdr = (NMHDR *) lParam; + if (nmhdr->idFrom == IDC_LIST_CONTACTSEX && nmhdr->code == CLN_OPTIONSCHANGED) + { + ResetListOptions(hwndDlg); + } + + return TRUE; + } + } + + return FALSE; +} + +bool Options::FTPAvail() +{ + DWORD atr = GetFileAttributes(instance->ftpExePath.c_str()); + return !(atr == INVALID_FILE_ATTRIBUTES || atr & FILE_ATTRIBUTE_DIRECTORY); +} diff --git a/plugins/BasicHistory/src/Options.h b/plugins/BasicHistory/src/Options.h new file mode 100644 index 0000000000..4a5d17229c --- /dev/null +++ b/plugins/BasicHistory/src/Options.h @@ -0,0 +1,199 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once +#include "IImport.h" +#include "IExport.h" + +struct FilterOptions +{ + FilterOptions() + :onlyIncomming(false), + onlyOutgoing(false) + { + } + + FilterOptions(const std::wstring& _name) + :name(_name), + onlyIncomming(false), + onlyOutgoing(false) + { + } + + std::wstring name; + std::vector events; + bool onlyIncomming; + bool onlyOutgoing; +}; + +struct TaskOptions +{ + bool compress; + bool useFtp; + bool isSystem; + bool active; + bool forceExecute; + bool showMBAfterExecute; + bool exportImported; + enum TaskType + { + Export, + Delete, + ExportAndDelete, + Import, + ImportAndMarge + } type; + + enum EventUnit + { + Minute, + Hour, + Day + } eventUnit; + + enum TrigerType + { + AtStart, + AtEnd, + Daily, + Weekly, + Monthly, + DeltaMin, + DeltaHour + } trigerType; + + IExport::ExportType exportType; + IImport::ImportType importType; + int eventDeltaTime; + int filterId; + int dayTime; + int dayOfWeek; + int dayOfMonth; + int deltaTime; + int orderNr; + time_t lastExport; + std::wstring ftpName; + std::wstring filterName; + std::wstring filePath; + std::wstring taskName; + std::string zipPassword; // char* because zip file using ANSI password + std::vector contacts; + TaskOptions() + { + forceExecute = false; + showMBAfterExecute = false; + exportImported = true; + type = Export; + eventUnit = Hour; + trigerType = AtStart; + exportType = IExport::RichHtml; + importType = IImport::Binary; + eventDeltaTime = 0; + filterId = 0; + compress = true; + useFtp = false; + isSystem = false; + active = true; + dayTime = 20 * 60; + dayOfWeek = 0; + dayOfMonth = 1; + deltaTime = 24; + orderNr = 0; + TCHAR buf[MAX_PATH]; + if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, buf))) + { + filePath = buf; + filePath += _T("\\"); + } + + filePath += TranslateT("History"); + filePath += _T("__."); + lastExport = time(NULL); + } +}; + +class Options +{ +private: + std::vector customFiltersTemp; +public: + Options(); + ~Options(); + static int InitOptions(WPARAM wParam, LPARAM lParam); + + static INT_PTR CALLBACK DlgProcOptsMain(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK DlgProcOptsGroupList(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK DlgProcOptsMessages(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK DlgProcOptsSearching(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK DlgProcOptsExport(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK DlgProcOptsScheduler(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK DlgProcOptsTask(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + static bool FTPAvail(); + + static Options *instance; + void Save(); + void SaveTasks(std::list* tasks); + void SaveTaskTime(TaskOptions& to); + void Load(void); + void LoadTasks(); + void Unload(); + + bool showContacts, showContactGroups, groupNewOnTop, groupShowEvents, groupShowTime, groupShowName, groupShowMessage; + bool messagesNewOnTop, messagesShowDate, messagesShowSec, messagesShowName, messagesShowEvents, messagesUseSmileys; + bool searchForInList, searchForInMess, searchMatchCase, searchMatchWhole, searchOnlyIn, searchOnlyOut, searchOnlyGroup, searchAllContacts; + bool schedulerAlerts, schedulerHistoryAlerts; + int groupMessageLen, groupTime, groupMessagesNumber; + + std::vector customFilters; + int defFilter; + unsigned int codepageTxt, codepageHtml1, codepageHtml2; + std::wstring encodingTxt, encodingHtml1, encodingHtml2; + bool exportHtml1ShowDate, exportHtml2ShowDate, exportHtml2UseSmileys; + std::wstring extCssHtml2; + std::vector taskOptions; + std::wstring ftpLogPath; + std::wstring ftpExePathDef; + std::wstring ftpExePath; + CRITICAL_SECTION criticalSection; + + enum Fonts + { + OutTimestamp = 0, + InTimestamp, + OutName, + InName, + OutMessages, + InMessages, + GroupList, + Find, + }; + + enum Colors + { + OutBackground = 0, + InBackground, + GroupListBackground, + WindowBackground, + ContactListBackground, + FindBackground, + }; + + COLORREF GetFont(Fonts fontId, PLOGFONT font); + COLORREF GetColor(Colors colorId); +}; + diff --git a/plugins/BasicHistory/src/PlainHtmlExport.cpp b/plugins/BasicHistory/src/PlainHtmlExport.cpp new file mode 100644 index 0000000000..050b4e457e --- /dev/null +++ b/plugins/BasicHistory/src/PlainHtmlExport.cpp @@ -0,0 +1,106 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "StdAfx.h" +#include "PlainHtmlExport.h" +#include "Options.h" +#define EXP_FILE (*stream) + +PlainHtmlExport::~PlainHtmlExport() +{ +} + +extern std::wstring MakeTextHtmled(const std::wstring& message, std::queue >* positionMap = NULL); +extern std::wstring UrlHighlightHtml(const std::wstring& message, bool& isUrl); + +void PlainHtmlExport::WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding) +{ + EXP_FILE << _T("\n"); + EXP_FILE << _T("\n\n"); + EXP_FILE << _T("") << TranslateT("History Log") << _T(" [") << MakeTextHtmled(myName) << _T("] - [") << MakeTextHtmled(name1) << _T("]\n"); + EXP_FILE << _T("\n\n

") << TranslateT("History Log") << _T("

\n

"); + EXP_FILE << MakeTextHtmled(myName); + if(proto1.length() || myId.length()) + { + EXP_FILE << _T(" (") << MakeTextHtmled(proto1) << _T(": ") << MakeTextHtmled(myId) << _T(") - "); + } + else + { + EXP_FILE << _T(" - "); + } + + EXP_FILE << MakeTextHtmled(name1); + if(proto1.length() || id1.length()) + { + EXP_FILE << _T(" (") << MakeTextHtmled(proto1) << _T(": ") << MakeTextHtmled(id1) << _T(")

\n"); + } + else + { + EXP_FILE << _T("\n"); + } + + EXP_FILE << _T("
") << TranslateT("Filter:") << _T(" ") << MakeTextHtmled(filterName) << _T("
\n"); +} + +void PlainHtmlExport::WriteFooter() +{ + EXP_FILE << _T("
\n\n"); +} + +void PlainHtmlExport::WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText) +{ + TCHAR buf[256]; + EXP_FILE << _T("
\n"); + _stprintf_s(buf, TranslateT("Conversation started at %s"), time.c_str()); + EXP_FILE << _T("
") << buf << _T("
\n"); + EXP_FILE << _T("
\n"); +} + +void PlainHtmlExport::WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei) +{ + TCHAR *id = isMe ? _T("out") : _T("inc"); + TCHAR* ev = (isMe ? _T("1") : _T("0")); + bool isUrl = false; + std::wstring& mes = UrlHighlightHtml(MakeTextHtmled(message), isUrl); + if(isUrl) + ev = _T("2"); + EXP_FILE << _T("
\n"); + EXP_FILE << _T("
") << MakeTextHtmled(user) << _T(":
\n"); + EXP_FILE << _T("
") << (Options::instance->exportHtml1ShowDate ? longDate : shortDate) << _T("
\n"); + EXP_FILE << _T("
\n"); + EXP_FILE << mes; + EXP_FILE << _T("\n
\n"); + EXP_FILE << _T("
\n"); +} diff --git a/plugins/BasicHistory/src/PlainHtmlExport.h b/plugins/BasicHistory/src/PlainHtmlExport.h new file mode 100644 index 0000000000..bb1c971ea3 --- /dev/null +++ b/plugins/BasicHistory/src/PlainHtmlExport.h @@ -0,0 +1,37 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once +#include "IExport.h" +class PlainHtmlExport : + public IExport +{ +public: + virtual const TCHAR* GetExt() + { + return _T("html"); + } + + virtual void WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding); + virtual void WriteFooter(); + virtual void WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText); + virtual void WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei); + + virtual ~PlainHtmlExport(); +}; + diff --git a/plugins/BasicHistory/src/RichHtmlExport.cpp b/plugins/BasicHistory/src/RichHtmlExport.cpp new file mode 100644 index 0000000000..5a772a4914 --- /dev/null +++ b/plugins/BasicHistory/src/RichHtmlExport.cpp @@ -0,0 +1,545 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "StdAfx.h" +#include "RichHtmlExport.h" +#include "Options.h" +#include "resource.h" +#define EXP_FILE (*stream) + +RichHtmlExport::~RichHtmlExport() +{ +} + +extern HINSTANCE hInst; +extern HANDLE *hEventIcons; +extern HANDLE hPlusExIcon, hMinusExIcon; +extern bool g_SmileyAddAvail; + +std::wstring MakeTextHtmled(const std::wstring& message, std::queue >* positionMap = NULL) +{ + std::wstring ret; + std::wstring search = _T("&<>\t\r\n"); + size_t start = 0; + size_t find; + size_t currentAdd = 0; + while((find = message.find_first_of(search, start)) < message.length()) + { + ret += message.substr(start, find - start); + switch(message[find]) + { + case _T('&'): + ret += _T("&"); + break; + case _T('<'): + ret += _T("<"); + break; + case _T('>'): + ret += _T(">"); + break; + case _T('\t'): + ret += _T(" "); + break; + case _T('\n'): + ret += _T("
"); + break; + } + + start = find + 1; + if(positionMap != NULL) + { + size_t len = ret.length() - start - currentAdd; + if(len != 0) + { + positionMap->push(std::pair(start + currentAdd, len)); + currentAdd += len; + } + } + } + + ret += message.substr(start, message.length() - start); + return ret; +} + +std::wstring UrlHighlightHtml(const std::wstring& message, bool& isUrl) +{ + std::wstring ret; + std::wstring htmlStop = _T("\'\" []<>\r\n"); + std::wstring search = _T("://"); + size_t start = 0; + size_t find; + while((find = message.find(search, start)) < message.length()) + { + size_t urlStart = message.find_last_of(htmlStop, find); + size_t urlEnd = message.find_first_of(htmlStop, find + 3); + if(urlStart >= message.length()) + urlStart = -1; + if(urlEnd >= message.length()) + urlEnd = message.length(); + if(((int)urlEnd -3 - (int)find > 0) && ((int)find - (int)urlStart -1 > 0)) + { + ret += message.substr(start, (urlStart + 1) - start); + std::wstring url = message.substr(urlStart + 1, urlEnd - urlStart - 1); + start = urlEnd; + ret += _T("") + url + _T(""); + isUrl = true; + } + else + { + ret += message.substr(start, (find + 3) - start); + start = find + 3; + } + } + + ret += message.substr(start, message.length() - start); + return ret; +} + +std::wstring RemoveExt(const std::wstring &fileName) +{ + size_t find = fileName.find_last_of(L'.'); + if(find < fileName.length()) + { + return fileName.substr(0, find); + } + + return fileName; +} + +std::wstring GetName(const std::wstring &path) +{ + size_t find = path.find_last_of(L"\\/"); + if(find < path.length()) + { + return path.substr(find + 1); + } + + return path; +} + +void ExtractFile(short int res, const std::wstring &fileName) +{ + HRSRC rSrc = FindResource(hInst, MAKEINTRESOURCE(res), MAKEINTRESOURCE(CUSTOMRES)); + if(rSrc != NULL) + { + HGLOBAL res = LoadResource(hInst, rSrc); + int size = SizeofResource(hInst, rSrc); + if(res != NULL) + { + char* resData = (char*)LockResource(res); + if(resData != NULL) + { + std::ofstream stream (fileName.c_str(), std::ios_base::binary); + if(stream.is_open()) + { + stream.write(resData, size); + stream.close(); + } + } + + FreeResource(res); + } + } +} + +#pragma pack(push, 2) +typedef struct +{ + BYTE bWidth; // Width, in pixels, of the image + BYTE bHeight; // Height, in pixels, of the image + BYTE bColorCount; // Number of colors in image (0 if >=8bpp) + BYTE bReserved; // Reserved ( must be 0) + WORD wPlanes; // Color Planes + WORD wBitCount; // Bits per pixel + DWORD dwBytesInRes; // How many bytes in this resource? + DWORD dwImageOffset; // Where in the file is this image? +} ICONDIRENTRY, *LPICONDIRENTRY; + +typedef struct +{ + WORD idReserved; // Reserved (must be 0) + WORD idType; // Resource Type (1 for icons) + WORD idCount; // How many images? + //ICONDIRENTRY idEntries; // An entry for each image (idCount of 'em) +} ICONDIR, *LPICONDIR; + +#pragma pack(pop) + +typedef struct tagMyBITMAPINFO { + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[256]; +} MYBITMAPINFO; + +void IcoSave(const std::wstring &fileName, HICON hicon) +{ + std::ofstream store (fileName.c_str(), std::ios_base::binary); + if(!store.is_open()) + return; + ICONINFO ii; + if(!GetIconInfo(hicon,&ii)) + { + store.close(); + return; + } + + HBITMAP hbmMask = ii.hbmMask; + HBITMAP hbmColor = ii.hbmColor; + BITMAP bmiMask; + BITMAP bmiColor; + if( + GetObject(hbmColor,sizeof(bmiColor),&bmiColor) && + GetObject(hbmMask,sizeof(bmiMask),&bmiMask) && + (bmiColor.bmWidth==bmiMask.bmWidth) && + (bmiColor.bmHeight==bmiMask.bmHeight) && + (bmiMask.bmHeight) > 0 && + (bmiMask.bmWidth) > 0 + ) + { + BITMAPINFOHEADER icobmi = {0}; + MYBITMAPINFO info1 = {0}; + MYBITMAPINFO info2 = {0}; + + HDC hDC = CreateCompatibleDC(NULL); + info1.bmiHeader.biSize = sizeof(info1.bmiHeader); + info1.bmiHeader.biWidth = bmiColor.bmWidth; + info1.bmiHeader.biHeight = bmiColor.bmHeight; + info1.bmiHeader.biPlanes = 1; + info1.bmiHeader.biBitCount = bmiColor.bmBitsPixel; + unsigned int size = GetDIBits(hDC,hbmColor,0,info1.bmiHeader.biHeight,NULL,(BITMAPINFO*)&info1,DIB_RGB_COLORS); + char* bits1 = new char[info1.bmiHeader.biSizeImage]; + size = GetDIBits(hDC,hbmColor,0,info1.bmiHeader.biHeight,bits1,(BITMAPINFO*)&info1,DIB_RGB_COLORS); + info2.bmiHeader.biSize = sizeof(info2.bmiHeader); + info2.bmiHeader.biWidth = bmiMask.bmWidth; + info2.bmiHeader.biHeight = bmiMask.bmHeight; + info2.bmiHeader.biPlanes = 1; + info2.bmiHeader.biBitCount = bmiMask.bmBitsPixel; + size = GetDIBits(hDC,hbmColor,0,info1.bmiHeader.biHeight,NULL,(BITMAPINFO*)&info2,DIB_RGB_COLORS); + char* bits2 = new char[info2.bmiHeader.biSizeImage]; + size = GetDIBits(hDC,hbmMask,0,info2.bmiHeader.biHeight,bits2,(BITMAPINFO*)&info2,DIB_RGB_COLORS); + + ICONDIR icodir; + ICONDIRENTRY icoent; + icodir.idReserved = 0; + icodir.idType = 1; + icodir.idCount = 1; + + icoent.bWidth = (unsigned char)bmiColor.bmWidth; + icoent.bHeight = (unsigned char)bmiColor.bmHeight; + icoent.bColorCount = 8<=bmiColor.bmBitsPixel?0:1<extCssHtml2.empty()) + { + cssCopied = CopyFile(Options::instance->extCssHtml2.c_str(), css.c_str(), FALSE); + } + + if(!cssCopied) + ExtractFile(IDR_CSS, css); + ExtractFile(IDR_JS, folder + _T("\\history.js")); + + HICON ico = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hPlusExIcon); + IcoSave(folder + _T("\\pnode.ico"), ico); + CallService(MS_SKIN2_RELEASEICON, (LPARAM)ico, 0); + ico = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hMinusExIcon); + IcoSave(folder + _T("\\mnode.ico"), ico); + CallService(MS_SKIN2_RELEASEICON, (LPARAM)ico, 0); + ico = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hEventIcons[0]); + IcoSave(folder + _T("\\event0.ico"), ico); + CallService(MS_SKIN2_RELEASEICON, (LPARAM)ico, 0); + ico = (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hEventIcons[1]); + IcoSave(folder + _T("\\event1.ico"), ico); + CallService(MS_SKIN2_RELEASEICON, (LPARAM)ico, 0); + + EXP_FILE << _T("\n"); + EXP_FILE << _T("\n\n"); + EXP_FILE << _T("") << TranslateT("History Log") << _T(" [") << MakeTextHtmled(myName) << _T("] - [") << MakeTextHtmled(name1) << _T("]\n"); + EXP_FILE << _T("\n"); + EXP_FILE << _T("\n"); + EXP_FILE << _T("\n"); + + EXP_FILE << _T("\n"); + EXP_FILE << _T("") << TranslateT("Menu") << _T("\n"); + EXP_FILE << _T("\n"); + EXP_FILE << _T("\n"); + EXP_FILE << _T("\n"); + EXP_FILE << _T("
\n"); + EXP_FILE << _T("\n"); + + EXP_FILE << _T("

") << TranslateT("History Log") << _T("

\n

"); + EXP_FILE << MakeTextHtmled(myName); + if(proto1.length() || myId.length()) + { + EXP_FILE << _T(" (") << MakeTextHtmled(proto1) << _T(": ") << MakeTextHtmled(myId) << _T(") - "); + } + else + { + EXP_FILE << _T(" - "); + } + + EXP_FILE << MakeTextHtmled(name1); + if(proto1.length() || id1.length()) + { + EXP_FILE << _T(" (") << MakeTextHtmled(proto1) << _T(": ") << MakeTextHtmled(id1) << _T(")

\n"); + } + else + { + EXP_FILE << _T("\n"); + } + + EXP_FILE << _T("
") << TranslateT("Filter:") << _T(" ") << MakeTextHtmled(filterName) << _T("
\n"); + groupId = 0; +} + +void RichHtmlExport::WriteFooter() +{ + if(groupId > 0) + { + EXP_FILE << _T("
\n"); + } + + EXP_FILE << _T("
\n\n"); +} + +void RichHtmlExport::WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText) +{ + TCHAR *id = isMe ? _T("out") : _T("inc"); + TCHAR* ev = (isMe ? _T("1") : _T("0")); + if(groupId > 0) + { + EXP_FILE << _T("\n"); + } + + bool isUrl = false; + std::wstring& mes = ReplaceSmileys(isMe, eventText, isUrl); + EXP_FILE << _T("
\n"); + EXP_FILE << _T(""); + EXP_FILE << _T("\n"); + EXP_FILE << _T("") << time << _T("\n\n") << mes; + EXP_FILE << _T("\n
\n"); + EXP_FILE << _T("
\n"); + ++groupId; +} + +void RichHtmlExport::WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei) +{ + TCHAR *id = isMe ? _T("out") : _T("inc"); + TCHAR* ev = (isMe ? _T("1") : _T("0")); + TCHAR* ev1 = ev; + bool isUrl = false; + std::wstring& mes = ReplaceSmileys(isMe, message, isUrl); + if(isUrl) + ev = _T("2"); + EXP_FILE << _T("
\n"); + EXP_FILE << _T("
") << _T("
\n"); + EXP_FILE << _T("
") << (Options::instance->exportHtml2ShowDate ? longDate : shortDate) << _T("
\n"); + EXP_FILE << _T("
") << MakeTextHtmled(user) << _T("
\n"); + EXP_FILE << _T("
\n"); + EXP_FILE << mes; + EXP_FILE << _T("\n
\n"); + EXP_FILE << _T("
\n"); +} + +std::wstring RichHtmlExport::ReplaceSmileys(bool isMe, const std::wstring &msg, bool &isUrl) +{ + if(Options::instance->exportHtml2UseSmileys && g_SmileyAddAvail) + { + TCHAR* msgbuf = new TCHAR[msg.length() + 1]; + memcpy_s(msgbuf, (msg.length() + 1) * sizeof(TCHAR), msg.c_str(), (msg.length() + 1) * sizeof(TCHAR)); + SMADD_BATCHPARSE2 sp = {0}; + SMADD_BATCHPARSERES *spr; + sp.cbSize = sizeof(sp); + sp.Protocolname = baseProto.length() == 0 ? NULL : baseProto.c_str(); + sp.str = msgbuf; + sp.flag = SAFL_TCHAR | SAFL_PATH | (isMe ? SAFL_OUTGOING : 0); + spr = (SMADD_BATCHPARSERES*)CallService(MS_SMILEYADD_BATCHPARSE, 0, (LPARAM)&sp); + delete[] msgbuf; + + if (spr == NULL || (INT_PTR)spr == CALLSERVICE_NOTFOUND) + { + // Did not find a simley + return UrlHighlightHtml(MakeTextHtmled(msg), isUrl); + } + + std::queue > positionMap; + std::wstring newMsg = MakeTextHtmled(msg, &positionMap); + std::wstring smileyMsg; + + size_t last_pos=0; + std::pair pos(0, 0); + size_t currentAdd = 0; + if(!positionMap.empty()) + { + pos = positionMap.front(); + positionMap.pop(); + } + + for (unsigned i = 0; i < sp.numSmileys; ++i) + { + size_t startChar = spr[i].startChar + currentAdd; + while(startChar >= pos.first && pos.second) + { + startChar += pos.second; + currentAdd += pos.second; + if(!positionMap.empty()) + { + pos = positionMap.front(); + positionMap.pop(); + } + else + { + pos = std::pair(0, 0); + } + } + + size_t endChar = spr[i].startChar + spr[i].size + currentAdd; + while(endChar >= pos.first && pos.second) + { + endChar += pos.second; + currentAdd += pos.second; + if(!positionMap.empty()) + { + pos = positionMap.front(); + positionMap.pop(); + } + else + { + pos = std::pair(0, 0); + } + } + + size_t size = endChar - startChar; + + if (spr[i].filepath != NULL) // For deffective smileypacks + { + // Add text + if (startChar - last_pos > 0) + { + smileyMsg += newMsg.substr(last_pos, startChar - last_pos); + } + + std::wstring smileyName = GetName(spr[i].filepath); + if(smileys.find(smileyName) == smileys.end()) + { + smileys.insert(smileyName); + CopyFile(spr[i].filepath, (folder + _T("\\") + smileyName).c_str(), FALSE); + } + + std::wstring smileyText = newMsg.substr(startChar, size); + smileyMsg += _T("\"");"); + } + + // Get next + last_pos = endChar; + } + + // Add rest of text + if (last_pos < newMsg.length()) + { + smileyMsg += newMsg.substr(last_pos); + } + + CallService(MS_SMILEYADD_BATCHFREE, 0, (LPARAM)spr); + return UrlHighlightHtml(smileyMsg, isUrl); + } + else + { + return UrlHighlightHtml(MakeTextHtmled(msg), isUrl); + } +} diff --git a/plugins/BasicHistory/src/RichHtmlExport.h b/plugins/BasicHistory/src/RichHtmlExport.h new file mode 100644 index 0000000000..f4f6686964 --- /dev/null +++ b/plugins/BasicHistory/src/RichHtmlExport.h @@ -0,0 +1,44 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once +#include "IExport.h" +class RichHtmlExport : + public IExport +{ +private: + int groupId; + std::wstring folder; + std::wstring folderName; + std::string baseProto; + stdext::hash_set smileys; + std::wstring ReplaceSmileys(bool isMe, const std::wstring &msg, bool &isUrl); +public: + virtual const TCHAR* GetExt() + { + return _T("html"); + } + + virtual void WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding); + virtual void WriteFooter(); + virtual void WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText); + virtual void WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei); + + virtual ~RichHtmlExport(); +}; + diff --git a/plugins/BasicHistory/src/Scheduler.cpp b/plugins/BasicHistory/src/Scheduler.cpp new file mode 100644 index 0000000000..3b2ba18ab9 --- /dev/null +++ b/plugins/BasicHistory/src/Scheduler.cpp @@ -0,0 +1,1576 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "StdAfx.h" +#include "Options.h" +#include "ExportManager.h" +#include "HistoryWindow.h" +#include "zip\zip.h" +#include "zip\unzip.h" +#include "zip\iowin32.h" + +// Sorry for plain C implementation +#define MODULE "BasicHistory" +extern HANDLE g_hMainThread; +bool bPopupsEnabled; +bool DoTask(TaskOptions& to); +bool IsValidTask(TaskOptions& to, std::list* top = NULL, std::wstring* err = NULL, std::wstring* errDescr = NULL); +std::wstring GetFileName(const std::wstring &baseName, std::wstring contactName, std::map& existingContacts, bool replaceContact); +std::wstring GetDirectoryName(const std::wstring &path); +std::wstring GetName(const std::wstring &path); +bool DeleteDirectory(LPCTSTR lpszDir, bool noRecycleBin = true); +void ListDirectory(const std::wstring &basePath, const std::wstring &path, std::list& files); +std::wstring ReplaceStr(const std::wstring& str, wchar_t oldCh, wchar_t newCh); +time_t GetNextExportTime(TaskOptions& to); +void SchedulerThreadFunc(void*); +volatile bool finishThread = false; +bool initTask = false; +HANDLE thread = NULL; +HANDLE threadEvent; +time_t nextExportTime; +void StartThread(bool init); +void StopThread(); +bool GetNextExportTime(bool init, time_t now); +bool ExecuteCurrentTask(time_t now); +void GetZipFileTime(const TCHAR *file, uLong *dt); +std::wstring ReplaceExt(const std::wstring& file, const TCHAR* ext); +bool ZipFiles(const std::wstring& dir, std::wstring zipFilePath, const std::string& password); +bool UnzipFiles(const std::wstring& dir, std::wstring& zipFilePath, const std::string& password); +bool FtpFiles(const std::wstring& dir, const std::wstring& filePath, const std::wstring& ftpName); +bool FtpGetFiles(const std::wstring& dir, const std::list& files, const std::wstring& ftpName); +void CreatePath(const TCHAR *szDir); +void DoError(const TaskOptions& to, const std::wstring error); + +void OptionsSchedulerChanged() +{ + StartThread(false); +} + +void InitScheduler() +{ + bPopupsEnabled = ServiceExists(MS_POPUP_ADDPOPUPT) || ServiceExists(MS_POPUP_ADDPOPUPCLASS); + if (ServiceExists(MS_POPUP_REGISTERCLASS)) + { + //hPopupIcon = LoadIconEx(I_CHKUPD); + POPUPCLASS test = {0}; + test.cbSize = sizeof(POPUPCLASS); + test.flags = PCF_TCHAR; + test.hIcon = LoadSkinnedIcon(SKINICON_OTHER_HISTORY); + test.iSeconds = 10; + test.ptszDescription = TranslateT("History task"); + test.pszName = MODULE; + CallService(MS_POPUP_REGISTERCLASS, 0, (WPARAM)&test); + } + + StartThread(true); +} + +void DeinitScheduler() +{ + StopThread(); +} + +int DoLastTask(WPARAM, LPARAM) +{ + for(std::vector::iterator it = Options::instance->taskOptions.begin(); it != Options::instance->taskOptions.end(); ++it) + { + if(it->trigerType == TaskOptions::AtEnd && it->active) + { + DoTask(*it); + } + } + + return 0; +} + +bool IsValidTask(TaskOptions& to, std::list* top, std::wstring* err, std::wstring* errDescr) +{ + if(to.taskName.empty()) + { + if(err != NULL) + *err = TranslateT("Name"); + return false; + } + if(top != NULL) + { + for(std::list::iterator it = top->begin(); it != top->end(); ++it) + { + if(it->taskName == to.taskName) + { + if(err != NULL) + *err = TranslateT("Name"); + return false; + } + } + } + if(!to.isSystem && to.contacts.size() == 0) + { + if(err != NULL) + *err = TranslateT("Contacts"); + if(errDescr != NULL) + *errDescr = TranslateT("At least one contact should be selected."); + return false; + } + + bool isImportTask = to.type == TaskOptions::Import || to.type == TaskOptions::ImportAndMarge; + if(!isImportTask) + { + if(to.filterId > 1) + { + int filter = 0; + + for(int i = 0; i < (int)Options::instance->customFilters.size(); ++i) + { + if(to.filterName == Options::instance->customFilters[i].name) + { + filter = i + 2; + break; + } + } + + if(filter < 2) + { + if(err != NULL) + *err = TranslateT("Filter"); + return false; + } + + to.filterId = filter; + } + else if(to.filterId < 0) + { + if(err != NULL) + *err = TranslateT("Filter"); + return false; + } + } + + if(to.type == TaskOptions::Delete) + { + return true; + } + + if(!Options::FTPAvail() && to.useFtp) + { + if(err != NULL) + *err = TranslateT("Upload to FTP"); + return false; + } + if(to.filePath.empty()) + { + if(err != NULL) + *err = TranslateT("Path to output file"); + return false; + } + if(to.useFtp && to.ftpName.empty()) + { + if(err != NULL) + *err = TranslateT("Session name"); + if(errDescr != NULL) + *errDescr = TranslateT("To create session open WinSCP, click New Session, enter data and save with specific name. Remember if FTP server using password you should save it in WinSCP."); + return false; + } + if(to.useFtp && (to.filePath.find(_T('\\')) < to.filePath.length() || to.filePath.find(_T(':')) < to.filePath.length() || to.filePath[0] != L'/')) + { + if(err != NULL) + *err = TranslateT("Path to file"); + if(errDescr != NULL) + *errDescr = TranslateT("FTP path must contains '/' instead '\\' and starts from '/'."); + return false; + } + if(isImportTask && to.filePath.find(_T("")) < to.filePath.length()) + { + if(err != NULL) + *err = TranslateT("Path to file"); + if(errDescr != NULL) + *errDescr = TranslateT("FTP path cannot contain in import task."); + return false; + } + if(!isImportTask && (to.exportType < IExport::RichHtml || to.exportType > IExport::Dat)) + { + if(err != NULL) + *err = TranslateT("Export to"); + return false; + } + if(isImportTask && (to.importType < IImport::Binary || to.importType > IImport::Dat)) + { + if(err != NULL) + *err = TranslateT("Import from"); + return false; + } + if((to.trigerType == TaskOptions::Daily || to.trigerType == TaskOptions::Weekly || to.trigerType == TaskOptions::Monthly) && (to.dayTime < 0 || to.dayTime >= 24 * 60)) + { + if(err != NULL) + *err = TranslateT("Time"); + return false; + } + if(to.trigerType == TaskOptions::Weekly && (to.dayOfWeek < 0 || to.dayOfWeek >= 7)) + { + if(err != NULL) + *err = TranslateT("Day of week"); + return false; + } + if(to.trigerType == TaskOptions::Monthly && (to.dayOfMonth <= 0 || to.dayOfMonth >= 32)) + { + if(err != NULL) + *err = TranslateT("Day"); + return false; + } + if((to.trigerType == TaskOptions::DeltaMin || to.trigerType == TaskOptions::DeltaHour) && (to.deltaTime < 0 || to.deltaTime >= 10000)) + { + if(err != NULL) + *err = TranslateT("Delta time"); + return false; + } + + return true; +} + +static void CALLBACK DoRebuildEventsInMainAPCFunc(ULONG_PTR dwParam) +{ + HANDLE* contacts = (HANDLE*) dwParam; + size_t size = (size_t)contacts[0]; + for(size_t i = 1; i <= size; ++i) + { + HistoryWindow::RebuildEvents(contacts[i]); + } + + delete[] contacts; +} + +bool DoTask(TaskOptions& to) +{ + std::wstring err; + std::wstring errDescr; + if(!IsValidTask(to, NULL, &err, &errDescr)) + { + TCHAR msg[256]; + if(err.empty()) + _tcscpy_s(msg, TranslateT("Some value is invalid")); + else if(errDescr.empty()) + { + _stprintf_s(msg, TranslateT("Invalid '%s' value."), err.c_str()); + } + else + { + _stprintf_s(msg, TranslateT("Invalid '%s' value.\n%s"), err.c_str(), errDescr.c_str()); + } + DoError(to, msg); + return true; + } + + DWORD now = time(NULL); + long long int t = to.eventDeltaTime * 60; + if(to.eventUnit > TaskOptions::Minute) + t *= 60LL; + if(to.eventUnit > TaskOptions::Hour) + t *= 24LL; + if(t > 2147483647LL) + { + DoError(to, TranslateT("Unknown error")); + return true; + } + + bool error = false; + std::wstring errorStr; + std::list managers; + if(to.type == TaskOptions::Delete) + { + if(to.isSystem) + { + ExportManager *exp = new ExportManager(NULL, NULL, to.filterId); + exp->SetDeleteWithoutExportEvents(t, now); + managers.push_back(exp); + } + + for(size_t i = 0; i < to.contacts.size(); ++i) + { + ExportManager *exp = new ExportManager(NULL, to.contacts[i], to.filterId); + exp->SetDeleteWithoutExportEvents(t, now); + managers.push_back(exp); + } + } + else if(to.type == TaskOptions::Import || to.type == TaskOptions::ImportAndMarge) + { + std::map existingContacts1; + ExportManager mExp = ExportManager(NULL, NULL, 1); + std::wstring filePath = to.filePath; + std::wstring dir; + std::list files; + std::vector contacts; + if(to.useFtp || to.compress) + { + std::map existingContacts; + TCHAR temp[MAX_PATH]; + temp[0] = 0; + GetTempPath(MAX_PATH, temp); + dir = temp; + dir += GetName(filePath); + dir = GetFileName(dir, L"", existingContacts, true); + dir = ReplaceExt(dir, L""); + size_t pos = dir.find_last_of(_T('.')); + if(pos < dir.length()) + { + dir = dir.substr(0, pos); + } + + DeleteDirectory(dir.c_str()); + CreateDirectory(dir.c_str(), NULL); + } + + const TCHAR* ext = ExportManager::GetExt(to.importType); + if(to.isSystem) + { + std::wstring n = GetFileName(filePath, mExp.GetContactName(), existingContacts1, true); + n = ReplaceExt(n, ext); + files.push_back(n); + contacts.push_back(NULL); + } + + for(size_t i = 0; i < to.contacts.size(); ++i) + { + mExp.hContact = to.contacts[i]; + std::wstring n = GetFileName(filePath, mExp.GetContactName(), existingContacts1, true); + n = ReplaceExt(n, ext); + files.push_back(n); + contacts.push_back(to.contacts[i]); + } + + if(to.useFtp) + { + if(to.compress) + { + std::map existingContacts; + std::wstring n = GetFileName(filePath, L"", existingContacts, true); + n = ReplaceExt(n, L"zip"); + files.clear(); + files.push_back(n); + filePath = dir + L"\\" + GetName(filePath); + } + + error = FtpGetFiles(dir, files, to.ftpName); + if(error) + { + if(!errorStr.empty()) + { + errorStr += L"\n"; + } + + errorStr += TranslateT("Cannot get FTP file(s)."); + } + } + + if(!error && to.compress) + { + error = UnzipFiles(dir, filePath, to.zipPassword); + if(error) + { + if(!errorStr.empty()) + { + errorStr += L"\n"; + } + + errorStr += TranslateT("Cannot unzip file(s)."); + } + + if(to.useFtp) + DeleteFile(filePath.c_str()); + } + + if(!error && (to.useFtp || to.compress)) + { + files.clear(); + std::list files1; + ListDirectory(dir, L"\\", files1); + for(std::list::iterator it = files1.begin(); it != files1.end(); ++it) + { + files.push_back(dir + *it); + } + } + + if(!error) + { + std::list contactList; + for(std::list::iterator it = files.begin(); it != files.end(); ++it) + { + mExp.SetAutoImport(*it); + int ret = mExp.Import(to.importType, contacts); + if(ret == -3) + { + if(contacts.size() == 1) + { + ret = 0; + } + else + { + std::map existingContacts; + std::wstring name = GetName(*it); + for(ret = 0; ret < (int)contacts.size(); ++ret) + { + mExp.hContact = contacts[ret]; + std::wstring n = GetFileName(to.filePath, mExp.GetContactName(), existingContacts, true); + n = ReplaceExt(n, ext); + n = GetName(n); + if(n == name) + break; + } + + if(ret >= (int)contacts.size()) + ret = -1; + } + } + + if(ret >= 0) + { + mExp.hContact = contacts[ret]; + if(to.type == TaskOptions::Import) + { + EventList::AddImporter(mExp.hContact, to.importType, *it); + contactList.push_back(mExp.hContact); + } + else + { + std::vector messages; + if(mExp.Import(to.importType, messages, NULL)) + { + mExp.MargeMessages(messages); + contactList.push_back(mExp.hContact); + } + } + } + else if(ret != -1) + { + if(!errorStr.empty()) + { + errorStr += L"\n"; + } + + TCHAR msg[1024]; + + _stprintf_s(msg, TranslateT("Incorrect file format: %s."), GetName(*it).c_str()); + errorStr += msg; + } + else + { + if(!errorStr.empty()) + { + errorStr += L"\n"; + } + + TCHAR msg[1024]; + + _stprintf_s(msg, TranslateT("Unknown contact in file: %s."), GetName(*it).c_str()); + errorStr += msg; + } + } + + if(contactList.size() > 0) + { + HANDLE* contacts = new HANDLE[contactList.size() + 1]; + contacts[0] = (HANDLE)contactList.size(); + int i = 1; + for(std::list::iterator it = contactList.begin(); it != contactList.end(); ++it) + { + contacts[i++] = *it; + } + + QueueUserAPC(DoRebuildEventsInMainAPCFunc, g_hMainThread, (ULONG_PTR) contacts); + } + } + + if(to.useFtp || to.compress) + { + DeleteDirectory(dir.c_str()); + } + } + else + { + std::map existingContacts; + std::wstring filePath = to.filePath; + std::wstring dir; + if(!to.useFtp && !to.compress) + { + dir = GetDirectoryName(filePath); + if(!dir.empty()) + { + CreateDirectory(dir.c_str(), NULL); + } + } + else + { + filePath = GetName(filePath); + TCHAR temp[MAX_PATH]; + temp[0] = 0; + GetTempPath(MAX_PATH, temp); + dir = temp; + dir += filePath; + dir = GetFileName(dir, L"", existingContacts, true); + dir = ReplaceExt(dir, L""); + size_t pos = dir.find_last_of(_T('.')); + if(pos < dir.length()) + { + dir = dir.substr(0, pos); + } + + DeleteDirectory(dir.c_str()); + CreateDirectory(dir.c_str(), NULL); + filePath = dir + L"\\" + filePath; + } + if(to.isSystem) + { + ExportManager *exp = new ExportManager(NULL, NULL, to.filterId); + exp->SetAutoExport(GetFileName(filePath, exp->GetContactName(), existingContacts, true), t, now); + exp->useImportedMessages = to.exportImported; + if(!exp->Export(to.exportType)) + { + error = true; + if(!errorStr.empty()) + { + errorStr += L"\n"; + } + + TCHAR msg[1024]; + + _stprintf_s(msg, TranslateT("Cannot export history for contact: %s."), exp->GetContactName().c_str()); + errorStr += msg; + } + + if(to.type == TaskOptions::Export) + { + delete exp; + } + else + { + managers.push_back(exp); + } + } + + if(!error) + { + for(size_t i = 0; i < to.contacts.size(); ++i) + { + ExportManager *exp = new ExportManager(NULL, to.contacts[i], to.filterId); + exp->SetAutoExport(GetFileName(filePath, exp->GetContactName(), existingContacts, true), t, now); + exp->useImportedMessages = to.exportImported; + if(!exp->Export(to.exportType)) + { + error = true; + if(!errorStr.empty()) + { + errorStr += L"\n"; + } + + TCHAR msg[1024]; + + _stprintf_s(msg, TranslateT("Cannot export history for contact: %s."), exp->GetContactName().c_str()); + errorStr += msg; + break; + } + + if(to.type == TaskOptions::Export) + { + delete exp; + } + else + { + managers.push_back(exp); + } + } + } + + if(error) + { + if(to.compress && !to.useFtp) + { + DeleteDirectory(dir.c_str()); + } + } + else if(to.compress) + { + std::wstring zipFilePath = to.filePath; + std::wstring zipDir = dir; + if(!to.useFtp) + { + zipDir = GetDirectoryName(zipFilePath); + if(!zipDir.empty()) + { + CreateDirectory(zipDir.c_str(), NULL); + } + } + else + { + zipFilePath = GetName(zipFilePath); + TCHAR temp[MAX_PATH]; + temp[0] = 0; + GetTempPath(MAX_PATH, temp); + zipDir = temp; + zipDir += L"zip"; + zipDir = GetFileName(zipDir, L"", existingContacts, true); + DeleteDirectory(zipDir.c_str()); + CreateDirectory(zipDir.c_str(), NULL); + zipFilePath = zipDir + L"\\" + zipFilePath; + } + error = ZipFiles(dir + L"\\", zipFilePath, to.zipPassword); + dir = zipDir; + if(error) + { + if(!errorStr.empty()) + { + errorStr += L"\n"; + } + + errorStr += TranslateT("Cannot compress file(s)."); + } + } + + if(to.useFtp) + { + if(!error) + { + error = FtpFiles(dir, to.filePath, to.ftpName); + if(error) + { + if(!errorStr.empty()) + { + errorStr += L"\n"; + } + + errorStr += TranslateT("Cannot send FTP file(s)."); + } + } + + DeleteDirectory(dir.c_str()); + } + } + + if(to.type == TaskOptions::Delete || to.type == TaskOptions::ExportAndDelete) + { + for(std::list::iterator it = managers.begin(); it != managers.end(); ++it) + { + if(!error) + { + (*it)->DeleteExportedEvents(); + } + + delete *it; + } + } + + if(error) + { + DoError(to, errorStr.empty() ? TranslateT("Unknown error") : errorStr); + } + + return error; +} + +std::wstring GetFileName(const std::wstring &baseName, std::wstring contactName, std::map& existingContacts, bool replaceContact) +{ + std::wstring str = baseName; + size_t pos = baseName.find(_T("")); + if(replaceContact && pos < baseName.length()) + { + str = baseName.substr(0, pos); + std::wstring baseName1 = contactName; + if(!baseName1.empty()) + { + std::wstring name = baseName1; + int i = 0; + TCHAR buf[32]; + std::map::iterator it = existingContacts.find(name); + while(it != existingContacts.end()) + { + _itot_s(++i, buf, 10); + name = baseName1 + buf; + it = existingContacts.find(name); + } + + str += name; + existingContacts[name] = true; + } + str += baseName.substr(pos + 9); + } + + pos = str.find(_T("")); + if(pos < str.length()) + { + TCHAR time[256]; + SYSTEMTIME st; + GetLocalTime(&st); + _stprintf_s(time, _T("%d-%02d-%02d %02d%02d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute); + std::wstring str1 = str.substr(0, pos); + str1 += time; + str1 += str.substr(pos + 6); + str = str1; + } + + return str; +} + +std::wstring GetDirectoryName(const std::wstring &path) +{ + size_t find = path.find_last_of(L"\\/"); + if(find < path.length()) + { + return path.substr(0, find); + } + + return L""; +} + +void ListDirectory(const std::wstring &basePath, const std::wstring &path, std::list& files) +{ + WIN32_FIND_DATA findFileData; + HANDLE hFind = FindFirstFile((basePath + path + _T("*")).c_str(), &findFileData); + if (hFind == INVALID_HANDLE_VALUE) + return; + do + { + if(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + std::wstring name = findFileData.cFileName; + if(name != L"." && name != L"..") + ListDirectory(basePath, path + findFileData.cFileName + _T("\\"), files); + } + else + { + files.push_back(path + findFileData.cFileName); + } + } + while(FindNextFile(hFind, &findFileData)); + FindClose(hFind); +} + +std::wstring ReplaceStr(const std::wstring& str, wchar_t oldCh, wchar_t newCh) +{ + std::wstring ret; + size_t start = 0; + size_t find; + while((find = str.find_first_of(oldCh, start)) < str.length()) + { + ret += str.substr(start, find - start); + ret += newCh; + start = find + 1; + } + + ret += str.substr(start, str.length() - start); + return ret; +} + +time_t GetNextExportTime(TaskOptions& to) +{ + switch(to.trigerType) + { + case TaskOptions::Daily: + { + tm t; + localtime_s(&t, &to.lastExport); + t.tm_hour = to.dayTime/60; + t.tm_min = to.dayTime%60; + t.tm_sec = 0; + time_t newTime = mktime(&t); + if(newTime <= to.lastExport) + { + newTime += 60 * 60 * 24; + } + + return newTime; + } + case TaskOptions::Weekly: + { + tm t; + localtime_s(&t, &to.lastExport); + t.tm_hour = to.dayTime/60; + t.tm_min = to.dayTime%60; + t.tm_sec = 0; + int dow = (to.dayOfWeek + 1) % 7; + time_t newTime = mktime(&t); + while(dow != t.tm_wday) + { + newTime += 60 * 60 * 24; + localtime_s(&t, &newTime); + newTime = mktime(&t); + } + + if(newTime <= to.lastExport) + { + newTime += 7 * 60 * 60 * 24; + } + + return newTime; + } + case TaskOptions::Monthly: + { + tm t; + localtime_s(&t, &to.lastExport); + t.tm_hour = to.dayTime/60; + t.tm_min = to.dayTime%60; + t.tm_sec = 0; + time_t newTime = mktime(&t); + int lastM = t.tm_mon; + int lastD; + while(to.dayOfMonth != t.tm_mday || newTime <= to.lastExport) + { + lastD = t.tm_mday; + newTime += 60 * 60 * 24; + localtime_s(&t, &newTime); + newTime = mktime(&t); + if(to.dayOfMonth > 28 && t.tm_mon != lastM && (newTime - 60 * 60 * 24) > to.lastExport) + { + lastM = t.tm_mon; + if(to.dayOfMonth > lastD) + { + newTime -= 60 * 60 * 24; + break; + } + } + } + + return newTime; + } + case TaskOptions::DeltaMin: + return to.lastExport + to.deltaTime * 60; + case TaskOptions::DeltaHour: + return to.lastExport + to.deltaTime * 60 * 60; + default: + return to.lastExport; + } +} + +void SchedulerThreadFunc(void*) +{ + if(initTask) + { + WaitForSingleObject(threadEvent, 5 * 1000); + initTask = false; + } + + while(!finishThread) + { + DWORD timeWait; + time_t now = time(NULL); + while(nextExportTime <= now) + { + if(!ExecuteCurrentTask(now)) + return; + } + + time_t dif = nextExportTime - now; + timeWait = (dif > 60 * 60 * 24) ? (60 * 60 * 1000) : (60 * 1000); + + WaitForSingleObject(threadEvent, timeWait); + } +} + +void StartThread(bool init) +{ + StopThread(); + + initTask = false; + bool isExport = GetNextExportTime(init, time(NULL)); + if(isExport) + { + finishThread = false; + threadEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + thread = mir_forkthread(SchedulerThreadFunc, NULL); + } +} + +void StopThread() +{ + if(thread != NULL) + { + finishThread = true; + SetEvent(threadEvent); + WaitForSingleObject(thread, INFINITE); + //CloseHandle(thread); + CloseHandle(threadEvent); + thread = NULL; + threadEvent = NULL; + } +} + +bool GetNextExportTime(bool init, time_t now) +{ + EnterCriticalSection(&Options::instance->criticalSection); + bool isExport = false; + for(std::vector::iterator it = Options::instance->taskOptions.begin(); it != Options::instance->taskOptions.end(); ++it) + { + if(it->forceExecute) + { + nextExportTime = now; + isExport = true; + initTask = init; + break; + } + else if(it->active && it->trigerType != TaskOptions::AtStart && it->trigerType != TaskOptions::AtEnd) + { + time_t t = GetNextExportTime(*it); + if(isExport) + { + if(t < nextExportTime) + nextExportTime = t; + } + else + { + nextExportTime = t; + isExport = true; + initTask = init; + } + } + else if(it->active && it->trigerType == TaskOptions::AtStart && init) + { + it->forceExecute = true; + it->showMBAfterExecute = false; + nextExportTime = now; + isExport = true; + initTask = true; + } + } + + LeaveCriticalSection(&Options::instance->criticalSection); + return isExport; +} + +static void CALLBACK DoTaskFinishInMainAPCFunc(ULONG_PTR dwParam) +{ + TCHAR *item = (TCHAR*) dwParam; + MessageBox(NULL, item, TranslateT("Task finished"), MB_OK | MB_ICONINFORMATION); + delete[] item; +} + +bool ExecuteCurrentTask(time_t now) +{ + EnterCriticalSection(&Options::instance->criticalSection); + TaskOptions to; + bool isExport = false; + for(std::vector::iterator it = Options::instance->taskOptions.begin(); it != Options::instance->taskOptions.end(); ++it) + { + if(it->forceExecute) + { + it->lastExport = time(NULL); + Options::instance->SaveTaskTime(*it); + to = *it; + isExport = true; + break; + } + else if(it->active && it->trigerType != TaskOptions::AtStart && it->trigerType != TaskOptions::AtEnd) + { + time_t t = GetNextExportTime(*it); + if(t <= now) + { + it->lastExport = time(NULL); + Options::instance->SaveTaskTime(*it); + to = *it; + isExport = true; + break; + } + } + } + + LeaveCriticalSection(&Options::instance->criticalSection); + + if(isExport) + { + bool error = DoTask(to); + if(to.forceExecute) + { + EnterCriticalSection(&Options::instance->criticalSection); + for(std::vector::iterator it = Options::instance->taskOptions.begin(); it != Options::instance->taskOptions.end(); ++it) + { + if(it->taskName == to.taskName) + { + it->forceExecute = false; + it->showMBAfterExecute = false; + break; + } + } + + LeaveCriticalSection(&Options::instance->criticalSection); + + if(to.showMBAfterExecute) + { + size_t size = to.taskName.size() + 1024; + TCHAR* name = new TCHAR[size]; + if(error) + { + _stprintf_s(name, size, TranslateT("Task '%s' execution failed"), to.taskName.c_str()); + } + else + { + _stprintf_s(name, size, TranslateT("Task '%s' finished successfully"), to.taskName.c_str()); + } + + QueueUserAPC(DoTaskFinishInMainAPCFunc, g_hMainThread, (ULONG_PTR) name); + } + } + } + + return GetNextExportTime(false, now); +} + +void GetZipFileTime(const TCHAR *file, uLong *dt) +{ + FILETIME ftLocal; + HANDLE hFind; + WIN32_FIND_DATA ff32; + + hFind = FindFirstFile(file, &ff32); + if (hFind != INVALID_HANDLE_VALUE) + { + FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal); + FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0); + FindClose(hFind); + } +} + +/* calculate the CRC32 of a file, + because to encrypt a file, we need known the CRC32 of the file before */ +bool GetFileCrc(const TCHAR* filenameinzip, unsigned char* buf, unsigned long size_buf, unsigned long* result_crc) +{ + unsigned long calculate_crc = 0; + bool error = true; + HANDLE hFile = CreateFile(filenameinzip, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if(hFile != INVALID_HANDLE_VALUE) + { + DWORD readed; + do + { + if(!ReadFile(hFile, buf, 1024, &readed, NULL)) + { + error = false; + break; + } + + if (readed > 0) + { + calculate_crc = crc32(calculate_crc, buf, readed); + } + } + while (readed > 0); + CloseHandle(hFile); + } + else + { + error = false; + } + + *result_crc=calculate_crc; + return error; +} + +bool ZipFiles(const std::wstring& dir, std::wstring zipFilePath, const std::string& password) +{ + std::list files; + std::map existingContacts; + ListDirectory(dir, L"", files); + bool error = false; + if(files.size() > 0) + { + zlib_filefunc_def pzlib_filefunc_def; + fill_win32_filefunc(&pzlib_filefunc_def); + zipFilePath = GetFileName(zipFilePath, L"", existingContacts, true); + zipFilePath = ReplaceExt(zipFilePath, L"zip"); + zipFile zf = zipOpen2((LPCSTR)(LPTSTR)zipFilePath.c_str(), APPEND_STATUS_CREATE, NULL, &pzlib_filefunc_def); + if (zf != NULL) + { + unsigned char buf[1024]; + char bufF[MAX_PATH + 20]; + while(files.size() > 0) + { + std::wstring zipDir = *files.begin(); + std::wstring localDir = dir + L"\\" + zipDir; + zip_fileinfo zi = {0}; + GetZipFileTime(localDir.c_str(), &zi.dosDate); + if(zipDir.size() > MAX_PATH + 19) + { + error = true; + break; + } + + BOOL badChar; + WideCharToMultiByte(CP_OEMCP, WC_NO_BEST_FIT_CHARS, zipDir.c_str(), -1, bufF, MAX_PATH + 20, NULL, &badChar); + int flag = 0; + if(badChar) + { + flag = 0x800; // UTF + WideCharToMultiByte(CP_UTF8, 0, zipDir.c_str(), -1, bufF, MAX_PATH + 20, NULL, NULL); + } + + unsigned long calculate_crc = 0; + const char* passwordCh = NULL; + if(password.size() > 0) + { + if(!GetFileCrc(localDir.c_str(), buf, 1024, &calculate_crc)) + { + error = true; + break; + } + + passwordCh = password.c_str(); + } + + int err = zipOpenNewFileInZip4_64 (zf, bufF, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, passwordCh, calculate_crc, 0, flag, 0); + if (err == ZIP_OK) + { + HANDLE hFile = CreateFile(localDir.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if(hFile != INVALID_HANDLE_VALUE) + { + DWORD readed; + do + { + err = ZIP_OK; + if(!ReadFile(hFile, buf, 1024, &readed, NULL)) + { + error = true; + break; + } + + if (readed > 0) + { + err = zipWriteInFileInZip(zf, buf, readed); + } + } + while ((err == ZIP_OK) && (readed > 0)); + CloseHandle(hFile); + } + + if(zipCloseFileInZip(zf) != ZIP_OK) + { + error = true; + break; + } + } + else + { + error = true; + break; + } + + files.pop_front(); + } + + zipClose(zf, NULL); + } + else + { + error = true; + } + } + + DeleteDirectory(dir.c_str()); + return error; +} + +bool UnzipFiles(const std::wstring& dir, std::wstring& zipFilePath, const std::string& password) +{ + std::list files; + bool error = false; + zlib_filefunc_def pzlib_filefunc_def; + fill_win32_filefunc(&pzlib_filefunc_def); + std::wstring fileNameInZip; + std::map existingContacts; + zipFilePath = GetFileName(zipFilePath, L"", existingContacts, true); + zipFilePath = ReplaceExt(zipFilePath, L"zip"); + unzFile zf = unzOpen2((LPCSTR)(LPTSTR)zipFilePath.c_str(), &pzlib_filefunc_def); + if (zf != NULL) + { + char buf[8192]; + char bufF[MAX_PATH + 20]; + unz_file_info file_info; + do + { + int err = unzGetCurrentFileInfo(zf, &file_info, bufF, MAX_PATH + 20, buf, 8192, NULL, 0); + if (err == UNZ_OK) + { + UINT cp = CP_OEMCP; + if(file_info.flag & 0x800)// UTF + { + cp = CP_UTF8; + } + + // Get Unicode file name for InfoZip style archives, otherwise assume PKZip/WinZip style + if (file_info.size_file_extra) + { + char *p = buf; + unsigned long size = min(file_info.size_file_extra, 8192); + while (size > 0) + { + unsigned short id = *(unsigned short*)p; + unsigned len = *(unsigned short*)(p + 2); + + if (size < (len + 4)) break; + + if (id == 0x7075 && len > 5 && (len - 5) < MAX_PATH + 20 && *(p + 4) == 1) + { + memcpy(bufF, p + 9, len - 5); + bufF[len - 5] = 0; + cp = CP_UTF8; + break; + } + size -= len + 4; + p += len + 4; + } + } + + int sizeC = (int)strlen(bufF); + int sizeW = MultiByteToWideChar(cp, 0, bufF, sizeC, NULL, 0); + fileNameInZip.resize(sizeW); + MultiByteToWideChar(cp, 0, bufF, sizeC, (wchar_t*)fileNameInZip.c_str(), sizeW); + fileNameInZip = dir + L"\\" + fileNameInZip; + for (size_t i = 0; i < fileNameInZip.length(); ++i) + { + if (fileNameInZip[i] == L'/') + fileNameInZip[i] = L'\\'; + } + + if (file_info.external_fa & FILE_ATTRIBUTE_DIRECTORY) + CreatePath(fileNameInZip.c_str()); + else + { + const char* passwordCh = NULL; + if(password.size() > 0) + { + passwordCh = password.c_str(); + } + + err = unzOpenCurrentFilePassword(zf, passwordCh); + if (err == UNZ_OK) + { + CreatePath(GetDirectoryName(fileNameInZip).c_str()); + HANDLE hFile = CreateFile(fileNameInZip.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); + if(hFile != INVALID_HANDLE_VALUE) + { + DWORD writed; + for (;;) + { + err = unzReadCurrentFile(zf, buf, 8192); + if (err <= 0) break; + + if (!WriteFile(hFile, buf, err, &writed, FALSE)) + { + err = -1; + break; + } + } + + CloseHandle(hFile); + if(err < 0) + { + error = true; + break; + } + } + else + { + unzCloseCurrentFile(zf); + error = true; + break; + } + + if(unzCloseCurrentFile(zf) != ZIP_OK) + { + error = true; + break; + } + } + else + { + error = true; + break; + } + } + } + else + { + error = true; + break; + } + } + while (unzGoToNextFile(zf) == UNZ_OK); + + unzClose(zf); + } + else + { + error = true; + } + + return error; +} + +bool FtpFiles(const std::wstring& dir, const std::wstring& filePath, const std::wstring& ftpName) +{ + std::list files; + std::map existingContacts; + ListDirectory(dir, L"\\", files); + if(files.size() > 0) + { + std::wofstream stream ((dir + _T("\\script.sc")).c_str()); + if(stream.is_open()) + { + std::wstring ftpDir = GetDirectoryName(filePath); + ftpDir = GetFileName(ftpDir, L"", existingContacts, false); + stream << "option batch continue\noption confirm off\nopen \"" + << ftpName << "\"\noption transfer binary\n"; + std::wstring lastCD; + size_t filSize = files.size(); + while(files.size() > 0) + { + std::wstring localDir = *files.begin(); + std::wstring currentCD = ftpDir + GetDirectoryName(ReplaceStr(localDir, L'\\', L'/')); + if(currentCD != lastCD) + { + if(!currentCD.empty() && currentCD != L"/") + stream << "mkdir \"" << currentCD << "\"\n"; + stream << "cd \"" << currentCD << "\"\n"; + lastCD = currentCD; + } + + std::wstring name = GetName(localDir); + stream << "call MDTM " << name << "\n"; + stream << "put \"." << localDir << "\"\n"; + stream << "call MDTM " << name << "\n"; + files.pop_front(); + } + + stream.close(); + std::wstring &log = Options::instance->ftpLogPath; + CreateDirectory(GetDirectoryName(log).c_str(), NULL); + DeleteFile(log.c_str()); + TCHAR cmdLine[MAX_PATH]; + _stprintf_s(cmdLine, _T("\"%s\" /nointeractiveinput /log=\"%s\" /script=script.sc"), Options::instance->ftpExePath.c_str(), log.c_str()); + STARTUPINFO startupInfo = {0}; + PROCESS_INFORMATION processInfo; + startupInfo.cb = sizeof(STARTUPINFO); + if(CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, dir.c_str(), &startupInfo, &processInfo)) + { + WaitForSingleObject(processInfo.hProcess, INFINITE); + CloseHandle(processInfo.hThread); + CloseHandle(processInfo.hProcess); + if(log.empty()) + { + return false; + } + + std::wifstream logStream (log.c_str()); + if(logStream.is_open()) + { + bool isInMDTM = false; + std::list dates; + while(!logStream.eof()) + { + std::wstring lineStr; + std::getline(logStream, lineStr); + if(lineStr.length() > 1) + { + if(lineStr[0] == L'>') + { + if(isInMDTM) + { + if(lineStr.find(L"Script:") < lineStr.length()) + { + dates.push_back(L""); + isInMDTM = false; + } + } + + if(lineStr.find(L"Script: call MDTM") < lineStr.length()) + { + isInMDTM = true; + } + } + else if(isInMDTM && lineStr[0] == L'<') + { + size_t ss = lineStr.find(L"Script: 213 "); + if(ss < lineStr.length()) + { + ss += 12; + if(ss < lineStr.length()) + { + lineStr = lineStr.substr(ss); + if(lineStr.size() == 14) + { + dates.push_back(lineStr); + isInMDTM = false; + } + } + } + } + } + } + + if(dates.size() > 0 && dates.size() == filSize * 2) + { + for(std::list::const_iterator it = dates.begin(); it != dates.end(); ++it) + { + std::wstring date1 = *it++; + if(it->empty() || date1 == *it) + return true; + + } + + return false; + } + } + } + } + } + + return true; +} + +bool FtpGetFiles(const std::wstring& dir, const std::list& files, const std::wstring& ftpName) +{ + std::map existingContacts; + std::wstring script = dir + _T("\\script.sc"); + std::wofstream stream (script.c_str()); + if(stream.is_open()) + { + stream << "option batch continue\noption confirm off\nopen \"" + << ftpName << "\"\noption transfer binary\n"; + std::wstring lastCD; + std::list localFiles; + for(std::list::const_iterator it = files.begin(); it != files.end(); ++it) + { + std::wstring fileName = GetName(*it); + localFiles.push_back(dir + L"\\" + fileName); + std::wstring currentCD = GetDirectoryName(*it); + if(currentCD != lastCD) + { + stream << "cd \"" << currentCD << "\"\n"; + lastCD = currentCD; + } + + stream << "get \"" << fileName << "\"\n"; + } + + stream.close(); + std::wstring &log = Options::instance->ftpLogPath; + CreateDirectory(GetDirectoryName(log).c_str(), NULL); + DeleteFile(log.c_str()); + TCHAR cmdLine[MAX_PATH]; + _stprintf_s(cmdLine, _T("\"%s\" /nointeractiveinput /log=\"%s\" /script=script.sc"), Options::instance->ftpExePath.c_str(), log.c_str()); + STARTUPINFO startupInfo = {0}; + PROCESS_INFORMATION processInfo; + startupInfo.cb = sizeof(STARTUPINFO); + if(CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, dir.c_str(), &startupInfo, &processInfo)) + { + WaitForSingleObject(processInfo.hProcess, INFINITE); + CloseHandle(processInfo.hThread); + CloseHandle(processInfo.hProcess); + } + + DeleteFile(script.c_str()); + for(std::list::const_iterator it = localFiles.begin(); it != localFiles.end(); ++it) + { + DWORD atr = GetFileAttributes(it->c_str()); + if(atr == INVALID_FILE_ATTRIBUTES || atr & FILE_ATTRIBUTE_DIRECTORY) + { + return true; + } + } + + return false; + } + + return true; +} + +void CreatePath(const TCHAR *szDir) +{ + if (!szDir) return; + + DWORD dwAttributes; + TCHAR *pszLastBackslash, szTestDir[ MAX_PATH ]; + + lstrcpyn( szTestDir, szDir, SIZEOF( szTestDir )); + if (( dwAttributes = GetFileAttributes( szTestDir )) != INVALID_FILE_ATTRIBUTES && ( dwAttributes & FILE_ATTRIBUTE_DIRECTORY )) + return; + + pszLastBackslash = _tcsrchr( szTestDir, '\\' ); + if ( pszLastBackslash == NULL ) + return; + + *pszLastBackslash = '\0'; + CreatePath( szTestDir ); + *pszLastBackslash = '\\'; + + CreateDirectory( szTestDir, NULL ); +} + +INT_PTR ExecuteTaskService(WPARAM wParam, LPARAM lParam) +{ + EnterCriticalSection(&Options::instance->criticalSection); + int taskNr = (int)wParam; + if(taskNr < 0 || taskNr >= (int)Options::instance->taskOptions.size()) + { + LeaveCriticalSection(&Options::instance->criticalSection); + return FALSE; + } + + Options::instance->taskOptions[taskNr].forceExecute = true; + Options::instance->taskOptions[taskNr].showMBAfterExecute = true; + LeaveCriticalSection(&Options::instance->criticalSection); + StartThread(false); + return TRUE; +} + +void DoError(const TaskOptions& to, const std::wstring _error) +{ + TCHAR msg[256]; + _stprintf_s(msg, TranslateT("Task '%s' execution failed:"), to.taskName.c_str()); + if(Options::instance->schedulerHistoryAlerts) + { + std::wstring error = msg; + error += L"\n"; + error += _error; + DBEVENTINFO dbei = {0}; + dbei.cbSize = sizeof(DBEVENTINFO); + dbei.szModule = MODULE; + dbei.flags = DBEF_UTF | DBEF_READ; + dbei.timestamp = time(NULL); + // For now I do not convert event data from string to blob, and event type must be message to handle it properly + dbei.eventType = EVENTTYPE_MESSAGE; + int len = (int)error.length() + 1; + dbei.cbBlob = WideCharToMultiByte(CP_UTF8, 0, error.c_str(), len, NULL, 0, NULL, NULL); + char* buf = new char[dbei.cbBlob]; + dbei.cbBlob = WideCharToMultiByte(CP_UTF8, 0, error.c_str(), len, buf, dbei.cbBlob, NULL, NULL); + dbei.pBlob = (PBYTE)buf; + CallService(MS_DB_EVENT_ADD, NULL, (LPARAM) & dbei); + } + + + if(Options::instance->schedulerAlerts) + { + if(CallService(MS_SYSTEM_TERMINATED, 0, 0)) return; + if(ServiceExists(MS_POPUP_ADDPOPUPCLASS)) + { + ShowClassPopupT(MODULE, msg, (wchar_t*)_error.c_str()); + } + else if (ServiceExists( MS_POPUP_ADDPOPUPT )) + { + POPUPDATAT ppd = {0}; + ppd.lchIcon = LoadSkinnedIcon(SKINICON_OTHER_HISTORY); + _tcscpy_s(ppd.lptzContactName, msg); + _tcscpy_s(ppd.lptzText, _error.c_str()); + CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&ppd, 0); + } + } +} diff --git a/plugins/BasicHistory/src/SearchContext.h b/plugins/BasicHistory/src/SearchContext.h new file mode 100644 index 0000000000..6b1655d857 --- /dev/null +++ b/plugins/BasicHistory/src/SearchContext.h @@ -0,0 +1,55 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once +#include "EventList.h" + +class SearchContext : public EventList +{ +public: + HWND editWindow; + HWND findWindow; + HWND toolbarWindow; + HWND listWindow; + int selected; + + virtual void SelectEventGroup(int sel) = 0; + virtual HANDLE GetNextContact(HANDLE hContact, int adder) = 0; + virtual void SelectContact(HANDLE _hContact) = 0; + + struct MessageData + { + MessageData(const std::wstring& _description, int _startPos, int _endPos, bool _isMe, DWORD _timestamp) + :description(_description) + { + startPos = _startPos; + endPos = _endPos; + isMe = _isMe; + timestamp = _timestamp; + } + + std::wstring description; + int startPos; + int endPos; + bool isMe; + DWORD timestamp; + }; + + std::vector currentGroup; +}; + diff --git a/plugins/BasicHistory/src/Searcher.cpp b/plugins/BasicHistory/src/Searcher.cpp new file mode 100644 index 0000000000..c93685bcf3 --- /dev/null +++ b/plugins/BasicHistory/src/Searcher.cpp @@ -0,0 +1,388 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "StdAfx.h" +#include "Searcher.h" +#include "resource.h" + +Searcher::Searcher() + :lastFindSelection(-1), + findBack(false), + matchCase(false), + matchWholeWords(false), + onlyIn(false), + onlyOut(false), + context(NULL) +{ +} + +void Searcher::ChangeFindDirection(bool isBack) +{ + if(isBack != findBack) + { + findBack = isBack; + ClearFind(); + TBBUTTONINFO tbInfo; + tbInfo.cbSize = sizeof(TBBUTTONINFO); + tbInfo.dwMask = TBIF_TEXT | TBIF_IMAGE; + if(isBack) + { + tbInfo.pszText = TranslateT("Find Previous"); + tbInfo.iImage = 1; + } + else + { + tbInfo.pszText = TranslateT("Find Next"); + tbInfo.iImage = 0; + } + SendMessage(context->toolbarWindow, TB_SETBUTTONINFO, (WPARAM)IDM_FIND, (LPARAM)&tbInfo); + } + + Find(); +} + +void Searcher::ClearFind() +{ + if(lastFindSelection != -1) + { + SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_AND,~ECO_NOHIDESEL); + lastFindSelection = -1; + } +} + +inline TCHAR mytoupper(TCHAR a, std::locale* loc) +{ + return std::toupper(a, *loc); +} + +bool Searcher::CompareStr(std::wstring str, TCHAR *strFind) +{ + std::locale loc; + if(!matchCase) + std::transform(str.begin(), str.end(), str.begin(), std::bind2nd(std::ptr_fun(mytoupper), &loc)); + if(!matchWholeWords) + return str.find(strFind) < str.length(); + size_t findid = str.find(strFind); + size_t findLen = _tcslen(strFind); + while(findid < str.length()) + { + if((findid == 0 || std::isspace(str[findid - 1], loc) || std::ispunct(str[findid - 1], loc)) && + (findid + findLen >= str.length() || std::isspace(str[findid + findLen], loc) || std::ispunct(str[findid + findLen], loc))) + return true; + findid = str.find(strFind, findid + 1); + } + + return false; +} + +void Searcher::Find() +{ + FINDTEXTEX ft; + TCHAR str[128]; + int curSel = 0; + bool isStart = false; + bool finished = false; + ft.chrg.cpMin = 0; + ft.chrg.cpMax = -1; + ft.lpstrText = str; + if(context->currentGroup.size() < 1) + { + SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_AND,~ECO_NOHIDESEL); + lastFindSelection = -1; + return; + } + + GetWindowText(context->findWindow, str, 128); + if(!str[0]) + { + TCHAR buf[256]; + mir_sntprintf(buf, 256, TranslateT("\"%s\" not found"), str); + MessageBox(context->hWnd, buf, TranslateT("Search"), MB_OK | MB_ICONINFORMATION); + return; + } + if(!matchCase) + { + std::locale loc; + std::transform(str, str + _tcslen(str), str, std::bind2nd(std::ptr_fun(mytoupper), &loc)); + } + + bool findBack1 = findBack ^ !searchForInMes; + bool findBack2 = findBack ^ !searchForInLG; + int adder1 = findBack1 ? -1 : 1; + int adder2 = findBack2 ? -1 : 1; + WPARAM findStyle = (findBack1 ? 0 : FR_DOWN) | (matchCase ? FR_MATCHCASE : 0) | (matchWholeWords ? FR_WHOLEWORD : 0); + if(lastFindSelection >= 0 && lastFindSelection < (int)context->currentGroup.size()) + { + if(onlyIn && context->currentGroup[lastFindSelection].isMe || onlyOut && !context->currentGroup[lastFindSelection].isMe) + { + curSel = lastFindSelection + adder1; + } + else + { + SendDlgItemMessage(context->hWnd,IDC_EDIT,EM_EXGETSEL,0,(LPARAM)&ft.chrg); + if(findBack1) + { + ft.chrg.cpMin = ft.chrg.cpMin < context->currentGroup[lastFindSelection].endPos ? ft.chrg.cpMin : context->currentGroup[lastFindSelection].endPos; + ft.chrg.cpMax = context->currentGroup[lastFindSelection].startPos; + } + else + { + ft.chrg.cpMin = ft.chrg.cpMax > context->currentGroup[lastFindSelection].startPos ? ft.chrg.cpMax : context->currentGroup[lastFindSelection].startPos; + ft.chrg.cpMax = context->currentGroup[lastFindSelection].endPos; + } + SendMessage(context->editWindow,EM_FINDTEXTEX, findStyle,(LPARAM)&ft); + if(ft.chrgText.cpMin < 0 || ft.chrgText.cpMax < 0) + { + curSel = lastFindSelection + adder1; + } + else + { + if(isFindContactChanged && startFindContact == context->hContact && isFindSelChanged && context->selected == startFindSel && ((!findBack1 && ft.chrg.cpMin >= startFindPos) || (findBack1 && ft.chrg.cpMax <= startFindPos))) + { + finished = true; + } + else + { + curSel = lastFindSelection; + SendMessage(context->editWindow,EM_EXSETSEL,0,(LPARAM)&ft.chrgText); + SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_OR,ECO_NOHIDESEL); + lastFindSelection = curSel; + return; + } + } + } + } + else + { + isStart = true; + SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_OR,ECO_NOHIDESEL); + SendMessage(context->editWindow,EM_EXGETSEL,0,(LPARAM)&ft.chrg); + startFindPos = findBack1 ? ft.chrg.cpMin : (ft.chrg.cpMax >= 0 ? ft.chrg.cpMax : ft.chrg.cpMin); + startFindSel = context->selected; + if(startFindPos < 0) + startFindPos = 0; + isFindSelChanged = false; + startFindContact = context->hContact; + isFindContactChanged = !allUsers; + if(findBack1) + for(curSel = (int)context->currentGroup.size() - 1; curSel >= 0; --curSel) + { + if(context->currentGroup[curSel].startPos < startFindPos) + break; + } + else + for(; curSel < (int)context->currentGroup.size(); ++curSel) + { + if(context->currentGroup[curSel].endPos > startFindPos) + break; + } + } + + if(!finished) + { + for(; curSel < (int)context->currentGroup.size() && curSel >= 0; curSel += adder1) + { + if(onlyIn && context->currentGroup[curSel].isMe || onlyOut && !context->currentGroup[curSel].isMe) + continue; + if(CompareStr(context->currentGroup[curSel].description, str)) + { + if(findBack1) + { + ft.chrg.cpMin = context->currentGroup[curSel].endPos; + ft.chrg.cpMax = context->currentGroup[curSel].startPos; + if(!isFindSelChanged && ft.chrg.cpMin > startFindPos) + ft.chrg.cpMin = startFindPos; + } + else + { + ft.chrg.cpMin = context->currentGroup[curSel].startPos; + ft.chrg.cpMax = context->currentGroup[curSel].endPos; + if(!isFindSelChanged && ft.chrg.cpMin < startFindPos) + ft.chrg.cpMin = startFindPos; + } + SendMessage(context->editWindow,EM_FINDTEXTEX, findStyle,(LPARAM)&ft); + if(!(ft.chrgText.cpMin < 0 || ft.chrgText.cpMax < 0)) + { + if(isFindContactChanged && startFindContact == context->hContact && isFindSelChanged && context->selected == startFindSel && ((!findBack1 && ft.chrg.cpMin >= startFindPos) || (findBack1 && ft.chrg.cpMax <= startFindPos))) + { + finished = true; + break; + } + SendMessage(context->editWindow,EM_EXSETSEL,0,(LPARAM)&ft.chrgText); + SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_OR,ECO_NOHIDESEL); + lastFindSelection = curSel; + return; + } + } + } + } + + if(isFindContactChanged && startFindContact == context->hContact && isFindSelChanged && context->selected == startFindSel) + { + finished = true; + } + + if(!finished) + { + isFindSelChanged = true; + if(onlyGroup) + { + if(IsInSel(context->selected, str)) + { + CHARRANGE ch; + ch.cpMin = ch.cpMax = findBack1 ? MAXLONG : 0; + SendMessage(context->editWindow,EM_EXSETSEL,0,(LPARAM)&ch); + lastFindSelection = findBack1 ? (int)context->currentGroup.size() - 1 : 0; + Find(); + return; + } + } + else + { + for(int sel = context->selected + adder2; ; sel += adder2) + { + if(sel < 0) + { + isFindContactChanged = true; + if(allUsers) + { + HANDLE hNext = context->hContact; + do + { + hNext = context->GetNextContact(hNext, adder2); + } + while(hNext != startFindContact && !context->SearchInContact(hNext, str, this)); + context->SelectContact(hNext); + } + + sel = (int)context->eventList.size() - 1; + } + else if(sel >= (int)context->eventList.size()) + { + isFindContactChanged = true; + if(allUsers) + { + HANDLE hNext = context->hContact; + do + { + hNext = context->GetNextContact(hNext, adder2); + } + while(hNext != startFindContact && !context->SearchInContact(hNext, str, this)); + context->SelectContact(hNext); + } + + sel = 0; + } + if(IsInSel(sel, str)) + { + LVITEM item = {0}; + item.mask = LVIF_STATE; + item.iItem = context->selected; + item.state = 0; + item.stateMask = LVIS_SELECTED; + ListView_SetItem(context->listWindow, &item); + item.iItem = sel; + item.state = LVIS_SELECTED; + ListView_SetItem(context->listWindow, &item); + ListView_EnsureVisible(context->listWindow, sel, FALSE); + CHARRANGE ch; + ch.cpMin = ch.cpMax = findBack1 ? MAXLONG : 0; + SendMessage(context->editWindow,EM_EXSETSEL,0,(LPARAM)&ch); + SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_OR,ECO_NOHIDESEL); + lastFindSelection = findBack1 ? (int)context->currentGroup.size() - 1 : 0; + isFindSelChanged = true; + Find(); + return; + } + if(startFindContact == context->hContact && sel == startFindSel) + break; + } + } + } + + if(startFindContact != context->hContact) + { + context->SelectContact(startFindContact); + } + + if(startFindSel != context->selected) + { + LVITEM item = {0}; + item.mask = LVIF_STATE; + item.iItem = context->selected; + item.state = 0; + item.stateMask = LVIS_SELECTED; + ListView_SetItem(context->listWindow, &item); + item.iItem = startFindSel; + item.state = LVIS_SELECTED; + ListView_SetItem(context->listWindow, &item); + ListView_EnsureVisible(context->listWindow, startFindSel, FALSE); + context->SelectEventGroup(startFindSel); + SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_OR,ECO_NOHIDESEL); + } + ft.chrgText.cpMin = startFindPos; + ft.chrgText.cpMax = startFindPos; + SendMessage(context->editWindow,EM_EXSETSEL,0,(LPARAM)&ft.chrgText); + SendMessage(context->editWindow,EM_SETOPTIONS,ECOOP_AND,~ECO_NOHIDESEL); + lastFindSelection = -1; + if(isStart) + { + TCHAR buf[256]; + GetWindowText(context->findWindow, str, 128); + mir_sntprintf(buf, 256, TranslateT("\"%s\" not found"), str); + MessageBox(context->hWnd, buf, TranslateT("Search"), MB_OK | MB_ICONINFORMATION); + } + else + { + MessageBox(context->hWnd, TranslateTS(onlyGroup ? LPGENT("You have reached the end of the group.") : LPGENT("You have reached the end of the history.")), TranslateT("Search"), MB_OK | MB_ICONINFORMATION); + } +} + +bool Searcher::IsInSel(int sel, TCHAR *strFind) +{ + if(sel < 0 || sel >= (int)context->eventList.size()) + return false; + + TCHAR str[MAXSELECTSTR + 8]; // for safety reason + EventList::EventData data; + for(std::deque::iterator it = context->eventList[sel].begin(); it != context->eventList[sel].end(); ++it) + { + EventList::EventIndex hDbEvent = *it; + if(context->GetEventData(hDbEvent, data)) + { + bool isMe = data.isMe; + if(onlyIn && isMe || onlyOut && !isMe) + continue; + context->GetEventMessage(hDbEvent, str); + if(CompareStr(str, strFind)) + { + return true; + } + } + } + + return false; +} + +bool Searcher::Compare(const bool isMe, const std::wstring& message, TCHAR *strFind) +{ + if(onlyIn && isMe || onlyOut && !isMe) + return false; + + return CompareStr(message, strFind); +} diff --git a/plugins/BasicHistory/src/Searcher.h b/plugins/BasicHistory/src/Searcher.h new file mode 100644 index 0000000000..2f5aff6e8b --- /dev/null +++ b/plugins/BasicHistory/src/Searcher.h @@ -0,0 +1,119 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once +#include "SearchContext.h" + +class Searcher : ComparatorInterface +{ +private: + SearchContext* context; + int lastFindSelection; + int startFindPos; + int startFindSel; + HANDLE startFindContact; + bool isFindSelChanged; + bool isFindContactChanged; + bool findBack, matchCase, matchWholeWords, onlyIn, onlyOut, onlyGroup, allUsers, searchForInLG, searchForInMes; + + bool CompareStr(std::wstring str, TCHAR *strFind); + bool IsInSel(int sel, TCHAR *strFind); +public: + Searcher(); + virtual bool Compare(const bool isMe, const std::wstring& message, TCHAR *strFind); + void Find(); + void ChangeFindDirection(bool isBack); + void ClearFind(); + void SetContect(SearchContext* _context){ + context = _context; + } + void SetMatchCase(bool val){ + matchCase = val; + ClearFind(); + } + void SetMatchWholeWords(bool val){ + matchWholeWords = val; + ClearFind(); + } + bool IsMatchCase(){ + return matchCase; + } + bool IsMatchWholeWords(){ + return matchWholeWords; + } + bool IsFindBack(){ + return findBack; + } + void SetOnlyIn(bool val){ + onlyIn = val; + if(val && onlyOut) + onlyOut = false; + ClearFind(); + } + void SetOnlyOut(bool val){ + onlyOut = val; + if(val && onlyIn) + onlyIn = false; + ClearFind(); + } + bool IsOnlyIn(){ + return onlyIn; + } + bool IsOnlyOut(){ + return onlyOut; + } + void SetOnlyGroup(bool val){ + onlyGroup = val; + if(onlyGroup) + allUsers = false; + ClearFind(); + } + bool IsOnlyGroup(){ + return onlyGroup; + } + void SetAllUsers(bool val){ + allUsers = val; + if(allUsers) + onlyGroup = false; + ClearFind(); + } + bool IsAllUsers(){ + return allUsers; + } + void SetSearchForInLG(bool val){ + if(searchForInLG != val) + { + searchForInLG = val; + ClearFind(); + } + } + void SetSearchForInMes(bool val){ + if(searchForInMes != val) + { + searchForInMes = val; + ClearFind(); + } + } + bool IsSearchForInLG(){ + return searchForInLG; + } + bool IsSearchForInMes(){ + return searchForInMes; + } +}; + diff --git a/plugins/BasicHistory/src/TxtExport.cpp b/plugins/BasicHistory/src/TxtExport.cpp new file mode 100644 index 0000000000..a5ca8afddf --- /dev/null +++ b/plugins/BasicHistory/src/TxtExport.cpp @@ -0,0 +1,65 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#include "StdAfx.h" +#include "TxtExport.h" +#define EXP_FILE (*stream) + +TxtExport::~TxtExport() +{ +} + +void TxtExport::WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding) +{ + TCHAR* start = TranslateT("###"); + EXP_FILE << start << "\n" << start << _T(" ") << TranslateT("History Log") << _T("\n"); + EXP_FILE << start << _T(" ") << myName; + if(proto1.length() || myId.length()) + { + EXP_FILE << _T(" (") << proto1 << _T(": ") << myId << _T(") - "); + } + else + { + EXP_FILE << _T(" - "); + } + + EXP_FILE << name1; + if(proto1.length() || id1.length()) + { + EXP_FILE << _T(" (") << proto1 << _T(": ") << id1 << _T(")\n"); + } + else + { + EXP_FILE << _T("\n"); + } + + EXP_FILE << start << _T(" ") << TranslateT("Filter:") << _T(" ") << filterName << _T("\n") << start << _T("\n"); +} + +void TxtExport::WriteFooter() +{ +} + +void TxtExport::WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText) +{ +} + +void TxtExport::WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei) +{ + EXP_FILE << "\n[" << longDate << "] " << user << ":\n" << message << "\n"; +} diff --git a/plugins/BasicHistory/src/TxtExport.h b/plugins/BasicHistory/src/TxtExport.h new file mode 100644 index 0000000000..bee2718649 --- /dev/null +++ b/plugins/BasicHistory/src/TxtExport.h @@ -0,0 +1,38 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once +#include "IExport.h" + +class TxtExport : + public IExport +{ +public: + virtual const TCHAR* GetExt() + { + return _T("txt"); + } + + virtual void WriteHeader(const std::wstring &fileName, const std::wstring &filterName, const std::wstring &myName, const std::wstring &myId, const std::wstring &name1, const std::wstring &proto1, const std::wstring &id1, const std::string& baseProto1, const std::wstring& encoding); + virtual void WriteFooter(); + virtual void WriteGroup(bool isMe, const std::wstring &time, const std::wstring &user, const std::wstring &eventText); + virtual void WriteMessage(bool isMe, const std::wstring &longDate, const std::wstring &shortDate, const std::wstring &user, const std::wstring &message, const DBEVENTINFO& dbei); + + virtual ~TxtExport(); +}; + diff --git a/plugins/BasicHistory/src/codecvt_CodePage.h b/plugins/BasicHistory/src/codecvt_CodePage.h new file mode 100644 index 0000000000..37b6b7d26f --- /dev/null +++ b/plugins/BasicHistory/src/codecvt_CodePage.h @@ -0,0 +1,98 @@ +/* +Basic History plugin +Copyright (C) 2011-2012 Krzysztof Kral + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +template +class codecvt_CodePage : public std::codecvt<_Elem, char, mbstate_t> +{ +private: + UINT codePage; +public: + typedef std::codecvt<_Elem, char, mbstate_t> _Mybase; + typedef typename _Mybase::result result; + typedef char _Byte; + typedef _Elem intern_type; + typedef _Byte extern_type; + typedef mbstate_t state_type; + + explicit codecvt_CodePage(UINT _codePage) + : _Mybase(0), + codePage(_codePage) + { // construct with ref count + } + + virtual ~codecvt_CodePage() + { // destroy the object + } + +protected: + virtual result do_in(mbstate_t& _State, const _Byte *_First1, const _Byte *_Last1, const _Byte *& _Mid1, _Elem *_First2, _Elem *_Last2, _Elem *& _Mid2) const + { // convert bytes [_First1, _Last1) to [_First2, _Last) + return (_Mybase::error); // not implemented + } + + virtual result do_out(mbstate_t& _State, const _Elem *_First1, const _Elem *_Last1, const _Elem *& _Mid1, _Byte *_First2, _Byte *_Last2, _Byte *& _Mid2) const + { // convert [_First1, _Last1) to bytes [_First2, _Last) + _Mid1 = _First1; + _Mid2 = _First2; + + int conv = WideCharToMultiByte(codePage, 0, _First1, _Last1 - _First1, _First2, _Last2 - _First2, NULL, NULL); + if(conv == 0) + { + if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) + return (_Mybase::partial); + else + return (_Mybase::error); + } + else + { + _Mid1 = _Last1; + _Mid2 = _First2 + conv; + } + + return (_Mybase::ok); + } + + virtual result do_unshift(mbstate_t&, + _Byte *_First2, _Byte *, _Byte *& _Mid2) const + { // generate bytes to return to default shift state + _Mid2 = _First2; + return (_Mybase::ok); + } + + virtual int do_length(const mbstate_t& _State, const _Byte *_First1, const _Byte *_Last1, size_t _Count) const _THROW0() + { // return min(_Count, converted length of bytes [_First1, _Last1)) + return (int)_Count; // not implemented + } + + virtual bool do_always_noconv() const _THROW0() + { // return true if conversions never change input + return (false); + } + + virtual int do_max_length() const _THROW0() + { // return maximum length required for a conversion + return 6; + } + + virtual int do_encoding() const _THROW0() + { // return length of code sequence (from codecvt) + return 0; // -1 => state dependent, 0 => varying length + } +}; diff --git a/plugins/BasicHistory/src/dllmain.cpp b/plugins/BasicHistory/src/dllmain.cpp new file mode 100644 index 0000000000..ad89773ec8 --- /dev/null +++ b/plugins/BasicHistory/src/dllmain.cpp @@ -0,0 +1,14 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include "stdafx.h" + +HINSTANCE hInst; + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + hInst = hModule; + return TRUE; +} + diff --git a/plugins/BasicHistory/src/resource.h b/plugins/BasicHistory/src/resource.h new file mode 100644 index 0000000000..71484f2343 --- /dev/null +++ b/plugins/BasicHistory/src/resource.h @@ -0,0 +1,157 @@ + +#define IDD_HISTORY 101 +#define IDD_OPT_MAIN 102 +#define IDD_OPT_GROUPLIST 103 +#define IDD_OPT_MESSAGES 104 +#define IDD_OPT_SEARCHING 105 +#define IDD_OPT_EXPORT 106 +#define IDD_OPT_SCHEDULER 107 +#define IDD_DLG_TASK 108 +#define IDC_EDIT 1001 +#define IDC_LIST 1002 +#define IDC_DELETEHISTORY 1004 +#define IDC_SPLITTER 1005 +#define IDC_FIND_TEXT 1006 +#define IDC_LIST_CONTACTS 1007 +#define IDC_SPLITTERV 1008 +#define IDC_SHOWHIDE 1009 +#define IDC_TOOLBAR 1010 +#define IDC_SHOWCONTACTS 1011 +#define IDC_NEWONTOP 1012 +#define IDC_SHOWEVENTS 1013 +#define IDC_SHOWTIME 1014 +#define IDC_SHOWNAME 1015 +#define IDC_SHOWMESSAGE 1016 +#define IDC_MESSAGELEN 1017 +#define IDC_MESSAGELEN_DESC 1018 +#define IDC_GROUPTIME 1019 +#define IDC_LIMITMESSAGES 1020 +#define IDC_SHOWDATE 1021 +#define IDC_SHOWSECOND 1022 +#define IDC_SHOWSMILEYS 1023 +#define IDC_FORLIST 1024 +#define IDC_FORMES 1025 +#define IDC_MATCHCASE 1026 +#define IDC_MATCHWHOLE 1027 +#define IDC_ONLYIN 1028 +#define IDC_ONLYOUT 1029 +#define IDC_ONLYGROUP 1030 +#define IDC_DEFFILTER 1031 +#define IDC_LIST_FILTERS 1032 +#define IDC_LIST_EVENTS 1033 +#define IDC_ADD_FILTER 1034 +#define IDC_DELETE_FILTER 1035 +#define IDC_FILTER_NAME 1036 +#define IDC_EVENT 1037 +#define IDC_ADD_EVENT 1038 +#define IDC_DELETE_EVENT 1039 +#define IDC_SHOWCONTACTGROUPS 1040 +#define IDC_TXTENC 1041 +#define IDC_HTML1ENC 1042 +#define IDC_HTML1DATE 1043 +#define IDC_HTML2ENC 1044 +#define IDC_HTML2DATE 1045 +#define IDC_HTML2SHOWSMILEYS 1046 +#define IDC_HTML2EXTCSS 1047 +#define IDC_HTML2EXTCSSFILE 1048 +#define IDC_LIST_TASKS 1049 +#define IDC_ADD_TASK 1050 +#define IDC_EDIT_TASK 1051 +#define IDC_DELETE_TASK 1052 +#define IDC_TASK_TYPE 1053 +#define IDC_TASK_FILTER 1054 +#define IDC_LIST_CONTACTSEX 1055 +#define IDC_EVENT_TIME 1056 +#define IDC_EVENT_UNIT 1057 +#define IDC_TRIGER_TYPE 1058 +#define IDC_EXPORT_TYPE 1059 +#define IDC_EXPORT_TYPE_LABEL 1060 +#define IDC_COMPRESS 1061 +#define IDC_EXPORT_PATH 1062 +#define IDC_EXPORT_PATH_LABEL 1063 +#define IDC_TASK_STAR 1064 +#define IDC_FTP 1065 +#define IDC_UPLOAD 1066 +#define IDC_FTP_LABEL 1067 +#define IDC_TRIGER_TIME 1068 +#define IDC_TRIGER_TIME_LABEL 1069 +#define IDC_TRIGER_WEEK 1070 +#define IDC_TRIGER_WEEK_LABEL 1071 +#define IDC_TRIGER_DAY 1072 +#define IDC_TRIGER_DAY_LABEL 1073 +#define IDC_TRIGER_DELTA_TIME 1074 +#define IDC_TRIGER_DELTA_TIME_LABEL 1075 +#define IDC_WINSCP 1076 +#define IDC_WINSCPLOG 1077 +#define IDC_TASK_NAME 1078 +#define IDC_TASK_ACTIVE 1079 +#define IDC_TASK_FILTER_LABEL 1080 +#define IDC_EVENT_LABEL 1081 +#define IDC_IMPORT_TYPE 1082 +#define IDC_PASSWORD 1083 +#define IDC_PASSWORD_LABEL 1084 +#define IDC_EXPIMP 1085 +#define IDC_WINSCP_BROWSE 1086 +#define IDC_WINSCPLOG_BROWSE 1087 +#define IDC_CSS_BROWSE 1088 +#define IDC_SCHEDULER_ALERTS 1089 +#define IDC_SCHEDULER_HISTORY_ALERTS 1090 +#define IDC_ALLCONTACTS 1091 +#define IDI_INM 20000 +#define IDI_OUTM 20001 +#define IDI_SHOW 20002 +#define IDI_HIDE 20003 +#define IDI_FINDNEXT 20004 +#define IDI_FINDPREV 20005 +#define IDI_STATUS 20008 +#define IDR_CSS 20009 +#define IDR_JS 20010 +#define IDI_PLUSEX 20011 +#define IDI_MINUSEX 20012 +#define IDM_FIND 40001 +#define IDM_CONFIG 40002 +#define IDM_FINDNEXT 40003 +#define IDM_FINDPREV 40004 +#define IDM_MATCHCASE 40005 +#define IDM_MATCHWHOLE 40006 +#define IDM_OPTIONS 40007 +#define IDM_FONTS 40008 +#define IDM_ICONS 40009 +#define IDM_HOTKEYS 40010 +#define IDM_SAVEPOS 40011 +#define IDM_SAVEPOSALL 40012 +#define IDM_ONLYIN 40013 +#define IDM_ONLYOUT 40014 +#define IDM_DELETE 40015 +#define IDM_DELETEGROUP 40016 +#define IDM_DELETEUSER 40017 +#define IDM_MESSAGE 40018 +#define IDM_COPY 40019 +#define IDM_OPENNEW 40020 +#define IDM_OPENEXISTING 40021 +#define IDM_COPYLINK 40022 +#define IDM_ONLYGROUP 40023 +#define IDM_QUOTE 40024 +#define IDM_FILTERDEF 40025 +#define IDM_FILTERALL 40026 +#define IDM_EXPORTRHTML 40027 +#define IDM_EXPORTPHTML 40028 +#define IDM_EXPORTTXT 40029 +#define IDM_EXPORTBINARY 40030 +#define IDM_IMPORTBINARY 40031 +#define IDM_EXPORTDAT 40032 +#define IDM_IMPORTDAT 40033 +#define IDM_ALLUSERS 40034 + +#define CUSTOMRES 300 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 106 +#define _APS_NEXT_COMMAND_VALUE 40024 +#define _APS_NEXT_CONTROL_VALUE 1030 +#define _APS_NEXT_SYMED_VALUE 106 +#endif +#endif diff --git a/plugins/BasicHistory/src/stdafx.cpp b/plugins/BasicHistory/src/stdafx.cpp new file mode 100644 index 0000000000..dd47c41552 --- /dev/null +++ b/plugins/BasicHistory/src/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// BasicHistory.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/plugins/BasicHistory/src/stdafx.h b/plugins/BasicHistory/src/stdafx.h new file mode 100644 index 0000000000..bc670d4358 --- /dev/null +++ b/plugins/BasicHistory/src/stdafx.h @@ -0,0 +1,88 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#ifndef _WIN64 +#define _USE_32BIT_TIME_T +#endif + +#define _CRT_SECURE_NO_WARNINGS +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MIRANDA_VER 0x0900 +#define MIRANDA_CUSTOM_LP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "m_updater.h" +#include "m_smileyadd.h" +#include "m_toolbar.h" +#include "m_metacontacts.h" + +#define HISTORY_HK_FIND 100 +#define HISTORY_HK_FINDNEXT 101 +#define HISTORY_HK_FINDPREV 102 +#define HISTORY_HK_MATCHCASE 103 +#define HISTORY_HK_MATCHWHOLE 104 +#define HISTORY_HK_SHOWCONTACTS 105 +#define HISTORY_HK_ONLYIN 106 +#define HISTORY_HK_ONLYOUT 107 +#define HISTORY_HK_DELETE 108 +#define HISTORY_HK_ONLYGROUP 109 +#define HISTORY_HK_EXRHTML 110 +#define HISTORY_HK_EXPHTML 111 +#define HISTORY_HK_EXTXT 112 +#define HISTORY_HK_EXBIN 113 +#define HISTORY_HK_IMPBIN 114 +#define HISTORY_HK_EXDAT 115 +#define HISTORY_HK_IMPDAT 116 +#define HISTORY_HK_ALLCONTACTS 117 + +#define EVENTTYPE_STATUSCHANGE 25368 +#define EVENTTYPE_SMTPSIMPLE 2350 \ No newline at end of file diff --git a/plugins/BasicHistory/src/targetver.h b/plugins/BasicHistory/src/targetver.h new file mode 100644 index 0000000000..90e767bfce --- /dev/null +++ b/plugins/BasicHistory/src/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/plugins/BasicHistory/src/version.h b/plugins/BasicHistory/src/version.h new file mode 100644 index 0000000000..8b7d5ce949 --- /dev/null +++ b/plugins/BasicHistory/src/version.h @@ -0,0 +1,20 @@ +#define __MAJOR_VERSION 1 +#define __MINOR_VERSION 0 +#define __RELEASE_NUM 1 +#define __BUILD_NUM 6 + +#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM +#define __FILEVERSION_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM + +#define __STRINGIFY_IMPL(x) #x +#define __STRINGIFY(x) __STRINGIFY_IMPL(x) +#define __VERSION_STRING __STRINGIFY(__FILEVERSION_DOTS) + +#define __PLUGIN_NAME "Basic History" +#define __INTERNAL_NAME "BasicHistory" +#define __FILENAME "BasicHistory.dll" +#define __DESCRIPTION "History viewer for Miranda IM." +#define __AUTHOR "Krzysztof Kral" +#define __AUTHOREMAIL "krzysztof.kral@gmail.com" +#define __AUTHORWEB "http://programista.free.of.pl/miranda/" +#define __COPYRIGHT "Copyright (c) 2011-2012 Krzysztof Kral" diff --git a/plugins/BasicHistory/stdafx.cpp b/plugins/BasicHistory/stdafx.cpp deleted file mode 100644 index dd47c41552..0000000000 --- a/plugins/BasicHistory/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// BasicHistory.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/plugins/BasicHistory/stdafx.h b/plugins/BasicHistory/stdafx.h deleted file mode 100644 index bc670d4358..0000000000 --- a/plugins/BasicHistory/stdafx.h +++ /dev/null @@ -1,88 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#include "targetver.h" - -#ifndef _WIN64 -#define _USE_32BIT_TIME_T -#endif - -#define _CRT_SECURE_NO_WARNINGS -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -// Windows Header Files: -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define MIRANDA_VER 0x0900 -#define MIRANDA_CUSTOM_LP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "m_updater.h" -#include "m_smileyadd.h" -#include "m_toolbar.h" -#include "m_metacontacts.h" - -#define HISTORY_HK_FIND 100 -#define HISTORY_HK_FINDNEXT 101 -#define HISTORY_HK_FINDPREV 102 -#define HISTORY_HK_MATCHCASE 103 -#define HISTORY_HK_MATCHWHOLE 104 -#define HISTORY_HK_SHOWCONTACTS 105 -#define HISTORY_HK_ONLYIN 106 -#define HISTORY_HK_ONLYOUT 107 -#define HISTORY_HK_DELETE 108 -#define HISTORY_HK_ONLYGROUP 109 -#define HISTORY_HK_EXRHTML 110 -#define HISTORY_HK_EXPHTML 111 -#define HISTORY_HK_EXTXT 112 -#define HISTORY_HK_EXBIN 113 -#define HISTORY_HK_IMPBIN 114 -#define HISTORY_HK_EXDAT 115 -#define HISTORY_HK_IMPDAT 116 -#define HISTORY_HK_ALLCONTACTS 117 - -#define EVENTTYPE_STATUSCHANGE 25368 -#define EVENTTYPE_SMTPSIMPLE 2350 \ No newline at end of file diff --git a/plugins/BasicHistory/targetver.h b/plugins/BasicHistory/targetver.h deleted file mode 100644 index 90e767bfce..0000000000 --- a/plugins/BasicHistory/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/plugins/BasicHistory/version.h b/plugins/BasicHistory/version.h deleted file mode 100644 index 8b7d5ce949..0000000000 --- a/plugins/BasicHistory/version.h +++ /dev/null @@ -1,20 +0,0 @@ -#define __MAJOR_VERSION 1 -#define __MINOR_VERSION 0 -#define __RELEASE_NUM 1 -#define __BUILD_NUM 6 - -#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM -#define __FILEVERSION_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM - -#define __STRINGIFY_IMPL(x) #x -#define __STRINGIFY(x) __STRINGIFY_IMPL(x) -#define __VERSION_STRING __STRINGIFY(__FILEVERSION_DOTS) - -#define __PLUGIN_NAME "Basic History" -#define __INTERNAL_NAME "BasicHistory" -#define __FILENAME "BasicHistory.dll" -#define __DESCRIPTION "History viewer for Miranda IM." -#define __AUTHOR "Krzysztof Kral" -#define __AUTHOREMAIL "krzysztof.kral@gmail.com" -#define __AUTHORWEB "http://programista.free.of.pl/miranda/" -#define __COPYRIGHT "Copyright (c) 2011-2012 Krzysztof Kral" diff --git a/plugins/BasicHistory/version.rc b/plugins/BasicHistory/version.rc deleted file mode 100644 index 3fcaa468d0..0000000000 --- a/plugins/BasicHistory/version.rc +++ /dev/null @@ -1,37 +0,0 @@ - -#include -#include "version.h" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION __FILEVERSION_STRING - PRODUCTVERSION __FILEVERSION_STRING - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#ifdef _DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS_NT_WINDOWS32 - FILETYPE VFT_DLL - FILESUBTYPE VFT2_UNKNOWN -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "Author", "Krzysztof Kral" - VALUE "CompanyName", "Krzysztof Kral" - VALUE "FileDescription", __DESCRIPTION - VALUE "FileVersion", __VERSION_STRING - VALUE "InternalName", __INTERNAL_NAME - VALUE "LegalCopyright", __COPYRIGHT - VALUE "OriginalFilename", __FILENAME - VALUE "ProductName", __PLUGIN_NAME - VALUE "ProductVersion", __VERSION_STRING - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0, 1200 - END -END -- cgit v1.2.3