summaryrefslogtreecommitdiff
path: root/plugins/NewStory/src/history_dlg.cpp
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2024-02-19 20:13:12 +0300
committerdartraiden <wowemuh@gmail.com>2024-02-19 20:16:52 +0300
commit2f47988d1ef6672929762fba39fa69ef1b4dfa7a (patch)
treebaa3433b11b1c44ab5a12c919ab004a24d645043 /plugins/NewStory/src/history_dlg.cpp
parentf50885f33f7d1e129d719f06a43cc73518e0ffb1 (diff)
NewStory:
- add [cX] tag to variables help - convert sources to CR+LF
Diffstat (limited to 'plugins/NewStory/src/history_dlg.cpp')
-rw-r--r--plugins/NewStory/src/history_dlg.cpp2446
1 files changed, 1223 insertions, 1223 deletions
diff --git a/plugins/NewStory/src/history_dlg.cpp b/plugins/NewStory/src/history_dlg.cpp
index 4ce49fbd20..0ace485a79 100644
--- a/plugins/NewStory/src/history_dlg.cpp
+++ b/plugins/NewStory/src/history_dlg.cpp
@@ -1,1223 +1,1223 @@
-/*
-Copyright (c) 2005 Victor Pavlychko (nullbyte@sotline.net.ua)
-Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org)
-
-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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "stdafx.h"
-
-static CMOption<int> g_splitter(MODULENAME, "SplitterY", 100);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Main history dialog
-
-enum
-{
- HIST_SHOW_IN = 0x001,
- HIST_SHOW_OUT = 0x002,
- HIST_SHOW_MSGS = 0x004,
- HIST_SHOW_FILES = 0x008,
- HIST_SHOW_URLS = 0x010,
- HIST_SHOW_STATUS = 0x020,
- HIST_SHOW_OTHER = 0x040,
- HIST_AUTO_FILTER = 0x080,
-};
-
-enum
-{
- WND_OPT_TIMETREE = 0x01,
- WND_OPT_SEARCHBAR = 0x02,
- WND_OPT_FILTERBAR = 0x04,
- WND_OPT_BOOKMARKS = 0x08,
-};
-
-enum
-{
- WND_SPACING = 4,
- TBTN_SIZE = 25,
-};
-
-struct InfoBarEvents
-{
- HWND hwndIco, hwndIcoIn, hwndIcoOut;
- HWND hwndTxt, hwndTxtIn, hwndTxtOut;
-};
-
-void LayoutFilterBar(HDWP hDwp, int x, int y, int w, InfoBarEvents *ib)
-{
- hDwp = DeferWindowPos(hDwp, ib->hwndIco, 0,
- x, y, 16, 16, SWP_NOZORDER);
- hDwp = DeferWindowPos(hDwp, ib->hwndTxt, 0,
- x + 16 + WND_SPACING, y, w - 16 - WND_SPACING, 16, SWP_NOZORDER);
-
- hDwp = DeferWindowPos(hDwp, ib->hwndIcoIn, 0,
- x + 16, y + 16 + WND_SPACING, 16, 16, SWP_NOZORDER);
- hDwp = DeferWindowPos(hDwp, ib->hwndTxtIn, 0,
- x + 32 + WND_SPACING, y + 16 + WND_SPACING, w - WND_SPACING - 32, 16, SWP_NOZORDER);
-
- hDwp = DeferWindowPos(hDwp, ib->hwndIcoOut, 0,
- x + 16, y + (16 + WND_SPACING) * 2, 16, 16, SWP_NOZORDER);
- DeferWindowPos(hDwp, ib->hwndTxtOut, 0,
- x + 32 + WND_SPACING, y + (16 + WND_SPACING) * 2, w - WND_SPACING - 32, 16, SWP_NOZORDER);
-}
-
-class CHistoryDlg : public CDlgBase
-{
- HMENU m_hMenu;
- uint16_t showFlags;
- bool m_bSearchChanged = false;
- MCONTACT m_hContact;
- int lastYear = -1, lastMonth = -1, lastDay = -1;
- HTREEITEM hLastYear = 0, hLastMonth = 0, hLastDay = 0;
- bool disableTimeTreeChange = false;
- bool bAppendOnly;
-
- // window flags
- uint32_t m_dwOptions = 0;
-
- // toolbar buttons
- struct Button
- {
- enum { RIGHT = 1, SPACED = 2 };
-
- Button(CCtrlMButton &_1, int _2 = 0) :
- hwnd(_1),
- options(_2)
- {}
-
- CCtrlMButton &hwnd;
- int options;
- };
- std::vector<Button> m_toolbar;
-
- // main controls
- int m_iSplitter;
-
- CCtrlBase m_histWindow;
- NewstoryListData *m_histCtrl;
-
- // bookmarks
- HIMAGELIST hBookmarksIcons = 0;
- std::map<MCONTACT, std::vector<MEVENT>> m_events; // for filtered events
-
- // searchbar
- HWND m_hwndBtnCloseSearch;
-
- // statusbar
- HWND m_hwndStatus;
-
- // filter bar
- HWND m_hwndChkDateFrom, m_hwndChkDateTo;
- HWND m_hwndDateFrom, m_hwndDateTo;
- InfoBarEvents ibMessages, ibFiles, ibUrls, ibTotal;
-
- OBJLIST<SearchResult> m_arResults;
-
- static int stubSortResults(const void *p1, const void *p2)
- {
- return int((*(SearchResult **)p1)->ts) - int((*(SearchResult **)p2)->ts);
- }
-
- void DoGlobalSearch()
- {
- ptrW wszPattern(edtSearchText.GetText());
- if (!mir_wstrlen(wszPattern))
- return;
-
- // clear messages array first
- m_histCtrl->Clear();
-
- CharLowerW(wszPattern);
- DoSearchContact(0, wszPattern);
- for (auto &hContact : Contacts())
- DoSearchContact(hContact, wszPattern);
-
- qsort(m_arResults.getArray(), m_arResults.getCount(), sizeof(void *), stubSortResults);
- m_histCtrl->AddResults(m_arResults);
- m_arResults.destroy();
-
- BuildTimeTree();
- }
-
- void DoSearchContact(MCONTACT hContact, const wchar_t *pwszPattern)
- {
- DB::ECPTR pCursor(DB::Events(hContact));
- while (MEVENT hDbEvent = pCursor.FetchNext()) {
- DB::EventInfo dbei(hDbEvent);
- if (!dbei)
- continue;
-
- ptrW pwszText(DbEvent_GetTextW(&dbei));
- if (!mir_wstrlen(pwszText))
- continue;
-
- CharLowerW(pwszText);
- if (wcsstr(pwszText, pwszPattern))
- m_arResults.insert(new SearchResult(hContact, hDbEvent, dbei.timestamp));
- }
- }
-
- void ShowHideControls()
- {
- int cmd = (m_dwOptions & WND_OPT_FILTERBAR) ? SW_SHOW : SW_HIDE;
- ShowWindow(ibMessages.hwndIco, cmd);
- ShowWindow(ibMessages.hwndIcoIn, cmd);
- ShowWindow(ibMessages.hwndIcoOut, cmd);
- ShowWindow(ibMessages.hwndTxt, cmd);
- ShowWindow(ibMessages.hwndTxtIn, cmd);
- ShowWindow(ibMessages.hwndTxtOut, cmd);
- ShowWindow(ibFiles.hwndIco, cmd);
- ShowWindow(ibFiles.hwndIcoIn, cmd);
- ShowWindow(ibFiles.hwndIcoOut, cmd);
- ShowWindow(ibFiles.hwndTxt, cmd);
- ShowWindow(ibFiles.hwndTxtIn, cmd);
- ShowWindow(ibFiles.hwndTxtOut, cmd);
- ShowWindow(ibUrls.hwndIco, cmd);
- ShowWindow(ibUrls.hwndIcoIn, cmd);
- ShowWindow(ibUrls.hwndIcoOut, cmd);
- ShowWindow(ibUrls.hwndTxt, cmd);
- ShowWindow(ibUrls.hwndTxtIn, cmd);
- ShowWindow(ibUrls.hwndTxtOut, cmd);
- ShowWindow(ibTotal.hwndIco, cmd);
- ShowWindow(ibTotal.hwndIcoIn, cmd);
- ShowWindow(ibTotal.hwndIcoOut, cmd);
- ShowWindow(ibTotal.hwndTxt, cmd);
- ShowWindow(ibTotal.hwndTxtIn, cmd);
- ShowWindow(ibTotal.hwndTxtOut, cmd);
- ShowWindow(m_hwndDateFrom, cmd);
- ShowWindow(m_hwndDateTo, cmd);
- ShowWindow(m_hwndChkDateFrom, cmd);
- ShowWindow(m_hwndChkDateTo, cmd);
- ShowWindow(GetDlgItem(m_hwnd, IDC_IB_SEPARATOR), cmd);
-
- cmd = (m_dwOptions & WND_OPT_SEARCHBAR) ? SW_SHOW : SW_HIDE;
- ShowWindow(m_hwndBtnCloseSearch, cmd);
- ShowWindow(btnFindNext.GetHwnd(), cmd);
- ShowWindow(btnFindPrev.GetHwnd(), cmd);
- ShowWindow(edtSearchText.GetHwnd(), cmd);
- if (cmd)
- SetFocus(edtSearchText.GetHwnd());
-
- bool bShowTime = (m_dwOptions & WND_OPT_TIMETREE) != 0;
- bool bShowBookmarks = (m_dwOptions & WND_OPT_BOOKMARKS) != 0;
- m_timeTree.Show(bShowTime);
- m_bookmarks.Show(bShowBookmarks);
- splitTime.Show(bShowTime || bShowBookmarks);
- }
-
- void UpdateTitle()
- {
- switch (m_hContact) {
- case INVALID_CONTACT_ID:
- SetWindowText(m_hwnd, TranslateT("Global history search"));
- break;
-
- case 0:
- SetWindowText(m_hwnd, TranslateT("System history"));
- break;
-
- default:
- SetWindowText(m_hwnd, TplFormatString(TPL_TITLE, m_hContact, 0));
- }
- }
-
- void BuildBookmarksList()
- {
- if (!(m_dwOptions & WND_OPT_BOOKMARKS))
- return;
-
- m_events.clear();
- m_bookmarks.DeleteAllItems();
- if (hBookmarksIcons)
- ImageList_Destroy(hBookmarksIcons);
-
- hBookmarksIcons = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 1, 0);
- m_bookmarks.SetImageList(hBookmarksIcons, LVSIL_SMALL);
-
- if (m_hContact == INVALID_CONTACT_ID) {
- auto *pDB = db_get_current();
-
- int iIconId = ImageList_ReplaceIcon(hBookmarksIcons, -1, g_plugin.getIcon(IDI_USERS));
- m_bookmarks.AddItem(TranslateT("All results"), iIconId, INVALID_CONTACT_ID);
-
- std::map<char *, int> protoMap;
-
- for (auto &cc : Contacts()) {
- bool bAdded = false;
- DB::ECPTR pCursor(pDB->EventCursor(cc, 0));
- while (MEVENT hEvent = pCursor.FetchNext()) {
- DB::EventInfo dbei(hEvent, false);
- if (dbei && dbei.flags & DBEF_BOOKMARK) {
- if (!bAdded) {
- auto *pa = Proto_GetContactAccount(cc);
- char *szProto = (pa == nullptr) ? "SomeShit" : pa->szModuleName;
- auto pProto = protoMap.find(szProto);
-
- if (pProto == protoMap.end()) {
- iIconId = ImageList_ReplaceIcon(hBookmarksIcons, -1, Skin_LoadProtoIcon(szProto, ID_STATUS_ONLINE));
- protoMap[szProto] = iIconId;
- }
- else iIconId = (*pProto).second;
-
- m_bookmarks.AddItem(Clist_GetContactDisplayName(cc, 0), iIconId, cc);
- bAdded = true;
- }
-
- m_events[cc].push_back(hEvent);
- }
- }
- }
- }
- else {
- ImageList_ReplaceIcon(hBookmarksIcons, -1, g_plugin.getIcon(IDI_BOOKMARK));
-
- int numItems = m_histCtrl->totalCount;
-
- for (int i = 0; i < numItems; i++) {
- auto *pItem = m_histCtrl->GetItem(i);
- if (pItem->fetch())
- if (pItem->dbe.flags & DBEF_BOOKMARK)
- m_bookmarks.AddItem(pItem->getWBuf(), 0, i);
- }
- }
- }
-
- void BuildTimeTree()
- {
- if (!(m_dwOptions & WND_OPT_TIMETREE))
- return;
-
- m_timeTree.DeleteAllItems();
- auto &pArray = m_histCtrl->items;
- int numItems = pArray.getCount();
-
- int CurYear = 0, CurMonth = 0, CurDay = 0, PrevYear = -1, PrevMonth = -1, PrevDay = -1;
- HTREEITEM hCurYear = 0, hCurMonth = 0, hCurDay = 0;
- for (int i = 0; i < numItems; i++) {
- auto *pItem = pArray.get(i, false);
- if (!pItem->fetch())
- continue;
-
- if (pItem->dbe.timestamp == 0)
- continue;
-
- struct tm ts = { 0 };
- time_t timestamp = pItem->dbe.timestamp;
- errno_t err = localtime_s(&ts, &timestamp); /* statically alloced, local time correction */
- if (err != 0)
- return;
-
- CurYear = ts.tm_year + 1900;
- CurMonth = ts.tm_mon + 1;
- CurDay = ts.tm_mday;
- wchar_t buf[50];
- TVINSERTSTRUCT tvi;
- tvi.hParent = nullptr;
- tvi.item.mask = TVIF_TEXT | TVIF_PARAM;
- if (CurYear != PrevYear) {
- _itow(CurYear, buf, 10);
- tvi.item.pszText = buf;
- tvi.item.lParam = 0;
- hCurYear = TreeView_InsertItem(m_timeTree.GetHwnd(), &tvi);
- PrevYear = CurYear;
- }
- if (CurMonth != PrevMonth) {
- tvi.hParent = hCurYear;
- tvi.item.pszText = TranslateW(months[CurMonth - 1]);
- tvi.item.lParam = CurMonth;
- hCurMonth = TreeView_InsertItem(m_timeTree.GetHwnd(), &tvi);
- PrevMonth = CurMonth;
- }
- if (CurDay != PrevDay) {
- _itow(CurDay, buf, 10);
- tvi.hParent = hCurMonth;
- tvi.item.pszText = buf;
- tvi.item.lParam = 0;
- hCurDay = TreeView_InsertItem(m_timeTree.GetHwnd(), &tvi);
- PrevDay = CurDay;
- }
- }
- disableTimeTreeChange = true;
- HTREEITEM root = m_timeTree.GetRoot();
- m_timeTree.SelectItem(root);
- }
-
- CSplitter splitTime;
- CCtrlEdit edtSearchText;
- CCtrlMButton btnUserInfo, btnSendMsg, btnUserMenu, btnCopy, btnOptions, btnFilter;
- CCtrlMButton btnCalendar, btnSearch, btnExport, btnFindNext, btnFindPrev, btnDelete, btnTimeTree, btnBookmarks;
- CCtrlListView m_bookmarks;
- CCtrlTreeView m_timeTree;
-
-public:
- CHistoryDlg(MCONTACT _hContact) :
- CDlgBase(g_plugin, IDD_HISTORY),
- m_arResults(10000),
- m_hContact(_hContact),
- m_iSplitter(g_splitter),
- m_bookmarks(this, IDC_BOOKMARKSLIST),
- m_timeTree(this, IDC_TIMETREEVIEW),
- m_histWindow(this, IDC_HISTORYCONTROL),
- splitTime(this, IDC_SPLITTERY),
- edtSearchText(this, IDC_SEARCHTEXT),
- btnCopy(this, IDC_COPY, g_plugin.getIcon(IDI_COPY), LPGEN("Copy")),
- btnExport(this, IDC_EXPORT, g_plugin.getIcon(IDI_EXPORT), LPGEN("Export...")),
- btnDelete(this, IDC_DELETE, SKINICON_OTHER_DELETE, LPGEN("Delete...")),
- btnFilter(this, IDC_FILTER, g_plugin.getIcon(IDI_FILTER), LPGEN("Filter")),
- btnSearch(this, IDC_SEARCH, g_plugin.getIcon(IDI_SEARCH), LPGEN("Search...")),
- btnOptions(this, IDC_LOGOPTIONS, g_plugin.getIcon(IDI_OPTIONS), LPGEN("Options")),
- btnSendMsg(this, IDC_MESSAGE, g_plugin.getIcon(IDI_SENDMSG), LPGEN("Send message")),
- btnCalendar(this, IDC_DATEPOPUP, g_plugin.getIcon(IDI_CALENDAR), LPGEN("Jump to date")),
- btnUserInfo(this, IDC_USERINFO, g_plugin.getIcon(IDI_USERINFO), LPGEN("User info")),
- btnUserMenu(this, IDC_USERMENU, g_plugin.getIcon(IDI_USERMENU), LPGEN("User menu")),
- btnFindNext(this, IDOK, g_plugin.getIcon(IDI_FINDNEXT), LPGEN("Find next")),
- btnFindPrev(this, IDC_FINDPREV, g_plugin.getIcon(IDI_FINDPREV), LPGEN("Find previous")),
- btnTimeTree(this, IDC_TIMETREE, g_plugin.getIcon(IDI_TIMETREE), LPGEN("Conversations")),
- btnBookmarks(this, IDC_BOOKMARKS, g_plugin.getIcon(IDI_BOOKMARK), LPGEN("Bookmarks"))
- {
- showFlags = g_plugin.getWord("showFlags", 0x7f);
- m_dwOptions = g_plugin.getDword("dwOptions");
-
- if (!GetDatabasePlugin("JSON")) {
- btnExport.Disable();
- btnExport.SetTooltip(LPGEN("You need to install the Import plugin to export events"));
- }
-
- if (m_hContact == INVALID_CONTACT_ID)
- m_dwOptions |= WND_OPT_SEARCHBAR;
- else if (m_hContact > 0) {
- m_toolbar.push_back(Button(btnUserMenu));
- m_toolbar.push_back(Button(btnUserInfo));
- m_toolbar.push_back(Button(btnSendMsg, Button::SPACED));
- }
-
- m_toolbar.push_back(Button(btnTimeTree));
- m_toolbar.push_back(Button(btnBookmarks));
- m_toolbar.push_back(Button(btnSearch));
- m_toolbar.push_back(Button(btnFilter));
- m_toolbar.push_back(Button(btnCalendar, Button::SPACED));
- m_toolbar.push_back(Button(btnCopy));
- m_toolbar.push_back(Button(btnDelete));
- m_toolbar.push_back(Button(btnExport));
- m_toolbar.push_back(Button(btnOptions, Button::RIGHT));
-
- m_timeTree.OnSelChanged = Callback(this, &CHistoryDlg::onSelChanged_TimeTree);
- m_bookmarks.OnItemChanged = Callback(this, &CHistoryDlg::onSelChanged_Bookmarks);
-
- edtSearchText.OnChange = Callback(this, &CHistoryDlg::onChange_SearchText);
-
- splitTime.OnChange = Callback(this, &CHistoryDlg::onChange_Splitter);
-
- btnCopy.OnClick = Callback(this, &CHistoryDlg::onClick_Copy);
- btnExport.OnClick = Callback(this, &CHistoryDlg::onClick_Export);
- btnDelete.OnClick = Callback(this, &CHistoryDlg::onClick_Delete);
- btnFilter.OnClick = Callback(this, &CHistoryDlg::onClick_Filter);
- btnSearch.OnClick = Callback(this, &CHistoryDlg::onClick_Search);
- btnOptions.OnClick = Callback(this, &CHistoryDlg::onClick_Options);
- btnSendMsg.OnClick = Callback(this, &CHistoryDlg::onClick_Message);
- btnCalendar.OnClick = Callback(this, &CHistoryDlg::onClick_Calendar);
- btnFindPrev.OnClick = Callback(this, &CHistoryDlg::onClick_FindPrev);
- btnUserInfo.OnClick = Callback(this, &CHistoryDlg::onClick_UserInfo);
- btnUserMenu.OnClick = Callback(this, &CHistoryDlg::onClick_UserMenu);
- btnTimeTree.OnClick = Callback(this, &CHistoryDlg::onClick_TimeTree);
- btnBookmarks.OnClick = Callback(this, &CHistoryDlg::onClick_Bookmarks);
-
- m_hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_POPUPS));
- TranslateMenu(m_hMenu);
-
- HMENU hMenu = GetSubMenu(m_hMenu, 0);
- CheckMenuItem(hMenu, ID_FILTER_INCOMING, (showFlags & HIST_SHOW_IN) ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(hMenu, ID_FILTER_OUTGOING, (showFlags & HIST_SHOW_OUT) ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(hMenu, ID_FILTER_MESSAGES, (showFlags & HIST_SHOW_MSGS) ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(hMenu, ID_FILTER_FILES, (showFlags & HIST_SHOW_FILES) ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(hMenu, ID_FILTER_URLS, (showFlags & HIST_SHOW_URLS) ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(hMenu, ID_FILTER_STATUS, (showFlags & HIST_SHOW_STATUS) ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(hMenu, ID_FILTER_OTHER, (showFlags & HIST_SHOW_OTHER) ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem(hMenu, ID_FILTER_AUTO, (showFlags & HIST_AUTO_FILTER) ? MF_CHECKED : MF_UNCHECKED);
- }
-
- bool OnInitDialog() override
- {
- // get handles
- m_hwndBtnCloseSearch = GetDlgItem(m_hwnd, IDC_SEARCHICON);
- m_hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, m_hwnd, NULL, g_plugin.getInst(), NULL);
- SendMessage(m_hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0);
-
- // bookmarks
- RECT rc;
- GetClientRect(m_bookmarks.GetHwnd(), &rc);
- m_bookmarks.AddColumn(0, TranslateT("Bookmarks"), rc.right - rc.left);
-
- // filterbar
- btnFilter.MakePush();
-
- btnTimeTree.MakePush();
- if (m_dwOptions & WND_OPT_TIMETREE)
- btnTimeTree.Push(true);
-
- btnSearch.MakePush();
- if (m_dwOptions & WND_OPT_SEARCHBAR)
- btnSearch.Push(true);
-
- btnBookmarks.MakePush();
- if (m_dwOptions & WND_OPT_BOOKMARKS)
- btnBookmarks.Push(true);
-
- // filters
- m_hwndChkDateFrom = GetDlgItem(m_hwnd, IDC_CHK_DATE_FROM);
- m_hwndChkDateTo = GetDlgItem(m_hwnd, IDC_CHK_DATE_TO);
- m_hwndDateFrom = GetDlgItem(m_hwnd, IDC_DATE_FROM);
- m_hwndDateTo = GetDlgItem(m_hwnd, IDC_DATE_TO);
-
- ibMessages.hwndIco = GetDlgItem(m_hwnd, IDC_ICO_MESSAGES);
- ibMessages.hwndTxt = GetDlgItem(m_hwnd, IDC_TXT_MESSAGES);
- ibMessages.hwndIcoIn = GetDlgItem(m_hwnd, IDC_ICO_MESSAGES_IN);
- SendMessage(ibMessages.hwndIcoIn, BUTTONSETASFLATBTN, 0, 0);
- SendMessage(ibMessages.hwndIcoIn, BUTTONSETASPUSHBTN, 0, 0);
- SendMessage(ibMessages.hwndIcoIn, BM_SETCHECK, BST_CHECKED, 0);
-
- ibMessages.hwndTxtIn = GetDlgItem(m_hwnd, IDC_TXT_MESSAGES_IN);
- ibMessages.hwndIcoOut = GetDlgItem(m_hwnd, IDC_ICO_MESSAGES_OUT);
- SendMessage(ibMessages.hwndIcoOut, BUTTONSETASFLATBTN, 0, 0);
- SendMessage(ibMessages.hwndIcoOut, BUTTONSETASPUSHBTN, 0, 0);
- SendMessage(ibMessages.hwndIcoOut, BM_SETCHECK, BST_CHECKED, 0);
- ibMessages.hwndTxtOut = GetDlgItem(m_hwnd, IDC_TXT_MESSAGES_OUT);
-
- ibFiles.hwndIco = GetDlgItem(m_hwnd, IDC_ICO_FILES);
- ibFiles.hwndTxt = GetDlgItem(m_hwnd, IDC_TXT_FILES);
- ibFiles.hwndIcoIn = GetDlgItem(m_hwnd, IDC_ICO_FILES_IN);
- SendMessage(ibFiles.hwndIcoIn, BUTTONSETASFLATBTN, 0, 0);
-
- SendMessage(ibFiles.hwndIcoIn, BUTTONSETASPUSHBTN, 0, 0);
- SendMessage(ibFiles.hwndIcoIn, BM_SETCHECK, BST_CHECKED, 0);
-
- ibFiles.hwndTxtIn = GetDlgItem(m_hwnd, IDC_TXT_FILES_IN);
- ibFiles.hwndIcoOut = GetDlgItem(m_hwnd, IDC_ICO_FILES_OUT);
- SendMessage(ibFiles.hwndIcoOut, BUTTONSETASFLATBTN, 0, 0);
- SendMessage(ibFiles.hwndIcoOut, BUTTONSETASPUSHBTN, 0, 0);
- SendMessage(ibFiles.hwndIcoOut, BM_SETCHECK, BST_CHECKED, 0);
- ibFiles.hwndTxtOut = GetDlgItem(m_hwnd, IDC_TXT_FILES_OUT);
-
- ibUrls.hwndIco = GetDlgItem(m_hwnd, IDC_ICO_URLS);
- ibUrls.hwndTxt = GetDlgItem(m_hwnd, IDC_TXT_URLS);
- ibUrls.hwndIcoIn = GetDlgItem(m_hwnd, IDC_ICO_URLS_IN);
- SendMessage(ibUrls.hwndIcoIn, BUTTONSETASFLATBTN, 0, 0);
- SendMessage(ibUrls.hwndIcoIn, BUTTONSETASPUSHBTN, 0, 0);
- SendMessage(ibUrls.hwndIcoIn, BM_SETCHECK, BST_CHECKED, 0);
-
- ibUrls.hwndTxtIn = GetDlgItem(m_hwnd, IDC_TXT_URLS_IN);
- ibUrls.hwndIcoOut = GetDlgItem(m_hwnd, IDC_ICO_URLS_OUT);
- SendMessage(ibUrls.hwndIcoOut, BUTTONSETASFLATBTN, 0, 0);
- SendMessage(ibUrls.hwndIcoOut, BUTTONSETASPUSHBTN, 0, 0);
- SendMessage(ibUrls.hwndIcoOut, BM_SETCHECK, BST_CHECKED, 0);
- ibUrls.hwndTxtOut = GetDlgItem(m_hwnd, IDC_TXT_URLS_OUT);
-
- ibTotal.hwndIco = GetDlgItem(m_hwnd, IDC_ICO_TOTAL);
- ibTotal.hwndTxt = GetDlgItem(m_hwnd, IDC_TXT_TOTAL);
- ibTotal.hwndIcoIn = GetDlgItem(m_hwnd, IDC_ICO_TOTAL_IN);
- SendMessage(ibTotal.hwndIcoIn, BUTTONSETASFLATBTN, 0, 0);
- SendMessage(ibTotal.hwndIcoIn, BUTTONSETASPUSHBTN, 0, 0);
- SendMessage(ibTotal.hwndIcoIn, BM_SETCHECK, BST_CHECKED, 0);
-
- ibTotal.hwndTxtIn = GetDlgItem(m_hwnd, IDC_TXT_TOTAL_IN);
- ibTotal.hwndIcoOut = GetDlgItem(m_hwnd, IDC_ICO_TOTAL_OUT);
- SendMessage(ibTotal.hwndIcoOut, BUTTONSETASFLATBTN, 0, 0);
- SendMessage(ibTotal.hwndIcoOut, BUTTONSETASPUSHBTN, 0, 0);
- SendMessage(ibTotal.hwndIcoOut, BM_SETCHECK, BST_CHECKED, 0);
- ibTotal.hwndTxtOut = GetDlgItem(m_hwnd, IDC_TXT_TOTAL_OUT);
-
- // Ask for layout
- PostMessage(m_hwnd, WM_SIZE, 0, 0);
-
- WindowList_Add(g_hNewstoryWindows, m_hwnd, m_hContact);
-
- ShowHideControls();
- UpdateTitle();
-
- m_histCtrl = (NewstoryListData *)GetWindowLongPtr(m_histWindow.GetHwnd(), 0);
-
- if (m_hContact == 0 || m_hContact == INVALID_CONTACT_ID) {
- btnSendMsg.Hide();
- btnUserInfo.Hide();
- btnUserMenu.Hide();
- }
-
- if (m_hContact != INVALID_CONTACT_ID) {
- Utils_RestoreWindowPosition(m_hwnd, m_hContact, MODULENAME, "wnd_");
-
- m_histCtrl->AddEvent(m_hContact, 0, -1);
-
- BuildTimeTree();
- SetFocus(m_histWindow.GetHwnd());
- }
- else Utils_RestoreWindowPosition(m_hwnd, 0, MODULENAME, "glb_");
-
- BuildBookmarksList();
-
- m_histCtrl->SetContact(m_hContact);
- m_histCtrl->ScrollBottom();
-
- Window_SetIcon_IcoLib(m_hwnd, g_plugin.getIconHandle(IDI_NEWSTORY));
-
- SendMessage(GetDlgItem(m_hwnd, IDC_SEARCHICON), STM_SETICON, (WPARAM)g_plugin.getIcon(IDI_SEARCH), 0);
-
- SendMessage(ibMessages.hwndIco, STM_SETICON, (LPARAM)g_plugin.getIcon(IDI_SENDMSG), 0);
- SendMessage(ibMessages.hwndIcoIn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGIN));
- SendMessage(ibMessages.hwndIcoOut, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGOUT));
-
- SendMessage(ibFiles.hwndIco, STM_SETICON, (LPARAM)Skin_LoadIcon(SKINICON_EVENT_FILE), 0);
- SendMessage(ibFiles.hwndIcoIn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGIN));
- SendMessage(ibFiles.hwndIcoOut, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGOUT));
-
- SendMessage(ibUrls.hwndIco, STM_SETICON, (LPARAM)Skin_LoadIcon(SKINICON_EVENT_URL), 0);
- SendMessage(ibUrls.hwndIcoIn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGIN));
- SendMessage(ibUrls.hwndIcoOut, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGOUT));
-
- SendMessage(ibTotal.hwndIco, STM_SETICON, (LPARAM)g_plugin.getIcon(IDI_UNKNOWN), 0);
- SendMessage(ibTotal.hwndIcoIn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGIN));
- SendMessage(ibTotal.hwndIcoOut, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGOUT));
- return true;
- }
-
- bool OnApply() override
- {
- if (m_bSearchChanged) {
- m_bSearchChanged = false;
- if (m_hContact == INVALID_CONTACT_ID)
- DoGlobalSearch();
- }
-
- int iOldCaret = m_histCtrl->caret;
- int res = m_histCtrl->FindNext(ptrW(edtSearchText.GetText()));
- if (res == -1)
- SetWindowTextW(m_hwndStatus, TranslateT("No more occuurences found"));
- else if (res < iOldCaret)
- SetWindowTextW(m_hwndStatus, TranslateT("Passed the end of history"));
- else
- SetWindowTextW(m_hwndStatus, L"");
-
- return false;
- }
-
- void OnResize() override
- {
- RECT rc;
- GetClientRect(m_hwnd, &rc);
- int y; // tmp vars
- int w = rc.right - rc.left;
- int h = rc.bottom - rc.top;
-
- HDWP hDwp = BeginDeferWindowPos(43 + (int)m_toolbar.size());
-
- // toolbar
- int hToolBar = TBTN_SIZE + WND_SPACING;
-
- int x = WND_SPACING;
- for (auto &it : m_toolbar) {
- if (it.options & Button::RIGHT)
- continue;
-
- hDwp = DeferWindowPos(hDwp, it.hwnd.GetHwnd(), 0, x, WND_SPACING, TBTN_SIZE, TBTN_SIZE, SWP_NOZORDER);
- x += TBTN_SIZE;
- if (it.options & Button::SPACED)
- x += 10;
- }
-
- x = w - WND_SPACING - TBTN_SIZE;
- for (auto &it : m_toolbar) {
- if (it.options & Button::RIGHT) {
- hDwp = DeferWindowPos(hDwp, it.hwnd.GetHwnd(), 0, x, WND_SPACING, TBTN_SIZE, TBTN_SIZE, SWP_NOZORDER);
- x -= TBTN_SIZE;
- }
- }
-
- // infobar
- // hDwp = DeferWindowPos(hDwp, hwndIcoProtocol, 0,
- // w-100+WND_SPACING, WND_SPACING,
- // 16, 16,
- // SWP_NOZORDER);
- // hDwp = DeferWindowPos(hDwp, hwndTxtNickname, 0,
- // w-100+WND_SPACING*2+16, WND_SPACING,
- // 100, 16,
- // SWP_NOZORDER);
- // hDwp = DeferWindowPos(hDwp, hwndTxtUID, 0,
- // w-100+WND_SPACING*2+16, WND_SPACING*2+16,
- // 100, 16,
- // SWP_NOZORDER);
-
- // filter bar
- int hFilterBar = 0;
- if (m_dwOptions & WND_OPT_FILTERBAR) {
- hFilterBar = WND_SPACING + (16 + WND_SPACING) * 3;
- LayoutFilterBar(hDwp, WND_SPACING + (WND_SPACING + 75) * 0, WND_SPACING * 2 + hToolBar, 75, &ibMessages);
- LayoutFilterBar(hDwp, WND_SPACING + (WND_SPACING + 75) * 1, WND_SPACING * 2 + hToolBar, 75, &ibFiles);
- LayoutFilterBar(hDwp, WND_SPACING + (WND_SPACING + 75) * 2, WND_SPACING * 2 + hToolBar, 75, &ibUrls);
- LayoutFilterBar(hDwp, WND_SPACING + (WND_SPACING + 75) * 3, WND_SPACING * 2 + hToolBar, 75, &ibTotal);
-
- GetWindowRect(m_hwndChkDateFrom, &rc);
- x = rc.right - rc.left;
- GetWindowRect(m_hwndDateFrom, &rc);
- y = hToolBar + WND_SPACING + (WND_SPACING + (16 + WND_SPACING) * 3 - (rc.bottom - rc.top) * 2 - WND_SPACING) / 2;
- hDwp = DeferWindowPos(hDwp, m_hwndChkDateFrom, 0,
- w - x - (rc.right - rc.left) - WND_SPACING * 2, y,
- x, rc.bottom - rc.top,
- SWP_NOZORDER | SWP_NOACTIVATE);
- hDwp = DeferWindowPos(hDwp, m_hwndDateFrom, 0,
- w - (rc.right - rc.left) - WND_SPACING, y,
- rc.right - rc.left, rc.bottom - rc.top,
- SWP_NOZORDER | SWP_NOACTIVATE);
-
- hDwp = DeferWindowPos(hDwp, m_hwndChkDateTo, 0,
- w - x - (rc.right - rc.left) - WND_SPACING * 2, y + (rc.bottom - rc.top) + WND_SPACING,
- x, rc.bottom - rc.top,
- SWP_NOZORDER | SWP_NOACTIVATE);
- hDwp = DeferWindowPos(hDwp, m_hwndDateTo, 0,
- w - (rc.right - rc.left) - WND_SPACING, y + (rc.bottom - rc.top) + WND_SPACING,
- rc.right - rc.left, rc.bottom - rc.top,
- SWP_NOZORDER | SWP_NOACTIVATE);
-
- hDwp = DeferWindowPos(hDwp, GetDlgItem(m_hwnd, IDC_IB_SEPARATOR), 0,
- WND_SPACING, hToolBar + WND_SPACING,
- w - WND_SPACING * 2, 2,
- SWP_NOZORDER | SWP_NOACTIVATE);
- }
-
- // general
- GetWindowRect(m_hwndStatus, &rc);
- int hStatus = rc.bottom - rc.top;
- hDwp = DeferWindowPos(hDwp, m_hwndStatus, 0,
- 0, h - hStatus,
- w, hStatus,
- SWP_NOZORDER | SWP_NOACTIVATE);
-
- // search bar
- int hSearch = 0;
- if (m_dwOptions & WND_OPT_SEARCHBAR) {
- GetWindowRect(edtSearchText.GetHwnd(), &rc);
- hSearch = rc.bottom - rc.top;
- hDwp = DeferWindowPos(hDwp, m_hwndBtnCloseSearch, 0,
- WND_SPACING, h - hSearch - hStatus - WND_SPACING,
- TBTN_SIZE, hSearch, SWP_NOZORDER | SWP_NOACTIVATE);
- hDwp = DeferWindowPos(hDwp, edtSearchText.GetHwnd(), 0,
- TBTN_SIZE + WND_SPACING * 2, h - hSearch - hStatus - WND_SPACING,
- w - WND_SPACING * 4 - TBTN_SIZE * 3, hSearch,
- SWP_NOZORDER | SWP_NOACTIVATE);
- hDwp = DeferWindowPos(hDwp, btnFindPrev.GetHwnd(), 0,
- w - WND_SPACING - TBTN_SIZE * 2, h - hSearch - hStatus - WND_SPACING,
- TBTN_SIZE, hSearch,
- SWP_NOZORDER | SWP_NOACTIVATE);
- hDwp = DeferWindowPos(hDwp, btnFindNext.GetHwnd(), 0,
- w - WND_SPACING - TBTN_SIZE * 1, h - hSearch - hStatus - WND_SPACING,
- TBTN_SIZE, hSearch,
- SWP_NOZORDER | SWP_NOACTIVATE);
- hSearch += WND_SPACING;
- }
-
- int iClientTop = WND_SPACING + hToolBar + hFilterBar;
- int iClientBottom = h - WND_SPACING - hSearch - hStatus - iClientTop;
-
- // time tree bar
- int hTimeTree = 0;
- bool bShowTime = (m_dwOptions & WND_OPT_TIMETREE) != 0;
- bool bShowBookmarks = (m_dwOptions & WND_OPT_BOOKMARKS) != 0;
-
- if (bShowTime || bShowBookmarks) {
- hTimeTree = m_iSplitter;
- hDwp = DeferWindowPos(hDwp, splitTime.GetHwnd(), 0, hTimeTree, iClientTop, WND_SPACING, iClientBottom, SWP_NOZORDER | SWP_NOACTIVATE);
-
- if (bShowTime && bShowBookmarks) {
- int hMiddle = iClientBottom / 2;
- hDwp = DeferWindowPos(hDwp, m_timeTree.GetHwnd(), 0, WND_SPACING, iClientTop, hTimeTree - WND_SPACING, hMiddle, SWP_NOZORDER | SWP_NOACTIVATE);
- hDwp = DeferWindowPos(hDwp, m_bookmarks.GetHwnd(), 0, WND_SPACING, iClientTop + hMiddle, hTimeTree - WND_SPACING, hMiddle, SWP_NOZORDER | SWP_NOACTIVATE);
- }
- else if (bShowTime)
- hDwp = DeferWindowPos(hDwp, m_timeTree.GetHwnd(), 0, WND_SPACING, iClientTop, hTimeTree - WND_SPACING, iClientBottom, SWP_NOZORDER | SWP_NOACTIVATE);
- else
- hDwp = DeferWindowPos(hDwp, m_bookmarks.GetHwnd(), 0, WND_SPACING, iClientTop, hTimeTree - WND_SPACING, iClientBottom, SWP_NOZORDER | SWP_NOACTIVATE);
- }
-
- hDwp = DeferWindowPos(hDwp, m_histWindow.GetHwnd(), 0,
- WND_SPACING + hTimeTree, iClientTop,
- w - WND_SPACING * 2 - hTimeTree, iClientBottom,
- SWP_NOZORDER | SWP_NOACTIVATE);
-
- EndDeferWindowPos(hDwp);
- }
-
- void OnDestroy() override
- {
- g_splitter = m_iSplitter;
-
- if (m_hContact != INVALID_CONTACT_ID)
- Utils_SaveWindowPosition(m_hwnd, m_hContact, MODULENAME, "wnd_");
- else
- Utils_SaveWindowPosition(m_hwnd, 0, MODULENAME, "glb_");
-
- g_plugin.setWord(0, "showFlags", showFlags);
- g_plugin.setDword(0, "dwOptions", m_dwOptions);
-
- Window_FreeIcon_IcoLib(m_hwnd);
- WindowList_Remove(g_hNewstoryWindows, m_hwnd);
-
- if (m_hwndStatus != nullptr) {
- DestroyWindow(m_hwndStatus);
- m_hwndStatus = nullptr;
- }
- }
-
- void onClick_Calendar(CCtrlButton *pButton)
- {
- RECT rc;
- GetWindowRect(pButton->GetHwnd(), &rc);
-
- CalendarTool_Show(m_hwnd, rc.left, rc.bottom);
- }
-
- void onClick_Copy(CCtrlButton *)
- {
- m_histCtrl->Copy();
- }
-
- void onClick_Delete(CCtrlButton *)
- {
- if (!CallService(MS_HISTORY_EMPTY, m_hContact, 0)) {
- m_histCtrl->Clear();
-
- UpdateTitle();
- BuildTimeTree();
- }
- }
-
- void onClick_TimeTree(CCtrlButton *)
- {
- if (m_dwOptions & WND_OPT_TIMETREE)
- m_dwOptions &= ~WND_OPT_TIMETREE;
- else
- m_dwOptions |= WND_OPT_TIMETREE;
-
- OnResize();
- ShowHideControls();
- BuildTimeTree();
- }
-
- void onClick_Bookmarks(CCtrlButton *)
- {
- if (m_dwOptions & WND_OPT_BOOKMARKS)
- m_dwOptions &= ~WND_OPT_BOOKMARKS;
- else
- m_dwOptions |= WND_OPT_BOOKMARKS;
-
- OnResize();
- ShowHideControls();
- BuildBookmarksList();
- }
-
- void onClick_Export(CCtrlButton *)
- {
- auto *pDriver = GetDatabasePlugin("JSON");
- if (pDriver == nullptr) {
- CMStringW wszText(TranslateT("The required plugin 'Import' isn't loaded to perform this operation."));
- if (ServiceExists(MS_PU_SHOWLIST)) {
- wszText.AppendFormat(L" %s", TranslateT("Do you want to install it using Plugin Updater?"));
- if (IDYES == MessageBoxW(m_hwnd, wszText, TranslateT("Missing plugin"), MB_YESNO | MB_ICONQUESTION))
- CallService(MS_PU_SHOWLIST);
- }
- else MessageBoxW(m_hwnd, wszText, TranslateT("Missing plugin"), MB_OK | MB_ICONERROR);
- return;
- }
-
- wchar_t FileName[MAX_PATH];
- VARSW tszMirDir(L"%miranda_userdata%\\NewStoryExport");
-
- if (db_mc_isMeta(m_hContact)) {
- CMStringW SubContactsList, MessageText;
- bool FirstTime = true;
- int subcount = db_mc_getSubCount(m_hContact);
- for (int i = 0; i < subcount; i++) {
- MCONTACT hSubContact = db_mc_getSub(m_hContact, i);
- char *subproto = Proto_GetBaseAccountName(hSubContact);
- ptrW subid(Contact::GetInfo(CNF_UNIQUEID, hSubContact, subproto));
- if (FirstTime)
- SubContactsList.Append(subid);
- else
- SubContactsList.AppendFormat(L"\r\n%s", subid.get());
- FirstTime = false;
- }
- MessageText.AppendFormat(TranslateT("It is metacontact. For export use one of this subcontacts:\r\n%s"), SubContactsList.c_str());
- MessageBox(m_hwnd, MessageText, TranslateT("Export warning"), MB_OK | MB_ICONWARNING);
- return;
- }
-
- OPENFILENAME ofn = { 0 };
- ofn.lStructSize = sizeof(ofn);
- CMStringW tszFilter, tszTitle, tszFileName;
- tszFilter.AppendFormat(L"%s (*.json)%c*.json%c%c", TranslateT("JSON files"), 0, 0, 0);
- tszTitle.AppendFormat(TranslateT("Export history"));
- ofn.lpstrFilter = tszFilter;
- ofn.hwndOwner = nullptr;
- ofn.lpstrTitle = tszTitle;
- ofn.lpstrFile = FileName;
- ofn.nMaxFile = MAX_PATH;
- ofn.nMaxFileTitle = MAX_PATH;
- ofn.Flags = OFN_HIDEREADONLY | OFN_SHAREAWARE | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
- ofn.lpstrInitialDir = tszMirDir;
- *FileName = '\0';
- ofn.lpstrDefExt = L"";
- if (!GetSaveFileName(&ofn))
- return;
-
- // create file
- CreatePathToFileW(FileName);
- if (PathFileExistsW(FileName))
- DeleteFileW(FileName);
-
- auto *pDB = pDriver->Export(FileName);
- pDB->BeginExport();
- pDB->ExportContact(m_hContact);
-
- // export events
- int iDone = 0;
- bAppendOnly = false;
- auto &arItems = m_histCtrl->items;
- int iCount = arItems.getCount();
- for (int i = 0; i < iCount; i++) {
- auto *pItem = arItems.get(i);
- if (pItem->m_bSelected) {
- DB::EventInfo dbei(pItem->hEvent);
- if (dbei)
- pDB->ExportEvent(dbei);
- iDone++;
- }
- }
-
- // no items selected? export whole history
- if (iDone == 0)
- for (int i = 0; i < iCount; i++) {
- auto *pItem = arItems.get(i);
- DB::EventInfo dbei(pItem->hEvent);
- if (dbei)
- pDB->ExportEvent(dbei);
- }
-
- // Close the file
- pDB->EndExport();
- MessageBox(m_hwnd, TranslateT("Complete"), TranslateT("History export"), MB_OK | MB_ICONINFORMATION);
- }
-
- void onClick_Filter(CCtrlButton *)
- {
- if (m_dwOptions & WND_OPT_FILTERBAR)
- m_dwOptions &= ~WND_OPT_FILTERBAR;
- else
- m_dwOptions |= WND_OPT_FILTERBAR;
-
- ShowHideControls();
- OnResize();
- }
-
- void onClick_FindPrev(CCtrlButton *)
- {
- int iOldCaret = m_histCtrl->caret;
- int res = m_histCtrl->FindPrev(ptrW(edtSearchText.GetText()));
- if (res == -1)
- SetWindowTextW(m_hwndStatus, TranslateT("No more occuurences found"));
- else if (res > iOldCaret)
- SetWindowTextW(m_hwndStatus, TranslateT("Passed the beginning of history"));
- else
- SetWindowTextW(m_hwndStatus, L"");
- }
-
- void onClick_Message(CCtrlButton *)
- {
- CallService(MS_MSG_SENDMESSAGE, m_hContact, 0);
- }
-
- void onClick_Options(CCtrlButton *pButton)
- {
- RECT rc;
- GetWindowRect(pButton->GetHwnd(), &rc);
-
- switch (TrackPopupMenu(GetSubMenu(m_hMenu, 1), TPM_RETURNCMD, rc.left, rc.bottom, 0, m_hwnd, NULL)) {
- case ID_LOGOPTIONS_OPTIONS:
- g_plugin.openOptions(L"History", L"NewStory", L"Advanced");
- break;
-
- case ID_LOGOPTIONS_TEMPLATES:
- g_plugin.openOptions(L"History", L"NewStory", L"Templates");
- break;
- }
- PostMessage(m_hwnd, WM_SIZE, 0, 0);
- }
-
- void onClick_Search(CCtrlButton *)
- {
- if (m_dwOptions & WND_OPT_SEARCHBAR)
- m_dwOptions &= ~WND_OPT_SEARCHBAR;
- else
- m_dwOptions |= WND_OPT_SEARCHBAR;
-
- ShowHideControls();
- OnResize();
- }
-
- void onClick_UserInfo(CCtrlButton *)
- {
- CallService(MS_USERINFO_SHOWDIALOG, m_hContact, 0);
- }
-
- void onClick_UserMenu(CCtrlButton *pButton)
- {
- RECT rc;
- GetWindowRect(pButton->GetHwnd(), &rc);
-
- HMENU hMenu = Menu_BuildContactMenu(m_hContact);
- TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, m_hwnd, NULL);
- DestroyMenu(hMenu);
- }
-
- void onChange_SearchText(CCtrlEdit *)
- {
- m_bSearchChanged = true;
-
- if (m_bInitialized)
- if (showFlags & HIST_AUTO_FILTER)
- PostMessage(m_hwnd, UM_REBUILDLIST, 0, 0);
- }
-
- void onChange_Splitter(CSplitter *)
- {
- m_iSplitter = splitTime.GetPos();
- }
-
- INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override
- {
- if ((msg >= NSM_FIRST) && (msg < NSM_LAST)) {
- LPARAM result = m_histWindow.SendMsg(msg, wParam, lParam);
- SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, result);
- return result;
- }
-
- MSG message = { m_hwnd, msg, wParam, lParam };
- switch (Hotkey_Check(&message, MODULENAME)) {
- case HOTKEY_SEEK_FORWARD:
- btnFindNext.Click();
- break;
- case HOTKEY_SEEK_BACK:
- btnFindPrev.Click();
- break;
- case HOTKEY_SEARCH:
- btnSearch.Click();
- break;
- }
-
- switch (msg) {
- case WM_CHARTOITEM:
- if (!((GetKeyState(VK_CONTROL) & 0x80) || (GetKeyState(VK_MENU) & 0x80))) {
- wchar_t s[] = { LOWORD(wParam), 0 };
- SetWindowText(GetDlgItem(m_hwnd, IDC_SEARCHTEXT), s);
- SendMessage(GetDlgItem(m_hwnd, IDC_SEARCHTEXT), EM_SETSEL, 1, 1);
- SetFocus(GetDlgItem(m_hwnd, IDC_SEARCHTEXT));
- }
- return -1;
-
- case WM_COMMAND:
- if (Clist_MenuProcessCommand(LOWORD(wParam), MPCF_CONTACTMENU, m_hContact))
- return TRUE;
- break;
-
- /*
- GetWindowRect(GetDlgItem(m_hwnd, LOWORD(wParam)), &rc);
-// uint32_t itemID = 0;
- bool doFilter = true;
- switch (TrackPopupMenu(GetSubMenu(hMenu, 1), TPM_RETURNCMD, rc.left, rc.bottom, 0, m_hwnd, NULL))
- {
- case ID_FILTER_INCOMING:
- {
- showFlags = toggleBit(showFlags, HIST_SHOW_IN);
- CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_INCOMING,
- showFlags&HIST_SHOW_IN ? MF_CHECKED : MF_UNCHECKED);
- break;
- }
- case ID_FILTER_OUTGOING:
- {
- showFlags = toggleBit(showFlags, HIST_SHOW_OUT);
- CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_OUTGOING,
- showFlags&HIST_SHOW_OUT ? MF_CHECKED : MF_UNCHECKED);
- break;
- }
- case ID_FILTER_MESSAGES:
- {
- showFlags = toggleBit(showFlags, HIST_SHOW_MSGS);
- CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_MESSAGES,
- showFlags&HIST_SHOW_MSGS ? MF_CHECKED : MF_UNCHECKED);
- break;
- }
- case ID_FILTER_FILES:
- {
- showFlags = toggleBit(showFlags, HIST_SHOW_FILES);
- CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_FILES,
- showFlags&HIST_SHOW_FILES ? MF_CHECKED : MF_UNCHECKED);
- break;
- }
- case ID_FILTER_URLS:
- {
- showFlags = toggleBit(showFlags, HIST_SHOW_URLS);
- CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_URLS,
- showFlags&HIST_SHOW_URLS ? MF_CHECKED : MF_UNCHECKED);
- break;
- }
- case ID_FILTER_STATUS:
- {
- showFlags = toggleBit(showFlags, HIST_SHOW_STATUS);
- CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_STATUS,
- showFlags&HIST_SHOW_STATUS ? MF_CHECKED : MF_UNCHECKED);
- break;
- }
- case ID_FILTER_OTHER:
- {
- showFlags = toggleBit(showFlags, HIST_SHOW_OTHER);
- CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_OTHER,
- showFlags&HIST_SHOW_OTHER ? MF_CHECKED : MF_UNCHECKED);
- break;
- }
- case ID_FILTER_AUTO:
- {
- showFlags = toggleBit(showFlags, HIST_AUTO_FILTER);
- CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_AUTO,
- showFlags&HIST_AUTO_FILTER ? MF_CHECKED : MF_UNCHECKED);
- break;
- }
- default:
- {
- doFilter = false;
- break;
- }
- }
- if (doFilter)
- PostMessage(m_hwnd, UM_REBUILDLIST, 0, 0);
- break;*/
-
- case UM_BOOKMARKS:
- BuildBookmarksList();
- break;
-
- case WM_USER + 0x600:
- if (wParam)
- m_histWindow.SendMsg(NSM_SEEKTIME, wParam, 0);
- }
-
- return CDlgBase::DlgProc(msg, wParam, lParam);
- }
-
- void onSelChanged_Bookmarks(CCtrlListView::TEventInfo *ev)
- {
- int idx = m_bookmarks.GetItemData(ev->nmlv->iItem);
-
- if (m_hContact == INVALID_CONTACT_ID) {
- m_histCtrl->Clear();
-
- if (idx == INVALID_CONTACT_ID) {
- for (auto &cc : m_events)
- for (auto &hEvent : cc.second)
- m_histCtrl->AddEvent(cc.first, hEvent, 1);
- }
- else for (auto &hEvent : m_events[idx])
- m_histCtrl->AddEvent(idx, hEvent, 1);
- }
- else m_histCtrl->SetPos(idx);
- }
-
- void onSelChanged_TimeTree(CCtrlTreeView::TEventInfo *)
- {
- wchar_t *val1, *val2, *val3;
- int yearsel = 0, monthsel = 0, daysel = 1;
- bool monthfound = false;
- if (disableTimeTreeChange)
- disableTimeTreeChange = false;
- else {
- HTREEITEM hti1 = m_timeTree.GetSelection();
- TVITEMEX tvi = { 0 };
- tvi.hItem = hti1;
- tvi.mask = TVIF_HANDLE | TVIF_TEXT | TVIF_PARAM;
- tvi.cchTextMax = MAX_PATH;
- tvi.lParam = 0;
- tvi.pszText = (wchar_t *)_alloca(MAX_PATH * sizeof(wchar_t));
-
- m_timeTree.GetItem(&tvi);
- val1 = tvi.pszText;
- if (tvi.lParam) {
- monthsel = tvi.lParam;
- monthfound = true;
- }
- HTREEITEM hti2 = m_timeTree.GetParent(hti1);
- if ((!monthfound) && (!hti2))
- yearsel = _wtoi(val1);
- if ((!monthfound) && (hti2))
- daysel = _wtoi(val1);
- if (hti2) {
- tvi.hItem = hti2;
- tvi.lParam = 0;
- m_timeTree.GetItem(&tvi);
- val2 = tvi.pszText;
- if (tvi.lParam) {
- monthsel = tvi.lParam;
- monthfound = true;
- }
- else
- yearsel = _wtoi(val2);
- HTREEITEM hti3 = m_timeTree.GetParent(hti2);
- if (hti3) {
- tvi.hItem = hti3;
- tvi.lParam = 0;
- m_timeTree.GetItem(&tvi);
- val3 = tvi.pszText;
- yearsel = _wtoi(val3);
- }
- }
- struct tm tm_sel;
- tm_sel.tm_hour = tm_sel.tm_min = tm_sel.tm_sec = 0;
- tm_sel.tm_isdst = 1;
- tm_sel.tm_mday = daysel;
- if (monthsel)
- tm_sel.tm_mon = monthsel - 1;
- else
- tm_sel.tm_mon = 0;
- tm_sel.tm_year = yearsel - 1900;
- PostMessage(m_hwnd, WM_USER + 0x600, mktime(&tm_sel), 0);
- }
- }
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Services
-
-INT_PTR svcShowNewstory(WPARAM hContact, LPARAM)
-{
- HWND hwnd = (HWND)WindowList_Find(g_hNewstoryWindows, hContact);
- if (!hwnd) {
- auto *pDlg = new CHistoryDlg(hContact);
- pDlg->Show();
- hwnd = pDlg->GetHwnd();
- }
-
- SetForegroundWindow(hwnd);
- SetFocus(hwnd);
- return 0;
-}
-
-INT_PTR svcGlobalSearch(WPARAM, LPARAM)
-{
- return svcShowNewstory(INVALID_CONTACT_ID, 0);
-}
+/*
+Copyright (c) 2005 Victor Pavlychko (nullbyte@sotline.net.ua)
+Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org)
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdafx.h"
+
+static CMOption<int> g_splitter(MODULENAME, "SplitterY", 100);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Main history dialog
+
+enum
+{
+ HIST_SHOW_IN = 0x001,
+ HIST_SHOW_OUT = 0x002,
+ HIST_SHOW_MSGS = 0x004,
+ HIST_SHOW_FILES = 0x008,
+ HIST_SHOW_URLS = 0x010,
+ HIST_SHOW_STATUS = 0x020,
+ HIST_SHOW_OTHER = 0x040,
+ HIST_AUTO_FILTER = 0x080,
+};
+
+enum
+{
+ WND_OPT_TIMETREE = 0x01,
+ WND_OPT_SEARCHBAR = 0x02,
+ WND_OPT_FILTERBAR = 0x04,
+ WND_OPT_BOOKMARKS = 0x08,
+};
+
+enum
+{
+ WND_SPACING = 4,
+ TBTN_SIZE = 25,
+};
+
+struct InfoBarEvents
+{
+ HWND hwndIco, hwndIcoIn, hwndIcoOut;
+ HWND hwndTxt, hwndTxtIn, hwndTxtOut;
+};
+
+void LayoutFilterBar(HDWP hDwp, int x, int y, int w, InfoBarEvents *ib)
+{
+ hDwp = DeferWindowPos(hDwp, ib->hwndIco, 0,
+ x, y, 16, 16, SWP_NOZORDER);
+ hDwp = DeferWindowPos(hDwp, ib->hwndTxt, 0,
+ x + 16 + WND_SPACING, y, w - 16 - WND_SPACING, 16, SWP_NOZORDER);
+
+ hDwp = DeferWindowPos(hDwp, ib->hwndIcoIn, 0,
+ x + 16, y + 16 + WND_SPACING, 16, 16, SWP_NOZORDER);
+ hDwp = DeferWindowPos(hDwp, ib->hwndTxtIn, 0,
+ x + 32 + WND_SPACING, y + 16 + WND_SPACING, w - WND_SPACING - 32, 16, SWP_NOZORDER);
+
+ hDwp = DeferWindowPos(hDwp, ib->hwndIcoOut, 0,
+ x + 16, y + (16 + WND_SPACING) * 2, 16, 16, SWP_NOZORDER);
+ DeferWindowPos(hDwp, ib->hwndTxtOut, 0,
+ x + 32 + WND_SPACING, y + (16 + WND_SPACING) * 2, w - WND_SPACING - 32, 16, SWP_NOZORDER);
+}
+
+class CHistoryDlg : public CDlgBase
+{
+ HMENU m_hMenu;
+ uint16_t showFlags;
+ bool m_bSearchChanged = false;
+ MCONTACT m_hContact;
+ int lastYear = -1, lastMonth = -1, lastDay = -1;
+ HTREEITEM hLastYear = 0, hLastMonth = 0, hLastDay = 0;
+ bool disableTimeTreeChange = false;
+ bool bAppendOnly;
+
+ // window flags
+ uint32_t m_dwOptions = 0;
+
+ // toolbar buttons
+ struct Button
+ {
+ enum { RIGHT = 1, SPACED = 2 };
+
+ Button(CCtrlMButton &_1, int _2 = 0) :
+ hwnd(_1),
+ options(_2)
+ {}
+
+ CCtrlMButton &hwnd;
+ int options;
+ };
+ std::vector<Button> m_toolbar;
+
+ // main controls
+ int m_iSplitter;
+
+ CCtrlBase m_histWindow;
+ NewstoryListData *m_histCtrl;
+
+ // bookmarks
+ HIMAGELIST hBookmarksIcons = 0;
+ std::map<MCONTACT, std::vector<MEVENT>> m_events; // for filtered events
+
+ // searchbar
+ HWND m_hwndBtnCloseSearch;
+
+ // statusbar
+ HWND m_hwndStatus;
+
+ // filter bar
+ HWND m_hwndChkDateFrom, m_hwndChkDateTo;
+ HWND m_hwndDateFrom, m_hwndDateTo;
+ InfoBarEvents ibMessages, ibFiles, ibUrls, ibTotal;
+
+ OBJLIST<SearchResult> m_arResults;
+
+ static int stubSortResults(const void *p1, const void *p2)
+ {
+ return int((*(SearchResult **)p1)->ts) - int((*(SearchResult **)p2)->ts);
+ }
+
+ void DoGlobalSearch()
+ {
+ ptrW wszPattern(edtSearchText.GetText());
+ if (!mir_wstrlen(wszPattern))
+ return;
+
+ // clear messages array first
+ m_histCtrl->Clear();
+
+ CharLowerW(wszPattern);
+ DoSearchContact(0, wszPattern);
+ for (auto &hContact : Contacts())
+ DoSearchContact(hContact, wszPattern);
+
+ qsort(m_arResults.getArray(), m_arResults.getCount(), sizeof(void *), stubSortResults);
+ m_histCtrl->AddResults(m_arResults);
+ m_arResults.destroy();
+
+ BuildTimeTree();
+ }
+
+ void DoSearchContact(MCONTACT hContact, const wchar_t *pwszPattern)
+ {
+ DB::ECPTR pCursor(DB::Events(hContact));
+ while (MEVENT hDbEvent = pCursor.FetchNext()) {
+ DB::EventInfo dbei(hDbEvent);
+ if (!dbei)
+ continue;
+
+ ptrW pwszText(DbEvent_GetTextW(&dbei));
+ if (!mir_wstrlen(pwszText))
+ continue;
+
+ CharLowerW(pwszText);
+ if (wcsstr(pwszText, pwszPattern))
+ m_arResults.insert(new SearchResult(hContact, hDbEvent, dbei.timestamp));
+ }
+ }
+
+ void ShowHideControls()
+ {
+ int cmd = (m_dwOptions & WND_OPT_FILTERBAR) ? SW_SHOW : SW_HIDE;
+ ShowWindow(ibMessages.hwndIco, cmd);
+ ShowWindow(ibMessages.hwndIcoIn, cmd);
+ ShowWindow(ibMessages.hwndIcoOut, cmd);
+ ShowWindow(ibMessages.hwndTxt, cmd);
+ ShowWindow(ibMessages.hwndTxtIn, cmd);
+ ShowWindow(ibMessages.hwndTxtOut, cmd);
+ ShowWindow(ibFiles.hwndIco, cmd);
+ ShowWindow(ibFiles.hwndIcoIn, cmd);
+ ShowWindow(ibFiles.hwndIcoOut, cmd);
+ ShowWindow(ibFiles.hwndTxt, cmd);
+ ShowWindow(ibFiles.hwndTxtIn, cmd);
+ ShowWindow(ibFiles.hwndTxtOut, cmd);
+ ShowWindow(ibUrls.hwndIco, cmd);
+ ShowWindow(ibUrls.hwndIcoIn, cmd);
+ ShowWindow(ibUrls.hwndIcoOut, cmd);
+ ShowWindow(ibUrls.hwndTxt, cmd);
+ ShowWindow(ibUrls.hwndTxtIn, cmd);
+ ShowWindow(ibUrls.hwndTxtOut, cmd);
+ ShowWindow(ibTotal.hwndIco, cmd);
+ ShowWindow(ibTotal.hwndIcoIn, cmd);
+ ShowWindow(ibTotal.hwndIcoOut, cmd);
+ ShowWindow(ibTotal.hwndTxt, cmd);
+ ShowWindow(ibTotal.hwndTxtIn, cmd);
+ ShowWindow(ibTotal.hwndTxtOut, cmd);
+ ShowWindow(m_hwndDateFrom, cmd);
+ ShowWindow(m_hwndDateTo, cmd);
+ ShowWindow(m_hwndChkDateFrom, cmd);
+ ShowWindow(m_hwndChkDateTo, cmd);
+ ShowWindow(GetDlgItem(m_hwnd, IDC_IB_SEPARATOR), cmd);
+
+ cmd = (m_dwOptions & WND_OPT_SEARCHBAR) ? SW_SHOW : SW_HIDE;
+ ShowWindow(m_hwndBtnCloseSearch, cmd);
+ ShowWindow(btnFindNext.GetHwnd(), cmd);
+ ShowWindow(btnFindPrev.GetHwnd(), cmd);
+ ShowWindow(edtSearchText.GetHwnd(), cmd);
+ if (cmd)
+ SetFocus(edtSearchText.GetHwnd());
+
+ bool bShowTime = (m_dwOptions & WND_OPT_TIMETREE) != 0;
+ bool bShowBookmarks = (m_dwOptions & WND_OPT_BOOKMARKS) != 0;
+ m_timeTree.Show(bShowTime);
+ m_bookmarks.Show(bShowBookmarks);
+ splitTime.Show(bShowTime || bShowBookmarks);
+ }
+
+ void UpdateTitle()
+ {
+ switch (m_hContact) {
+ case INVALID_CONTACT_ID:
+ SetWindowText(m_hwnd, TranslateT("Global history search"));
+ break;
+
+ case 0:
+ SetWindowText(m_hwnd, TranslateT("System history"));
+ break;
+
+ default:
+ SetWindowText(m_hwnd, TplFormatString(TPL_TITLE, m_hContact, 0));
+ }
+ }
+
+ void BuildBookmarksList()
+ {
+ if (!(m_dwOptions & WND_OPT_BOOKMARKS))
+ return;
+
+ m_events.clear();
+ m_bookmarks.DeleteAllItems();
+ if (hBookmarksIcons)
+ ImageList_Destroy(hBookmarksIcons);
+
+ hBookmarksIcons = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 1, 0);
+ m_bookmarks.SetImageList(hBookmarksIcons, LVSIL_SMALL);
+
+ if (m_hContact == INVALID_CONTACT_ID) {
+ auto *pDB = db_get_current();
+
+ int iIconId = ImageList_ReplaceIcon(hBookmarksIcons, -1, g_plugin.getIcon(IDI_USERS));
+ m_bookmarks.AddItem(TranslateT("All results"), iIconId, INVALID_CONTACT_ID);
+
+ std::map<char *, int> protoMap;
+
+ for (auto &cc : Contacts()) {
+ bool bAdded = false;
+ DB::ECPTR pCursor(pDB->EventCursor(cc, 0));
+ while (MEVENT hEvent = pCursor.FetchNext()) {
+ DB::EventInfo dbei(hEvent, false);
+ if (dbei && dbei.flags & DBEF_BOOKMARK) {
+ if (!bAdded) {
+ auto *pa = Proto_GetContactAccount(cc);
+ char *szProto = (pa == nullptr) ? "SomeShit" : pa->szModuleName;
+ auto pProto = protoMap.find(szProto);
+
+ if (pProto == protoMap.end()) {
+ iIconId = ImageList_ReplaceIcon(hBookmarksIcons, -1, Skin_LoadProtoIcon(szProto, ID_STATUS_ONLINE));
+ protoMap[szProto] = iIconId;
+ }
+ else iIconId = (*pProto).second;
+
+ m_bookmarks.AddItem(Clist_GetContactDisplayName(cc, 0), iIconId, cc);
+ bAdded = true;
+ }
+
+ m_events[cc].push_back(hEvent);
+ }
+ }
+ }
+ }
+ else {
+ ImageList_ReplaceIcon(hBookmarksIcons, -1, g_plugin.getIcon(IDI_BOOKMARK));
+
+ int numItems = m_histCtrl->totalCount;
+
+ for (int i = 0; i < numItems; i++) {
+ auto *pItem = m_histCtrl->GetItem(i);
+ if (pItem->fetch())
+ if (pItem->dbe.flags & DBEF_BOOKMARK)
+ m_bookmarks.AddItem(pItem->getWBuf(), 0, i);
+ }
+ }
+ }
+
+ void BuildTimeTree()
+ {
+ if (!(m_dwOptions & WND_OPT_TIMETREE))
+ return;
+
+ m_timeTree.DeleteAllItems();
+ auto &pArray = m_histCtrl->items;
+ int numItems = pArray.getCount();
+
+ int CurYear = 0, CurMonth = 0, CurDay = 0, PrevYear = -1, PrevMonth = -1, PrevDay = -1;
+ HTREEITEM hCurYear = 0, hCurMonth = 0, hCurDay = 0;
+ for (int i = 0; i < numItems; i++) {
+ auto *pItem = pArray.get(i, false);
+ if (!pItem->fetch())
+ continue;
+
+ if (pItem->dbe.timestamp == 0)
+ continue;
+
+ struct tm ts = { 0 };
+ time_t timestamp = pItem->dbe.timestamp;
+ errno_t err = localtime_s(&ts, &timestamp); /* statically alloced, local time correction */
+ if (err != 0)
+ return;
+
+ CurYear = ts.tm_year + 1900;
+ CurMonth = ts.tm_mon + 1;
+ CurDay = ts.tm_mday;
+ wchar_t buf[50];
+ TVINSERTSTRUCT tvi;
+ tvi.hParent = nullptr;
+ tvi.item.mask = TVIF_TEXT | TVIF_PARAM;
+ if (CurYear != PrevYear) {
+ _itow(CurYear, buf, 10);
+ tvi.item.pszText = buf;
+ tvi.item.lParam = 0;
+ hCurYear = TreeView_InsertItem(m_timeTree.GetHwnd(), &tvi);
+ PrevYear = CurYear;
+ }
+ if (CurMonth != PrevMonth) {
+ tvi.hParent = hCurYear;
+ tvi.item.pszText = TranslateW(months[CurMonth - 1]);
+ tvi.item.lParam = CurMonth;
+ hCurMonth = TreeView_InsertItem(m_timeTree.GetHwnd(), &tvi);
+ PrevMonth = CurMonth;
+ }
+ if (CurDay != PrevDay) {
+ _itow(CurDay, buf, 10);
+ tvi.hParent = hCurMonth;
+ tvi.item.pszText = buf;
+ tvi.item.lParam = 0;
+ hCurDay = TreeView_InsertItem(m_timeTree.GetHwnd(), &tvi);
+ PrevDay = CurDay;
+ }
+ }
+ disableTimeTreeChange = true;
+ HTREEITEM root = m_timeTree.GetRoot();
+ m_timeTree.SelectItem(root);
+ }
+
+ CSplitter splitTime;
+ CCtrlEdit edtSearchText;
+ CCtrlMButton btnUserInfo, btnSendMsg, btnUserMenu, btnCopy, btnOptions, btnFilter;
+ CCtrlMButton btnCalendar, btnSearch, btnExport, btnFindNext, btnFindPrev, btnDelete, btnTimeTree, btnBookmarks;
+ CCtrlListView m_bookmarks;
+ CCtrlTreeView m_timeTree;
+
+public:
+ CHistoryDlg(MCONTACT _hContact) :
+ CDlgBase(g_plugin, IDD_HISTORY),
+ m_arResults(10000),
+ m_hContact(_hContact),
+ m_iSplitter(g_splitter),
+ m_bookmarks(this, IDC_BOOKMARKSLIST),
+ m_timeTree(this, IDC_TIMETREEVIEW),
+ m_histWindow(this, IDC_HISTORYCONTROL),
+ splitTime(this, IDC_SPLITTERY),
+ edtSearchText(this, IDC_SEARCHTEXT),
+ btnCopy(this, IDC_COPY, g_plugin.getIcon(IDI_COPY), LPGEN("Copy")),
+ btnExport(this, IDC_EXPORT, g_plugin.getIcon(IDI_EXPORT), LPGEN("Export...")),
+ btnDelete(this, IDC_DELETE, SKINICON_OTHER_DELETE, LPGEN("Delete...")),
+ btnFilter(this, IDC_FILTER, g_plugin.getIcon(IDI_FILTER), LPGEN("Filter")),
+ btnSearch(this, IDC_SEARCH, g_plugin.getIcon(IDI_SEARCH), LPGEN("Search...")),
+ btnOptions(this, IDC_LOGOPTIONS, g_plugin.getIcon(IDI_OPTIONS), LPGEN("Options")),
+ btnSendMsg(this, IDC_MESSAGE, g_plugin.getIcon(IDI_SENDMSG), LPGEN("Send message")),
+ btnCalendar(this, IDC_DATEPOPUP, g_plugin.getIcon(IDI_CALENDAR), LPGEN("Jump to date")),
+ btnUserInfo(this, IDC_USERINFO, g_plugin.getIcon(IDI_USERINFO), LPGEN("User info")),
+ btnUserMenu(this, IDC_USERMENU, g_plugin.getIcon(IDI_USERMENU), LPGEN("User menu")),
+ btnFindNext(this, IDOK, g_plugin.getIcon(IDI_FINDNEXT), LPGEN("Find next")),
+ btnFindPrev(this, IDC_FINDPREV, g_plugin.getIcon(IDI_FINDPREV), LPGEN("Find previous")),
+ btnTimeTree(this, IDC_TIMETREE, g_plugin.getIcon(IDI_TIMETREE), LPGEN("Conversations")),
+ btnBookmarks(this, IDC_BOOKMARKS, g_plugin.getIcon(IDI_BOOKMARK), LPGEN("Bookmarks"))
+ {
+ showFlags = g_plugin.getWord("showFlags", 0x7f);
+ m_dwOptions = g_plugin.getDword("dwOptions");
+
+ if (!GetDatabasePlugin("JSON")) {
+ btnExport.Disable();
+ btnExport.SetTooltip(LPGEN("You need to install the Import plugin to export events"));
+ }
+
+ if (m_hContact == INVALID_CONTACT_ID)
+ m_dwOptions |= WND_OPT_SEARCHBAR;
+ else if (m_hContact > 0) {
+ m_toolbar.push_back(Button(btnUserMenu));
+ m_toolbar.push_back(Button(btnUserInfo));
+ m_toolbar.push_back(Button(btnSendMsg, Button::SPACED));
+ }
+
+ m_toolbar.push_back(Button(btnTimeTree));
+ m_toolbar.push_back(Button(btnBookmarks));
+ m_toolbar.push_back(Button(btnSearch));
+ m_toolbar.push_back(Button(btnFilter));
+ m_toolbar.push_back(Button(btnCalendar, Button::SPACED));
+ m_toolbar.push_back(Button(btnCopy));
+ m_toolbar.push_back(Button(btnDelete));
+ m_toolbar.push_back(Button(btnExport));
+ m_toolbar.push_back(Button(btnOptions, Button::RIGHT));
+
+ m_timeTree.OnSelChanged = Callback(this, &CHistoryDlg::onSelChanged_TimeTree);
+ m_bookmarks.OnItemChanged = Callback(this, &CHistoryDlg::onSelChanged_Bookmarks);
+
+ edtSearchText.OnChange = Callback(this, &CHistoryDlg::onChange_SearchText);
+
+ splitTime.OnChange = Callback(this, &CHistoryDlg::onChange_Splitter);
+
+ btnCopy.OnClick = Callback(this, &CHistoryDlg::onClick_Copy);
+ btnExport.OnClick = Callback(this, &CHistoryDlg::onClick_Export);
+ btnDelete.OnClick = Callback(this, &CHistoryDlg::onClick_Delete);
+ btnFilter.OnClick = Callback(this, &CHistoryDlg::onClick_Filter);
+ btnSearch.OnClick = Callback(this, &CHistoryDlg::onClick_Search);
+ btnOptions.OnClick = Callback(this, &CHistoryDlg::onClick_Options);
+ btnSendMsg.OnClick = Callback(this, &CHistoryDlg::onClick_Message);
+ btnCalendar.OnClick = Callback(this, &CHistoryDlg::onClick_Calendar);
+ btnFindPrev.OnClick = Callback(this, &CHistoryDlg::onClick_FindPrev);
+ btnUserInfo.OnClick = Callback(this, &CHistoryDlg::onClick_UserInfo);
+ btnUserMenu.OnClick = Callback(this, &CHistoryDlg::onClick_UserMenu);
+ btnTimeTree.OnClick = Callback(this, &CHistoryDlg::onClick_TimeTree);
+ btnBookmarks.OnClick = Callback(this, &CHistoryDlg::onClick_Bookmarks);
+
+ m_hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_POPUPS));
+ TranslateMenu(m_hMenu);
+
+ HMENU hMenu = GetSubMenu(m_hMenu, 0);
+ CheckMenuItem(hMenu, ID_FILTER_INCOMING, (showFlags & HIST_SHOW_IN) ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem(hMenu, ID_FILTER_OUTGOING, (showFlags & HIST_SHOW_OUT) ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem(hMenu, ID_FILTER_MESSAGES, (showFlags & HIST_SHOW_MSGS) ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem(hMenu, ID_FILTER_FILES, (showFlags & HIST_SHOW_FILES) ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem(hMenu, ID_FILTER_URLS, (showFlags & HIST_SHOW_URLS) ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem(hMenu, ID_FILTER_STATUS, (showFlags & HIST_SHOW_STATUS) ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem(hMenu, ID_FILTER_OTHER, (showFlags & HIST_SHOW_OTHER) ? MF_CHECKED : MF_UNCHECKED);
+ CheckMenuItem(hMenu, ID_FILTER_AUTO, (showFlags & HIST_AUTO_FILTER) ? MF_CHECKED : MF_UNCHECKED);
+ }
+
+ bool OnInitDialog() override
+ {
+ // get handles
+ m_hwndBtnCloseSearch = GetDlgItem(m_hwnd, IDC_SEARCHICON);
+ m_hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, m_hwnd, NULL, g_plugin.getInst(), NULL);
+ SendMessage(m_hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0);
+
+ // bookmarks
+ RECT rc;
+ GetClientRect(m_bookmarks.GetHwnd(), &rc);
+ m_bookmarks.AddColumn(0, TranslateT("Bookmarks"), rc.right - rc.left);
+
+ // filterbar
+ btnFilter.MakePush();
+
+ btnTimeTree.MakePush();
+ if (m_dwOptions & WND_OPT_TIMETREE)
+ btnTimeTree.Push(true);
+
+ btnSearch.MakePush();
+ if (m_dwOptions & WND_OPT_SEARCHBAR)
+ btnSearch.Push(true);
+
+ btnBookmarks.MakePush();
+ if (m_dwOptions & WND_OPT_BOOKMARKS)
+ btnBookmarks.Push(true);
+
+ // filters
+ m_hwndChkDateFrom = GetDlgItem(m_hwnd, IDC_CHK_DATE_FROM);
+ m_hwndChkDateTo = GetDlgItem(m_hwnd, IDC_CHK_DATE_TO);
+ m_hwndDateFrom = GetDlgItem(m_hwnd, IDC_DATE_FROM);
+ m_hwndDateTo = GetDlgItem(m_hwnd, IDC_DATE_TO);
+
+ ibMessages.hwndIco = GetDlgItem(m_hwnd, IDC_ICO_MESSAGES);
+ ibMessages.hwndTxt = GetDlgItem(m_hwnd, IDC_TXT_MESSAGES);
+ ibMessages.hwndIcoIn = GetDlgItem(m_hwnd, IDC_ICO_MESSAGES_IN);
+ SendMessage(ibMessages.hwndIcoIn, BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(ibMessages.hwndIcoIn, BUTTONSETASPUSHBTN, 0, 0);
+ SendMessage(ibMessages.hwndIcoIn, BM_SETCHECK, BST_CHECKED, 0);
+
+ ibMessages.hwndTxtIn = GetDlgItem(m_hwnd, IDC_TXT_MESSAGES_IN);
+ ibMessages.hwndIcoOut = GetDlgItem(m_hwnd, IDC_ICO_MESSAGES_OUT);
+ SendMessage(ibMessages.hwndIcoOut, BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(ibMessages.hwndIcoOut, BUTTONSETASPUSHBTN, 0, 0);
+ SendMessage(ibMessages.hwndIcoOut, BM_SETCHECK, BST_CHECKED, 0);
+ ibMessages.hwndTxtOut = GetDlgItem(m_hwnd, IDC_TXT_MESSAGES_OUT);
+
+ ibFiles.hwndIco = GetDlgItem(m_hwnd, IDC_ICO_FILES);
+ ibFiles.hwndTxt = GetDlgItem(m_hwnd, IDC_TXT_FILES);
+ ibFiles.hwndIcoIn = GetDlgItem(m_hwnd, IDC_ICO_FILES_IN);
+ SendMessage(ibFiles.hwndIcoIn, BUTTONSETASFLATBTN, 0, 0);
+
+ SendMessage(ibFiles.hwndIcoIn, BUTTONSETASPUSHBTN, 0, 0);
+ SendMessage(ibFiles.hwndIcoIn, BM_SETCHECK, BST_CHECKED, 0);
+
+ ibFiles.hwndTxtIn = GetDlgItem(m_hwnd, IDC_TXT_FILES_IN);
+ ibFiles.hwndIcoOut = GetDlgItem(m_hwnd, IDC_ICO_FILES_OUT);
+ SendMessage(ibFiles.hwndIcoOut, BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(ibFiles.hwndIcoOut, BUTTONSETASPUSHBTN, 0, 0);
+ SendMessage(ibFiles.hwndIcoOut, BM_SETCHECK, BST_CHECKED, 0);
+ ibFiles.hwndTxtOut = GetDlgItem(m_hwnd, IDC_TXT_FILES_OUT);
+
+ ibUrls.hwndIco = GetDlgItem(m_hwnd, IDC_ICO_URLS);
+ ibUrls.hwndTxt = GetDlgItem(m_hwnd, IDC_TXT_URLS);
+ ibUrls.hwndIcoIn = GetDlgItem(m_hwnd, IDC_ICO_URLS_IN);
+ SendMessage(ibUrls.hwndIcoIn, BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(ibUrls.hwndIcoIn, BUTTONSETASPUSHBTN, 0, 0);
+ SendMessage(ibUrls.hwndIcoIn, BM_SETCHECK, BST_CHECKED, 0);
+
+ ibUrls.hwndTxtIn = GetDlgItem(m_hwnd, IDC_TXT_URLS_IN);
+ ibUrls.hwndIcoOut = GetDlgItem(m_hwnd, IDC_ICO_URLS_OUT);
+ SendMessage(ibUrls.hwndIcoOut, BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(ibUrls.hwndIcoOut, BUTTONSETASPUSHBTN, 0, 0);
+ SendMessage(ibUrls.hwndIcoOut, BM_SETCHECK, BST_CHECKED, 0);
+ ibUrls.hwndTxtOut = GetDlgItem(m_hwnd, IDC_TXT_URLS_OUT);
+
+ ibTotal.hwndIco = GetDlgItem(m_hwnd, IDC_ICO_TOTAL);
+ ibTotal.hwndTxt = GetDlgItem(m_hwnd, IDC_TXT_TOTAL);
+ ibTotal.hwndIcoIn = GetDlgItem(m_hwnd, IDC_ICO_TOTAL_IN);
+ SendMessage(ibTotal.hwndIcoIn, BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(ibTotal.hwndIcoIn, BUTTONSETASPUSHBTN, 0, 0);
+ SendMessage(ibTotal.hwndIcoIn, BM_SETCHECK, BST_CHECKED, 0);
+
+ ibTotal.hwndTxtIn = GetDlgItem(m_hwnd, IDC_TXT_TOTAL_IN);
+ ibTotal.hwndIcoOut = GetDlgItem(m_hwnd, IDC_ICO_TOTAL_OUT);
+ SendMessage(ibTotal.hwndIcoOut, BUTTONSETASFLATBTN, 0, 0);
+ SendMessage(ibTotal.hwndIcoOut, BUTTONSETASPUSHBTN, 0, 0);
+ SendMessage(ibTotal.hwndIcoOut, BM_SETCHECK, BST_CHECKED, 0);
+ ibTotal.hwndTxtOut = GetDlgItem(m_hwnd, IDC_TXT_TOTAL_OUT);
+
+ // Ask for layout
+ PostMessage(m_hwnd, WM_SIZE, 0, 0);
+
+ WindowList_Add(g_hNewstoryWindows, m_hwnd, m_hContact);
+
+ ShowHideControls();
+ UpdateTitle();
+
+ m_histCtrl = (NewstoryListData *)GetWindowLongPtr(m_histWindow.GetHwnd(), 0);
+
+ if (m_hContact == 0 || m_hContact == INVALID_CONTACT_ID) {
+ btnSendMsg.Hide();
+ btnUserInfo.Hide();
+ btnUserMenu.Hide();
+ }
+
+ if (m_hContact != INVALID_CONTACT_ID) {
+ Utils_RestoreWindowPosition(m_hwnd, m_hContact, MODULENAME, "wnd_");
+
+ m_histCtrl->AddEvent(m_hContact, 0, -1);
+
+ BuildTimeTree();
+ SetFocus(m_histWindow.GetHwnd());
+ }
+ else Utils_RestoreWindowPosition(m_hwnd, 0, MODULENAME, "glb_");
+
+ BuildBookmarksList();
+
+ m_histCtrl->SetContact(m_hContact);
+ m_histCtrl->ScrollBottom();
+
+ Window_SetIcon_IcoLib(m_hwnd, g_plugin.getIconHandle(IDI_NEWSTORY));
+
+ SendMessage(GetDlgItem(m_hwnd, IDC_SEARCHICON), STM_SETICON, (WPARAM)g_plugin.getIcon(IDI_SEARCH), 0);
+
+ SendMessage(ibMessages.hwndIco, STM_SETICON, (LPARAM)g_plugin.getIcon(IDI_SENDMSG), 0);
+ SendMessage(ibMessages.hwndIcoIn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGIN));
+ SendMessage(ibMessages.hwndIcoOut, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGOUT));
+
+ SendMessage(ibFiles.hwndIco, STM_SETICON, (LPARAM)Skin_LoadIcon(SKINICON_EVENT_FILE), 0);
+ SendMessage(ibFiles.hwndIcoIn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGIN));
+ SendMessage(ibFiles.hwndIcoOut, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGOUT));
+
+ SendMessage(ibUrls.hwndIco, STM_SETICON, (LPARAM)Skin_LoadIcon(SKINICON_EVENT_URL), 0);
+ SendMessage(ibUrls.hwndIcoIn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGIN));
+ SendMessage(ibUrls.hwndIcoOut, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGOUT));
+
+ SendMessage(ibTotal.hwndIco, STM_SETICON, (LPARAM)g_plugin.getIcon(IDI_UNKNOWN), 0);
+ SendMessage(ibTotal.hwndIcoIn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGIN));
+ SendMessage(ibTotal.hwndIcoOut, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_plugin.getIcon(IDI_MSGOUT));
+ return true;
+ }
+
+ bool OnApply() override
+ {
+ if (m_bSearchChanged) {
+ m_bSearchChanged = false;
+ if (m_hContact == INVALID_CONTACT_ID)
+ DoGlobalSearch();
+ }
+
+ int iOldCaret = m_histCtrl->caret;
+ int res = m_histCtrl->FindNext(ptrW(edtSearchText.GetText()));
+ if (res == -1)
+ SetWindowTextW(m_hwndStatus, TranslateT("No more occuurences found"));
+ else if (res < iOldCaret)
+ SetWindowTextW(m_hwndStatus, TranslateT("Passed the end of history"));
+ else
+ SetWindowTextW(m_hwndStatus, L"");
+
+ return false;
+ }
+
+ void OnResize() override
+ {
+ RECT rc;
+ GetClientRect(m_hwnd, &rc);
+ int y; // tmp vars
+ int w = rc.right - rc.left;
+ int h = rc.bottom - rc.top;
+
+ HDWP hDwp = BeginDeferWindowPos(43 + (int)m_toolbar.size());
+
+ // toolbar
+ int hToolBar = TBTN_SIZE + WND_SPACING;
+
+ int x = WND_SPACING;
+ for (auto &it : m_toolbar) {
+ if (it.options & Button::RIGHT)
+ continue;
+
+ hDwp = DeferWindowPos(hDwp, it.hwnd.GetHwnd(), 0, x, WND_SPACING, TBTN_SIZE, TBTN_SIZE, SWP_NOZORDER);
+ x += TBTN_SIZE;
+ if (it.options & Button::SPACED)
+ x += 10;
+ }
+
+ x = w - WND_SPACING - TBTN_SIZE;
+ for (auto &it : m_toolbar) {
+ if (it.options & Button::RIGHT) {
+ hDwp = DeferWindowPos(hDwp, it.hwnd.GetHwnd(), 0, x, WND_SPACING, TBTN_SIZE, TBTN_SIZE, SWP_NOZORDER);
+ x -= TBTN_SIZE;
+ }
+ }
+
+ // infobar
+ // hDwp = DeferWindowPos(hDwp, hwndIcoProtocol, 0,
+ // w-100+WND_SPACING, WND_SPACING,
+ // 16, 16,
+ // SWP_NOZORDER);
+ // hDwp = DeferWindowPos(hDwp, hwndTxtNickname, 0,
+ // w-100+WND_SPACING*2+16, WND_SPACING,
+ // 100, 16,
+ // SWP_NOZORDER);
+ // hDwp = DeferWindowPos(hDwp, hwndTxtUID, 0,
+ // w-100+WND_SPACING*2+16, WND_SPACING*2+16,
+ // 100, 16,
+ // SWP_NOZORDER);
+
+ // filter bar
+ int hFilterBar = 0;
+ if (m_dwOptions & WND_OPT_FILTERBAR) {
+ hFilterBar = WND_SPACING + (16 + WND_SPACING) * 3;
+ LayoutFilterBar(hDwp, WND_SPACING + (WND_SPACING + 75) * 0, WND_SPACING * 2 + hToolBar, 75, &ibMessages);
+ LayoutFilterBar(hDwp, WND_SPACING + (WND_SPACING + 75) * 1, WND_SPACING * 2 + hToolBar, 75, &ibFiles);
+ LayoutFilterBar(hDwp, WND_SPACING + (WND_SPACING + 75) * 2, WND_SPACING * 2 + hToolBar, 75, &ibUrls);
+ LayoutFilterBar(hDwp, WND_SPACING + (WND_SPACING + 75) * 3, WND_SPACING * 2 + hToolBar, 75, &ibTotal);
+
+ GetWindowRect(m_hwndChkDateFrom, &rc);
+ x = rc.right - rc.left;
+ GetWindowRect(m_hwndDateFrom, &rc);
+ y = hToolBar + WND_SPACING + (WND_SPACING + (16 + WND_SPACING) * 3 - (rc.bottom - rc.top) * 2 - WND_SPACING) / 2;
+ hDwp = DeferWindowPos(hDwp, m_hwndChkDateFrom, 0,
+ w - x - (rc.right - rc.left) - WND_SPACING * 2, y,
+ x, rc.bottom - rc.top,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+ hDwp = DeferWindowPos(hDwp, m_hwndDateFrom, 0,
+ w - (rc.right - rc.left) - WND_SPACING, y,
+ rc.right - rc.left, rc.bottom - rc.top,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+
+ hDwp = DeferWindowPos(hDwp, m_hwndChkDateTo, 0,
+ w - x - (rc.right - rc.left) - WND_SPACING * 2, y + (rc.bottom - rc.top) + WND_SPACING,
+ x, rc.bottom - rc.top,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+ hDwp = DeferWindowPos(hDwp, m_hwndDateTo, 0,
+ w - (rc.right - rc.left) - WND_SPACING, y + (rc.bottom - rc.top) + WND_SPACING,
+ rc.right - rc.left, rc.bottom - rc.top,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+
+ hDwp = DeferWindowPos(hDwp, GetDlgItem(m_hwnd, IDC_IB_SEPARATOR), 0,
+ WND_SPACING, hToolBar + WND_SPACING,
+ w - WND_SPACING * 2, 2,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+ }
+
+ // general
+ GetWindowRect(m_hwndStatus, &rc);
+ int hStatus = rc.bottom - rc.top;
+ hDwp = DeferWindowPos(hDwp, m_hwndStatus, 0,
+ 0, h - hStatus,
+ w, hStatus,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+
+ // search bar
+ int hSearch = 0;
+ if (m_dwOptions & WND_OPT_SEARCHBAR) {
+ GetWindowRect(edtSearchText.GetHwnd(), &rc);
+ hSearch = rc.bottom - rc.top;
+ hDwp = DeferWindowPos(hDwp, m_hwndBtnCloseSearch, 0,
+ WND_SPACING, h - hSearch - hStatus - WND_SPACING,
+ TBTN_SIZE, hSearch, SWP_NOZORDER | SWP_NOACTIVATE);
+ hDwp = DeferWindowPos(hDwp, edtSearchText.GetHwnd(), 0,
+ TBTN_SIZE + WND_SPACING * 2, h - hSearch - hStatus - WND_SPACING,
+ w - WND_SPACING * 4 - TBTN_SIZE * 3, hSearch,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+ hDwp = DeferWindowPos(hDwp, btnFindPrev.GetHwnd(), 0,
+ w - WND_SPACING - TBTN_SIZE * 2, h - hSearch - hStatus - WND_SPACING,
+ TBTN_SIZE, hSearch,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+ hDwp = DeferWindowPos(hDwp, btnFindNext.GetHwnd(), 0,
+ w - WND_SPACING - TBTN_SIZE * 1, h - hSearch - hStatus - WND_SPACING,
+ TBTN_SIZE, hSearch,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+ hSearch += WND_SPACING;
+ }
+
+ int iClientTop = WND_SPACING + hToolBar + hFilterBar;
+ int iClientBottom = h - WND_SPACING - hSearch - hStatus - iClientTop;
+
+ // time tree bar
+ int hTimeTree = 0;
+ bool bShowTime = (m_dwOptions & WND_OPT_TIMETREE) != 0;
+ bool bShowBookmarks = (m_dwOptions & WND_OPT_BOOKMARKS) != 0;
+
+ if (bShowTime || bShowBookmarks) {
+ hTimeTree = m_iSplitter;
+ hDwp = DeferWindowPos(hDwp, splitTime.GetHwnd(), 0, hTimeTree, iClientTop, WND_SPACING, iClientBottom, SWP_NOZORDER | SWP_NOACTIVATE);
+
+ if (bShowTime && bShowBookmarks) {
+ int hMiddle = iClientBottom / 2;
+ hDwp = DeferWindowPos(hDwp, m_timeTree.GetHwnd(), 0, WND_SPACING, iClientTop, hTimeTree - WND_SPACING, hMiddle, SWP_NOZORDER | SWP_NOACTIVATE);
+ hDwp = DeferWindowPos(hDwp, m_bookmarks.GetHwnd(), 0, WND_SPACING, iClientTop + hMiddle, hTimeTree - WND_SPACING, hMiddle, SWP_NOZORDER | SWP_NOACTIVATE);
+ }
+ else if (bShowTime)
+ hDwp = DeferWindowPos(hDwp, m_timeTree.GetHwnd(), 0, WND_SPACING, iClientTop, hTimeTree - WND_SPACING, iClientBottom, SWP_NOZORDER | SWP_NOACTIVATE);
+ else
+ hDwp = DeferWindowPos(hDwp, m_bookmarks.GetHwnd(), 0, WND_SPACING, iClientTop, hTimeTree - WND_SPACING, iClientBottom, SWP_NOZORDER | SWP_NOACTIVATE);
+ }
+
+ hDwp = DeferWindowPos(hDwp, m_histWindow.GetHwnd(), 0,
+ WND_SPACING + hTimeTree, iClientTop,
+ w - WND_SPACING * 2 - hTimeTree, iClientBottom,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+
+ EndDeferWindowPos(hDwp);
+ }
+
+ void OnDestroy() override
+ {
+ g_splitter = m_iSplitter;
+
+ if (m_hContact != INVALID_CONTACT_ID)
+ Utils_SaveWindowPosition(m_hwnd, m_hContact, MODULENAME, "wnd_");
+ else
+ Utils_SaveWindowPosition(m_hwnd, 0, MODULENAME, "glb_");
+
+ g_plugin.setWord(0, "showFlags", showFlags);
+ g_plugin.setDword(0, "dwOptions", m_dwOptions);
+
+ Window_FreeIcon_IcoLib(m_hwnd);
+ WindowList_Remove(g_hNewstoryWindows, m_hwnd);
+
+ if (m_hwndStatus != nullptr) {
+ DestroyWindow(m_hwndStatus);
+ m_hwndStatus = nullptr;
+ }
+ }
+
+ void onClick_Calendar(CCtrlButton *pButton)
+ {
+ RECT rc;
+ GetWindowRect(pButton->GetHwnd(), &rc);
+
+ CalendarTool_Show(m_hwnd, rc.left, rc.bottom);
+ }
+
+ void onClick_Copy(CCtrlButton *)
+ {
+ m_histCtrl->Copy();
+ }
+
+ void onClick_Delete(CCtrlButton *)
+ {
+ if (!CallService(MS_HISTORY_EMPTY, m_hContact, 0)) {
+ m_histCtrl->Clear();
+
+ UpdateTitle();
+ BuildTimeTree();
+ }
+ }
+
+ void onClick_TimeTree(CCtrlButton *)
+ {
+ if (m_dwOptions & WND_OPT_TIMETREE)
+ m_dwOptions &= ~WND_OPT_TIMETREE;
+ else
+ m_dwOptions |= WND_OPT_TIMETREE;
+
+ OnResize();
+ ShowHideControls();
+ BuildTimeTree();
+ }
+
+ void onClick_Bookmarks(CCtrlButton *)
+ {
+ if (m_dwOptions & WND_OPT_BOOKMARKS)
+ m_dwOptions &= ~WND_OPT_BOOKMARKS;
+ else
+ m_dwOptions |= WND_OPT_BOOKMARKS;
+
+ OnResize();
+ ShowHideControls();
+ BuildBookmarksList();
+ }
+
+ void onClick_Export(CCtrlButton *)
+ {
+ auto *pDriver = GetDatabasePlugin("JSON");
+ if (pDriver == nullptr) {
+ CMStringW wszText(TranslateT("The required plugin 'Import' isn't loaded to perform this operation."));
+ if (ServiceExists(MS_PU_SHOWLIST)) {
+ wszText.AppendFormat(L" %s", TranslateT("Do you want to install it using Plugin Updater?"));
+ if (IDYES == MessageBoxW(m_hwnd, wszText, TranslateT("Missing plugin"), MB_YESNO | MB_ICONQUESTION))
+ CallService(MS_PU_SHOWLIST);
+ }
+ else MessageBoxW(m_hwnd, wszText, TranslateT("Missing plugin"), MB_OK | MB_ICONERROR);
+ return;
+ }
+
+ wchar_t FileName[MAX_PATH];
+ VARSW tszMirDir(L"%miranda_userdata%\\NewStoryExport");
+
+ if (db_mc_isMeta(m_hContact)) {
+ CMStringW SubContactsList, MessageText;
+ bool FirstTime = true;
+ int subcount = db_mc_getSubCount(m_hContact);
+ for (int i = 0; i < subcount; i++) {
+ MCONTACT hSubContact = db_mc_getSub(m_hContact, i);
+ char *subproto = Proto_GetBaseAccountName(hSubContact);
+ ptrW subid(Contact::GetInfo(CNF_UNIQUEID, hSubContact, subproto));
+ if (FirstTime)
+ SubContactsList.Append(subid);
+ else
+ SubContactsList.AppendFormat(L"\r\n%s", subid.get());
+ FirstTime = false;
+ }
+ MessageText.AppendFormat(TranslateT("It is metacontact. For export use one of this subcontacts:\r\n%s"), SubContactsList.c_str());
+ MessageBox(m_hwnd, MessageText, TranslateT("Export warning"), MB_OK | MB_ICONWARNING);
+ return;
+ }
+
+ OPENFILENAME ofn = { 0 };
+ ofn.lStructSize = sizeof(ofn);
+ CMStringW tszFilter, tszTitle, tszFileName;
+ tszFilter.AppendFormat(L"%s (*.json)%c*.json%c%c", TranslateT("JSON files"), 0, 0, 0);
+ tszTitle.AppendFormat(TranslateT("Export history"));
+ ofn.lpstrFilter = tszFilter;
+ ofn.hwndOwner = nullptr;
+ ofn.lpstrTitle = tszTitle;
+ ofn.lpstrFile = FileName;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.nMaxFileTitle = MAX_PATH;
+ ofn.Flags = OFN_HIDEREADONLY | OFN_SHAREAWARE | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
+ ofn.lpstrInitialDir = tszMirDir;
+ *FileName = '\0';
+ ofn.lpstrDefExt = L"";
+ if (!GetSaveFileName(&ofn))
+ return;
+
+ // create file
+ CreatePathToFileW(FileName);
+ if (PathFileExistsW(FileName))
+ DeleteFileW(FileName);
+
+ auto *pDB = pDriver->Export(FileName);
+ pDB->BeginExport();
+ pDB->ExportContact(m_hContact);
+
+ // export events
+ int iDone = 0;
+ bAppendOnly = false;
+ auto &arItems = m_histCtrl->items;
+ int iCount = arItems.getCount();
+ for (int i = 0; i < iCount; i++) {
+ auto *pItem = arItems.get(i);
+ if (pItem->m_bSelected) {
+ DB::EventInfo dbei(pItem->hEvent);
+ if (dbei)
+ pDB->ExportEvent(dbei);
+ iDone++;
+ }
+ }
+
+ // no items selected? export whole history
+ if (iDone == 0)
+ for (int i = 0; i < iCount; i++) {
+ auto *pItem = arItems.get(i);
+ DB::EventInfo dbei(pItem->hEvent);
+ if (dbei)
+ pDB->ExportEvent(dbei);
+ }
+
+ // Close the file
+ pDB->EndExport();
+ MessageBox(m_hwnd, TranslateT("Complete"), TranslateT("History export"), MB_OK | MB_ICONINFORMATION);
+ }
+
+ void onClick_Filter(CCtrlButton *)
+ {
+ if (m_dwOptions & WND_OPT_FILTERBAR)
+ m_dwOptions &= ~WND_OPT_FILTERBAR;
+ else
+ m_dwOptions |= WND_OPT_FILTERBAR;
+
+ ShowHideControls();
+ OnResize();
+ }
+
+ void onClick_FindPrev(CCtrlButton *)
+ {
+ int iOldCaret = m_histCtrl->caret;
+ int res = m_histCtrl->FindPrev(ptrW(edtSearchText.GetText()));
+ if (res == -1)
+ SetWindowTextW(m_hwndStatus, TranslateT("No more occuurences found"));
+ else if (res > iOldCaret)
+ SetWindowTextW(m_hwndStatus, TranslateT("Passed the beginning of history"));
+ else
+ SetWindowTextW(m_hwndStatus, L"");
+ }
+
+ void onClick_Message(CCtrlButton *)
+ {
+ CallService(MS_MSG_SENDMESSAGE, m_hContact, 0);
+ }
+
+ void onClick_Options(CCtrlButton *pButton)
+ {
+ RECT rc;
+ GetWindowRect(pButton->GetHwnd(), &rc);
+
+ switch (TrackPopupMenu(GetSubMenu(m_hMenu, 1), TPM_RETURNCMD, rc.left, rc.bottom, 0, m_hwnd, NULL)) {
+ case ID_LOGOPTIONS_OPTIONS:
+ g_plugin.openOptions(L"History", L"NewStory", L"Advanced");
+ break;
+
+ case ID_LOGOPTIONS_TEMPLATES:
+ g_plugin.openOptions(L"History", L"NewStory", L"Templates");
+ break;
+ }
+ PostMessage(m_hwnd, WM_SIZE, 0, 0);
+ }
+
+ void onClick_Search(CCtrlButton *)
+ {
+ if (m_dwOptions & WND_OPT_SEARCHBAR)
+ m_dwOptions &= ~WND_OPT_SEARCHBAR;
+ else
+ m_dwOptions |= WND_OPT_SEARCHBAR;
+
+ ShowHideControls();
+ OnResize();
+ }
+
+ void onClick_UserInfo(CCtrlButton *)
+ {
+ CallService(MS_USERINFO_SHOWDIALOG, m_hContact, 0);
+ }
+
+ void onClick_UserMenu(CCtrlButton *pButton)
+ {
+ RECT rc;
+ GetWindowRect(pButton->GetHwnd(), &rc);
+
+ HMENU hMenu = Menu_BuildContactMenu(m_hContact);
+ TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, m_hwnd, NULL);
+ DestroyMenu(hMenu);
+ }
+
+ void onChange_SearchText(CCtrlEdit *)
+ {
+ m_bSearchChanged = true;
+
+ if (m_bInitialized)
+ if (showFlags & HIST_AUTO_FILTER)
+ PostMessage(m_hwnd, UM_REBUILDLIST, 0, 0);
+ }
+
+ void onChange_Splitter(CSplitter *)
+ {
+ m_iSplitter = splitTime.GetPos();
+ }
+
+ INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override
+ {
+ if ((msg >= NSM_FIRST) && (msg < NSM_LAST)) {
+ LPARAM result = m_histWindow.SendMsg(msg, wParam, lParam);
+ SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, result);
+ return result;
+ }
+
+ MSG message = { m_hwnd, msg, wParam, lParam };
+ switch (Hotkey_Check(&message, MODULENAME)) {
+ case HOTKEY_SEEK_FORWARD:
+ btnFindNext.Click();
+ break;
+ case HOTKEY_SEEK_BACK:
+ btnFindPrev.Click();
+ break;
+ case HOTKEY_SEARCH:
+ btnSearch.Click();
+ break;
+ }
+
+ switch (msg) {
+ case WM_CHARTOITEM:
+ if (!((GetKeyState(VK_CONTROL) & 0x80) || (GetKeyState(VK_MENU) & 0x80))) {
+ wchar_t s[] = { LOWORD(wParam), 0 };
+ SetWindowText(GetDlgItem(m_hwnd, IDC_SEARCHTEXT), s);
+ SendMessage(GetDlgItem(m_hwnd, IDC_SEARCHTEXT), EM_SETSEL, 1, 1);
+ SetFocus(GetDlgItem(m_hwnd, IDC_SEARCHTEXT));
+ }
+ return -1;
+
+ case WM_COMMAND:
+ if (Clist_MenuProcessCommand(LOWORD(wParam), MPCF_CONTACTMENU, m_hContact))
+ return TRUE;
+ break;
+
+ /*
+ GetWindowRect(GetDlgItem(m_hwnd, LOWORD(wParam)), &rc);
+// uint32_t itemID = 0;
+ bool doFilter = true;
+ switch (TrackPopupMenu(GetSubMenu(hMenu, 1), TPM_RETURNCMD, rc.left, rc.bottom, 0, m_hwnd, NULL))
+ {
+ case ID_FILTER_INCOMING:
+ {
+ showFlags = toggleBit(showFlags, HIST_SHOW_IN);
+ CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_INCOMING,
+ showFlags&HIST_SHOW_IN ? MF_CHECKED : MF_UNCHECKED);
+ break;
+ }
+ case ID_FILTER_OUTGOING:
+ {
+ showFlags = toggleBit(showFlags, HIST_SHOW_OUT);
+ CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_OUTGOING,
+ showFlags&HIST_SHOW_OUT ? MF_CHECKED : MF_UNCHECKED);
+ break;
+ }
+ case ID_FILTER_MESSAGES:
+ {
+ showFlags = toggleBit(showFlags, HIST_SHOW_MSGS);
+ CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_MESSAGES,
+ showFlags&HIST_SHOW_MSGS ? MF_CHECKED : MF_UNCHECKED);
+ break;
+ }
+ case ID_FILTER_FILES:
+ {
+ showFlags = toggleBit(showFlags, HIST_SHOW_FILES);
+ CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_FILES,
+ showFlags&HIST_SHOW_FILES ? MF_CHECKED : MF_UNCHECKED);
+ break;
+ }
+ case ID_FILTER_URLS:
+ {
+ showFlags = toggleBit(showFlags, HIST_SHOW_URLS);
+ CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_URLS,
+ showFlags&HIST_SHOW_URLS ? MF_CHECKED : MF_UNCHECKED);
+ break;
+ }
+ case ID_FILTER_STATUS:
+ {
+ showFlags = toggleBit(showFlags, HIST_SHOW_STATUS);
+ CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_STATUS,
+ showFlags&HIST_SHOW_STATUS ? MF_CHECKED : MF_UNCHECKED);
+ break;
+ }
+ case ID_FILTER_OTHER:
+ {
+ showFlags = toggleBit(showFlags, HIST_SHOW_OTHER);
+ CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_OTHER,
+ showFlags&HIST_SHOW_OTHER ? MF_CHECKED : MF_UNCHECKED);
+ break;
+ }
+ case ID_FILTER_AUTO:
+ {
+ showFlags = toggleBit(showFlags, HIST_AUTO_FILTER);
+ CheckMenuItem(GetSubMenu(hMenu, 1), ID_FILTER_AUTO,
+ showFlags&HIST_AUTO_FILTER ? MF_CHECKED : MF_UNCHECKED);
+ break;
+ }
+ default:
+ {
+ doFilter = false;
+ break;
+ }
+ }
+ if (doFilter)
+ PostMessage(m_hwnd, UM_REBUILDLIST, 0, 0);
+ break;*/
+
+ case UM_BOOKMARKS:
+ BuildBookmarksList();
+ break;
+
+ case WM_USER + 0x600:
+ if (wParam)
+ m_histWindow.SendMsg(NSM_SEEKTIME, wParam, 0);
+ }
+
+ return CDlgBase::DlgProc(msg, wParam, lParam);
+ }
+
+ void onSelChanged_Bookmarks(CCtrlListView::TEventInfo *ev)
+ {
+ int idx = m_bookmarks.GetItemData(ev->nmlv->iItem);
+
+ if (m_hContact == INVALID_CONTACT_ID) {
+ m_histCtrl->Clear();
+
+ if (idx == INVALID_CONTACT_ID) {
+ for (auto &cc : m_events)
+ for (auto &hEvent : cc.second)
+ m_histCtrl->AddEvent(cc.first, hEvent, 1);
+ }
+ else for (auto &hEvent : m_events[idx])
+ m_histCtrl->AddEvent(idx, hEvent, 1);
+ }
+ else m_histCtrl->SetPos(idx);
+ }
+
+ void onSelChanged_TimeTree(CCtrlTreeView::TEventInfo *)
+ {
+ wchar_t *val1, *val2, *val3;
+ int yearsel = 0, monthsel = 0, daysel = 1;
+ bool monthfound = false;
+ if (disableTimeTreeChange)
+ disableTimeTreeChange = false;
+ else {
+ HTREEITEM hti1 = m_timeTree.GetSelection();
+ TVITEMEX tvi = { 0 };
+ tvi.hItem = hti1;
+ tvi.mask = TVIF_HANDLE | TVIF_TEXT | TVIF_PARAM;
+ tvi.cchTextMax = MAX_PATH;
+ tvi.lParam = 0;
+ tvi.pszText = (wchar_t *)_alloca(MAX_PATH * sizeof(wchar_t));
+
+ m_timeTree.GetItem(&tvi);
+ val1 = tvi.pszText;
+ if (tvi.lParam) {
+ monthsel = tvi.lParam;
+ monthfound = true;
+ }
+ HTREEITEM hti2 = m_timeTree.GetParent(hti1);
+ if ((!monthfound) && (!hti2))
+ yearsel = _wtoi(val1);
+ if ((!monthfound) && (hti2))
+ daysel = _wtoi(val1);
+ if (hti2) {
+ tvi.hItem = hti2;
+ tvi.lParam = 0;
+ m_timeTree.GetItem(&tvi);
+ val2 = tvi.pszText;
+ if (tvi.lParam) {
+ monthsel = tvi.lParam;
+ monthfound = true;
+ }
+ else
+ yearsel = _wtoi(val2);
+ HTREEITEM hti3 = m_timeTree.GetParent(hti2);
+ if (hti3) {
+ tvi.hItem = hti3;
+ tvi.lParam = 0;
+ m_timeTree.GetItem(&tvi);
+ val3 = tvi.pszText;
+ yearsel = _wtoi(val3);
+ }
+ }
+ struct tm tm_sel;
+ tm_sel.tm_hour = tm_sel.tm_min = tm_sel.tm_sec = 0;
+ tm_sel.tm_isdst = 1;
+ tm_sel.tm_mday = daysel;
+ if (monthsel)
+ tm_sel.tm_mon = monthsel - 1;
+ else
+ tm_sel.tm_mon = 0;
+ tm_sel.tm_year = yearsel - 1900;
+ PostMessage(m_hwnd, WM_USER + 0x600, mktime(&tm_sel), 0);
+ }
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Services
+
+INT_PTR svcShowNewstory(WPARAM hContact, LPARAM)
+{
+ HWND hwnd = (HWND)WindowList_Find(g_hNewstoryWindows, hContact);
+ if (!hwnd) {
+ auto *pDlg = new CHistoryDlg(hContact);
+ pDlg->Show();
+ hwnd = pDlg->GetHwnd();
+ }
+
+ SetForegroundWindow(hwnd);
+ SetFocus(hwnd);
+ return 0;
+}
+
+INT_PTR svcGlobalSearch(WPARAM, LPARAM)
+{
+ return svcShowNewstory(INVALID_CONTACT_ID, 0);
+}