/* Copyright (C) 2012-22 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 . */ #include "stdafx.h" class COptionsDlg : public CDlgBase { OBJLIST m_columns; void AddColumn(int idx, ColumnItem *pCol) { LVITEM lvi = {}; lvi.mask = LVIF_PARAM; lvi.iItem = idx; lvi.lParam = LPARAM(pCol); m_list.InsertItem(&lvi); } void CheckDirection(int iItem) { btnUp.Enable(iItem > 0); btnDown.Enable(iItem < m_list.GetItemCount()-1); } void ClearScreen() { // setting ShowWindow(GetDlgItem(m_hwnd, IDC_S_DATATYPE), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_C_DATATYPE), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_S_MODULE), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_E_MODULE), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_S_SETTING), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_E_SETTING), SW_HIDE); // contact info ShowWindow(GetDlgItem(m_hwnd, IDC_S_CNFTYPE), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_C_CNFTYPE), SW_HIDE); // others ShowWindow(GetDlgItem(m_hwnd, IDC_C_OTHER), SW_HIDE); } void DisplayCurInfo(const ColumnItem *pCol) { ClearScreen(); SetupScreen(pCol->setting_type); editTitle.SetText(pCol->title); cmbVarType.SelectData(pCol->setting_type); switch (pCol->setting_type) { case QST_SETTING: cmbDataType.SelectData(pCol->datatype); editModule.SetTextA(pCol->module); editSetting.SetTextA(pCol->setting); break; case QST_SCRIPT: SetDlgItemTextW(m_hwnd, IDC_E_SCRIPT, pCol->script); break; case QST_CONTACTINFO: cmbCnfType.SelectData(pCol->cnftype); break; case QST_OTHER: cmbOther.SelectData(pCol->other); break; } } void FillTableLine(int item, ColumnItem *pColumn) { m_list.SetItemText(item, 1, pColumn->title); switch (pColumn->setting_type) { case QST_SETTING: m_list.SetItemText(item, 2, _A2T(pColumn->module)); m_list.SetItemText(item, 3, _A2T(pColumn->setting)); break; case QST_SCRIPT: m_list.SetItemText(item, 2, TranslateT("Script")); break; case QST_SERVICE: m_list.SetItemText(item, 2, TranslateT("Service")); m_list.SetItemText(item, 3, _A2T(pColumn->svc.service)); break; case QST_CONTACTINFO: m_list.SetItemText(item, 2, TranslateT("Contact info")); m_list.SetItemText(item, 3, cnf2str(pColumn->cnftype)); break; case QST_OTHER: m_list.SetItemText(item, 2, TranslateT("Other")); if (pColumn->other == QSTO_METACONTACT) m_list.SetItemText(item, 3, TranslateT("Metacontact")); break; } } void InitScreen() { // setting cmbDataType.SetCurSel(0); editModule.SetText(L""); editSetting.SetText(L""); // contact info cmbCnfType.SetCurSel(0); // others cmbOther.SetCurSel(0); } void ResizeControl(int id, int width) { HWND hwnd = GetDlgItem(m_hwnd, id); RECT rc; ::GetWindowRect(hwnd, &rc); ::SetWindowPos(hwnd, 0, 0, 0, width, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW); } void SetupScreen(int type) { if (!IsWindowVisible(GetDlgItem(m_hwnd, IDC_E_TITLE))) return; // setting int cmd = (type == QST_SETTING) ? SW_SHOW : SW_HIDE; ShowWindow(GetDlgItem(m_hwnd, IDC_S_DATATYPE), cmd); ShowWindow(GetDlgItem(m_hwnd, IDC_C_DATATYPE), cmd); ShowWindow(GetDlgItem(m_hwnd, IDC_S_MODULE), cmd); editModule.Show(cmd == SW_SHOW); ShowWindow(GetDlgItem(m_hwnd, IDC_S_SETTING), cmd); editSetting.Show(cmd == SW_SHOW); // contact info cmd = (type == QST_CONTACTINFO) ? SW_SHOW : SW_HIDE; ShowWindow(GetDlgItem(m_hwnd, IDC_S_CNFTYPE), cmd); ShowWindow(GetDlgItem(m_hwnd, IDC_C_CNFTYPE), cmd); // script cmd = (type == QST_SCRIPT) ? SW_SHOW : SW_HIDE; ShowWindow(GetDlgItem(m_hwnd, IDC_E_SCRIPT), cmd); // others cmd = (type == QST_OTHER) ? SW_SHOW : SW_HIDE; ShowWindow(GetDlgItem(m_hwnd, IDC_C_OTHER), cmd); } void UpdateList() { m_list.DeleteAllItems(); int cnt = 0; for (auto &it : m_columns) { AddColumn(cnt, it); FillTableLine(cnt, it); m_list.SetCheckState(cnt, it->bEnabled); cnt++; } m_list.SetCurSel(0); } CCtrlEdit editTitle, editModule, editSetting; CCtrlCheck chkSortStatus, chkAutoClose, chkUseToolstyle, chkDrawGrid, chkSavePattern, chkClientIcons; CCtrlCombo cmbVarType, cmbDataType, cmbOther, cmbCnfType; CCtrlListView m_list; CCtrlButton btnSave, btnResize; CCtrlMButton btnNew, btnUp, btnDown, btnDelete, btnDefault, btnReload; public: COptionsDlg() : CDlgBase(g_plugin, IDD_OPTIONS), m_columns(1), m_list(this, IDC_LIST), btnSave(this, IDC_SETITEM), btnResize(this, IDC_B_RESIZE), btnUp(this, IDC_UP, g_plugin.getIcon(IDI_UP), LPGEN("Up")), btnNew(this, IDC_NEW, g_plugin.getIcon(IDI_NEW), LPGEN("New")), btnDown(this, IDC_DN, g_plugin.getIcon(IDI_DOWN), LPGEN("Down")), btnDelete(this, IDC_DELETE, g_plugin.getIcon(IDI_DELETE), LPGEN("Delete")), btnReload(this, IDC_RELOAD, g_plugin.getIcon(IDI_RELOAD), LPGEN("Reload")), btnDefault(this, IDC_DEFAULT, g_plugin.getIcon(IDI_DEFAULT), LPGEN("Default")), editTitle(this, IDC_E_TITLE), editModule(this, IDC_E_MODULE), editSetting(this, IDC_E_SETTING), cmbOther(this, IDC_C_OTHER), cmbCnfType(this, IDC_C_CNFTYPE), cmbVarType(this, IDC_C_VARTYPE), cmbDataType(this, IDC_C_DATATYPE), chkDrawGrid(this, IDC_CH_DRAWGRID), chkAutoClose(this, IDC_CH_AUTOCLOSE), chkSortStatus(this, IDC_CH_SORTSTATUS), chkSavePattern(this, IDC_CH_SAVEPATTERN), chkClientIcons(this, IDC_CH_CLIENTICONS), chkUseToolstyle(this, IDC_CH_USETOOLSTYLE) { m_list.OnItemChanged = Callback(this, &COptionsDlg::onItemChanged_List); btnUp.OnClick = Callback(this, &COptionsDlg::onClick_Up); btnNew.OnClick = Callback(this, &COptionsDlg::onClick_New); btnDown.OnClick = Callback(this, &COptionsDlg::onClick_Down); btnSave.OnClick = Callback(this, &COptionsDlg::onClick_Save); btnDelete.OnClick = Callback(this, &COptionsDlg::onClick_Delete); btnReload.OnClick = Callback(this, &COptionsDlg::onClick_Reload); btnResize.OnClick = Callback(this, &COptionsDlg::onClick_Resize); btnDefault.OnClick = Callback(this, &COptionsDlg::onClick_Default); cmbVarType.OnSelChanged = Callback(this, &COptionsDlg::onSelChanged_Var); } bool OnInitDialog() override { editTitle.SetSilent(); editModule.SetSilent(); editSetting.SetSilent(); cmbOther.SetSilent(); cmbCnfType.SetSilent(); cmbVarType.SetSilent(); cmbDataType.SetSilent(); m_list.SetExtendedListViewStyle(m_list.GetExtendedListViewStyle() | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES); m_list.AddColumn(0, L"#", 20); m_list.AddColumn(1, TranslateT("Title"), g_plugin.getWord("col1", 95)); m_list.AddColumn(2, TranslateT("Module/Info type"), g_plugin.getWord("col2", 105)); m_list.AddColumn(3, TranslateT("Setting"), g_plugin.getWord("col3", 85)); cmbVarType.AddString(TranslateT("Database setting"), QST_SETTING); cmbVarType.AddString(TranslateT("Script"), QST_SCRIPT); cmbVarType.AddString(TranslateT("Contact info"), QST_CONTACTINFO); cmbVarType.AddString(TranslateT("Other"), QST_OTHER); cmbVarType.SetCurSel(0); cmbDataType.AddString(TranslateT("Byte"), QSTS_BYTE); cmbDataType.AddString(TranslateT("Word"), QSTS_WORD); cmbDataType.AddString(TranslateT("Dword"), QSTS_DWORD); cmbDataType.AddString(TranslateT("Signed"), QSTS_SIGNED); cmbDataType.AddString(TranslateT("Hexadecimal"), QSTS_HEXNUM); cmbDataType.AddString(TranslateT("String"), QSTS_STRING); cmbDataType.AddString(TranslateT("Timestamp"), QSTS_TIMESTAMP); cmbDataType.SetCurSel(0); cmbOther.AddString(TranslateT("Last seen"), QSTO_LASTSEEN); cmbOther.AddString(TranslateT("Last event"), QSTO_LASTEVENT); cmbOther.AddString(TranslateT("Metacontact"), QSTO_METACONTACT); cmbOther.AddString(TranslateT("Event count"), QSTO_EVENTCOUNT); cmbOther.AddString(TranslateT("Display name"), QSTO_DISPLAYNAME); cmbOther.AddString(TranslateT("Account name"), QSTO_ACCOUNT); cmbOther.SetCurSel(0); for (int i = CNF_FIRSTNAME; i < CNF_MAX; i++) if (auto *pwszText = cnf2str(i)) cmbCnfType.AddString(pwszText, i); cmbCnfType.SetCurSel(0); chkDrawGrid.SetState((g_plugin.m_flags & QSO_DRAWGRID) != 0); chkAutoClose.SetState((g_plugin.m_flags & QSO_AUTOCLOSE) != 0); chkSortStatus.SetState((g_plugin.m_flags & QSO_SORTBYSTATUS) != 0); chkClientIcons.SetState((g_plugin.m_flags & QSO_CLIENTICONS) != 0); chkSavePattern.SetState((g_plugin.m_flags & QSO_SAVEPATTERN) != 0); chkUseToolstyle.SetState((g_plugin.m_flags & QSO_TOOLSTYLE) != 0); // make local copy of column descriptions for (auto &it : g_plugin.m_columns) m_columns.insert(new ColumnItem(*it)); UpdateList(); onClick_Resize(0); if (m_columns.getCount()) DisplayCurInfo(&m_columns[0]); return true; } bool OnApply() override { // checkboxes g_plugin.m_flags &= ~QSO_MAINOPTIONS; if (chkDrawGrid.IsChecked()) g_plugin.m_flags |= QSO_DRAWGRID; if (chkAutoClose.IsChecked()) g_plugin.m_flags |= QSO_AUTOCLOSE; if (chkSortStatus.IsChecked()) g_plugin.m_flags |= QSO_SORTBYSTATUS; if (chkClientIcons.IsChecked()) g_plugin.m_flags |= QSO_CLIENTICONS; if (chkSavePattern.IsChecked()) g_plugin.m_flags |= QSO_SAVEPATTERN; if (chkUseToolstyle.IsChecked()) g_plugin.m_flags |= QSO_TOOLSTYLE; int tmpbool = CloseSrWindow(false); g_plugin.m_columns.destroy(); int nCount = m_list.GetItemCount(); for (int i = 0; i < nCount; i++) { auto *pCol = (ColumnItem *)m_list.GetItemData(i); pCol->bEnabled = m_list.GetCheckState(i) != 0; g_plugin.m_columns.insert(new ColumnItem(*pCol)); } g_plugin.SaveOptions(); if (tmpbool) OpenSrWindow(0); return true; } void OnDestroy() override { m_columns.destroy(); g_plugin.setWord("col1", m_list.GetColumnWidth(1)); g_plugin.setWord("col2", m_list.GetColumnWidth(2)); g_plugin.setWord("col3", m_list.GetColumnWidth(3)); } void onClick_New(CCtrlButton *) { int idx = m_list.GetSelectionMark()+1; auto *pNew = new ColumnItem(TranslateT("New column")); m_columns.insert(pNew); AddColumn(idx, pNew); m_list.EnsureVisible(idx, FALSE); m_list.SetCurSel(idx); InitScreen(); CheckDirection(idx); btnDelete.Enable(); NotifyChange(); } void onClick_Delete(CCtrlButton *) { int idx = m_list.GetSelectionMark(); auto *pCol = (ColumnItem *)m_list.GetItemData(idx); m_list.DeleteItem(idx); m_columns.remove(pCol); int nCount = m_list.GetItemCount(); if (nCount == 0) { m_list.Disable(); InitScreen(); } else { if (nCount == idx) idx--; m_list.SetCurSel(idx); } CheckDirection(idx); NotifyChange(); } void onClick_Up(CCtrlButton *) { int idx = m_list.GetSelectionMark(); if (idx > 0) { CheckDirection(m_list.MoveItem(idx, -1)); NotifyChange(); } } void onClick_Down(CCtrlButton *) { int idx = m_list.GetSelectionMark(); if (idx < m_list.GetItemCount() - 1) { CheckDirection(m_list.MoveItem(idx, 1)); NotifyChange(); } } void onClick_Reload(CCtrlButton *) { g_plugin.LoadColumns(m_columns); UpdateList(); } void onClick_Default(CCtrlButton *) { LoadDefaultColumns(m_columns); UpdateList(); NotifyChange(); } void onClick_Save(CCtrlButton *) { if (m_list.GetItemCount() == 0) { AddColumn(0, new ColumnItem(TranslateT("New column"))); m_list.SetCurSel(0); btnDelete.Enable(); } int idx = m_list.GetSelectionMark(); auto *pCol = (ColumnItem *)m_list.GetItemData(idx); pCol->dwFlags = 0; if (m_list.GetCheckState(idx)) pCol->bEnabled = pCol->bFilter = true; pCol->setting_type = cmbVarType.GetItemData(cmbVarType.GetCurSel()); replaceStrW(pCol->title, editTitle.GetText()); switch (pCol->setting_type) { case QST_SETTING: pCol->datatype = cmbDataType.GetItemData(cmbDataType.GetCurSel()); pCol->module = mir_u2a(ptrW(editModule.GetText())); pCol->setting = mir_u2a(ptrW(editSetting.GetText())); break; case QST_CONTACTINFO: pCol->cnftype = cmbCnfType.GetItemData(cmbCnfType.GetCurSel()); break; case QST_OTHER: pCol->other = cmbCnfType.GetItemData(cmbCnfType.GetCurSel()); break; } FillTableLine(idx, pCol); NotifyChange(); } void onClick_Resize(CCtrlButton *) { wchar_t *pcw; int dx, rside; RECT rc, rc1; GetClientRect(m_hwnd, &rc); GetWindowRect(btnResize.GetHwnd(), &rc1); POINT pt = { rc1.left, 0 }; ScreenToClient(m_hwnd, &pt); if (pt.x < (rc.right - 50)) { rside = SW_HIDE; dx = rc.right - (rc1.right - rc1.left) - 4; pcw = L"<"; } else { rside = SW_SHOW; GetWindowRect(GetDlgItem(m_hwnd, IDC_S_COLSETTING), &rc); pt.x = rc.left; pt.y = 0; ScreenToClient(m_hwnd, &pt); dx = pt.x - (rc1.right - rc1.left) - 4; pcw = L">"; } btnResize.SetText(pcw); // move separator button SetWindowPos(btnResize.GetHwnd(), 0, dx + 2, 2, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); // resize left side controls ResizeControl(IDC_LIST, dx); ResizeControl(IDC_CH_GROUP, dx); ResizeControl(IDC_CH_USETOOLSTYLE, dx - 8); ResizeControl(IDC_CH_DRAWGRID, dx - 8); ResizeControl(IDC_CH_SAVEPATTERN, dx - 8); ResizeControl(IDC_CH_AUTOCLOSE, dx - 8); ResizeControl(IDC_CH_SORTSTATUS, dx - 8); ResizeControl(IDC_CH_CLIENTICONS, dx - 8); // show/hide setting block (ugly, i know!) ShowWindow(GetDlgItem(m_hwnd, IDC_S_COLSETTING), rside); ShowWindow(GetDlgItem(m_hwnd, IDC_S_LINE), rside); ShowWindow(GetDlgItem(m_hwnd, IDC_S_TITLE), rside); ShowWindow(GetDlgItem(m_hwnd, IDC_E_TITLE), rside); ShowWindow(GetDlgItem(m_hwnd, IDC_E_SCRIPT), rside); ShowWindow(GetDlgItem(m_hwnd, IDC_E_MODULE), rside); ShowWindow(GetDlgItem(m_hwnd, IDC_E_SETTING), rside); ShowWindow(GetDlgItem(m_hwnd, IDC_S_VARTYPE), rside); ShowWindow(GetDlgItem(m_hwnd, IDC_C_VARTYPE), rside); ShowWindow(GetDlgItem(m_hwnd, IDC_C_OTHER), rside); ShowWindow(GetDlgItem(m_hwnd, IDC_C_CNFTYPE), rside); ShowWindow(GetDlgItem(m_hwnd, IDC_C_DATATYPE), rside); ShowWindow(GetDlgItem(m_hwnd, IDC_SETITEM), rside); ClearScreen(); if (rside == SW_SHOW) SetupScreen(cmbVarType.GetItemData(cmbVarType.GetCurSel())); } void onItemChanged_List(CCtrlListView::TEventInfo *ev) { auto *nmlv = ev->nmlv; // we got new focus if ((nmlv->uOldState & LVNI_FOCUSED) < (nmlv->uNewState & LVNI_FOCUSED)) { CheckDirection(nmlv->iItem); InitScreen(); DisplayCurInfo((ColumnItem*)nmlv->lParam); } } void onSelChanged_Var(CCtrlCombo *pCombo) { SetupScreen(pCombo->GetItemData(pCombo->GetCurSel())); } }; int OnOptInit(WPARAM wParam, LPARAM) { OPTIONSDIALOGPAGE odp = {}; odp.flags = ODPF_BOLDGROUPS; odp.szGroup.a = LPGEN("Contacts"); odp.szTitle.a = LPGEN("Quick Search"); odp.position = 900003000; odp.pDialog = new COptionsDlg(); g_plugin.addOptions(wParam, &odp); return 0; }