/* MetaContacts Plugin for Miranda IM. Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. 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; either version 2 of the License, or (at your option) any later version. 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /** @file addto.c * * Functions for the 'Add To' Dialog. * Contains all the functions and all the structures * needed to display and control the 'Add To' Dialog. */ #include "metacontacts.h" //! Holds information about a contact. typedef struct { char *name; //!< Name of the contact char *proto; //!< Protocol under which the contact has been registered HANDLE hUser; //!< Identifier of the contact in the DB. }USERINFO; //! Holds information for the callback function. typedef struct { USERINFO uInfo; //!< Information about the contact to add }ADDTO_INFO; /** Adds all the metacontacts desired in the listview. * * Adds all the metacontacts present in the database in the list, * * @param list : \c HANDLE to the list which will contain the columns. * @param nb_contacts : Number of loaded contacts. * @param contacts : A list of the contacts' identifiers * * @param id : Reference to a list of the MetaContacts IDs loaded in the listview. * Since this list is resized, its address must be passed. * * @return An integer specifying the number of rows added in the list. */ int FillList(HWND list, BOOL sort) { DWORD metaID; HANDLE hMetaUser = db_find_first(); int i=0; int index; //BOOL mbs = FALSE; while(hMetaUser) // The DB is searched through, to get all the metacontacts { if ((metaID = db_get_dw(hMetaUser, META_PROTO, META_ID,(DWORD)-1))==(DWORD)-1) { // This isn't a MetaContact, go to the next hMetaUser = db_find_next(hMetaUser); continue; } { // get contact display name from clist char *szCDN = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hMetaUser, 0); if (os_unicode_enabled) { wchar_t *ptszCDN = (wchar_t *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hMetaUser, GCDNF_UNICODE), *swzContactDisplayName; // detect if the clist provided unicode display name by comparing with non-unicode if (szCDN && ptszCDN && strncmp(szCDN, (char *)ptszCDN, strlen(szCDN)) != 0) { swzContactDisplayName = ptszCDN; } else { // no? convert to unicode if (szCDN) { swzContactDisplayName = (wchar_t *) _alloca(sizeof(wchar_t) * (strlen(szCDN) + 1)); MultiByteToWideChar(CP_ACP, 0, (char *) szCDN, -1, swzContactDisplayName, (int)strlen((char *)szCDN) + 1); } else { swzContactDisplayName = TranslateW(L"(Unknown Contact)"); } } // don't insert huge strings that we have to compare with later if (wcslen(swzContactDisplayName) > 1023) swzContactDisplayName[1024] = 0; if (sort) { int j; wchar_t buff[1024]; for (j = 0; j < i; j++) { SendMessageW(list, LB_GETTEXT, j, (LPARAM)buff); if (wcscmp(buff, swzContactDisplayName) > 0) break; } index = SendMessageW(list, LB_INSERTSTRING, (WPARAM)j, (LPARAM)swzContactDisplayName); } else { index = SendMessageW(list, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)swzContactDisplayName); } } else { // don't insert huge strings that we have to compare with later if (strlen(szCDN) > 1023) szCDN[1024] = 0; if (sort) { int j; char buff[1024]; for (j = 0; j < i; j++) { SendMessage(list, LB_GETTEXT, j, (LPARAM)buff); if (strcmp(buff, szCDN) > 0) break; } index = SendMessage(list, LB_INSERTSTRING, (WPARAM)j, (LPARAM)szCDN); } else { index = SendMessage(list, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)szCDN); } } SendMessage(list, LB_SETITEMDATA, (WPARAM)index, (LPARAM)hMetaUser); } i++; hMetaUser = db_find_next(hMetaUser); } return i; } /** Build or update the list. * * @param list : \c HANDLE to the list which will contain the columns * @param id : Reference to a list that will contain all the MetaContacts IDs loaded in the listview * otherwise the list is only refilled \n (Warning : this value must be * set to \c TRUE only once per Dialog display, otherwise all columns will be doubled) * * @returns An integer specifying the number of rows inserted or \c -1 if there was a problem */ int BuildList(HWND list, BOOL sort) { int ret=-1; SendMessage(list, LB_RESETCONTENT, 0, 0); ret = FillList(list, sort); return ret; } /** Callback function for the 'Add To' Dialog. * * All the UI is controlled here, from display to functionnalities. * * @param hwndDlg : \c HANDLE to the 'Add To' \c Dialog. * @param uMsg : Specifies the message received by this dialog. * @param wParam : Specifies additional message-specific information. * @param lParam : Specifies additional message-specific information. * * @return \c TRUE if the dialog processed the message, \c FALSE if it did not. */ #define szConvMsg "Either there is no MetaContact in the database (in this case you should first convert a contact into one)\n\ or there is none that can host this contact.\n\ Another solution could be to convert this contact into a new MetaContact.\n\nConvert this contact into a new MetaContact?" INT_PTR CALLBACK Meta_SelectDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_INITDIALOG: TranslateDialogDefault( hwndDlg ); if ( db_get_dw((HANDLE)lParam, META_PROTO, META_ID, (DWORD)-1) != (DWORD)-1) { MessageBox(hwndDlg, TranslateT("This contact is a MetaContact.\nYou can't add a MetaContact to another MetaContact.\n\nPlease choose another."), TranslateT("MetaContact Conflict"),MB_ICONERROR); DestroyWindow(hwndDlg); return TRUE; } if (db_get_dw((HANDLE)lParam, META_PROTO, META_LINK, (DWORD)-1) != (DWORD)-1) { MessageBox(hwndDlg, TranslateT("This contact is already associated to a MetaContact.\nYou cannot add a contact to multiple MetaContacts."), TranslateT("Multiple MetaContacts"),MB_ICONERROR); DestroyWindow(hwndDlg); return TRUE; } SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); // user data is contact handle SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIconEx(I_ADD)); // Initialize the graphical part CheckDlgButton(hwndDlg, IDC_ONLYAVAIL, BST_CHECKED); // Initially checked; display all metacontacts is only an option // Besides, we can check if there is at least one metacontact to add the contact to. if ( BuildList(GetDlgItem(hwndDlg, IDC_METALIST), FALSE) <= 0) { if ( MessageBox(hwndDlg, TranslateT(szConvMsg), TranslateT("No suitable MetaContact found"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1) == IDYES) Meta_Convert((WPARAM)lParam,0); DestroyWindow(hwndDlg); return TRUE; } else { // get contact display name from clist TCHAR *ptszCDN = (TCHAR*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, lParam, GCDNF_TCHAR); if (!ptszCDN) ptszCDN = TranslateT("a contact"); // ... and set it to the Window title. TCHAR buf[256]; mir_sntprintf(buf, SIZEOF(buf), TranslateT("Adding %s..."), ptszCDN); SetWindowText(hwndDlg, buf); } ShowWindow(hwndDlg,SW_SHOWNORMAL); 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: { HANDLE hContact = (HANDLE)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); int item; // Get the index of the selected metacontact if ((item = SendMessage(GetDlgItem(hwndDlg, IDC_METALIST),LB_GETCURSEL, 0, 0))==-1) return IDOK == MessageBox(hwndDlg, TranslateT("Please select a MetaContact"), TranslateT("No MetaContact selected"), MB_ICONHAND); HANDLE hMeta = (HANDLE)SendMessage(GetDlgItem(hwndDlg, IDC_METALIST), LB_GETITEMDATA, (WPARAM)item, 0); if ( !Meta_Assign(hContact,hMeta, FALSE)) MessageBox(hwndDlg, TranslateT("Assignment to the MetaContact failed."), TranslateT("Assignment failure"),MB_ICONERROR); } case IDCANCEL: DestroyWindow(hwndDlg); break; case IDC_CHK_SRT: SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_METALIST), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_METALIST), GWL_STYLE) ^ LBS_SORT); if (BuildList(GetDlgItem(hwndDlg,IDC_METALIST), IsDlgButtonChecked(hwndDlg, IDC_CHK_SRT) ? TRUE : FALSE) <= 0) { if (MessageBox(hwndDlg, TranslateT(szConvMsg), TranslateT("No suitable MetaContact found"),MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON1) == IDYES) Meta_Convert((WPARAM)lParam, 0); DestroyWindow(hwndDlg); return TRUE; } break; } break; case WM_DESTROY: // Free all allocated memory and return the focus to the CList HWND clist = GetParent(hwndDlg); ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0)); EndDialog(hwndDlg,TRUE); SetFocus(clist); return TRUE; } return FALSE; // All other Message are not handled }