From a469e9b981b6e34300e96b7283d31064e8f856fd Mon Sep 17 00:00:00 2001 From: George Hazan Date: Tue, 16 Dec 2014 18:18:39 +0000 Subject: merge from branch git-svn-id: http://svn.miranda-ng.org/main/trunk@11473 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Import/src/import.cpp | 230 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 210 insertions(+), 20 deletions(-) (limited to 'plugins/Import/src/import.cpp') diff --git a/plugins/Import/src/import.cpp b/plugins/Import/src/import.cpp index adf7609965..507936a201 100644 --- a/plugins/Import/src/import.cpp +++ b/plugins/Import/src/import.cpp @@ -26,14 +26,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. struct AccountMap { - AccountMap(const char *_src, const char *_dst) : + AccountMap(const char *_src, const TCHAR *_srcName, PROTOACCOUNT *_dst) : szSrcAcc(mir_strdup(_src)), - szDstAcc(mir_strdup(_dst)) + tszSrcName(mir_tstrdup(_srcName)), + szDstAcc(mir_strdup(_dst->szModuleName)), + pa(_dst) {} ~AccountMap() {} ptrA szSrcAcc, szDstAcc; + ptrT tszSrcName; + PROTOACCOUNT *pa; }; static int CompareAccs(const AccountMap *p1, const AccountMap *p2) @@ -126,7 +130,7 @@ static MCONTACT HContactFromNumericID(char *pszProtoName, char *pszSetting, DWOR for (MCONTACT hContact = dstDb->FindFirstContact(); hContact; hContact = dstDb->FindNextContact(hContact)) { if (db_get_dw(hContact, pszProtoName, pszSetting, 0) == dwID) { char* szProto = GetContactProto(hContact); - if (szProto != NULL && !lstrcmpA(szProto, pszProtoName)) + if (szProto != NULL && !mir_strcmp(szProto, pszProtoName)) return hContact; } } @@ -137,9 +141,9 @@ static MCONTACT HContactFromID(char *pszProtoName, char *pszSetting, TCHAR *pwsz { for (MCONTACT hContact = dstDb->FindFirstContact(); hContact; hContact = dstDb->FindNextContact(hContact)) { char *szProto = GetContactProto(hContact); - if (!lstrcmpA(szProto, pszProtoName)) { + if (!mir_strcmp(szProto, pszProtoName)) { ptrW id(db_get_tsa(hContact, pszProtoName, pszSetting)); - if (!lstrcmp(pwszID, id)) + if (!mir_tstrcmp(pwszID, id)) return hContact; } } @@ -194,6 +198,169 @@ void CopySettings(MCONTACT srcID, const char *szSrcModule, MCONTACT dstID, const } } +///////////////////////////////////////////////////////////////////////////////////////// +// accounts matcher dialog + +static HWND hwndList, hwndCombo; +static int iPrevIndex = -1; + +static void SetAccountName(int idx, PROTOACCOUNT *pa) +{ + ListView_SetItemText(hwndList, idx, 1, (pa == NULL) ? TranslateT("") : pa->tszAccountName); +} + +static LRESULT CALLBACK ComboWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg == WM_KILLFOCUS && LPARAM(hwnd) == lParam) { + if (iPrevIndex != -1) { + AccountMap *pMap = (AccountMap*)SendMessage(hwnd, CB_GETITEMDATA, 0, 0); + + int idx = SendMessage(hwnd, CB_GETCURSEL, 0, 0); + if (idx == 0) { + pMap->tszSrcName = NULL; + pMap->pa = NULL; + } + else { + PROTOACCOUNT *pa = (PROTOACCOUNT*)SendMessage(hwnd, CB_GETITEMDATA, idx, 0); + pMap->pa = pa; + pMap->tszSrcName = mir_tstrdup(pa->tszAccountName); + } + SetAccountName(iPrevIndex, pMap->pa); + iPrevIndex = -1; + } + + DestroyWindow(hwnd); + hwndCombo = 0; + } + return mir_callNextSubclass(hwnd, ComboWndProc, uMsg, wParam, lParam); +} + +static LRESULT CALLBACK ListWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) { + case WM_LBUTTONDOWN: + long x = (long)LOWORD(lParam), y = (long)HIWORD(lParam); + + LVHITTESTINFO hit; + hit.pt.x = x; + hit.pt.y = y; + int lResult = ListView_SubItemHitTest(hwnd, &hit); + if (lResult == -1 || hit.iSubItem != 1) { + SendMessage(hwndCombo, WM_KILLFOCUS, 0, (LPARAM)hwndCombo); + break; + } + + RECT r; + ListView_GetSubItemRect(hwnd, hit.iItem, 1, LVIR_BOUNDS, &r); + r.top--; r.bottom--; + + TCHAR tszText[100]; + ListView_GetItemText(hwnd, hit.iItem, 1, tszText, SIZEOF(tszText)); + + LVITEM lvitem; + lvitem.iItem = hit.iItem; + lvitem.iSubItem = 0; + lvitem.mask = LVIF_PARAM; + ListView_GetItem(hwnd, &lvitem); + + if (hwndCombo != NULL) + SendMessage(hwndCombo, WM_KILLFOCUS, 0, (LPARAM)hwndCombo); + + hwndCombo = CreateWindowEx(WS_EX_CLIENTEDGE, WC_COMBOBOX, _T(""), WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, + r.left+3, r.top, r.right - r.left - 3, r.bottom - r.top, hwnd, 0, hInst, NULL); + + // copy a font from listview + HFONT hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0); + SendMessage(hwndCombo, WM_SETFONT, (WPARAM)hFont, 0); + + SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)TranslateT("")); + SendMessage(hwndCombo, CB_SETITEMDATA, 0, lvitem.lParam); + + int protoCount, iSel = 0; + PROTOACCOUNT **accs; + ProtoEnumAccounts(&protoCount, &accs); + for (int i = 0; i < protoCount; i++) { + int idx = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)accs[i]->tszAccountName); + SendMessage(hwndCombo, CB_SETITEMDATA, idx, (LPARAM)accs[i]); + + if (!mir_tstrcmpi(accs[i]->tszAccountName, tszText)) + iSel = idx; + } + + SendMessage(hwndCombo, CB_SETCURSEL, iSel, 0); + + SetFocus(hwndCombo); + mir_subclassWindow(hwndCombo, ComboWndProc); + + iPrevIndex = hit.iItem; + } + + return mir_callNextSubclass(hwnd, ListWndProc, uMsg, wParam, lParam); +} + +static INT_PTR CALLBACK AccountsMatcherProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + hwndList = GetDlgItem(hwndDlg, IDC_LIST); + { + LVCOLUMN col = { 0 }; + col.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_FMT | LVCF_SUBITEM; + col.fmt = LVCFMT_LEFT; + col.cx = 100; + col.pszText = TranslateT("Old account"); + ListView_InsertColumn(hwndList, 0, &col); + + col.iSubItem = 1; + col.pszText = TranslateT("New account"); + ListView_InsertColumn(hwndList, 1, &col); + + LVITEM lvi = { 0 }; + lvi.mask = LVIF_TEXT | LVIF_PARAM; + for (int i = 0; i < arAccountMap.getCount(); i++) { + AccountMap &p = arAccountMap[i]; + lvi.iItem = i; + lvi.iSubItem = 0; + lvi.pszText = p.tszSrcName; + lvi.lParam = (LPARAM)&p; + ListView_InsertItem(hwndList, &lvi); + + SetAccountName(i, p.pa); + } + mir_subclassWindow(hwndList, ListWndProc); + } + return TRUE; + + case WM_COMMAND: + if (HIWORD(wParam) != BN_CLICKED) + break; // Only clicks of buttons are relevant, let other COMMANDs through + + switch (LOWORD(wParam)) { + case IDOK: + EndDialog(hwndDlg, IDOK); + break; + + case IDCANCEL: + EndDialog(hwndDlg, IDCANCEL); + } + break; + + case WM_NOTIFY: + LPNMHDR hdr = (LPNMHDR)lParam; + if (hdr->idFrom != IDC_LIST) + break; + + switch (hdr->code) { + case LVN_ITEMCHANGED: + case LVN_ITEMACTIVATE: + ; + } + } + + return FALSE; +} + ///////////////////////////////////////////////////////////////////////////////////////// static bool FindDestAccount(const char *szProto) @@ -210,7 +377,7 @@ static bool FindDestAccount(const char *szProto) return false; } -static PROTOACCOUNT* FindMyAccount(const char *szProto, const char *szBaseProto, const TCHAR *ptszName) +static PROTOACCOUNT* FindMyAccount(const char *szProto, const char *szBaseProto, const TCHAR *ptszName, bool bStrict) { int destProtoCount; PROTOACCOUNT **destAccs; @@ -224,7 +391,7 @@ static PROTOACCOUNT* FindMyAccount(const char *szProto, const char *szBaseProto, continue; // different base protocotol type -> skip - if (lstrcmpA(pa->szProtoName, szBaseProto)) + if (mir_strcmp(pa->szProtoName, szBaseProto)) continue; // these protocols have no accounts, and their name match -> success @@ -256,12 +423,13 @@ static PROTOACCOUNT* FindMyAccount(const char *szProto, const char *szBaseProto, if (bEqual) return pa; } - return pProto; + return (bStrict) ? NULL : pProto; } -void ImportAccounts() +bool ImportAccounts() { int protoCount = myGetD(NULL, "Protocols", "ProtoCount", 0); + bool bNeedManualMerge = false; for (int i = 0; i < protoCount; i++) { char szSetting[100], szProto[100]; @@ -269,19 +437,28 @@ void ImportAccounts() if (myGetS(NULL, "Protocols", szSetting, szProto)) continue; + itoa(800 + i, szSetting, 10); + ptrT tszName(myGetWs(NULL, "Protocols", szSetting)); + // check if it's an account-based proto or an old style proto char szBaseProto[100]; if (myGetS(NULL, szProto, "AM_BaseProto", szBaseProto)) { - arAccountMap.insert(new AccountMap(szProto, NULL)); + arAccountMap.insert(new AccountMap(szProto, tszName, NULL)); + bNeedManualMerge = true; continue; } - itoa(800+i, szSetting, 10); - ptrT tszName(myGetWs(NULL, "Protocols", szSetting)); - - PROTOACCOUNT *pa = FindMyAccount(szProto, szBaseProto, tszName); + // try the precise match first + PROTOACCOUNT *pa = FindMyAccount(szProto, szBaseProto, tszName, true); if (pa) { - arAccountMap.insert(new AccountMap(szProto, pa->szModuleName)); + arAccountMap.insert(new AccountMap(szProto, tszName, pa)); + continue; + } + + // if fail, try to found an account by its name + if (pa = FindMyAccount(szProto, szBaseProto, tszName, false)) { + arAccountMap.insert(new AccountMap(szProto, tszName, pa)); + bNeedManualMerge = true; continue; } @@ -297,11 +474,12 @@ void ImportAccounts() pa = ProtoCreateAccount(&newacc); if (pa == NULL) { - arAccountMap.insert(new AccountMap(szProto, NULL)); + arAccountMap.insert(new AccountMap(szProto, tszName, NULL)); + bNeedManualMerge = true; continue; } - arAccountMap.insert(new AccountMap(szProto, pa->szModuleName)); + arAccountMap.insert(new AccountMap(szProto, tszName, pa)); itoa(400 + i, szSetting, 10); int iVal = myGetD(NULL, "Protocols", szSetting, 1); @@ -317,6 +495,12 @@ void ImportAccounts() CopySettings(NULL, szProto, NULL, pa->szModuleName); } + + // all accounts to be converted automatically, no need to raise a dialog + if (!bNeedManualMerge) + return true; + + return DialogBox(hInst, MAKEINTRESOURCE(IDD_ACCMERGE), NULL, AccountsMatcherProc) == IDOK; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -545,8 +729,11 @@ void ImportMeta(DBCachedContact *ccSrc) else AddMessage(LPGENT("Added metacontact")); } - AccountMap pda(META_PROTO, META_PROTO); - ImportContactSettings(&pda, ccSrc->contactID, ccDst->contactID); + PROTOACCOUNT *pa = ProtoGetAccount(META_PROTO); + if (pa) { + AccountMap pda(META_PROTO, _T(META_PROTO), pa); + ImportContactSettings(&pda, ccSrc->contactID, ccDst->contactID); + } arContactMap.insert(new ContactMap(ccSrc->contactID, ccDst->contactID)); } @@ -799,7 +986,10 @@ void MirandaImport(HWND hdlg) // Start benchmark timer DWORD dwTimer = time(NULL); - ImportAccounts(); + if (!ImportAccounts()) { + AddMessage(LPGENT("Error mapping accounts, exiting.")); + return; + } // Import Groups if (nImportOption == IMPORT_ALL || (nCustomOptions & IOPT_GROUPS)) { -- cgit v1.2.3