diff options
-rw-r--r-- | plugins/MirOTR/res/resource.rc | 14 | ||||
-rw-r--r-- | plugins/MirOTR/src/options.cpp | 697 | ||||
-rw-r--r-- | plugins/MirOTR/src/options.h | 4 | ||||
-rw-r--r-- | plugins/MirOTR/src/resource.h | 5 |
4 files changed, 364 insertions, 356 deletions
diff --git a/plugins/MirOTR/res/resource.rc b/plugins/MirOTR/res/resource.rc index b6b419e54d..978c792500 100644 --- a/plugins/MirOTR/res/resource.rc +++ b/plugins/MirOTR/res/resource.rc @@ -85,8 +85,6 @@ BEGIN CONTROL "",IDC_LV_PROTO_PROTOS,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP,0,18,296,170
LTEXT "Current policy:",IDC_STC_PROTO2,3,193,152,9,SS_NOPREFIX | NOT WS_GROUP
COMBOBOX IDC_CMB_PROTO_POLICY,3,206,152,12,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_TABSTOP
- PUSHBUTTON "Generate new private key",IDC_BTN_PROTO_NEWKEY,162,192,123,14
- PUSHBUTTON "Forget private key",IDC_BTN_PROTO_FORGET,162,208,123,14
END
IDD_OPT_CONTACTS DIALOGEX 0, 0, 296, 223
@@ -174,6 +172,18 @@ BEGIN END
END
+IDR_OPT_ACCOUNT MENU
+BEGIN
+ POPUP ""
+ BEGIN
+ MENUITEM "Generate new private key", IDM_OPT_PROTO_NEWKEY
+ MENUITEM SEPARATOR
+ MENUITEM "Copy", IDM_OPT_COPY
+ MENUITEM SEPARATOR
+ MENUITEM "Forget private key", IDM_OPT_PROTO_FORGET
+ END
+END
+
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
diff --git a/plugins/MirOTR/src/options.cpp b/plugins/MirOTR/src/options.cpp index 7881bd4348..da607a301f 100644 --- a/plugins/MirOTR/src/options.cpp +++ b/plugins/MirOTR/src/options.cpp @@ -10,13 +10,6 @@ HANDLE hPATH_MIROTR; Options options; #define DATA_DIRECTORY MIRANDA_USERDATAW L"\\" _A2W(MODULENAME) -struct PROTOREGENKEYOPTIONS -{ - HWND refresh; - char *szProto; - wchar_t wszTitle[129]; -}; - void SetFilenames(const wchar_t *path) { if (!path || !path[0]) @@ -232,6 +225,18 @@ static INT_PTR CALLBACK DlgProcMirOTROpts(HWND hwndDlg, UINT msg, WPARAM wParam, return FALSE; } +///////////////////////////////////////////////////////////////////////////////////////// +// Account tab + +#define WMU_REFRESHPROTOLIST (WM_USER + 0x100) + +struct PROTOREGENKEYOPTIONS +{ + HWND refresh; + char *szProto; + wchar_t wszTitle[129]; +}; + static unsigned int CALLBACK regen_key_thread(void* param) { Thread_Push(nullptr); @@ -242,7 +247,7 @@ static unsigned int CALLBACK regen_key_thread(void* param) EnableWindow(opts->refresh, FALSE); if (IDYES == MessageBox(opts->refresh, buff, TranslateT(LANG_OTR_INFO), MB_ICONQUESTION|MB_YESNO)) { otr_gui_create_privkey(nullptr, opts->szProto, opts->szProto); - SendMessage(opts->refresh, WMU_REFRESHPROTOLIST, 0, 0); + PostMessage(opts->refresh, WMU_REFRESHPROTOLIST, 0, 0); } EnableWindow(opts->refresh, TRUE); delete opts; @@ -250,381 +255,385 @@ static unsigned int CALLBACK regen_key_thread(void* param) return 0; } -static char* GetProtoName(HWND hwndList, int iItem) +class CAccountOptionsDlg : public CDlgBase { - LV_ITEM item; - item.iItem = iItem; - item.mask = LVIF_PARAM; - return (ListView_GetItem(hwndList, &item) == -1) ? nullptr : (char*)item.lParam; -} + bool bMenuEnable = false; + CCtrlListView m_list; + CCtrlCombo cmbPolicy; -static void ChangeContactSetting(HWND hwndDlg, int iItem, bool changeHtml) -{ - if (iItem < 0) - return; + char* GetProtoName(int iItem) + { + LV_ITEM item; + item.iItem = iItem; + item.mask = LVIF_PARAM; + return (!m_list.GetItem(&item)) ? nullptr : (char *)item.lParam; + } - LVITEM lvi = { 0 }; - lvi.mask = LVIF_PARAM; - lvi.iItem = iItem; - lvi.iSubItem = 0; - - ListView_GetItem(GetDlgItem(hwndDlg, IDC_LV_CONT_CONTACTS), &lvi); + void RefreshList() + { + m_list.DeleteAllItems(); - ContactPolicyMap* cpm = (ContactPolicyMap*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - MCONTACT hContact = (MCONTACT)lvi.lParam; + LV_ITEM item = { 0 }; - // Handle HtmlConv - { - wchar_t buff[50]; - ListView_GetItemText(GetDlgItem(hwndDlg, IDC_LV_CONT_CONTACTS), lvi.iItem, 3, buff, _countof(buff)); + for (auto &pa : Accounts()) { + if (!mir_strcmp(pa->szModuleName, META_PROTO)) + continue; + if ((CallProtoService(pa->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IM) == 0) + continue; - bool htmlEnabled = !wcsncmp(buff, TranslateW(LANG_YES), 50); - if (changeHtml) { - htmlEnabled = !htmlEnabled; + item.mask = LVIF_TEXT | LVIF_PARAM; + item.pszText = pa->tszAccountName; + item.lParam = (LPARAM)pa->szModuleName; + int ilvItem = m_list.InsertItem(&item); + + m_list.SetItemText(ilvItem, 1, (wchar_t *)policy_to_string(db_get_dw(0, MODULENAME"_ProtoPol", pa->szModuleName, CONTACT_DEFAULT_POLICY))); + + char fprint[45]; + if (otrl_privkey_fingerprint(otr_user_state, fprint, pa->szModuleName, pa->szModuleName)) + m_list.SetItemText(ilvItem, 2, _A2T(fprint)); } + } - // Update wanted state - (*cpm)[hContact].htmlconv = htmlEnabled ? HTMLCONV_ENABLE : HTMLCONV_DISABLE; - ListView_SetItemText(GetDlgItem(hwndDlg, IDC_LV_CONT_CONTACTS), lvi.iItem, 3, TranslateW(htmlEnabled ? LANG_YES : LANG_NO)); +public: + CAccountOptionsDlg() : + CDlgBase(g_plugin, IDD_OPT_PROTO), + m_list(this, IDC_LV_PROTO_PROTOS), + cmbPolicy(this, IDC_CMB_PROTO_POLICY) + { + cmbPolicy.OnSelChanged = Callback(this, &CAccountOptionsDlg::onSelChanged_Combo); + + m_list.OnBuildMenu = Callback(this, &CAccountOptionsDlg::onContextMenu_List); + m_list.OnItemChanged = Callback(this, &CAccountOptionsDlg::onItemChanged_List); } - - // Handle Policy + + bool OnInitDialog() override { - OtrlPolicy policy = CONTACT_DEFAULT_POLICY; + cmbPolicy.AddString(TranslateW(LANG_POLICY_DEFAULT)); + cmbPolicy.AddString(TranslateW(LANG_POLICY_ALWAYS)); + cmbPolicy.AddString(TranslateW(LANG_POLICY_OPP)); + cmbPolicy.AddString(TranslateW(LANG_POLICY_MANUAL)); + cmbPolicy.AddString(TranslateW(LANG_POLICY_NEVER)); + cmbPolicy.SetCurSel(-1); + cmbPolicy.Disable(); - int sel = SendDlgItemMessage(hwndDlg, IDC_CMB_CONT_POLICY, CB_GETCURSEL, 0, 0); - if (sel != CB_ERR) { - int len = SendDlgItemMessage(hwndDlg, IDC_CMB_CONT_POLICY, CB_GETLBTEXTLEN, sel, 0); - if (len >= 0) { - wchar_t *text = new wchar_t[len + 1]; - SendDlgItemMessage(hwndDlg, IDC_CMB_CONT_POLICY, CB_GETLBTEXT, sel, (LPARAM)text); - ListView_SetItemText(GetDlgItem(hwndDlg, IDC_LV_CONT_CONTACTS), iItem, 2, text); - policy = policy_from_string(text); - delete[] text; - } - } + m_list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); - (*cpm)[hContact].policy = policy; - } + // add list columns + LVCOLUMN lvc; + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + lvc.fmt = LVCFMT_LEFT; - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); -} + lvc.iSubItem = 0; + lvc.pszText = TranslateW(LANG_PROTO); + lvc.cx = 85; // width of column in pixels + m_list.InsertColumn(0, &lvc); -static INT_PTR CALLBACK DlgProcMirOTROptsProto(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HWND hwndList = GetDlgItem(hwndDlg, IDC_LV_PROTO_PROTOS); - int sel; + lvc.iSubItem = 1; + lvc.pszText = TranslateW(LANG_POLICY); + lvc.cx = 80; // width of column in pixels + m_list.InsertColumn(1, &lvc); - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - { - HWND cmb = GetDlgItem(hwndDlg, IDC_CMB_PROTO_POLICY); - SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateW(LANG_POLICY_DEFAULT)); - SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateW(LANG_POLICY_ALWAYS)); - SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateW(LANG_POLICY_OPP)); - SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateW(LANG_POLICY_MANUAL)); - SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateW(LANG_POLICY_NEVER)); - SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_SETCURSEL, (LPARAM)-1, 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_PROTO_POLICY), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_NEWKEY), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_FORGET), FALSE); - } + lvc.iSubItem = 2; + lvc.pszText = TranslateW(LANG_FINGERPRINT); + lvc.cx = 275; // width of column in pixels + m_list.InsertColumn(2, &lvc); + + RefreshList(); + return true; + } + + bool OnApply() override + { + int cnt = m_list.GetItemCount(); + wchar_t policy[64]; + for (int i = 0; i < cnt; ++i) { + char *proto = GetProtoName(i); + if (proto == nullptr) + continue; - SendMessage(hwndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);// | LVS_EX_CHECKBOXES); - { - // add list columns - LVCOLUMN lvc; - // Initialize the LVCOLUMN structure. - // The mask specifies that the format, width, text, and - // subitem members of the structure are valid. - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - lvc.fmt = LVCFMT_LEFT; - - lvc.iSubItem = 0; - lvc.pszText = TranslateW(LANG_PROTO); - lvc.cx = 85; // width of column in pixels - ListView_InsertColumn(hwndList, 0, &lvc); - - lvc.iSubItem = 1; - lvc.pszText = TranslateW(LANG_POLICY); - lvc.cx = 80; // width of column in pixels - ListView_InsertColumn(hwndList, 1, &lvc); - - lvc.iSubItem = 2; - lvc.pszText = TranslateW(LANG_FINGERPRINT); - lvc.cx = 275; // width of column in pixels - ListView_InsertColumn(hwndList, 2, &lvc); + m_list.GetItemText(i, 1, policy, _countof(policy)); + db_set_dw(0, MODULENAME"_ProtoPol", proto, policy_from_string(policy)); } - PostMessage(hwndDlg, WMU_REFRESHPROTOLIST, 0, 0); - return TRUE; + return true; + } + + UI_MESSAGE_MAP(CAccountOptionsDlg, CDlgBase); case WMU_REFRESHPROTOLIST: - ListView_DeleteAllItems(hwndList); - { - LV_ITEM item = { 0 }; + RefreshList(); + break; + UI_MESSAGE_MAP_END(); - for (auto &pa : Accounts()) { - if (!mir_strcmp(pa->szModuleName, META_PROTO)) - continue; - if ((CallProtoService(pa->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IM) == 0) - continue; + void onSelChanged_Combo(CCtrlCombo *) + { + int proto = m_list.GetSelectionMark(); + if (proto == -1) return; + + int sel = cmbPolicy.GetCurSel(); + if (sel == CB_ERR) return; + + size_t len = cmbPolicy.SendMsg(CB_GETLBTEXTLEN, sel, 0); + if (len < 0) return; + + wchar_t *text = new wchar_t[len + 1]; + cmbPolicy.SendMsg(CB_GETLBTEXT, sel, (LPARAM)text); + m_list.SetItemText(proto, 1, text); + delete[] text; + NotifyChange(); + } - item.mask = LVIF_TEXT | LVIF_PARAM; - item.pszText = pa->tszAccountName; - item.lParam = (LPARAM)pa->szModuleName; - int ilvItem = ListView_InsertItem(hwndList, &item); + void onContextMenu_List(CCtrlListView *) + { + int sel = m_list.GetSelectionMark(); + if (sel == -1) + return; + + POINT pt; + GetCursorPos(&pt); + char *proto = GetProtoName(sel); - ListView_SetItemText(hwndList, ilvItem, 1, (wchar_t*)policy_to_string(db_get_dw(0, MODULENAME"_ProtoPol", pa->szModuleName, CONTACT_DEFAULT_POLICY))); + HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_OPT_ACCOUNT)); + TranslateMenu(hMenu); - char fprint[45]; - if (otrl_privkey_fingerprint(otr_user_state, fprint, pa->szModuleName, pa->szModuleName)) { - wchar_t *temp = mir_a2u(fprint); - ListView_SetItemText(hwndList, ilvItem, 2, temp); - mir_free(temp); - } + switch (TrackPopupMenu(GetSubMenu(hMenu, 0), TPM_RETURNCMD, pt.x, pt.y, 0, m_hwnd, 0)) { + case IDM_OPT_PROTO_NEWKEY: + { + PROTOREGENKEYOPTIONS *opts = new PROTOREGENKEYOPTIONS(); + opts->refresh = m_hwnd; + opts->szProto = GetProtoName(sel); + m_list.GetItemText(sel, 0, opts->wszTitle, _countof(opts->wszTitle)); + CloseHandle((HANDLE)_beginthreadex(nullptr, 0, regen_key_thread, opts, 0, nullptr)); } - } - return TRUE; + break; - case WM_COMMAND: - switch (HIWORD(wParam)) { - case BN_CLICKED: - switch (LOWORD(wParam)) { - case IDC_BTN_PROTO_NEWKEY: - sel = ListView_GetSelectionMark(hwndList); - if (sel != -1) { - PROTOREGENKEYOPTIONS *opts = new PROTOREGENKEYOPTIONS(); - opts->refresh = hwndDlg; - opts->szProto = GetProtoName(hwndList, sel); - ListView_GetItemText(hwndList, sel, 0, opts->wszTitle, _countof(opts->wszTitle)); - CloseHandle((HANDLE)_beginthreadex(nullptr, 0, regen_key_thread, opts, 0, nullptr)); - } - break; - - case IDC_BTN_PROTO_FORGET: - sel = ListView_GetSelectionMark(hwndList); - if (sel != -1) { - wchar_t buff_proto[128]; - ListView_GetItemText(hwndList, sel, 0, buff_proto, _countof(buff_proto)); - wchar_t buff[512]; - mir_snwprintf(buff, TranslateW(LANG_OTR_ASK_REMOVEKEY), buff_proto); - if (IDYES == MessageBox(hwndDlg, buff, TranslateT(LANG_OTR_INFO), MB_ICONQUESTION | MB_YESNO)) { - char *proto = GetProtoName(hwndList, sel); - if (proto == nullptr) - break; - - OtrlPrivKey *key = otrl_privkey_find(otr_user_state, proto, proto); - if (key) { - otrl_privkey_forget(key); - otrl_privkey_write(otr_user_state, g_private_key_filename); - ListView_SetItemText(hwndList, sel, 2, L""); - } - } - } + case IDM_OPT_COPY: + if (proto) { + char fprint[45]; + if (otrl_privkey_fingerprint(otr_user_state, fprint, proto, proto)) + CopyToClipboard(_A2T(fprint)); } break; - case CBN_SELCHANGE: - switch (LOWORD(wParam)) { - case IDC_CMB_PROTO_POLICY: - int proto = ListView_GetSelectionMark(hwndList); - if (proto == -1) break; - sel = SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_GETCURSEL, 0, 0); - if (sel == CB_ERR) break; - int len = SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_GETLBTEXTLEN, sel, 0); - if (len < 0) break; - wchar_t *text = new wchar_t[len + 1]; - SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_GETLBTEXT, sel, (LPARAM)text); - ListView_SetItemText(hwndList, proto, 1, text); - delete[] text; - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + case IDM_OPT_PROTO_FORGET: + wchar_t buff_proto[128]; + m_list.GetItemText(sel, 0, buff_proto, _countof(buff_proto)); + + wchar_t buff[512]; + mir_snwprintf(buff, TranslateW(LANG_OTR_ASK_REMOVEKEY), buff_proto); + if (IDYES == MessageBox(m_hwnd, buff, TranslateT(LANG_OTR_INFO), MB_ICONQUESTION | MB_YESNO)) { + if (proto == nullptr) + break; + + OtrlPrivKey *key = otrl_privkey_find(otr_user_state, proto, proto); + if (key) { + otrl_privkey_forget(key); + otrl_privkey_write(otr_user_state, g_private_key_filename); + m_list.SetItemText(sel, 2, L""); + } } break; } - break; - case WM_NOTIFY: - if (((LPNMHDR)lParam)->code == LVN_ITEMCHANGED && ((LPNMHDR)lParam)->hwndFrom == hwndList) { - LPNMLISTVIEW notif = (LPNMLISTVIEW)lParam; - if ((notif->uNewState & LVIS_SELECTED) == 0) - break; + DestroyMenu(hMenu); + } - if (notif->iItem == -1) { - SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_SETCURSEL, (LPARAM)-1, 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_PROTO_POLICY), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_NEWKEY), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_FORGET), FALSE); - } - else { - EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_PROTO_POLICY), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_NEWKEY), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_PROTO_FORGET), TRUE); - wchar_t buff[50]; - ListView_GetItemText(((LPNMHDR)lParam)->hwndFrom, notif->iItem, 1, buff, _countof(buff)); - SendDlgItemMessage(hwndDlg, IDC_CMB_PROTO_POLICY, CB_SELECTSTRING, (LPARAM)-1, (WPARAM)buff); - } + void onItemChanged_List(CCtrlListView::TEventInfo *ev) + { + LPNMLISTVIEW notif = ev->nmlv; + if ((notif->uNewState & LVIS_SELECTED) == 0) + return; + + if (notif->iItem == -1) { + cmbPolicy.SetCurSel(-1); + cmbPolicy.Disable(); + bMenuEnable = false; } - else if (((LPNMHDR)lParam)->code == PSN_APPLY) { - int cnt = ListView_GetItemCount(hwndList); - wchar_t policy[64]; - for (int i = 0; i < cnt; ++i) { - char *proto = GetProtoName(hwndList, i); - if (proto == nullptr) - continue; + else { + cmbPolicy.Enable(); + bMenuEnable = true; - ListView_GetItemText(hwndList, i, 1, policy, _countof(policy)); - db_set_dw(0, MODULENAME"_ProtoPol", proto, policy_from_string(policy)); - } - // handle apply - return TRUE; + wchar_t buff[50]; + m_list.GetItemText(notif->iItem, 1, buff, _countof(buff)); + cmbPolicy.SelectString(buff); } - break; } - return FALSE; -} +}; + +///////////////////////////////////////////////////////////////////////////////////////// +// Contacts tab -static INT_PTR CALLBACK DlgProcMirOTROptsContacts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +class CContactOptionsDlg : public CDlgBase { - HWND hwndList = GetDlgItem(hwndDlg, IDC_LV_CONT_CONTACTS); + CCtrlCombo cmbPolicy; + CCtrlListView m_list; + std::map<MCONTACT, CONTACT_DATA> m_map; - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - { - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) new ContactPolicyMap()); - - HWND cmb = GetDlgItem(hwndDlg, IDC_CMB_CONT_POLICY); - SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateW(LANG_POLICY_DEFAULT)); - SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateW(LANG_POLICY_ALWAYS)); - SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateW(LANG_POLICY_OPP)); - SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateW(LANG_POLICY_MANUAL)); - SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateW(LANG_POLICY_NEVER)); - EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_CONT_POLICY), FALSE); - - SendDlgItemMessage(hwndDlg, IDC_LV_CONT_CONTACTS, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);// | LVS_EX_CHECKBOXES); - - // add list columns - LVCOLUMN lvc; - // Initialize the LVCOLUMN structure. - // The mask specifies that the format, width, text, and - // subitem members of the structure are valid. - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - lvc.fmt = LVCFMT_LEFT; - - lvc.iSubItem = 0; - lvc.pszText = TranslateW(LANG_CONTACT); - lvc.cx = 150; // width of column in pixels - ListView_InsertColumn(hwndList, 0, &lvc); - - lvc.iSubItem = 1; - lvc.pszText = TranslateW(LANG_PROTO); - lvc.cx = 100; // width of column in pixels - ListView_InsertColumn(hwndList, 1, &lvc); - - lvc.iSubItem = 2; - lvc.pszText = TranslateW(LANG_POLICY); - lvc.cx = 90; // width of column in pixels - ListView_InsertColumn(hwndList, 2, &lvc); - - lvc.iSubItem = 3; - lvc.pszText = TranslateW(LANG_HTMLCONV); - lvc.cx = 80; // width of column in pixels - ListView_InsertColumn(hwndList, 3, &lvc); + void ChangeContactSetting(int iItem, bool changeHtml) + { + if (iItem < 0) + return; + + LVITEM lvi = { 0 }; + lvi.mask = LVIF_PARAM; + lvi.iItem = iItem; + lvi.iSubItem = 0; + m_list.GetItem(&lvi); + + MCONTACT hContact = (MCONTACT)lvi.lParam; + + // Handle HtmlConv + wchar_t buff[50]; + m_list.GetItemText(lvi.iItem, 3, buff, _countof(buff)); + + bool htmlEnabled = !wcsncmp(buff, TranslateW(LANG_YES), 50); + if (changeHtml) { + htmlEnabled = !htmlEnabled; } - SendMessage(hwndDlg, WMU_REFRESHLIST, 0, 0); - return TRUE; - - case WMU_REFRESHLIST: - ListView_DeleteAllItems(hwndList); - { - LVITEM lvI = { 0 }; - - // Some code to create the list-view control. - // Initialize LVITEM members that are common to all - // items. - lvI.mask = LVIF_TEXT | LVIF_PARAM;// | LVIF_NORECOMPUTE;// | LVIF_IMAGE; - - for (auto &hContact : Contacts()) { - const char *proto = Proto_GetBaseAccountName(hContact); - if (proto && db_get_b(hContact, proto, "ChatRoom", 0) == 0 && Proto_IsProtoOnContact(hContact, MODULENAME) // ignore chatrooms - && mir_strcmp(proto, META_PROTO) != 0) // and MetaContacts - { - lvI.iItem = 0; - lvI.iSubItem = 0; - lvI.lParam = hContact; - lvI.pszText = (wchar_t*)contact_get_nameT(hContact); - lvI.iItem = ListView_InsertItem(hwndList, &lvI); - - PROTOACCOUNT *pa = Proto_GetAccount(proto); - ListView_SetItemText(hwndList, lvI.iItem, 1, pa->tszAccountName); - - ListView_SetItemText(hwndList, lvI.iItem, 2, (wchar_t*)policy_to_string((OtrlPolicy)g_plugin.getDword(hContact, "Policy", CONTACT_DEFAULT_POLICY))); - ListView_SetItemText(hwndList, lvI.iItem, 3, (g_plugin.getByte(hContact, "HTMLConv", 0)) ? TranslateW(LANG_YES) : TranslateW(LANG_NO)); - } + + // Update wanted state + m_map[hContact].htmlconv = htmlEnabled ? HTMLCONV_ENABLE : HTMLCONV_DISABLE; + m_list.SetItemText(lvi.iItem, 3, TranslateW(htmlEnabled ? LANG_YES : LANG_NO)); + + // Handle Policy + OtrlPolicy policy = CONTACT_DEFAULT_POLICY; + + int sel = cmbPolicy.GetCurSel(); + if (sel != CB_ERR) { + int len = cmbPolicy.SendMsg(CB_GETLBTEXTLEN, sel, 0); + if (len >= 0) { + wchar_t *text = new wchar_t[len + 1]; + cmbPolicy.SendMsg(CB_GETLBTEXT, sel, (LPARAM)text); + m_list.SetItemText(iItem, 2, text); + policy = policy_from_string(text); + delete[] text; } } - return TRUE; - case WM_COMMAND: - switch (HIWORD(wParam)) { - case CBN_SELCHANGE: - switch (LOWORD(wParam)) { - case IDC_CMB_CONT_POLICY: - int iUser = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LV_CONT_CONTACTS)); - ChangeContactSetting(hwndDlg, iUser, false); - break; + m_map[hContact].policy = policy; + + NotifyChange(); + } + + void RefreshList() + { + m_list.DeleteAllItems(); + + LVITEM lvI = { 0 }; + lvI.mask = LVIF_TEXT | LVIF_PARAM; + + for (auto &hContact : Contacts()) { + const char *proto = Proto_GetBaseAccountName(hContact); + if (proto && db_get_b(hContact, proto, "ChatRoom", 0) == 0 && Proto_IsProtoOnContact(hContact, MODULENAME) // ignore chatrooms + && mir_strcmp(proto, META_PROTO) != 0) // and MetaContacts + { + lvI.iItem = 0; + lvI.iSubItem = 0; + lvI.lParam = hContact; + lvI.pszText = (wchar_t *)contact_get_nameT(hContact); + lvI.iItem = m_list.InsertItem(&lvI); + + PROTOACCOUNT *pa = Proto_GetAccount(proto); + m_list.SetItemText(lvI.iItem, 1, pa->tszAccountName); + + m_list.SetItemText(lvI.iItem, 2, (wchar_t *)policy_to_string((OtrlPolicy)g_plugin.getDword(hContact, "Policy", CONTACT_DEFAULT_POLICY))); + m_list.SetItemText(lvI.iItem, 3, (g_plugin.getByte(hContact, "HTMLConv", 0)) ? TranslateW(LANG_YES) : TranslateW(LANG_NO)); } - break; } - break; + } - case WM_NOTIFY: - if (((LPNMHDR)lParam)->code == PSN_APPLY) { - // handle apply - ContactPolicyMap *cpm = (ContactPolicyMap*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - // Iterate over the map and print out all key/value pairs. - // Using a const_iterator since we are not going to change the values. - for (ContactPolicyMap::const_iterator it = cpm->begin(); it != cpm->end(); ++it) { - if (!it->first) continue; - db_set_dw(it->first, MODULENAME, "Policy", (DWORD)it->second.policy); - db_set_b(it->first, MODULENAME, "HTMLConv", it->second.htmlconv); - } - return TRUE; +public: + CContactOptionsDlg() : + CDlgBase(g_plugin, IDD_OPT_CONTACTS), + m_list(this, IDC_LV_CONT_CONTACTS), + cmbPolicy(this, IDC_CMB_CONT_POLICY) + { + cmbPolicy.OnSelChanged = Callback(this, &CContactOptionsDlg::onSelChanged_Combo); + + m_list.OnClick = Callback(this, &CContactOptionsDlg::onClick_List); + m_list.OnItemChanged = Callback(this, &CContactOptionsDlg::onItemChanged_List); + } + + bool OnInitDialog() override + { + cmbPolicy.AddString(TranslateW(LANG_POLICY_DEFAULT)); + cmbPolicy.AddString(TranslateW(LANG_POLICY_ALWAYS)); + cmbPolicy.AddString(TranslateW(LANG_POLICY_OPP)); + cmbPolicy.AddString(TranslateW(LANG_POLICY_MANUAL)); + cmbPolicy.AddString(TranslateW(LANG_POLICY_NEVER)); + cmbPolicy.Disable(); + + m_list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); + + // add list columns + LVCOLUMN lvc; + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + lvc.fmt = LVCFMT_LEFT; + + lvc.iSubItem = 0; + lvc.pszText = TranslateW(LANG_CONTACT); + lvc.cx = 150; + m_list.InsertColumn(0, &lvc); + + lvc.iSubItem = 1; + lvc.pszText = TranslateW(LANG_PROTO); + lvc.cx = 100; + m_list.InsertColumn(1, &lvc); + + lvc.iSubItem = 2; + lvc.pszText = TranslateW(LANG_POLICY); + lvc.cx = 90; + m_list.InsertColumn(2, &lvc); + + lvc.iSubItem = 3; + lvc.pszText = TranslateW(LANG_HTMLCONV); + lvc.cx = 80; + m_list.InsertColumn(3, &lvc); + + RefreshList(); + return true; + } + + bool OnApply() override + { + for (auto &it : m_map) { + if (!it.first) continue; + db_set_dw(it.first, MODULENAME, "Policy", (DWORD)it.second.policy); + db_set_b(it.first, MODULENAME, "HTMLConv", it.second.htmlconv); } - if (((LPNMHDR)lParam)->hwndFrom == hwndList) { - LPNMLISTVIEW notif = (LPNMLISTVIEW)lParam; - if (((LPNMHDR)lParam)->code == LVN_ITEMCHANGED && (notif->uNewState & LVIS_SELECTED)) { - if (notif->iItem == -1) { - SendDlgItemMessage(hwndDlg, IDC_CMB_CONT_POLICY, CB_SETCURSEL, (LPARAM)-1, 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_CONT_POLICY), FALSE); - } - else { - EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_CONT_POLICY), TRUE); - wchar_t buff[50]; - ListView_GetItemText(((LPNMHDR)lParam)->hwndFrom, notif->iItem, 2, buff, _countof(buff)); - SendDlgItemMessage(hwndDlg, IDC_CMB_CONT_POLICY, CB_SELECTSTRING, (LPARAM)-1, (WPARAM)buff); - } + return true; + } + + void onClick_List(CCtrlListView::TEventInfo *ev) + { + if (ev->nmlv->iSubItem == 3) + ChangeContactSetting(ev->nmlv->iItem, true); + } + + void onItemChanged_List(CCtrlListView::TEventInfo *ev) { + LPNMLISTVIEW notif = ev->nmlv; + if (notif->uNewState & LVIS_SELECTED) { + if (notif->iItem == -1) { + cmbPolicy.SetCurSel(-1); + cmbPolicy.Disable(); } - else if (((LPNMHDR)lParam)->code == NM_CLICK) { - if (notif->iSubItem == 3) { - ChangeContactSetting(hwndDlg, notif->iItem, true); - } + else { + cmbPolicy.Enable(); + + wchar_t buff[50]; + m_list.GetItemText(notif->iItem, 2, buff, _countof(buff)); + cmbPolicy.SelectString(buff); } } - break; + } - case WM_DESTROY: - ContactPolicyMap *cpm = (ContactPolicyMap*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - cpm->clear(); - delete cpm; - break; + void onSelChanged_Combo(CCtrlListView *) + { + ChangeContactSetting(m_list.GetSelectionMark(), false); } - return FALSE; -} +}; ///////////////////////////////////////////////////////////////////////////////////////// +// Fingerprints tab class CFingerOptionsDlg : public CDlgBase { @@ -633,14 +642,11 @@ class CFingerOptionsDlg : public CDlgBase void RefreshList() { - // enumerate contacts, fill in list m_list.DeleteAllItems(); - // Some code to create the list-view control. - // Initialize LVITEM members that are common to all - // items. + // enumerate contacts, fill in list LVITEM lvI = { }; - lvI.mask = LVIF_TEXT | LVIF_PARAM;// | LVIF_NORECOMPUTE;// | LVIF_IMAGE; + lvI.mask = LVIF_TEXT | LVIF_PARAM; for (ConnContext *context = otr_user_state->context_root; context; context = context->next) { if (!context->app_data) @@ -682,35 +688,32 @@ public: // add list columns LVCOLUMN lvc; - // Initialize the LVCOLUMN structure. - // The mask specifies that the format, width, text, and - // subitem members of the structure are valid. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = LVCFMT_LEFT; lvc.iSubItem = 0; lvc.pszText = TranslateW(LANG_CONTACT); - lvc.cx = 100; // width of column in pixels + lvc.cx = 100; m_list.InsertColumn(0, &lvc); lvc.iSubItem = 1; lvc.pszText = TranslateW(LANG_PROTO); - lvc.cx = 90; // width of column in pixels + lvc.cx = 90; m_list.InsertColumn(1, &lvc); lvc.iSubItem = 2; lvc.pszText = TranslateW(LANG_ACTIVE); - lvc.cx = 50; // width of column in pixels + lvc.cx = 50; m_list.InsertColumn(2, &lvc); lvc.iSubItem = 3; lvc.pszText = TranslateW(LANG_VERIFIED); - lvc.cx = 50; // width of column in pixels + lvc.cx = 50; m_list.InsertColumn(3, &lvc); lvc.iSubItem = 4; lvc.pszText = TranslateW(LANG_FINGERPRINT); - lvc.cx = 300; // width of column in pixels + lvc.cx = 300; m_list.InsertColumn(4, &lvc); RefreshList(); @@ -719,8 +722,6 @@ public: bool OnApply() override { - // Iterate over the map and print out all key/value pairs. - // Using a const_iterator since we are not going to change the values. for (auto &it : m_map) { if (!it.first) continue; switch (it.second) { @@ -831,20 +832,18 @@ static int OpenOptions(WPARAM wParam, LPARAM) odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_GENERAL); odp.pfnDlgProc = DlgProcMirOTROpts; g_plugin.addOptions(wParam, &odp); + odp.pszTemplate = 0; + odp.pfnDlgProc = 0; odp.szTab.a = LPGEN("Accounts"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_PROTO); - odp.pfnDlgProc = DlgProcMirOTROptsProto; + odp.pDialog = new CAccountOptionsDlg(); g_plugin.addOptions(wParam, &odp); odp.szTab.a = LPGEN("Contacts"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_CONTACTS); - odp.pfnDlgProc = DlgProcMirOTROptsContacts; + odp.pDialog = new CContactOptionsDlg(); g_plugin.addOptions(wParam, &odp); odp.szTab.a = LPGEN("Fingerprints"); - odp.pszTemplate = 0; - odp.pfnDlgProc = 0; odp.pDialog = new CFingerOptionsDlg(); g_plugin.addOptions(wParam, &odp); return 0; diff --git a/plugins/MirOTR/src/options.h b/plugins/MirOTR/src/options.h index 1e8953edbf..bdd873653d 100644 --- a/plugins/MirOTR/src/options.h +++ b/plugins/MirOTR/src/options.h @@ -38,8 +38,6 @@ typedef struct { extern Options options; -#define WMU_REFRESHLIST (WM_USER + 241) -#define WMU_REFRESHPROTOLIST (WM_USER + 242) #define CONTACT_DEFAULT_POLICY 0xFFFF #include <map> @@ -51,7 +49,7 @@ struct CONTACT_DATA { OtrlPolicy policy; int htmlconv; }; -typedef std::map<MCONTACT, CONTACT_DATA> ContactPolicyMap; + typedef enum {FPM_VERIFY, FPM_NOTRUST, FPM_DELETE } FPModify; int OptInit(WPARAM wParam, LPARAM lParam); diff --git a/plugins/MirOTR/src/resource.h b/plugins/MirOTR/src/resource.h index d6102c36a3..2470d2e2e3 100644 --- a/plugins/MirOTR/src/resource.h +++ b/plugins/MirOTR/src/resource.h @@ -16,6 +16,7 @@ #define IDI_UNVERIFIED 112
#define IDI_PRIVATE 113
#define IDI_FINISHED 114
+#define IDR_OPT_ACCOUNT 115
#define IDC_GRP_POLICY 1051
#define IDC_RAD_ALWAYS 1052
@@ -32,9 +33,7 @@ #define IDC_CHK_ENDCLOSE 1064
#define IDC_CHK_PREVENTSYSSAVE 1065
#define IDC_LV_PROTO_PROTOS 1101
-#define IDC_BTN_PROTO_NEWKEY 1102
#define IDC_CMB_PROTO_POLICY 1103
-#define IDC_BTN_PROTO_FORGET 1104
#define IDC_STC_PROTO1 1151
#define IDC_STC_PROTO2 1152
#define IDC_LV_CONT_CONTACTS 1201
@@ -67,6 +66,8 @@ #define IDM_OPT_FINGER_FORGET 10007
#define IDM_OPT_FINGER_TRUST 10008
#define IDM_OPT_FINGER_DONTTRUST 10009
+#define IDM_OPT_PROTO_NEWKEY 10010
+#define IDM_OPT_PROTO_FORGET 10011
// Next default values for new objects
|