From 58b0e3644f47f9cd2746d43263d23f3900f7fe17 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 23 Nov 2016 00:14:38 +0300 Subject: account manager partially rewritten using UI Utils --- src/mir_app/src/options.cpp | 1 - src/mir_app/src/proto_opts.cpp | 1289 ++++++++++++++++++++-------------------- 2 files changed, 650 insertions(+), 640 deletions(-) (limited to 'src/mir_app') diff --git a/src/mir_app/src/options.cpp b/src/mir_app/src/options.cpp index 18d0d70c63..e2d7c54df1 100644 --- a/src/mir_app/src/options.cpp +++ b/src/mir_app/src/options.cpp @@ -1159,7 +1159,6 @@ void OpenAccountOptions(PROTOACCOUNT *pa) psh.pszCaption = tszTitle; psh.ppsp = (PROPSHEETPAGE*)arPages.getArray(); hwndOptions = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_OPTIONSPAGE), NULL, OptionsDlgProc, (LPARAM)&psh); - mir_free((void*)ood.pszPage); } static void OpenOptionsNow(int _hLang, const wchar_t *pszGroup, const wchar_t *pszPage, const wchar_t *pszTab, bool bSinglePage) diff --git a/src/mir_app/src/proto_opts.cpp b/src/mir_app/src/proto_opts.cpp index 4cc607130e..e265d59d06 100644 --- a/src/mir_app/src/proto_opts.cpp +++ b/src/mir_app/src/proto_opts.cpp @@ -24,11 +24,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "stdafx.h" -#define LBN_MY_CHECK 0x1000 -#define LBN_MY_RENAME 0x1001 +#define LBN_MY_RENAME 0x1000 #define WM_MY_REFRESH (WM_USER+0x1000) -#define WM_MY_RENAME (WM_USER+0x1001) bool CheckProtocolOrder(void); @@ -52,7 +50,7 @@ Here you can set up your IM accounts.\n\n\ Select an account from the list on the left to see the available options. \ Alternatively, just click on the Plus sign underneath the list to set up a new IM account.") -static HWND hAccMgr = NULL; +static class CAccountManagerDlg *pAccMgr = NULL; extern HANDLE hAccListChanged; @@ -120,7 +118,7 @@ static bool FindAccountByName(const char *szModuleName) static bool OnCreateAccount(HWND hwndDlg) { - AccFormDlgParam* param = (AccFormDlgParam*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + AccFormDlgParam *param = (AccFormDlgParam*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); PROTOACCOUNT *pa = param->pa; wchar_t tszAccName[256]; @@ -233,763 +231,778 @@ static INT_PTR CALLBACK AccFormDlgProc(HWND hwndDlg, UINT message, WPARAM wParam return FALSE; } -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Accounts manager +///////////////////////////////////////////////////////////////////////////////////////// +// Account manager dialog -struct TAccMgrData +class CAccountListCtrl : public CCtrlListBox { - HFONT hfntTitle, hfntText; - int titleHeight, textHeight; - int selectedHeight, normalHeight; - int iSelected; -}; + friend class CAccountManagerDlg; -struct TAccListData -{ - int iItem; - RECT rcCheck; - HWND hwndEdit; -}; + int m_iItem; + RECT m_rcCheck; + HWND m_hwndEdit; -static void sttClickButton(HWND hwndDlg, int idcButton) -{ - if (IsWindowEnabled(GetDlgItem(hwndDlg, idcButton))) - PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(idcButton, BN_CLICKED), (LPARAM)GetDlgItem(hwndDlg, idcButton)); -} - -static LRESULT CALLBACK sttEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_KEYDOWN: - switch (wParam) { - case VK_RETURN: - DestroyWindow(hwnd); - return 0; +public: + CAccountListCtrl(CDlgBase* dlg, int ctrlId) : + CCtrlListBox(dlg, ctrlId), + m_iItem(-1), + m_hwndEdit(NULL) + {} - case VK_ESCAPE: - SetWindowLongPtr(hwnd, GWLP_WNDPROC, GetWindowLongPtr(hwnd, GWLP_USERDATA)); - DestroyWindow(hwnd); - return 0; - } - break; + __forceinline CAccountManagerDlg* PARENT() { return (CAccountManagerDlg*)m_parentWnd; } - case WM_GETDLGCODE: - if (wParam == VK_RETURN || wParam == VK_ESCAPE) - return DLGC_WANTMESSAGE; - break; - - case WM_KILLFOCUS: - int length = GetWindowTextLength(hwnd) + 1; - wchar_t *str = (wchar_t*)mir_alloc(sizeof(wchar_t) * length); - GetWindowText(hwnd, str, length); - SendMessage(GetParent(GetParent(hwnd)), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(GetParent(hwnd), GWL_ID), LBN_MY_RENAME), (LPARAM)str); - DestroyWindow(hwnd); - return 0; + virtual void OnInit() + { + CCtrlListBox::OnInit(); + Subclass(); } - return mir_callNextSubclass(hwnd, sttEditSubclassProc, msg, wParam, lParam); -} -static LRESULT CALLBACK AccListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - struct TAccListData *dat = (struct TAccListData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); - if (!dat) - return DefWindowProc(hwnd, msg, wParam, lParam); + virtual BOOL OnDrawItem(DRAWITEMSTRUCT *lps) override; + virtual BOOL OnMeasureItem(MEASUREITEMSTRUCT *lps) override; - switch (msg) { - case WM_LBUTTONDOWN: - { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - int iItem = LOWORD(SendMessage(hwnd, LB_ITEMFROMPOINT, 0, lParam)); - ListBox_GetItemRect(hwnd, iItem, &dat->rcCheck); + virtual LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam) override; - dat->rcCheck.right = dat->rcCheck.left + g_iIconSX + 4; - dat->rcCheck.bottom = dat->rcCheck.top + g_iIconSY + 4; - if (PtInRect(&dat->rcCheck, pt)) - dat->iItem = iItem; - else - dat->iItem = -1; - } - break; - - case WM_LBUTTONUP: - { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - if ((dat->iItem >= 0) && PtInRect(&dat->rcCheck, pt)) - PostMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(hwnd, GWL_ID), LBN_MY_CHECK), (LPARAM)dat->iItem); - dat->iItem = -1; - } - break; - - case WM_CHAR: - if (wParam == ' ') { - int iItem = ListBox_GetCurSel(hwnd); - if (iItem >= 0) - PostMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(hwnd, GWL_ID), LBN_MY_CHECK), (LPARAM)iItem); - return 0; - } - - if (wParam == 10 /* enter */) - return 0; - - break; - - case WM_GETDLGCODE: - if (wParam == VK_RETURN) - return DLGC_WANTMESSAGE; - break; + void InitRename(); +}; - case WM_MY_RENAME: - RECT rc; - { - struct TAccMgrData *parentDat = (struct TAccMgrData *)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); - PROTOACCOUNT *pa = (PROTOACCOUNT *)ListBox_GetItemData(hwnd, ListBox_GetCurSel(hwnd)); - if (!pa || pa->bOldProto || pa->bDynDisabled) - return 0; - - ListBox_GetItemRect(hwnd, ListBox_GetCurSel(hwnd), &rc); - rc.left += 2 * g_iIconSX + 4; - rc.bottom = rc.top + max(g_iIconSX, parentDat->titleHeight) + 4 - 1; - ++rc.top; --rc.right; - - dat->hwndEdit = CreateWindow(L"EDIT", pa->tszAccountName, WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hwnd, NULL, g_hInst, NULL); - mir_subclassWindow(dat->hwndEdit, sttEditSubclassProc); - SendMessage(dat->hwndEdit, WM_SETFONT, (WPARAM)parentDat->hfntTitle, 0); - SendMessage(dat->hwndEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN | EC_USEFONTINFO, 0); - SendMessage(dat->hwndEdit, EM_SETSEL, 0, -1); - ShowWindow(dat->hwndEdit, SW_SHOW); - } - SetFocus(dat->hwndEdit); - break; +class CAccountManagerDlg : public CDlgBase +{ + friend class CAccountListCtrl; - case WM_KEYDOWN: - switch (wParam) { - case VK_F2: - PostMessage(hwnd, WM_MY_RENAME, 0, 0); - return 0; + HFONT m_hfntTitle, m_hfntText; + int m_titleHeight, m_textHeight; + int m_selectedHeight, m_normalHeight; + int m_iSelected; - case VK_INSERT: - sttClickButton(GetParent(hwnd), IDC_ADD); - return 0; + CAccountListCtrl m_accList; + CCtrlButton m_btnAdd, m_btnEdit, m_btnUpgrade, m_btnRemove, m_btnOptions, m_btnNetwork; + CCtrlButton m_btnOk, m_btnCancel; - case VK_DELETE: - sttClickButton(GetParent(hwnd), IDC_REMOVE); - return 0; - - case VK_RETURN: - if (GetAsyncKeyState(VK_CONTROL)) - sttClickButton(GetParent(hwnd), IDC_EDIT); - else - sttClickButton(GetParent(hwnd), IDOK); - return 0; - } - break; + void ClickButton(CCtrlButton &btn) + { + if (btn.Enabled()) + ::PostMessage(m_hwnd, WM_COMMAND, MAKEWPARAM(btn.GetCtrlId(), BN_CLICKED), (LPARAM)btn.GetHwnd()); } - return mir_callNextSubclass(hwnd, AccListWndProc, msg, wParam, lParam); -} + void SelectItem(int iItem) + { + if ((m_iSelected != iItem) && (m_iSelected >= 0)) + m_accList.SetItemHeight(m_iSelected, m_normalHeight); -static void sttSubclassAccList(HWND hwnd, BOOL subclass) -{ - if (subclass) { - struct TAccListData *dat = (struct TAccListData *)mir_alloc(sizeof(struct TAccListData)); - dat->iItem = -1; - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat); - mir_subclassWindow(hwnd, AccListWndProc); - } - else { - struct TAccListData *dat = (struct TAccListData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); - SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); - mir_free(dat); + m_iSelected = iItem; + m_accList.SetItemHeight(m_iSelected, m_selectedHeight); + RedrawWindow(m_accList.GetHwnd(), NULL, NULL, RDW_INVALIDATE); } -} -static void sttSelectItem(struct TAccMgrData *dat, HWND hwndList, int iItem) -{ - if ((dat->iSelected != iItem) && (dat->iSelected >= 0)) - ListBox_SetItemHeight(hwndList, dat->iSelected, dat->normalHeight); - - dat->iSelected = iItem; - ListBox_SetItemHeight(hwndList, dat->iSelected, dat->selectedHeight); - RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); -} - -static void sttUpdateAccountInfo(HWND hwndDlg, struct TAccMgrData *dat) -{ - HWND hwndList = GetDlgItem(hwndDlg, IDC_ACCLIST); - int curSel = ListBox_GetCurSel(hwndList); - if (curSel != LB_ERR) { - PROTOACCOUNT *pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, curSel); - if (pa) { - EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), pa->bOldProto || pa->bDynDisabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), !pa->bOldProto && !pa->bDynDisabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), pa->ppro != 0); - - if (dat->iSelected >= 0) { - PROTOACCOUNT *pa_old = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, dat->iSelected); - if (pa_old && pa_old != pa && pa_old->hwndAccMgrUI) - ShowWindow(pa_old->hwndAccMgrUI, SW_HIDE); - } + void UpdateAccountInfo() + { + int curSel = m_accList.GetCurSel(); + if (curSel != LB_ERR) { + PROTOACCOUNT *pa = (PROTOACCOUNT *)m_accList.GetItemData(curSel); + if (pa) { + m_btnEdit.Enable(!pa->bOldProto && !pa->bDynDisabled); + m_btnRemove.Enable(true); + m_btnUpgrade.Enable(pa->bOldProto || pa->bDynDisabled); + m_btnOptions.Enable(pa->ppro != 0); + + if (m_iSelected >= 0) { + PROTOACCOUNT *pa_old = (PROTOACCOUNT *)m_accList.GetItemData(m_iSelected); + if (pa_old && pa_old != pa && pa_old->hwndAccMgrUI) + ShowWindow(pa_old->hwndAccMgrUI, SW_HIDE); + } - if (pa->hwndAccMgrUI) { - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_HIDE); - ShowWindow(pa->hwndAccMgrUI, SW_SHOW); - } - else if (!pa->ppro) { - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW); - SetDlgItemText(hwndDlg, IDC_TXT_INFO, TranslateT("Account is disabled. Please activate it to access options.")); - } - else { - HWND hwnd = (HWND)CallProtoService(pa->szModuleName, PS_CREATEACCMGRUI, 0, (LPARAM)hwndDlg); - if (hwnd && (hwnd != (HWND)CALLSERVICE_NOTFOUND)) { - RECT rc; + if (pa->hwndAccMgrUI) { + ShowWindow(GetDlgItem(m_hwnd, IDC_TXT_INFO), SW_HIDE); + ShowWindow(pa->hwndAccMgrUI, SW_SHOW); + } + else if (!pa->ppro) { + ShowWindow(GetDlgItem(m_hwnd, IDC_TXT_INFO), SW_SHOW); + SetDlgItemText(m_hwnd, IDC_TXT_INFO, TranslateT("Account is disabled. Please activate it to access options.")); + } + else { + HWND hwnd = (HWND)CallProtoService(pa->szModuleName, PS_CREATEACCMGRUI, 0, (LPARAM)m_hwnd); + if (hwnd && (hwnd != (HWND)CALLSERVICE_NOTFOUND)) { + RECT rc; - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_HIDE); + ShowWindow(GetDlgItem(m_hwnd, IDC_TXT_INFO), SW_HIDE); - GetWindowRect(GetDlgItem(hwndDlg, IDC_TXT_INFO), &rc); - MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rc, 2); - SetWindowPos(hwnd, hwndList, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); + GetWindowRect(GetDlgItem(m_hwnd, IDC_TXT_INFO), &rc); + MapWindowPoints(NULL, m_hwnd, (LPPOINT)&rc, 2); + SetWindowPos(hwnd, m_accList.GetHwnd(), rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); - pa->hwndAccMgrUI = hwnd; - } - else { - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW); - SetDlgItemText(hwndDlg, IDC_TXT_INFO, legacyMsg); + pa->hwndAccMgrUI = hwnd; + } + else { + ShowWindow(GetDlgItem(m_hwnd, IDC_TXT_INFO), SW_SHOW); + SetDlgItemText(m_hwnd, IDC_TXT_INFO, legacyMsg); + } } + return; } - return; } + + m_btnEdit.Disable(); + m_btnRemove.Disable(); + m_btnUpgrade.Disable(); + m_btnOptions.Disable(); + + ShowWindow(GetDlgItem(m_hwnd, IDC_TXT_INFO), SW_SHOW); + SetDlgItemText(m_hwnd, IDC_TXT_INFO, welcomeMsg); } - EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), FALSE); +public: + CAccountManagerDlg() : + CDlgBase(g_hInst, IDD_ACCMGR), + m_accList(this, IDC_ACCLIST), + m_btnOk(this, IDOK), + m_btnAdd(this, IDC_ADD), + m_btnEdit(this, IDC_EDIT), + m_btnCancel(this, IDCANCEL), + m_btnRemove(this, IDC_REMOVE), + m_btnUpgrade(this, IDC_UPGRADE), + m_btnOptions(this, IDC_OPTIONS), + m_btnNetwork(this, IDC_LNK_NETWORK) + { + m_accList.OnDblClick = Callback(this, &CAccountManagerDlg::OnListDblClick); + m_accList.OnSelChange = Callback(this, &CAccountManagerDlg::OnListSelChange); + m_accList.OnBuildMenu = Callback(this, &CAccountManagerDlg::OnListMenu); + + m_btnOk.OnClick = Callback(this, &CAccountManagerDlg::OnOk); + m_btnAdd.OnClick = Callback(this, &CAccountManagerDlg::OnAdd); + m_btnEdit.OnClick = Callback(this, &CAccountManagerDlg::OnEdit); + m_btnRemove.OnClick = Callback(this, &CAccountManagerDlg::OnRemove); + m_btnCancel.OnClick = Callback(this, &CAccountManagerDlg::OnCancel); + m_btnUpgrade.OnClick = Callback(this, &CAccountManagerDlg::OnUpgrade); + m_btnOptions.OnClick = Callback(this, &CAccountManagerDlg::OnOptions); + m_btnNetwork.OnClick = Callback(this, &CAccountManagerDlg::OnNetwork); + } - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW); - SetDlgItemText(hwndDlg, IDC_TXT_INFO, welcomeMsg); -} + virtual void OnInitDialog() override + { + Window_SetSkinIcon_IcoLib(m_hwnd, SKINICON_OTHER_ACCMGR); -INT_PTR CALLBACK AccMgrDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - struct TAccMgrData *dat = (struct TAccMgrData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - HWND hwndList = GetDlgItem(hwndDlg, IDC_ACCLIST); - PROTOACCOUNT *pa; - int idx; - PSHNOTIFY pshn; + Button_SetIcon_IcoLib(m_hwnd, IDC_ADD, SKINICON_OTHER_ADDCONTACT, LPGEN("New account")); + Button_SetIcon_IcoLib(m_hwnd, IDC_EDIT, SKINICON_OTHER_RENAME, LPGEN("Edit")); + Button_SetIcon_IcoLib(m_hwnd, IDC_REMOVE, SKINICON_OTHER_DELETE, LPGEN("Remove account")); + Button_SetIcon_IcoLib(m_hwnd, IDC_OPTIONS, SKINICON_OTHER_OPTIONS, LPGEN("Configure...")); + Button_SetIcon_IcoLib(m_hwnd, IDC_UPGRADE, SKINICON_OTHER_ACCMGR, LPGEN("Upgrade account")); - switch (message) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - Window_SetSkinIcon_IcoLib(hwndDlg, SKINICON_OTHER_ACCMGR); + m_btnEdit.Disable(); + m_btnRemove.Disable(); + m_btnUpgrade.Disable(); + m_btnOptions.Disable(); - dat = (TAccMgrData *)mir_alloc(sizeof(TAccMgrData)); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); + LOGFONT lf; + GetObject((HFONT)SendMessage(m_hwnd, WM_GETFONT, 0, 0), sizeof(lf), &lf); + m_hfntText = ::CreateFontIndirect(&lf); - Button_SetIcon_IcoLib(hwndDlg, IDC_ADD, SKINICON_OTHER_ADDCONTACT, LPGEN("New account")); - Button_SetIcon_IcoLib(hwndDlg, IDC_EDIT, SKINICON_OTHER_RENAME, LPGEN("Edit")); - Button_SetIcon_IcoLib(hwndDlg, IDC_REMOVE, SKINICON_OTHER_DELETE, LPGEN("Remove account")); - Button_SetIcon_IcoLib(hwndDlg, IDC_OPTIONS, SKINICON_OTHER_OPTIONS, LPGEN("Configure...")); - Button_SetIcon_IcoLib(hwndDlg, IDC_UPGRADE, SKINICON_OTHER_ACCMGR, LPGEN("Upgrade account")); + GetObject((HFONT)SendMessage(m_hwnd, WM_GETFONT, 0, 0), sizeof(lf), &lf); + lf.lfWeight = FW_BOLD; + m_hfntTitle = ::CreateFontIndirect(&lf); - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), FALSE); - { - LOGFONT lf; - GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf); - dat->hfntText = CreateFontIndirect(&lf); + HDC hdc = GetDC(m_hwnd); + HFONT hfnt = (HFONT)::SelectObject(hdc, m_hfntTitle); - GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf); - lf.lfWeight = FW_BOLD; - dat->hfntTitle = CreateFontIndirect(&lf); + TEXTMETRIC tm; + GetTextMetrics(hdc, &tm); + m_titleHeight = tm.tmHeight; + ::SelectObject(hdc, m_hfntText); - HDC hdc = GetDC(hwndDlg); - HFONT hfnt = (HFONT)SelectObject(hdc, dat->hfntTitle); + GetTextMetrics(hdc, &tm); + m_textHeight = tm.tmHeight; + ::SelectObject(hdc, hfnt); + ::ReleaseDC(m_hwnd, hdc); - TEXTMETRIC tm; - GetTextMetrics(hdc, &tm); - dat->titleHeight = tm.tmHeight; - SelectObject(hdc, dat->hfntText); + m_normalHeight = 4 + max(m_titleHeight, g_iIconSY); + m_selectedHeight = m_normalHeight + 4 + 2 * m_textHeight; - GetTextMetrics(hdc, &tm); - dat->textHeight = tm.tmHeight; - SelectObject(hdc, hfnt); - ReleaseDC(hwndDlg, hdc); + SendDlgItemMessage(m_hwnd, IDC_NAME, WM_SETFONT, (WPARAM)m_hfntTitle, 0); + SendDlgItemMessage(m_hwnd, IDC_TXT_ACCOUNT, WM_SETFONT, (WPARAM)m_hfntTitle, 0); + SendDlgItemMessage(m_hwnd, IDC_TXT_ADDITIONAL, WM_SETFONT, (WPARAM)m_hfntTitle, 0); - dat->normalHeight = 4 + max(dat->titleHeight, g_iIconSY); - dat->selectedHeight = dat->normalHeight + 4 + 2 * dat->textHeight; - } + m_iSelected = -1; + SendMessage(m_hwnd, WM_MY_REFRESH, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_NAME, WM_SETFONT, (WPARAM)dat->hfntTitle, 0); - SendDlgItemMessage(hwndDlg, IDC_TXT_ACCOUNT, WM_SETFONT, (WPARAM)dat->hfntTitle, 0); - SendDlgItemMessage(hwndDlg, IDC_TXT_ADDITIONAL, WM_SETFONT, (WPARAM)dat->hfntTitle, 0); + Utils_RestoreWindowPositionNoSize(m_hwnd, NULL, "AccMgr", ""); + } - dat->iSelected = -1; - sttSubclassAccList(GetDlgItem(hwndDlg, IDC_ACCLIST), TRUE); - SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); + virtual void OnApply() override + { + PSHNOTIFY pshn; + pshn.hdr.idFrom = 0; + pshn.hdr.code = PSN_APPLY; + for (int i = 0; i < accounts.getCount(); i++) { + PROTOACCOUNT *pa = accounts[i]; + if (pa->hwndAccMgrUI && pa->bAccMgrUIChanged) { + pshn.hdr.hwndFrom = pa->hwndAccMgrUI; + SendMessage(pa->hwndAccMgrUI, WM_NOTIFY, 0, (LPARAM)&pshn); + pa->bAccMgrUIChanged = FALSE; + } + } + } - Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "AccMgr", ""); - return TRUE; + virtual void OnReset() override + { + PSHNOTIFY pshn; + pshn.hdr.idFrom = 0; + pshn.hdr.code = PSN_RESET; + for (int i = 0; i < accounts.getCount(); i++) { + PROTOACCOUNT *pa = accounts[i]; + if (pa->hwndAccMgrUI && pa->bAccMgrUIChanged) { + pshn.hdr.hwndFrom = pa->hwndAccMgrUI; + SendMessage(pa->hwndAccMgrUI, WM_NOTIFY, 0, (LPARAM)&pshn); + pa->bAccMgrUIChanged = FALSE; + } + } + } - case WM_CTLCOLORSTATIC: - switch (GetDlgCtrlID((HWND)lParam)) { - case IDC_WHITERECT: - case IDC_NAME: - SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); - return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); + virtual void OnDestroy() override + { + for (int i = 0; i < accounts.getCount(); i++) { + PROTOACCOUNT *pa = accounts[i]; + pa->bAccMgrUIChanged = FALSE; + if (pa->hwndAccMgrUI) { + ::DestroyWindow(pa->hwndAccMgrUI); + pa->hwndAccMgrUI = NULL; + } } - break; - case WM_MEASUREITEM: - { - LPMEASUREITEMSTRUCT lps = (LPMEASUREITEMSTRUCT)lParam; - PROTOACCOUNT *acc = (PROTOACCOUNT *)lps->itemData; + Window_FreeIcon_IcoLib(m_hwnd); + Button_FreeIcon_IcoLib(m_hwnd, IDC_ADD); + Button_FreeIcon_IcoLib(m_hwnd, IDC_EDIT); + Button_FreeIcon_IcoLib(m_hwnd, IDC_REMOVE); + Button_FreeIcon_IcoLib(m_hwnd, IDC_OPTIONS); + Button_FreeIcon_IcoLib(m_hwnd, IDC_UPGRADE); + Utils_SaveWindowPosition(m_hwnd, NULL, "AccMgr", ""); + DeleteObject(m_hfntTitle); + DeleteObject(m_hfntText); + pAccMgr = NULL; + } - if ((lps->CtlID != IDC_ACCLIST) || !acc) - break; + void OnListMenu(void*) + { + POINT pt; + GetCursorPos(&pt); - lps->itemWidth = 10; - lps->itemHeight = dat->normalHeight; - } - return TRUE; + // menu was activated with mouse = > find item under cursor & set focus to our control. + POINT ptItem = pt; + ScreenToClient(m_accList.GetHwnd(), &ptItem); + int iItem = (short)LOWORD(m_accList.SendMsg(LB_ITEMFROMPOINT, 0, MAKELPARAM(ptItem.x, ptItem.y))); + if (iItem == -1) + return; - case WM_DRAWITEM: - HBRUSH hbrBack; - SIZE sz; - { - int cxIcon = g_iIconSX; - int cyIcon = g_iIconSY; + m_accList.SetCurSel(iItem); + UpdateAccountInfo(); + SelectItem(iItem); + SetFocus(m_accList.GetHwnd()); - LPDRAWITEMSTRUCT lps = (LPDRAWITEMSTRUCT)lParam; - PROTOACCOUNT *acc = (PROTOACCOUNT *)lps->itemData; - if ((lps->CtlID != IDC_ACCLIST) || (lps->itemID == -1) || !acc) - break; + PROTOACCOUNT *pa = (PROTOACCOUNT*)m_accList.GetItemData(iItem); + HMENU hMenu = CreatePopupMenu(); + if (!pa->bOldProto && !pa->bDynDisabled) + AppendMenu(hMenu, MF_STRING, 1, TranslateT("Rename")); - SetBkMode(lps->hDC, TRANSPARENT); - if (lps->itemState & ODS_SELECTED) { - hbrBack = GetSysColorBrush(COLOR_HIGHLIGHT); - SetTextColor(lps->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); - } - else { - hbrBack = GetSysColorBrush(COLOR_WINDOW); - SetTextColor(lps->hDC, GetSysColor(COLOR_WINDOWTEXT)); - } - FillRect(lps->hDC, &lps->rcItem, hbrBack); + AppendMenu(hMenu, MF_STRING, 3, TranslateT("Delete")); - lps->rcItem.left += 2; - lps->rcItem.top += 2; - lps->rcItem.bottom -= 2; + if (Proto_IsAccountEnabled(pa)) + AppendMenu(hMenu, MF_STRING, 4, TranslateT("Configure")); - int tmp; - if (acc->bOldProto) - tmp = SKINICON_OTHER_ON; - else if (acc->bDynDisabled) - tmp = SKINICON_OTHER_OFF; - else - tmp = acc->bIsEnabled ? SKINICON_OTHER_TICK : SKINICON_OTHER_NOTICK; + if (pa->bOldProto || pa->bDynDisabled) + AppendMenu(hMenu, MF_STRING, 5, TranslateT("Upgrade")); - HICON hIcon = Skin_LoadIcon(tmp); - DrawIconEx(lps->hDC, lps->rcItem.left, lps->rcItem.top, hIcon, cxIcon, cyIcon, 0, hbrBack, DI_NORMAL); - IcoLib_ReleaseIcon(hIcon); + switch (TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_hwnd, NULL)) { + case 1: + m_accList.InitRename(); + break; - lps->rcItem.left += cxIcon + 2; + case 2: + ClickButton(m_btnEdit); + break; - if (acc->ppro) { - hIcon = IcoLib_GetIconByHandle(acc->ppro->m_hProtoIcon); - DrawIconEx(lps->hDC, lps->rcItem.left, lps->rcItem.top, hIcon, cxIcon, cyIcon, 0, hbrBack, DI_NORMAL); - IcoLib_ReleaseIcon(hIcon); - } - lps->rcItem.left += cxIcon + 2; - - int length = SendDlgItemMessage(hwndDlg, IDC_ACCLIST, LB_GETTEXTLEN, lps->itemID, 0); - int size = max(length + 1, 256); - wchar_t *text = (wchar_t *)_alloca(sizeof(wchar_t) * size); - SendDlgItemMessage(hwndDlg, IDC_ACCLIST, LB_GETTEXT, lps->itemID, (LPARAM)text); - - SelectObject(lps->hDC, dat->hfntTitle); - tmp = lps->rcItem.bottom; - lps->rcItem.bottom = lps->rcItem.top + max(cyIcon, dat->titleHeight); - DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS | DT_VCENTER); - lps->rcItem.bottom = tmp; - GetTextExtentPoint32(lps->hDC, text, length, &sz); - lps->rcItem.top += max(cxIcon, sz.cy) + 2; - - if (lps->itemID == (unsigned)dat->iSelected) { - SelectObject(lps->hDC, dat->hfntText); - mir_snwprintf(text, size, L"%s: %S", TranslateT("Protocol"), acc->szProtoName); - length = (int)mir_wstrlen(text); - DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS); - GetTextExtentPoint32(lps->hDC, text, length, &sz); - lps->rcItem.top += sz.cy + 2; - - if (acc->ppro && Proto_IsProtocolLoaded(acc->szProtoName)) { - char *szIdName = (char *)acc->ppro->GetCaps(PFLAG_UNIQUEIDTEXT, 0); - ptrW tszIdName(szIdName ? mir_a2u(szIdName) : mir_wstrdup(TranslateT("Account ID"))); - ptrW tszUniqueID(Contact_GetInfo(CNF_UNIQUEID, NULL, acc->szModuleName)); - if (tszUniqueID != NULL) - mir_snwprintf(text, size, L"%s: %s", tszIdName, tszUniqueID); - else - mir_snwprintf(text, size, L"%s: %s", tszIdName, TranslateT("")); - } - else mir_snwprintf(text, size, TranslateT("Protocol is not loaded.")); + case 3: + ClickButton(m_btnRemove); + break; - length = (int)mir_wstrlen(text); - DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS); - GetTextExtentPoint32(lps->hDC, text, length, &sz); - lps->rcItem.top += sz.cy + 2; - } + case 4: + ClickButton(m_btnOptions); + break; + + case 5: + ClickButton(m_btnUpgrade); + break; } - return TRUE; + DestroyMenu(hMenu); + } - case WM_MY_REFRESH: - dat->iSelected = -1; - { - int i = ListBox_GetCurSel(hwndList); - PROTOACCOUNT *acc = (i == LB_ERR) ? NULL : (PROTOACCOUNT *)ListBox_GetItemData(hwndList, i); + void OnListSelChange(void*) + { + UpdateAccountInfo(); + SelectItem(m_accList.GetCurSel()); + ::SetFocus(m_accList.GetHwnd()); + } - SendMessage(hwndList, LB_RESETCONTENT, 0, 0); - for (i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *p = accounts[i]; - PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(p->szProtoName); - if (pd != NULL && pd->type != PROTOTYPE_PROTOCOL) - continue; + void OnListDblClick(void*) + { + m_accList.InitRename(); + } - int iItem = SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)p->tszAccountName); - SendMessage(hwndList, LB_SETITEMDATA, iItem, (LPARAM)p); + void OnAccountCheck(int iItem) + { + PROTOACCOUNT *pa = (PROTOACCOUNT*)m_accList.GetItemData(iItem); + if (pa == NULL || pa->bOldProto || pa->bDynDisabled) + return; - if (p == acc) - ListBox_SetCurSel(hwndList, iItem); + pa->bIsEnabled = !pa->bIsEnabled; + if (pa->bIsEnabled) { + if (ActivateAccount(pa)) { + pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); + if (!db_get_b(NULL, "CList", "MoveProtoMenus", TRUE)) + pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); + } + } + else { + DWORD dwStatus = CallProtoServiceInt(NULL, pa->szModuleName, PS_GETSTATUS, 0, 0); + if (dwStatus >= ID_STATUS_ONLINE) { + wchar_t buf[200]; + mir_snwprintf(buf, TranslateT("Account %s is being disabled"), pa->tszAccountName); + if (IDNO == ::MessageBox(m_hwnd, TranslateT("Account is online. Disable account?"), buf, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO)) + pa->bIsEnabled = 1; // stay enabled } - dat->iSelected = ListBox_GetCurSel(hwndList); // -1 if error = > nothing selected in our case - if (dat->iSelected >= 0) - sttSelectItem(dat, hwndList, dat->iSelected); - else if (acc && acc->hwndAccMgrUI) - ShowWindow(acc->hwndAccMgrUI, SW_HIDE); + if (!pa->bIsEnabled) + DeactivateAccount(pa, true, false); } - sttUpdateAccountInfo(hwndDlg, dat); - break; - case WM_CONTEXTMENU: - if (GetWindowLongPtr((HWND)wParam, GWL_ID) == IDC_ACCLIST) { - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - int iItem = ListBox_GetCurSel(hwndList); - - if (pt.x == -1 && pt.y == -1) { - if (iItem != LB_ERR) { - RECT rc; - ListBox_GetItemRect(hwndList, iItem, &rc); - pt.x = rc.left + g_iIconSX + 4; - pt.y = rc.top + 4 + max(g_iIconSX, dat->titleHeight); - ClientToScreen(hwndList, &pt); - } - } - else { - // menu was activated with mouse = > find item under cursor & set focus to our control. - POINT ptItem = pt; - ScreenToClient(hwndList, &ptItem); - iItem = (short)LOWORD(SendMessage(hwndList, LB_ITEMFROMPOINT, 0, MAKELPARAM(ptItem.x, ptItem.y))); - if (iItem != LB_ERR) { - ListBox_SetCurSel(hwndList, iItem); - sttUpdateAccountInfo(hwndDlg, dat); - sttSelectItem(dat, hwndList, iItem); - SetFocus(hwndList); - } - } + WriteDbAccounts(); + NotifyEventHooks(hAccListChanged, PRAC_CHECKED, (LPARAM)pa); + UpdateAccountInfo(); + RedrawWindow(m_accList.GetHwnd(), NULL, NULL, RDW_INVALIDATE); + } - if (iItem != LB_ERR) { - pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, iItem); - HMENU hMenu = CreatePopupMenu(); - if (!pa->bOldProto && !pa->bDynDisabled) - AppendMenu(hMenu, MF_STRING, 1, TranslateT("Rename")); + void OnOk(CCtrlButton*) + { + PSHNOTIFY pshn; + pshn.hdr.idFrom = 0; + pshn.hdr.code = PSN_APPLY; + pshn.hdr.hwndFrom = m_hwnd; + SendMessage(m_hwnd, WM_NOTIFY, 0, (LPARAM)&pshn); + } - AppendMenu(hMenu, MF_STRING, 3, TranslateT("Delete")); + void OnCancel(CCtrlButton*) + { + PSHNOTIFY pshn; + pshn.hdr.idFrom = 0; + pshn.hdr.code = PSN_RESET; + pshn.hdr.hwndFrom = m_hwnd; + SendMessage(m_hwnd, WM_NOTIFY, 0, (LPARAM)&pshn); + } - if (Proto_IsAccountEnabled(pa)) - AppendMenu(hMenu, MF_STRING, 4, TranslateT("Configure")); + void OnAdd(CCtrlButton*) + { + AccFormDlgParam param = { PRAC_ADDED, NULL }; + if (IDOK == DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_ACCFORM), m_hwnd, AccFormDlgProc, (LPARAM)¶m)) + SendMessage(m_hwnd, WM_MY_REFRESH, 0, 0); + } - if (pa->bOldProto || pa->bDynDisabled) - AppendMenu(hMenu, MF_STRING, 5, TranslateT("Upgrade")); + void OnEdit(CCtrlButton*) + { + int idx = m_accList.GetCurSel(); + if (idx != -1) + m_accList.InitRename(); + } - switch (TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) { - case 1: - PostMessage(hwndList, WM_MY_RENAME, 0, 0); - break; + void OnNetwork(CCtrlButton*) + { + PSHNOTIFY pshn; + pshn.hdr.idFrom = 0; + pshn.hdr.code = PSN_APPLY; + pshn.hdr.hwndFrom = m_hwnd; + SendMessage(m_hwnd, WM_NOTIFY, 0, (LPARAM)&pshn); - case 2: - sttClickButton(hwndDlg, IDC_EDIT); - break; + Options_Open(L"Network"); + } - case 3: - sttClickButton(hwndDlg, IDC_REMOVE); - break; + void OnOptions(CCtrlButton*) + { + int idx = m_accList.GetCurSel(); + if (idx != -1) { + PROTOACCOUNT *pa = (PROTOACCOUNT*)m_accList.GetItemData(idx); + if (pa->bOldProto) + Options_Open(L"Network", _A2T(pa->szModuleName)); + else + OpenAccountOptions(pa); + } + } - case 4: - sttClickButton(hwndDlg, IDC_OPTIONS); - break; + void OnRemove(CCtrlButton*) + { + int idx = m_accList.GetCurSel(); + if (idx == -1) + return; - case 5: - sttClickButton(hwndDlg, IDC_UPGRADE); - break; - } - DestroyMenu(hMenu); - } + PROTOACCOUNT *pa = (PROTOACCOUNT*)m_accList.GetItemData(idx); + wchar_t buf[200]; + mir_snwprintf(buf, TranslateT("Account %s is being deleted"), pa->tszAccountName); + if (pa->bOldProto) { + MessageBox(m_hwnd, TranslateT("You need to disable plugin to delete this account"), buf, MB_ICONERROR | MB_OK); + return; } - break; + if (IDYES == MessageBox(m_hwnd, errMsg, buf, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO)) { + // lock controls to avoid changes during remove process + m_accList.SetCurSel(-1); + UpdateAccountInfo(); + m_accList.Disable(); + m_btnAdd.Disable(); - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_ACCLIST: - switch (HIWORD(wParam)) { - case LBN_SELCHANGE: - sttUpdateAccountInfo(hwndDlg, dat); - sttSelectItem(dat, hwndList, ListBox_GetCurSel(hwndList)); - SetFocus(hwndList); - break; + m_accList.SetItemData(idx, 0); - case LBN_DBLCLK: - PostMessage(hwndList, WM_MY_RENAME, 0, 0); - break; + accounts.remove(pa); - case LBN_MY_CHECK: - pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, lParam); - if (pa) { - if (pa->bOldProto || pa->bDynDisabled) - break; - - pa->bIsEnabled = !pa->bIsEnabled; - if (pa->bIsEnabled) { - if (ActivateAccount(pa)) { - pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); - if (!db_get_b(NULL, "CList", "MoveProtoMenus", TRUE)) - pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); - } - } - else { - DWORD dwStatus = CallProtoServiceInt(NULL, pa->szModuleName, PS_GETSTATUS, 0, 0); - if (dwStatus >= ID_STATUS_ONLINE) { - wchar_t buf[200]; - mir_snwprintf(buf, TranslateT("Account %s is being disabled"), pa->tszAccountName); - if (IDNO == ::MessageBox(hwndDlg, - TranslateT("Account is online. Disable account?"), - buf, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO)) { - pa->bIsEnabled = 1; //stay enabled - } - } - - if (!pa->bIsEnabled) - DeactivateAccount(pa, true, false); - } + CheckProtocolOrder(); - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, PRAC_CHECKED, (LPARAM)pa); - sttUpdateAccountInfo(hwndDlg, dat); - RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); - } - break; + WriteDbAccounts(); + NotifyEventHooks(hAccListChanged, PRAC_REMOVED, (LPARAM)pa); - case LBN_MY_RENAME: - int iItem = ListBox_GetCurSel(hwndList); - pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, iItem); - if (pa) { - mir_free(pa->tszAccountName); - pa->tszAccountName = (wchar_t*)lParam; - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, PRAC_CHANGED, (LPARAM)pa); + UnloadAccount(pa, true, true); + SendMessage(m_hwnd, WM_MY_REFRESH, 0, 0); - ListBox_DeleteString(hwndList, iItem); - iItem = ListBox_AddString(hwndList, pa->tszAccountName); - ListBox_SetItemData(hwndList, iItem, (LPARAM)pa); - ListBox_SetCurSel(hwndList, iItem); + m_accList.Enable(); + m_btnAdd.Enable(); + } + } - sttSelectItem(dat, hwndList, iItem); + void OnUpgrade(CCtrlButton*) + { + int idx = m_accList.GetCurSel(); + if (idx != -1) { + AccFormDlgParam param = { PRAC_UPGRADED, (PROTOACCOUNT*)m_accList.GetItemData(idx) }; + DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_ACCFORM), m_hwnd, AccFormDlgProc, (LPARAM)¶m); + } + } - RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); - } - else mir_free((wchar_t*)lParam); + virtual LRESULT DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override + { + switch (msg) { + case WM_CTLCOLORSTATIC: + switch (GetDlgCtrlID((HWND)lParam)) { + case IDC_WHITERECT: + case IDC_NAME: + SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); + return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); } break; - case IDC_ADD: + case WM_MY_REFRESH: + m_iSelected = -1; { - AccFormDlgParam param = { PRAC_ADDED, NULL }; - if (IDOK == DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_ACCFORM), hwndDlg, AccFormDlgProc, (LPARAM)¶m)) - SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); + int i = m_accList.GetCurSel(); + PROTOACCOUNT *acc = (i == LB_ERR) ? NULL : (PROTOACCOUNT *)m_accList.GetItemData(i); + + m_accList.ResetContent(); + for (i = 0; i < accounts.getCount(); i++) { + PROTOACCOUNT *p = accounts[i]; + PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(p->szProtoName); + if (pd != NULL && pd->type != PROTOTYPE_PROTOCOL) + continue; + + int iItem = m_accList.AddString(p->tszAccountName); + m_accList.SetItemData(iItem, (LPARAM)p); + + if (p == acc) + m_accList.SetCurSel(iItem); + } + + m_iSelected = m_accList.GetCurSel(); // -1 if error = > nothing selected in our case + if (m_iSelected >= 0) + SelectItem(m_iSelected); + else if (acc && acc->hwndAccMgrUI) + ShowWindow(acc->hwndAccMgrUI, SW_HIDE); } + UpdateAccountInfo(); break; - case IDC_EDIT: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) - PostMessage(hwndList, WM_MY_RENAME, 0, 0); + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_ACCLIST: + switch (HIWORD(wParam)) { + case LBN_MY_RENAME: + int iItem = m_accList.GetCurSel(); + PROTOACCOUNT *pa = (PROTOACCOUNT *)m_accList.GetItemData(iItem); + if (pa) { + mir_free(pa->tszAccountName); + pa->tszAccountName = (wchar_t*)lParam; + WriteDbAccounts(); + NotifyEventHooks(hAccListChanged, PRAC_CHANGED, (LPARAM)pa); + + m_accList.DeleteString(iItem); + iItem = m_accList.AddString(pa->tszAccountName, (LPARAM)pa); + m_accList.SetCurSel(iItem); + + SelectItem(iItem); + RedrawWindow(m_accList.GetHwnd(), NULL, NULL, RDW_INVALIDATE); + } + else mir_free((wchar_t*)lParam); + } + break; + + case IDC_LNK_ADDONS: + Utils_OpenUrl("http://miranda-ng.org/"); + break; + } break; - case IDC_REMOVE: - idx = ListBox_GetCurSel(hwndList); + case PSM_CHANGED: + int idx = m_accList.GetCurSel(); if (idx != -1) { - pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, idx); - wchar_t buf[200]; - mir_snwprintf(buf, TranslateT("Account %s is being deleted"), pa->tszAccountName); - if (pa->bOldProto) { - MessageBox(hwndDlg, TranslateT("You need to disable plugin to delete this account"), buf, MB_ICONERROR | MB_OK); - break; + PROTOACCOUNT *pa = (PROTOACCOUNT *)m_accList.GetItemData(idx); + if (pa) { + pa->bAccMgrUIChanged = TRUE; + SendMessage(GetParent(m_hwnd), PSM_CHANGED, 0, 0); } - if (IDYES == MessageBox(hwndDlg, errMsg, buf, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO)) { - // lock controls to avoid changes during remove process - ListBox_SetCurSel(hwndList, -1); - sttUpdateAccountInfo(hwndDlg, dat); - EnableWindow(hwndList, FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); + } + break; + } - ListBox_SetItemData(hwndList, idx, 0); + return CDlgBase::DlgProc(msg, wParam, lParam); + } +}; - accounts.remove(pa); +///////////////////////////////////////////////////////////////////////////////////////// - CheckProtocolOrder(); +BOOL CAccountListCtrl::OnDrawItem(DRAWITEMSTRUCT *lps) +{ + HBRUSH hbrBack; + SIZE sz; - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, PRAC_REMOVED, (LPARAM)pa); + int cxIcon = g_iIconSX; + int cyIcon = g_iIconSY; - UnloadAccount(pa, true, true); - SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); + PROTOACCOUNT *acc = (PROTOACCOUNT *)lps->itemData; + if (lps->itemID == -1 || acc == NULL) + return FALSE; - EnableWindow(hwndList, TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), TRUE); - } - } - break; + SetBkMode(lps->hDC, TRANSPARENT); + if (lps->itemState & ODS_SELECTED) { + hbrBack = GetSysColorBrush(COLOR_HIGHLIGHT); + SetTextColor(lps->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); + } + else { + hbrBack = GetSysColorBrush(COLOR_WINDOW); + SetTextColor(lps->hDC, GetSysColor(COLOR_WINDOWTEXT)); + } + FillRect(lps->hDC, &lps->rcItem, hbrBack); + + lps->rcItem.left += 2; + lps->rcItem.top += 2; + lps->rcItem.bottom -= 2; + + int tmp; + if (acc->bOldProto) + tmp = SKINICON_OTHER_ON; + else if (acc->bDynDisabled) + tmp = SKINICON_OTHER_OFF; + else + tmp = acc->bIsEnabled ? SKINICON_OTHER_TICK : SKINICON_OTHER_NOTICK; + + HICON hIcon = Skin_LoadIcon(tmp); + DrawIconEx(lps->hDC, lps->rcItem.left, lps->rcItem.top, hIcon, cxIcon, cyIcon, 0, hbrBack, DI_NORMAL); + IcoLib_ReleaseIcon(hIcon); + + lps->rcItem.left += cxIcon + 2; + + if (acc->ppro) { + hIcon = IcoLib_GetIconByHandle(acc->ppro->m_hProtoIcon); + DrawIconEx(lps->hDC, lps->rcItem.left, lps->rcItem.top, hIcon, cxIcon, cyIcon, 0, hbrBack, DI_NORMAL); + IcoLib_ReleaseIcon(hIcon); + } + lps->rcItem.left += cxIcon + 2; + { + ptrW text(GetItemText(lps->itemID)); + size_t length = mir_wstrlen(text); + + SelectObject(lps->hDC, PARENT()->m_hfntTitle); + tmp = lps->rcItem.bottom; + lps->rcItem.bottom = lps->rcItem.top + max(cyIcon, PARENT()->m_titleHeight); + DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS | DT_VCENTER); + lps->rcItem.bottom = tmp; + GetTextExtentPoint32(lps->hDC, text, (int)length, &sz); + lps->rcItem.top += max(cxIcon, sz.cy) + 2; + } - case IDC_OPTIONS: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) { - pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, idx); - if (pa->bOldProto) - Options_Open(L"Network", _A2T(pa->szModuleName)); - else - OpenAccountOptions(pa); - } - break; + if (lps->itemID == (unsigned)PARENT()->m_iSelected) { + SelectObject(lps->hDC, PARENT()->m_hfntText); - case IDC_UPGRADE: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) { - AccFormDlgParam param = { PRAC_UPGRADED, (PROTOACCOUNT*)ListBox_GetItemData(hwndList, idx) }; - DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_ACCFORM), hwndDlg, AccFormDlgProc, (LPARAM)¶m); - } - break; + CMStringW text(FORMAT, L"%s: %S", TranslateT("Protocol"), acc->szProtoName); + DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS); + GetTextExtentPoint32(lps->hDC, text, text.GetLength(), &sz); + lps->rcItem.top += sz.cy + 2; - case IDC_LNK_NETWORK: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_APPLY; - pshn.hdr.hwndFrom = hwndDlg; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn); + if (acc->ppro && Proto_IsProtocolLoaded(acc->szProtoName)) { + char *szIdName = (char *)acc->ppro->GetCaps(PFLAG_UNIQUEIDTEXT, 0); + ptrW tszIdName(szIdName ? mir_a2u(szIdName) : mir_wstrdup(TranslateT("Account ID"))); + ptrW tszUniqueID(Contact_GetInfo(CNF_UNIQUEID, NULL, acc->szModuleName)); + if (tszUniqueID != NULL) + text.Format(L"%s: %s", tszIdName, tszUniqueID); + else + text.Format(L"%s: %s", tszIdName, TranslateT("")); + } + else text.Format(TranslateT("Protocol is not loaded.")); - Options_Open(L"Network"); - break; + DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS); + GetTextExtentPoint32(lps->hDC, text, text.GetLength(), &sz); + lps->rcItem.top += sz.cy + 2; + } - case IDC_LNK_ADDONS: - Utils_OpenUrl("http://miranda-ng.org/"); - break; + return TRUE; +} - case IDOK: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_APPLY; - pshn.hdr.hwndFrom = hwndDlg; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn); - DestroyWindow(hwndDlg); - break; +BOOL CAccountListCtrl::OnMeasureItem(MEASUREITEMSTRUCT *lps) +{ + PROTOACCOUNT *acc = (PROTOACCOUNT*)lps->itemData; + if (acc == NULL) + return FALSE; - case IDCANCEL: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_RESET; - pshn.hdr.hwndFrom = hwndDlg; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn); - DestroyWindow(hwndDlg); - break; + lps->itemWidth = 10; + lps->itemHeight = PARENT()->m_normalHeight; + return TRUE; +} + +LRESULT CAccountListCtrl::CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_LBUTTONDOWN: + { + POINT pt = { LOWORD(lParam), HIWORD(lParam) }; + int iItem = LOWORD(SendMessage(m_hwnd, LB_ITEMFROMPOINT, 0, lParam)); + GetItemRect(iItem, &m_rcCheck); + + m_rcCheck.right = m_rcCheck.left + g_iIconSX + 4; + m_rcCheck.bottom = m_rcCheck.top + g_iIconSY + 4; + if (PtInRect(&m_rcCheck, pt)) + m_iItem = iItem; + else + m_iItem = -1; } break; - case PSM_CHANGED: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) { - pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, idx); - if (pa) { - pa->bAccMgrUIChanged = TRUE; - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } + case WM_LBUTTONUP: + { + POINT pt = { LOWORD(lParam), HIWORD(lParam) }; + if ((m_iItem >= 0) && PtInRect(&m_rcCheck, pt)) + PARENT()->OnAccountCheck(m_iItem); + m_iItem = -1; } break; - case WM_NOTIFY: - if (((LPNMHDR)lParam)->idFrom == 0) { - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_APPLY; - for (int i = 0; i < accounts.getCount(); i++) { - pa = accounts[i]; - if (pa->hwndAccMgrUI && pa->bAccMgrUIChanged) { - pshn.hdr.hwndFrom = pa->hwndAccMgrUI; - SendMessage(pa->hwndAccMgrUI, WM_NOTIFY, 0, (LPARAM)&pshn); - pa->bAccMgrUIChanged = FALSE; - } - } - return TRUE; - - case PSN_RESET: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_RESET; - for (int i = 0; i < accounts.getCount(); i++) { - pa = accounts[i]; - if (pa->hwndAccMgrUI && pa->bAccMgrUIChanged) { - pshn.hdr.hwndFrom = pa->hwndAccMgrUI; - SendMessage(pa->hwndAccMgrUI, WM_NOTIFY, 0, (LPARAM)&pshn); - pa->bAccMgrUIChanged = FALSE; - } - } - return TRUE; - } + case WM_CHAR: + if (wParam == ' ') { + int iItem = GetCurSel(); + if (iItem >= 0) + PARENT()->OnAccountCheck(m_iItem); + return 0; } + + if (wParam == 10 /* enter */) + return 0; + break; - case WM_DESTROY: - for (int i = 0; i < accounts.getCount(); i++) { - pa = accounts[i]; - pa->bAccMgrUIChanged = FALSE; - if (pa->hwndAccMgrUI) { - DestroyWindow(pa->hwndAccMgrUI); - pa->hwndAccMgrUI = NULL; - } + case WM_GETDLGCODE: + if (wParam == VK_RETURN) + return DLGC_WANTMESSAGE; + break; + + case WM_KEYDOWN: + switch (wParam) { + case VK_F2: + InitRename(); + return 0; + + case VK_INSERT: + PARENT()->ClickButton(PARENT()->m_btnAdd); + return 0; + + case VK_DELETE: + PARENT()->ClickButton(PARENT()->m_btnRemove); + return 0; + + case VK_RETURN: + if (GetAsyncKeyState(VK_CONTROL)) + PARENT()->ClickButton(PARENT()->m_btnEdit); + else + PARENT()->ClickButton(PARENT()->m_btnOk); + return 0; + } + break; + } + + return CCtrlListBox::CustomWndProc(msg, wParam, lParam); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static LRESULT CALLBACK sttEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_KEYDOWN: + switch (wParam) { + case VK_RETURN: + DestroyWindow(hwnd); + return 0; + + case VK_ESCAPE: + SetWindowLongPtr(hwnd, GWLP_WNDPROC, GetWindowLongPtr(hwnd, GWLP_USERDATA)); + DestroyWindow(hwnd); + return 0; } + break; - Window_FreeIcon_IcoLib(hwndDlg); - Button_FreeIcon_IcoLib(hwndDlg, IDC_ADD); - Button_FreeIcon_IcoLib(hwndDlg, IDC_EDIT); - Button_FreeIcon_IcoLib(hwndDlg, IDC_REMOVE); - Button_FreeIcon_IcoLib(hwndDlg, IDC_OPTIONS); - Button_FreeIcon_IcoLib(hwndDlg, IDC_UPGRADE); - Utils_SaveWindowPosition(hwndDlg, NULL, "AccMgr", ""); - sttSubclassAccList(GetDlgItem(hwndDlg, IDC_ACCLIST), FALSE); - DeleteObject(dat->hfntTitle); - DeleteObject(dat->hfntText); - mir_free(dat); - hAccMgr = NULL; + case WM_GETDLGCODE: + if (wParam == VK_RETURN || wParam == VK_ESCAPE) + return DLGC_WANTMESSAGE; break; + + case WM_KILLFOCUS: + int length = GetWindowTextLength(hwnd) + 1; + wchar_t *str = (wchar_t*)mir_alloc(sizeof(wchar_t) * length); + GetWindowText(hwnd, str, length); + SendMessage(GetParent(GetParent(hwnd)), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(GetParent(hwnd), GWL_ID), LBN_MY_RENAME), (LPARAM)str); + DestroyWindow(hwnd); + return 0; } + return mir_callNextSubclass(hwnd, sttEditSubclassProc, msg, wParam, lParam); +} - return FALSE; +void CAccountListCtrl::InitRename() +{ + PROTOACCOUNT *pa = (PROTOACCOUNT *)GetItemData(GetCurSel()); + if (!pa || pa->bOldProto || pa->bDynDisabled) + return; + + RECT rc; + GetItemRect(GetCurSel(), &rc); + rc.left += 2 * g_iIconSX + 4; + rc.bottom = rc.top + max(g_iIconSX, PARENT()->m_titleHeight) + 4 - 1; + ++rc.top; --rc.right; + + m_hwndEdit = ::CreateWindow(L"EDIT", pa->tszAccountName, WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, m_hwnd, NULL, g_hInst, NULL); + mir_subclassWindow(m_hwndEdit, sttEditSubclassProc); + SendMessage(m_hwndEdit, WM_SETFONT, (WPARAM)PARENT()->m_hfntTitle, 0); + SendMessage(m_hwndEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN | EC_USEFONTINFO, 0); + SendMessage(m_hwndEdit, EM_SETSEL, 0, -1); + ShowWindow(m_hwndEdit, SW_SHOW); + SetFocus(m_hwndEdit); } +///////////////////////////////////////////////////////////////////////////////////////// + static INT_PTR OptProtosShow(WPARAM, LPARAM) { - if (!hAccMgr) - hAccMgr = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_ACCMGR), NULL, AccMgrDlgProc, 0); + if (!pAccMgr) + pAccMgr = new CAccountManagerDlg(); - ShowWindow(hAccMgr, SW_RESTORE); - SetForegroundWindow(hAccMgr); - SetActiveWindow(hAccMgr); + pAccMgr->Show(SW_RESTORE); + SetForegroundWindow(pAccMgr->GetHwnd()); + SetActiveWindow(pAccMgr->GetHwnd()); return 0; } @@ -1025,9 +1038,7 @@ static int OnAccListChanged(WPARAM eventCode, LPARAM lParam) static int ShutdownAccMgr(WPARAM, LPARAM) { - if (IsWindow(hAccMgr)) - DestroyWindow(hAccMgr); - hAccMgr = NULL; + delete pAccMgr; pAccMgr = NULL; return 0; } -- cgit v1.2.3