From c507a151a8011784ba37228d33610fa0406736eb Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Sat, 23 Jun 2012 14:21:20 +0000 Subject: MetaContacts: renamed to .cpp git-svn-id: http://svn.miranda-ng.org/main/trunk@557 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/MetaContacts/MetaContacts.rc | 43 +- plugins/MetaContacts/addto.c | 301 ----- plugins/MetaContacts/addto.cpp | 301 +++++ plugins/MetaContacts/edit.c | 585 --------- plugins/MetaContacts/edit.cpp | 585 +++++++++ plugins/MetaContacts/icons.c | 101 -- plugins/MetaContacts/icons.cpp | 101 ++ plugins/MetaContacts/meta_api.c | 245 ---- plugins/MetaContacts/meta_api.cpp | 245 ++++ plugins/MetaContacts/meta_main.c | 266 ---- plugins/MetaContacts/meta_main.cpp | 266 ++++ plugins/MetaContacts/meta_menu.c | 562 --------- plugins/MetaContacts/meta_menu.cpp | 562 +++++++++ plugins/MetaContacts/meta_options.c | 640 ---------- plugins/MetaContacts/meta_options.cpp | 640 ++++++++++ plugins/MetaContacts/meta_services.c | 2104 -------------------------------- plugins/MetaContacts/meta_services.cpp | 2104 ++++++++++++++++++++++++++++++++ plugins/MetaContacts/meta_utils.c | 1717 -------------------------- plugins/MetaContacts/meta_utils.cpp | 1717 ++++++++++++++++++++++++++ plugins/MetaContacts/version.h | 2 +- 20 files changed, 6535 insertions(+), 6552 deletions(-) delete mode 100644 plugins/MetaContacts/addto.c create mode 100644 plugins/MetaContacts/addto.cpp delete mode 100644 plugins/MetaContacts/edit.c create mode 100644 plugins/MetaContacts/edit.cpp delete mode 100644 plugins/MetaContacts/icons.c create mode 100644 plugins/MetaContacts/icons.cpp delete mode 100644 plugins/MetaContacts/meta_api.c create mode 100644 plugins/MetaContacts/meta_api.cpp delete mode 100644 plugins/MetaContacts/meta_main.c create mode 100644 plugins/MetaContacts/meta_main.cpp delete mode 100644 plugins/MetaContacts/meta_menu.c create mode 100644 plugins/MetaContacts/meta_menu.cpp delete mode 100644 plugins/MetaContacts/meta_options.c create mode 100644 plugins/MetaContacts/meta_options.cpp delete mode 100644 plugins/MetaContacts/meta_services.c create mode 100644 plugins/MetaContacts/meta_services.cpp delete mode 100644 plugins/MetaContacts/meta_utils.c create mode 100644 plugins/MetaContacts/meta_utils.cpp diff --git a/plugins/MetaContacts/MetaContacts.rc b/plugins/MetaContacts/MetaContacts.rc index 1eee03456c..42862c843c 100644 --- a/plugins/MetaContacts/MetaContacts.rc +++ b/plugins/MetaContacts/MetaContacts.rc @@ -85,8 +85,7 @@ BEGIN EDITTEXT IDC_ED_NAME,158,23,135,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP CONTROL "List1",IDC_LST_CONTACTS,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,53,79,276,89,WS_EX_CLIENTEDGE GROUPBOX "",IDC_STATIC,35,66,313,138 - CONTROL "Force use of default for sending (even if offline)",IDC_CHK_FORCEDEFAULT, - "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,110,215,209,10 + CONTROL "Force use of default for sending (even if offline)",IDC_CHK_FORCEDEFAULT,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,110,215,209,10 PUSHBUTTON "Send &Offline",IDC_BTN_SETOFFLINE,161,181,50,14 END @@ -141,15 +140,6 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT #pragma code_page(1252) #endif //_WIN32 -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_MCMENU ICON "mcmenu.ico" -IDI_MCMENUOFF ICON "mcmenuof.ico" #endif // Neutral (Sys. Default) resources ///////////////////////////////////////////////////////////////////////////// @@ -225,13 +215,10 @@ STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - CONTROL "Set default contact on receipt of message",IDC_CHK_SETDEFAULTRECV, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,9,290,10 - CONTROL "Always send to default contact if not offline",IDC_CHK_ALWAYSUSEDEFAULT, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,31,290,10 + CONTROL "Set default contact on receipt of message",IDC_CHK_SETDEFAULTRECV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,9,290,10 + CONTROL "Always send to default contact if not offline",IDC_CHK_ALWAYSUSEDEFAULT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,31,290,10 GROUPBOX "Options",IDC_STATIC,0,0,297,178 - CONTROL "Suppress status notification for subcontacts",IDC_CHK_SUPPRESSSTATUS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,42,290,10 + CONTROL "Suppress status notification for subcontacts",IDC_CHK_SUPPRESSSTATUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,42,290,10 GROUPBOX "Context Menu",IDC_STATIC,4,79,289,58 CONTROL "Use contact's unique id",IDC_RAD_UID,"Button",BS_AUTORADIOBUTTON | WS_GROUP,13,100,112,10 CONTROL "Use contact's display name",IDC_RAD_DID,"Button",BS_AUTORADIOBUTTON | WS_GROUP,13,114,112,10 @@ -243,14 +230,11 @@ BEGIN GROUPBOX "Contact List",IDC_STATIC,4,139,289,33,WS_GROUP CONTROL "Display subcontact nickname",IDC_RAD_NICK,"Button",BS_AUTORADIOBUTTON | WS_GROUP,9,149,144,10 CONTROL "Display subcontact display name",IDC_RAD_NAME,"Button",BS_AUTORADIOBUTTON | WS_GROUP,9,160,144,10 - CONTROL "Hide in status bar and status menu (*requires restart, uncheck to set proto icons)",IDC_CHK_SUPPRESSPROTO, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,53,290,10 - CONTROL "Use subcontact message windows",IDC_CHK_SUBWINDOW, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,64,165,10 - CONTROL "Copy subcontact data",IDC_CHK_COPYDATA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,64,118,10 + CONTROL "Hide in status bar and status menu (*requires restart, uncheck to set proto icons)",IDC_CHK_SUPPRESSPROTO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,53,290,10 + CONTROL "Use subcontact message windows",IDC_CHK_SUBWINDOW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,64,155,10 + CONTROL "Copy subcontact data",IDC_CHK_COPYDATA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,64,133,10 CONTROL "Lock name to first contact",IDC_CHK_LOCKHANDLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,155,115,10 - CONTROL "but only for the current conversation",IDC_CHK_TEMPDEFAULT, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,20,260,10 + CONTROL "but only for the current conversation",IDC_CHK_TEMPDEFAULT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,20,260,10 END IDD_COPYPROGRESS DIALOG 0, 0, 186, 90 @@ -294,14 +278,11 @@ STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - CONTROL "Copy subcontact history to MetaContact when creating or adding",IDC_CHK_COPYHISTORY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,23,258,10 + CONTROL "Copy subcontact history to MetaContact when creating or adding",IDC_CHK_COPYHISTORY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,23,258,10 RTEXT "Number of days to copy (0=all):",IDC_STATIC,13,37,125,8 EDITTEXT IDC_ED_DAYS,158,35,31,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER - CONTROL "Keep MetaContact history synchronized with subcontacts",IDC_CHK_METAHISTORY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,60,258,10 - CONTROL "Keep subcontact history synchronized with MetaContact",IDC_CHK_SUBHISTORY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,78,258,10 + CONTROL "Keep MetaContact history synchronized with subcontacts",IDC_CHK_METAHISTORY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,60,258,10 + CONTROL "Keep subcontact history synchronized with MetaContact",IDC_CHK_SUBHISTORY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,78,258,10 GROUPBOX "History (** beware - change at your own risk **)",IDC_STATIC,7,7,273,95,WS_GROUP END @@ -313,6 +294,8 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. +IDI_MCMENU ICON "mcmenu.ico" +IDI_MCMENUOFF ICON "mcmenuof.ico" IDI_MCEDIT ICON "meta_edit.ico" IDI_MCREMOVE ICON "meta_remove2.ico" IDI_MCCONVERT ICON "meta_convert.ico" diff --git a/plugins/MetaContacts/addto.c b/plugins/MetaContacts/addto.c deleted file mode 100644 index b92e97b978..0000000000 --- a/plugins/MetaContacts/addto.c +++ /dev/null @@ -1,301 +0,0 @@ -/* -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 = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); - int i=0; - int index; - //BOOL mbs = FALSE; - - while(hMetaUser) // The DB is searched through, to get all the metacontacts - { - if ((metaID=DBGetContactSettingDword(hMetaUser,META_PROTO,META_ID,(DWORD)-1))==(DWORD)-1) - { - // This isn't a MetaContact, go to the next - hMetaUser = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hMetaUser,0); - continue; - } - - - { - // get contact display name from clist - char *szCDN = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hMetaUser, 0); - - if (os_unicode_enabled) { - wchar_t *swzCDN = (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 && swzCDN && strncmp(szCDN, (char *)swzCDN, strlen(szCDN)) != 0) { - swzContactDisplayName = swzCDN; - } 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 = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hMetaUser,0); - } - 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. -*/ -INT_PTR CALLBACK Meta_SelectDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault( hwndDlg ); - - - if (DBGetContactSettingDword((HANDLE)lParam,META_PROTO,META_ID,(DWORD)-1)!=(DWORD)-1) - { - MessageBox(hwndDlg,Translate("This contact is a MetaContact.\nYou can't add a MetaContact to another MetaContact.\n\nPlease choose another."), - Translate("MetaContact Conflict"),MB_ICONERROR); - DestroyWindow(hwndDlg); - return TRUE; - } - if (DBGetContactSettingDword((HANDLE)lParam,META_PROTO,META_LINK,(DWORD)-1)!=(DWORD)-1) - { - MessageBox(hwndDlg,Translate("This contact is already associated to a MetaContact.\nYou cannot add a contact to multiple MetaContacts."), - Translate("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)); - //SendMessage(GetDlgItem(hwndDlg,IDC_METALIST),LVM_SETEXTENDEDLISTVIEWSTYLE,0,LVS_EX_FULLROWSELECT); - - // 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,Translate("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?"), - Translate("No suitable MetaContact found"),MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON1)==IDYES) - Meta_Convert((WPARAM)lParam,0); - DestroyWindow(hwndDlg); - return TRUE; - } - else - { - // Get the name displayed in the CList... - - // get contact display name from clist - char *szCDN = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)lParam, 0); - if (os_unicode_enabled) { - wchar_t *swzCDN = (wchar_t *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)lParam, GCDNF_UNICODE), - *swzContactDisplayName; - wchar_t buf[256]; - - // detect if the clist provided unicode display name by comparing with non-unicode - if (szCDN && swzCDN && strncmp(szCDN, (char *)swzCDN, strlen(szCDN)) != 0) { - swzContactDisplayName = swzCDN; - } 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"a contact"); - } - } - - // ... and set it to the Window title. - //MessageBoxW(hwndDlg, swzContactDisplayName, L"Setting window title", MB_OK); - - // note - the swprintf function has changed (includes size_t for vc8+) - //swprintf(buf, 256, TranslateW(L"Adding %s..."), swzContactDisplayName); - // this *should* work for vc6, 7, and 8 (thx George) - _snwprintf(buf, 256, TranslateW(L"Adding %s..."), swzContactDisplayName); - - SetWindowTextW(hwndDlg, buf); - } else { - char buf[256]; - sprintf(buf,Translate("Adding %s..."), szCDN); - 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 hMeta, 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,Translate("Please select a MetaContact"),Translate("No MetaContact selected"),MB_ICONHAND); - - hMeta = (HANDLE)SendMessage(GetDlgItem(hwndDlg, IDC_METALIST), LB_GETITEMDATA, (WPARAM)item, 0); - - { - if (!Meta_Assign(hContact,hMeta, FALSE)) - { - MessageBox(hwndDlg, Translate("Assignment to the MetaContact failed."), Translate("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,Translate("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?"), - Translate("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 -} diff --git a/plugins/MetaContacts/addto.cpp b/plugins/MetaContacts/addto.cpp new file mode 100644 index 0000000000..b92e97b978 --- /dev/null +++ b/plugins/MetaContacts/addto.cpp @@ -0,0 +1,301 @@ +/* +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 = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + int i=0; + int index; + //BOOL mbs = FALSE; + + while(hMetaUser) // The DB is searched through, to get all the metacontacts + { + if ((metaID=DBGetContactSettingDword(hMetaUser,META_PROTO,META_ID,(DWORD)-1))==(DWORD)-1) + { + // This isn't a MetaContact, go to the next + hMetaUser = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hMetaUser,0); + continue; + } + + + { + // get contact display name from clist + char *szCDN = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hMetaUser, 0); + + if (os_unicode_enabled) { + wchar_t *swzCDN = (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 && swzCDN && strncmp(szCDN, (char *)swzCDN, strlen(szCDN)) != 0) { + swzContactDisplayName = swzCDN; + } 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 = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hMetaUser,0); + } + 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. +*/ +INT_PTR CALLBACK Meta_SelectDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault( hwndDlg ); + + + if (DBGetContactSettingDword((HANDLE)lParam,META_PROTO,META_ID,(DWORD)-1)!=(DWORD)-1) + { + MessageBox(hwndDlg,Translate("This contact is a MetaContact.\nYou can't add a MetaContact to another MetaContact.\n\nPlease choose another."), + Translate("MetaContact Conflict"),MB_ICONERROR); + DestroyWindow(hwndDlg); + return TRUE; + } + if (DBGetContactSettingDword((HANDLE)lParam,META_PROTO,META_LINK,(DWORD)-1)!=(DWORD)-1) + { + MessageBox(hwndDlg,Translate("This contact is already associated to a MetaContact.\nYou cannot add a contact to multiple MetaContacts."), + Translate("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)); + //SendMessage(GetDlgItem(hwndDlg,IDC_METALIST),LVM_SETEXTENDEDLISTVIEWSTYLE,0,LVS_EX_FULLROWSELECT); + + // 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,Translate("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?"), + Translate("No suitable MetaContact found"),MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON1)==IDYES) + Meta_Convert((WPARAM)lParam,0); + DestroyWindow(hwndDlg); + return TRUE; + } + else + { + // Get the name displayed in the CList... + + // get contact display name from clist + char *szCDN = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)lParam, 0); + if (os_unicode_enabled) { + wchar_t *swzCDN = (wchar_t *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)lParam, GCDNF_UNICODE), + *swzContactDisplayName; + wchar_t buf[256]; + + // detect if the clist provided unicode display name by comparing with non-unicode + if (szCDN && swzCDN && strncmp(szCDN, (char *)swzCDN, strlen(szCDN)) != 0) { + swzContactDisplayName = swzCDN; + } 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"a contact"); + } + } + + // ... and set it to the Window title. + //MessageBoxW(hwndDlg, swzContactDisplayName, L"Setting window title", MB_OK); + + // note - the swprintf function has changed (includes size_t for vc8+) + //swprintf(buf, 256, TranslateW(L"Adding %s..."), swzContactDisplayName); + // this *should* work for vc6, 7, and 8 (thx George) + _snwprintf(buf, 256, TranslateW(L"Adding %s..."), swzContactDisplayName); + + SetWindowTextW(hwndDlg, buf); + } else { + char buf[256]; + sprintf(buf,Translate("Adding %s..."), szCDN); + 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 hMeta, 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,Translate("Please select a MetaContact"),Translate("No MetaContact selected"),MB_ICONHAND); + + hMeta = (HANDLE)SendMessage(GetDlgItem(hwndDlg, IDC_METALIST), LB_GETITEMDATA, (WPARAM)item, 0); + + { + if (!Meta_Assign(hContact,hMeta, FALSE)) + { + MessageBox(hwndDlg, Translate("Assignment to the MetaContact failed."), Translate("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,Translate("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?"), + Translate("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 +} diff --git a/plugins/MetaContacts/edit.c b/plugins/MetaContacts/edit.c deleted file mode 100644 index a5866576dd..0000000000 --- a/plugins/MetaContacts/edit.c +++ /dev/null @@ -1,585 +0,0 @@ -/* -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 edit.c -* -* Functions for the 'Edit' Dialog. -* Contains all the functions and all the structures -* needed to display and control the 'Edit' Dialog. -*/ -#include "metacontacts.h" - -//! Holds the differents changes that have to made -typedef struct tag_CHANGES { - HANDLE hMeta; //!< \c HANDLE of the MetaContact that is edited. - HANDLE hDefaultContact; //!< \c HANDLE of the new default contact - HANDLE hOfflineContact; - int num_deleted, //!< \c DWORD number of deleted contacts - num_contacts; //!< \c DWORD number of contacts - HANDLE hDeletedContacts[MAX_CONTACTS]; //!< \c HANDLEs of the subcontacts to be removed from this metacontact - HANDLE hContact[MAX_CONTACTS]; //!< \c HANDLEs of the subcontacts, in the order they should be in - int force_default; -} CHANGES; - -CHANGES changes; //!< \c global CHANGES structure - -/** Fills the list of contacts -* -* @param chg : Structure holding all the change info (See CHANGES). -*/ -void FillContactList(HWND hWndDlg, CHANGES *chg) { - HWND hList = GetDlgItem(hWndDlg, IDC_LST_CONTACTS); - char *proto, *field, buff[256]; - int i; - LVITEM LvItem; - DBVARIANT dbv; - LVITEMW LvItemW; // for unicode nicks - - - SendMessage(hList,LVM_DELETEALLITEMS,0,0); - - ZeroMemory(&LvItem, sizeof(LvItem)); - LvItem.mask=LVIF_TEXT; // Text Style - LvItem.cchTextMax = 256; // Max size of test - - ZeroMemory(&LvItemW, sizeof(LvItemW)); - LvItemW.mask=LVIF_TEXT; // Text Style - LvItemW.cchTextMax = 256; // Max size of test - - for (i = 0; i < chg->num_contacts; i++) { - LvItem.iItem = i; - LvItemW.iItem = i; - - { - - char *szCDN = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)chg->hContact[i], 0); - - if (os_unicode_enabled) { - wchar_t *swzCDN = (wchar_t *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)chg->hContact[i], GCDNF_UNICODE), - *swzContactDisplayName; - - LvItemW.iSubItem = 0; // clist display name - - // detect if the clist provided unicode display name by comparing with non-unicode - if (szCDN && swzCDN && strncmp(szCDN, (char *)swzCDN, strlen(szCDN)) != 0 && wcslen(swzCDN) >= strlen(szCDN)) { - swzContactDisplayName = swzCDN; - } 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)"); - } - } - - LvItemW.pszText = swzContactDisplayName; - SendMessageW(hList, LVM_INSERTITEMW, (WPARAM)0, (LPARAM)&LvItemW); - } else { - LvItem.iSubItem = 0; // clist display name - LvItem.pszText = szCDN; - SendMessage(hList, LVM_INSERTITEM, (WPARAM)0, (LPARAM)&LvItem); - } - } - - - - LvItem.iSubItem = 1; // id - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)chg->hContact[i], 0); - if (proto) { - field = (char *)CallProtoService(proto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0); - - DBGetContactSetting(chg->hContact[i],proto,field,&dbv); - switch(dbv.type) - { - case DBVT_ASCIIZ: - sprintf(buff,"%s",dbv.pszVal); - break; - case DBVT_BYTE: - sprintf(buff,"%d",dbv.bVal); - break; - case DBVT_WORD: - sprintf(buff,"%d",dbv.wVal); - break; - case DBVT_DWORD: - sprintf(buff,"%d",(int)dbv.dVal); - break; - default: - //sprintf(buff,""); - buff[0] = 0; - } - DBFreeVariant(&dbv); - - LvItem.pszText = buff; - SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems - - LvItem.iSubItem = 2; // protocol - LvItem.pszText = proto; - SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems - } else { - LvItem.pszText = "Unknown"; - SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems - - LvItem.iSubItem = 2; // protocol - LvItem.pszText = "Unknown"; - SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems - } - LvItem.iSubItem = 3; // Default (Yes/No) - LvItem.pszText = (chg->hContact[i] == chg->hDefaultContact ? Translate("Yes") : Translate("No")); - SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems - - LvItem.iSubItem = 4; // Offline (Yes/No) - LvItem.pszText = (chg->hContact[i] == chg->hOfflineContact ? Translate("Yes") : Translate("No")); - SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems - } -} - - -void SetListSelection(HWND hList, int sel) { - LVITEM LvItem; - - ZeroMemory(&LvItem, sizeof(LvItem)); - LvItem.iItem = sel; - LvItem.mask = LVIF_STATE; - LvItem.stateMask = LVIS_SELECTED|LVIS_FOCUSED; - LvItem.state = LVIS_SELECTED|LVIS_FOCUSED; - - SendMessage(hList, LVM_SETITEMSTATE, (WPARAM)sel, (LPARAM)&LvItem); - -} - -/** Scans the \c CHANGES and call the appropriate function for each change. -* -* @param chg : Structure holding all the change info (See CHANGES). -*/ -void ApplyChanges(CHANGES *chg) -{ - HANDLE most_online; - int i; - - // remove removed contacts - for (i = 0; i < chg->num_deleted; i++) { - Meta_Delete((WPARAM)chg->hDeletedContacts[i], 0); - if (chg->hDeletedContacts[i] == chg->hDefaultContact) - chg->hDefaultContact = 0; - if (chg->hDeletedContacts[i] == chg->hOfflineContact) - chg->hOfflineContact = 0; - } - - // set contact positions - for (i = 0; i < chg->num_contacts; i++) { - if (Meta_GetContactNumber(chg->hContact[i]) != i) - Meta_SwapContacts(chg->hMeta, Meta_GetContactNumber(chg->hContact[i]), i); - } - - NotifyEventHooks(hSubcontactsChanged, (WPARAM)chg->hMeta, (LPARAM)chg->hDefaultContact); - - // set default - if (chg->hDefaultContact) - DBWriteContactSettingDword(chg->hMeta, META_PROTO, "Default", Meta_GetContactNumber(chg->hDefaultContact)); - else - DBWriteContactSettingDword(chg->hMeta, META_PROTO, "Default", 0); - NotifyEventHooks(hEventDefaultChanged, (WPARAM)chg->hMeta, (LPARAM)chg->hDefaultContact); - - // set offline - if (chg->hOfflineContact) - DBWriteContactSettingDword(chg->hMeta, META_PROTO, "OfflineSend", Meta_GetContactNumber(chg->hOfflineContact)); - else - DBWriteContactSettingDword(chg->hMeta, META_PROTO, "OfflineSend", (DWORD)-1); - - // fix nick - most_online = Meta_GetMostOnline(chg->hMeta); - Meta_CopyContactNick(chg->hMeta, most_online); - - // fix status - Meta_FixStatus(chg->hMeta); - - // fix avatar - most_online = Meta_GetMostOnlineSupporting(chg->hMeta, PFLAGNUM_4, PF4_AVATARS); - if (most_online) { - PROTO_AVATAR_INFORMATIONT AI; - - AI.cbSize = sizeof(AI); - AI.hContact = chg->hMeta; - AI.format = PA_FORMAT_UNKNOWN; - _tcscpy(AI.filename, _T("X")); - - if ((int)CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) - DBWriteContactSettingTString(chg->hMeta, "ContactPhoto", "File",AI.filename); - } - - if (MetaAPI_GetForceState((WPARAM)chg->hMeta, 0) != chg->force_default) - MetaAPI_ForceDefault((WPARAM)chg->hMeta, 0); -} - -LRESULT ProcessCustomDraw (LPARAM lParam) -{ - LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam; - - switch(lplvcd->nmcd.dwDrawStage) - { - case CDDS_PREPAINT : //Before the paint cycle begins - //request notifications for individual listview items - return CDRF_NOTIFYITEMDRAW; - - case CDDS_ITEMPREPAINT: //Before an item is drawn - /* - if (((int)lplvcd->nmcd.dwItemSpec%2)==0) - { - //customize item appearance - //lplvcd->clrText = RGB(255,0,0); - lplvcd->clrTextBk = RGB(200,200,200); - } - else{ - //lplvcd->clrText = RGB(0,0,255); - lplvcd->clrTextBk = RGB(255,255,255); - } - */ - if (changes.hContact[(int)lplvcd->nmcd.dwItemSpec] == changes.hDefaultContact) { - lplvcd->clrText = RGB(255, 0, 0); - } - return CDRF_NEWFONT; - } - - return 0; -} - -/** Callback function for the 'Edit' Dialog. -* -* All the UI is controlled here, from display to functionnalities. -* -* @param hwndDlg : \c HANDLE to the 'Edit' \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 (handle of MetaContact to edit) -* -* @return \c TRUE if the dialog processed the message, \c FALSE if it did not. -*/ -#define WMU_SETTITLE (WM_USER + 1) - -INT_PTR CALLBACK Meta_EditDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HWND hwnd; - char *str; - int sel, i; - - switch(msg) - { - case WM_INITDIALOG: - { - // Font necessary for all controls created with CreateWindowsEx - //HFONT hfDefault = GetStockObject(DEFAULT_GUI_FONT); - //HWND combo = GetDlgItem(hwndDlg,IDC_DEFAULT); - int nb_contacts, default_contact_number, offline_contact_number; - LVCOLUMN LvCol; - - TranslateDialogDefault( hwndDlg ); - - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIconEx(I_EDIT)); - - // Disable the 'Apply' button. - EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),FALSE); - - // (from http://www.codeproject.com/listctrl/listview.asp) - // initialize list - hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); - SendMessage(hwnd,LVM_SETEXTENDEDLISTVIEWSTYLE, 0,LVS_EX_FULLROWSELECT); // Set style - - // Create list columns - ZeroMemory(&LvCol, sizeof(LvCol)); - LvCol.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; // Type of mask - - // Inserting Couloms as much as we want - LvCol.pszText=Translate("Contact"); // First Header Text - LvCol.cx=100; // width of column - SendMessage(hwnd,LVM_INSERTCOLUMN,0,(LPARAM)&LvCol); // Insert/Show the coloum - - LvCol.pszText=Translate("Id"); // Next coloum - LvCol.cx=130; // width of column - SendMessage(hwnd,LVM_INSERTCOLUMN,1,(LPARAM)&LvCol); // ... - LvCol.pszText=Translate("Protocol"); // - LvCol.cx=100; // width of column - SendMessage(hwnd,LVM_INSERTCOLUMN,2,(LPARAM)&LvCol); // - LvCol.pszText=Translate("Default"); // - LvCol.cx=60; // width of column - SendMessage(hwnd,LVM_INSERTCOLUMN,3,(LPARAM)&LvCol); // - LvCol.pszText=Translate("Send Offline"); // - LvCol.cx=85; // width of column - SendMessage(hwnd,LVM_INSERTCOLUMN,4,(LPARAM)&LvCol); // - - // disable buttons until a selection is made in the list - hwnd = GetDlgItem(hwndDlg, IDC_BTN_REM); - EnableWindow(hwnd, FALSE); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_SETDEFAULT); - EnableWindow(hwnd, FALSE); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_SETOFFLINE); - EnableWindow(hwnd, FALSE); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_UP); - EnableWindow(hwnd, FALSE); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_DOWN); - EnableWindow(hwnd, FALSE); - - nb_contacts = DBGetContactSettingDword((HANDLE)lParam, META_PROTO, "NumContacts", 0); - default_contact_number = DBGetContactSettingDword((HANDLE)lParam, META_PROTO, "Default", (DWORD)-1); - offline_contact_number = DBGetContactSettingDword((HANDLE)lParam, META_PROTO, "OfflineSend", (DWORD)-1); - - changes.hMeta = (HANDLE)lParam; - changes.num_contacts = nb_contacts; - changes.num_deleted = 0; - changes.hDefaultContact = Meta_GetContactHandle((HANDLE)lParam, default_contact_number); - changes.hOfflineContact = Meta_GetContactHandle((HANDLE)lParam, offline_contact_number); - for (i = 0; i < nb_contacts; i++) - changes.hContact[i] = Meta_GetContactHandle((HANDLE)lParam, i); - changes.force_default = MetaAPI_GetForceState((WPARAM)lParam, 0); - - SendMessage(hwndDlg, WMU_SETTITLE, 0, lParam); - - CheckDlgButton(hwndDlg, IDC_CHK_FORCEDEFAULT, changes.force_default); - - FillContactList(hwndDlg, &changes); - return TRUE; - } - case WMU_SETTITLE: - { - - char *szCDN = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)lParam, 0); - if (os_unicode_enabled) { - wchar_t *swzCDN = (wchar_t *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)lParam, GCDNF_UNICODE), - *swzContactDisplayName; - - // detect if the clist provided unicode display name by comparing with non-unicode - if (szCDN && swzCDN && strncmp(szCDN, (char *)swzCDN, strlen(szCDN)) != 0 && wcslen(swzCDN) >= strlen(szCDN)) { - swzContactDisplayName = swzCDN; - } 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)"); - } - } - - SetWindowTextW(GetDlgItem(hwndDlg,IDC_ED_NAME), swzContactDisplayName); - } else { - SetWindowText(GetDlgItem(hwndDlg,IDC_ED_NAME), szCDN); - } - } - return TRUE; - case WM_NOTIFY: // the message that is being sent always - switch(LOWORD(wParam)) // hit control - { - case IDC_LST_CONTACTS: // did we hit our ListView contorl? - if (((LPNMHDR)lParam)->code == NM_CLICK) { - hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); - sel=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED|LVNI_SELECTED); // return item selected - // enable buttons - hwnd = GetDlgItem(hwndDlg, IDC_BTN_REM); - EnableWindow(hwnd, sel!=-1); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_SETDEFAULT); - EnableWindow(hwnd, sel!=-1 && changes.hContact[sel] != changes.hDefaultContact); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_SETOFFLINE); - EnableWindow(hwnd, sel!=-1 && changes.hContact[sel] != changes.hOfflineContact); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_UP); - EnableWindow(hwnd, (sel > 0)); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_DOWN); - EnableWindow(hwnd, (sel != -1) && (sel < changes.num_contacts - 1)); -/* - // custom draw stuff - change colour of listview things - doesn't affect selection :( - } else if (((LPNMHDR)lParam)->code == NM_CUSTOMDRAW) { - SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, (LONG)ProcessCustomDraw(lParam)); - return TRUE; -*/ - } - break; - } - break; - case WM_COMMAND: - switch(HIWORD(wParam)) - { - case BN_CLICKED: // A button ('Remove', 'Ok', 'Cancel' or 'Apply', normally) has been clicked - switch(LOWORD(wParam)) - { - case IDC_VALIDATE: // Apply changes, if there is still one contact attached to the metacontact. - if (changes.num_contacts == 0) // Otherwise, delete the metacontact. - { - if (MessageBox(hwndDlg,Translate("You are going to remove all the contacts associated with this MetaContact.\nThis will delete the MetaContact.\n\nProceed Anyway?"), - Translate("Delete MetaContact?"),MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON1)!=IDYES) - return TRUE; - else - { - Meta_Delete((WPARAM)changes.hMeta,(LPARAM)NULL); - DestroyWindow(hwndDlg); - return TRUE; - } - } - ApplyChanges(&changes); - - // Disable the 'Apply' button. - EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),FALSE); - break; - case IDOK: - if (IsWindowEnabled(GetDlgItem(hwndDlg,IDC_VALIDATE))) - { // If there are changes that could be made, - if (changes.num_contacts == 0) // do the work that would have be done if - { // the button 'Apply' has been clicked. - if (MessageBox(hwndDlg,Translate("You are going to remove all the contacts associated with this MetaContact.\nThis will delete the MetaContact.\n\nProceed Anyway?"), - Translate("Delete MetaContact?"),MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON1)!=IDYES) - { - return TRUE; - } else { - Meta_Delete((WPARAM)changes.hMeta,(LPARAM)NULL); - DestroyWindow(hwndDlg); - return TRUE; - } - } - ApplyChanges(&changes); - } - EndDialog(hwndDlg, IDOK); - return TRUE; - case IDCANCEL: // Simply close the dialog - EndDialog(hwndDlg, IDCANCEL); - return TRUE; - case IDC_BTN_SETDEFAULT: - hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); - sel=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED|LVNI_SELECTED); // return item selected - InvalidateRect(hwnd, 0, TRUE); - changes.hDefaultContact = changes.hContact[sel]; - SendMessage(hwndDlg, WMU_SETTITLE, 0, (LPARAM)changes.hContact[sel]); - - FillContactList(hwndDlg, &changes); - SetListSelection(hwnd, sel); - // Disable set default button - EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_SETDEFAULT),FALSE); - // Enable the 'Apply' button. - EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); - - // repaint list - return TRUE; - case IDC_BTN_SETOFFLINE: - hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); - sel=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED|LVNI_SELECTED); // return item selected - InvalidateRect(hwnd, 0, TRUE); - changes.hOfflineContact = changes.hContact[sel]; - - FillContactList(hwndDlg, &changes); - SetListSelection(hwnd, sel); - // Disable set offline button - EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_SETOFFLINE),FALSE); - // Enable the 'Apply' button. - EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); - - // repaint list - return TRUE; - case IDC_BTN_REM: - hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); - sel=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED|LVNI_SELECTED); // return item selected - changes.num_contacts--; - changes.hDeletedContacts[changes.num_deleted++] = changes.hContact[sel]; - if (changes.hDefaultContact == changes.hContact[sel]) { - if (changes.num_contacts > 0) { - changes.hDefaultContact = changes.hContact[0]; - str = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)changes.hDefaultContact, 0); - SetWindowText(GetDlgItem(hwndDlg,IDC_ED_DEFAULT),str); - } else { - changes.hDefaultContact = 0; - SetWindowText(GetDlgItem(hwndDlg,IDC_ED_DEFAULT),"None"); - } - - } - - for (i = sel; i < changes.num_contacts; i++) - changes.hContact[i] = changes.hContact[i + 1]; - FillContactList(hwndDlg, &changes); - // disable buttons - hwnd = GetDlgItem(hwndDlg, IDC_BTN_REM); - EnableWindow(hwnd, FALSE); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_SETDEFAULT); - EnableWindow(hwnd, FALSE); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_SETOFFLINE); - EnableWindow(hwnd, FALSE); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_UP); - EnableWindow(hwnd, FALSE); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_DOWN); - EnableWindow(hwnd, FALSE); - // Enable the 'Apply' button. - EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); - return TRUE; - case IDC_BTN_UP: - hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); - sel=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED|LVNI_SELECTED); // return item selected - - { - HANDLE temp = changes.hContact[sel]; - changes.hContact[sel] = changes.hContact[sel - 1]; - changes.hContact[sel - 1] = temp; - } - FillContactList(hwndDlg, &changes); - sel--; - SetListSelection(hwnd, sel); - - hwnd = GetDlgItem(hwndDlg, IDC_BTN_UP); - EnableWindow(hwnd, (sel > 0)); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_DOWN); - EnableWindow(hwnd, (sel < changes.num_contacts - 1)); - // Enable the 'Apply' button. - EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); - return TRUE; - case IDC_BTN_DOWN: - hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); - sel=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED|LVNI_SELECTED); // return item selected - - { - HANDLE temp = changes.hContact[sel]; - changes.hContact[sel] = changes.hContact[sel + 1]; - changes.hContact[sel + 1] = temp; - } - FillContactList(hwndDlg, &changes); - sel++; - SetListSelection(hwnd, sel); - - hwnd = GetDlgItem(hwndDlg, IDC_BTN_UP); - EnableWindow(hwnd, (sel > 0)); - hwnd = GetDlgItem(hwndDlg, IDC_BTN_DOWN); - EnableWindow(hwnd, (sel < changes.num_contacts - 1)); - // Enable the 'Apply' button. - EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); - return TRUE; - case IDC_CHK_FORCEDEFAULT: - changes.force_default = IsDlgButtonChecked(hwndDlg, IDC_CHK_FORCEDEFAULT); - // Enable the 'Apply' button. - EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); - return TRUE; - } - } - break; - case WM_CLOSE: - DestroyWindow(hwndDlg); - return TRUE; - - case WM_DESTROY: - ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0)); - EndDialog(hwndDlg, IDCANCEL); - break; - } - - return FALSE; -} diff --git a/plugins/MetaContacts/edit.cpp b/plugins/MetaContacts/edit.cpp new file mode 100644 index 0000000000..a5866576dd --- /dev/null +++ b/plugins/MetaContacts/edit.cpp @@ -0,0 +1,585 @@ +/* +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 edit.c +* +* Functions for the 'Edit' Dialog. +* Contains all the functions and all the structures +* needed to display and control the 'Edit' Dialog. +*/ +#include "metacontacts.h" + +//! Holds the differents changes that have to made +typedef struct tag_CHANGES { + HANDLE hMeta; //!< \c HANDLE of the MetaContact that is edited. + HANDLE hDefaultContact; //!< \c HANDLE of the new default contact + HANDLE hOfflineContact; + int num_deleted, //!< \c DWORD number of deleted contacts + num_contacts; //!< \c DWORD number of contacts + HANDLE hDeletedContacts[MAX_CONTACTS]; //!< \c HANDLEs of the subcontacts to be removed from this metacontact + HANDLE hContact[MAX_CONTACTS]; //!< \c HANDLEs of the subcontacts, in the order they should be in + int force_default; +} CHANGES; + +CHANGES changes; //!< \c global CHANGES structure + +/** Fills the list of contacts +* +* @param chg : Structure holding all the change info (See CHANGES). +*/ +void FillContactList(HWND hWndDlg, CHANGES *chg) { + HWND hList = GetDlgItem(hWndDlg, IDC_LST_CONTACTS); + char *proto, *field, buff[256]; + int i; + LVITEM LvItem; + DBVARIANT dbv; + LVITEMW LvItemW; // for unicode nicks + + + SendMessage(hList,LVM_DELETEALLITEMS,0,0); + + ZeroMemory(&LvItem, sizeof(LvItem)); + LvItem.mask=LVIF_TEXT; // Text Style + LvItem.cchTextMax = 256; // Max size of test + + ZeroMemory(&LvItemW, sizeof(LvItemW)); + LvItemW.mask=LVIF_TEXT; // Text Style + LvItemW.cchTextMax = 256; // Max size of test + + for (i = 0; i < chg->num_contacts; i++) { + LvItem.iItem = i; + LvItemW.iItem = i; + + { + + char *szCDN = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)chg->hContact[i], 0); + + if (os_unicode_enabled) { + wchar_t *swzCDN = (wchar_t *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)chg->hContact[i], GCDNF_UNICODE), + *swzContactDisplayName; + + LvItemW.iSubItem = 0; // clist display name + + // detect if the clist provided unicode display name by comparing with non-unicode + if (szCDN && swzCDN && strncmp(szCDN, (char *)swzCDN, strlen(szCDN)) != 0 && wcslen(swzCDN) >= strlen(szCDN)) { + swzContactDisplayName = swzCDN; + } 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)"); + } + } + + LvItemW.pszText = swzContactDisplayName; + SendMessageW(hList, LVM_INSERTITEMW, (WPARAM)0, (LPARAM)&LvItemW); + } else { + LvItem.iSubItem = 0; // clist display name + LvItem.pszText = szCDN; + SendMessage(hList, LVM_INSERTITEM, (WPARAM)0, (LPARAM)&LvItem); + } + } + + + + LvItem.iSubItem = 1; // id + + proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)chg->hContact[i], 0); + if (proto) { + field = (char *)CallProtoService(proto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0); + + DBGetContactSetting(chg->hContact[i],proto,field,&dbv); + switch(dbv.type) + { + case DBVT_ASCIIZ: + sprintf(buff,"%s",dbv.pszVal); + break; + case DBVT_BYTE: + sprintf(buff,"%d",dbv.bVal); + break; + case DBVT_WORD: + sprintf(buff,"%d",dbv.wVal); + break; + case DBVT_DWORD: + sprintf(buff,"%d",(int)dbv.dVal); + break; + default: + //sprintf(buff,""); + buff[0] = 0; + } + DBFreeVariant(&dbv); + + LvItem.pszText = buff; + SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems + + LvItem.iSubItem = 2; // protocol + LvItem.pszText = proto; + SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems + } else { + LvItem.pszText = "Unknown"; + SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems + + LvItem.iSubItem = 2; // protocol + LvItem.pszText = "Unknown"; + SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems + } + LvItem.iSubItem = 3; // Default (Yes/No) + LvItem.pszText = (chg->hContact[i] == chg->hDefaultContact ? Translate("Yes") : Translate("No")); + SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems + + LvItem.iSubItem = 4; // Offline (Yes/No) + LvItem.pszText = (chg->hContact[i] == chg->hOfflineContact ? Translate("Yes") : Translate("No")); + SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems + } +} + + +void SetListSelection(HWND hList, int sel) { + LVITEM LvItem; + + ZeroMemory(&LvItem, sizeof(LvItem)); + LvItem.iItem = sel; + LvItem.mask = LVIF_STATE; + LvItem.stateMask = LVIS_SELECTED|LVIS_FOCUSED; + LvItem.state = LVIS_SELECTED|LVIS_FOCUSED; + + SendMessage(hList, LVM_SETITEMSTATE, (WPARAM)sel, (LPARAM)&LvItem); + +} + +/** Scans the \c CHANGES and call the appropriate function for each change. +* +* @param chg : Structure holding all the change info (See CHANGES). +*/ +void ApplyChanges(CHANGES *chg) +{ + HANDLE most_online; + int i; + + // remove removed contacts + for (i = 0; i < chg->num_deleted; i++) { + Meta_Delete((WPARAM)chg->hDeletedContacts[i], 0); + if (chg->hDeletedContacts[i] == chg->hDefaultContact) + chg->hDefaultContact = 0; + if (chg->hDeletedContacts[i] == chg->hOfflineContact) + chg->hOfflineContact = 0; + } + + // set contact positions + for (i = 0; i < chg->num_contacts; i++) { + if (Meta_GetContactNumber(chg->hContact[i]) != i) + Meta_SwapContacts(chg->hMeta, Meta_GetContactNumber(chg->hContact[i]), i); + } + + NotifyEventHooks(hSubcontactsChanged, (WPARAM)chg->hMeta, (LPARAM)chg->hDefaultContact); + + // set default + if (chg->hDefaultContact) + DBWriteContactSettingDword(chg->hMeta, META_PROTO, "Default", Meta_GetContactNumber(chg->hDefaultContact)); + else + DBWriteContactSettingDword(chg->hMeta, META_PROTO, "Default", 0); + NotifyEventHooks(hEventDefaultChanged, (WPARAM)chg->hMeta, (LPARAM)chg->hDefaultContact); + + // set offline + if (chg->hOfflineContact) + DBWriteContactSettingDword(chg->hMeta, META_PROTO, "OfflineSend", Meta_GetContactNumber(chg->hOfflineContact)); + else + DBWriteContactSettingDword(chg->hMeta, META_PROTO, "OfflineSend", (DWORD)-1); + + // fix nick + most_online = Meta_GetMostOnline(chg->hMeta); + Meta_CopyContactNick(chg->hMeta, most_online); + + // fix status + Meta_FixStatus(chg->hMeta); + + // fix avatar + most_online = Meta_GetMostOnlineSupporting(chg->hMeta, PFLAGNUM_4, PF4_AVATARS); + if (most_online) { + PROTO_AVATAR_INFORMATIONT AI; + + AI.cbSize = sizeof(AI); + AI.hContact = chg->hMeta; + AI.format = PA_FORMAT_UNKNOWN; + _tcscpy(AI.filename, _T("X")); + + if ((int)CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) + DBWriteContactSettingTString(chg->hMeta, "ContactPhoto", "File",AI.filename); + } + + if (MetaAPI_GetForceState((WPARAM)chg->hMeta, 0) != chg->force_default) + MetaAPI_ForceDefault((WPARAM)chg->hMeta, 0); +} + +LRESULT ProcessCustomDraw (LPARAM lParam) +{ + LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam; + + switch(lplvcd->nmcd.dwDrawStage) + { + case CDDS_PREPAINT : //Before the paint cycle begins + //request notifications for individual listview items + return CDRF_NOTIFYITEMDRAW; + + case CDDS_ITEMPREPAINT: //Before an item is drawn + /* + if (((int)lplvcd->nmcd.dwItemSpec%2)==0) + { + //customize item appearance + //lplvcd->clrText = RGB(255,0,0); + lplvcd->clrTextBk = RGB(200,200,200); + } + else{ + //lplvcd->clrText = RGB(0,0,255); + lplvcd->clrTextBk = RGB(255,255,255); + } + */ + if (changes.hContact[(int)lplvcd->nmcd.dwItemSpec] == changes.hDefaultContact) { + lplvcd->clrText = RGB(255, 0, 0); + } + return CDRF_NEWFONT; + } + + return 0; +} + +/** Callback function for the 'Edit' Dialog. +* +* All the UI is controlled here, from display to functionnalities. +* +* @param hwndDlg : \c HANDLE to the 'Edit' \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 (handle of MetaContact to edit) +* +* @return \c TRUE if the dialog processed the message, \c FALSE if it did not. +*/ +#define WMU_SETTITLE (WM_USER + 1) + +INT_PTR CALLBACK Meta_EditDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd; + char *str; + int sel, i; + + switch(msg) + { + case WM_INITDIALOG: + { + // Font necessary for all controls created with CreateWindowsEx + //HFONT hfDefault = GetStockObject(DEFAULT_GUI_FONT); + //HWND combo = GetDlgItem(hwndDlg,IDC_DEFAULT); + int nb_contacts, default_contact_number, offline_contact_number; + LVCOLUMN LvCol; + + TranslateDialogDefault( hwndDlg ); + + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIconEx(I_EDIT)); + + // Disable the 'Apply' button. + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),FALSE); + + // (from http://www.codeproject.com/listctrl/listview.asp) + // initialize list + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + SendMessage(hwnd,LVM_SETEXTENDEDLISTVIEWSTYLE, 0,LVS_EX_FULLROWSELECT); // Set style + + // Create list columns + ZeroMemory(&LvCol, sizeof(LvCol)); + LvCol.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; // Type of mask + + // Inserting Couloms as much as we want + LvCol.pszText=Translate("Contact"); // First Header Text + LvCol.cx=100; // width of column + SendMessage(hwnd,LVM_INSERTCOLUMN,0,(LPARAM)&LvCol); // Insert/Show the coloum + + LvCol.pszText=Translate("Id"); // Next coloum + LvCol.cx=130; // width of column + SendMessage(hwnd,LVM_INSERTCOLUMN,1,(LPARAM)&LvCol); // ... + LvCol.pszText=Translate("Protocol"); // + LvCol.cx=100; // width of column + SendMessage(hwnd,LVM_INSERTCOLUMN,2,(LPARAM)&LvCol); // + LvCol.pszText=Translate("Default"); // + LvCol.cx=60; // width of column + SendMessage(hwnd,LVM_INSERTCOLUMN,3,(LPARAM)&LvCol); // + LvCol.pszText=Translate("Send Offline"); // + LvCol.cx=85; // width of column + SendMessage(hwnd,LVM_INSERTCOLUMN,4,(LPARAM)&LvCol); // + + // disable buttons until a selection is made in the list + hwnd = GetDlgItem(hwndDlg, IDC_BTN_REM); + EnableWindow(hwnd, FALSE); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_SETDEFAULT); + EnableWindow(hwnd, FALSE); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_SETOFFLINE); + EnableWindow(hwnd, FALSE); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_UP); + EnableWindow(hwnd, FALSE); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_DOWN); + EnableWindow(hwnd, FALSE); + + nb_contacts = DBGetContactSettingDword((HANDLE)lParam, META_PROTO, "NumContacts", 0); + default_contact_number = DBGetContactSettingDword((HANDLE)lParam, META_PROTO, "Default", (DWORD)-1); + offline_contact_number = DBGetContactSettingDword((HANDLE)lParam, META_PROTO, "OfflineSend", (DWORD)-1); + + changes.hMeta = (HANDLE)lParam; + changes.num_contacts = nb_contacts; + changes.num_deleted = 0; + changes.hDefaultContact = Meta_GetContactHandle((HANDLE)lParam, default_contact_number); + changes.hOfflineContact = Meta_GetContactHandle((HANDLE)lParam, offline_contact_number); + for (i = 0; i < nb_contacts; i++) + changes.hContact[i] = Meta_GetContactHandle((HANDLE)lParam, i); + changes.force_default = MetaAPI_GetForceState((WPARAM)lParam, 0); + + SendMessage(hwndDlg, WMU_SETTITLE, 0, lParam); + + CheckDlgButton(hwndDlg, IDC_CHK_FORCEDEFAULT, changes.force_default); + + FillContactList(hwndDlg, &changes); + return TRUE; + } + case WMU_SETTITLE: + { + + char *szCDN = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)lParam, 0); + if (os_unicode_enabled) { + wchar_t *swzCDN = (wchar_t *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)lParam, GCDNF_UNICODE), + *swzContactDisplayName; + + // detect if the clist provided unicode display name by comparing with non-unicode + if (szCDN && swzCDN && strncmp(szCDN, (char *)swzCDN, strlen(szCDN)) != 0 && wcslen(swzCDN) >= strlen(szCDN)) { + swzContactDisplayName = swzCDN; + } 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)"); + } + } + + SetWindowTextW(GetDlgItem(hwndDlg,IDC_ED_NAME), swzContactDisplayName); + } else { + SetWindowText(GetDlgItem(hwndDlg,IDC_ED_NAME), szCDN); + } + } + return TRUE; + case WM_NOTIFY: // the message that is being sent always + switch(LOWORD(wParam)) // hit control + { + case IDC_LST_CONTACTS: // did we hit our ListView contorl? + if (((LPNMHDR)lParam)->code == NM_CLICK) { + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + sel=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED|LVNI_SELECTED); // return item selected + // enable buttons + hwnd = GetDlgItem(hwndDlg, IDC_BTN_REM); + EnableWindow(hwnd, sel!=-1); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_SETDEFAULT); + EnableWindow(hwnd, sel!=-1 && changes.hContact[sel] != changes.hDefaultContact); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_SETOFFLINE); + EnableWindow(hwnd, sel!=-1 && changes.hContact[sel] != changes.hOfflineContact); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_UP); + EnableWindow(hwnd, (sel > 0)); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_DOWN); + EnableWindow(hwnd, (sel != -1) && (sel < changes.num_contacts - 1)); +/* + // custom draw stuff - change colour of listview things - doesn't affect selection :( + } else if (((LPNMHDR)lParam)->code == NM_CUSTOMDRAW) { + SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, (LONG)ProcessCustomDraw(lParam)); + return TRUE; +*/ + } + break; + } + break; + case WM_COMMAND: + switch(HIWORD(wParam)) + { + case BN_CLICKED: // A button ('Remove', 'Ok', 'Cancel' or 'Apply', normally) has been clicked + switch(LOWORD(wParam)) + { + case IDC_VALIDATE: // Apply changes, if there is still one contact attached to the metacontact. + if (changes.num_contacts == 0) // Otherwise, delete the metacontact. + { + if (MessageBox(hwndDlg,Translate("You are going to remove all the contacts associated with this MetaContact.\nThis will delete the MetaContact.\n\nProceed Anyway?"), + Translate("Delete MetaContact?"),MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON1)!=IDYES) + return TRUE; + else + { + Meta_Delete((WPARAM)changes.hMeta,(LPARAM)NULL); + DestroyWindow(hwndDlg); + return TRUE; + } + } + ApplyChanges(&changes); + + // Disable the 'Apply' button. + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),FALSE); + break; + case IDOK: + if (IsWindowEnabled(GetDlgItem(hwndDlg,IDC_VALIDATE))) + { // If there are changes that could be made, + if (changes.num_contacts == 0) // do the work that would have be done if + { // the button 'Apply' has been clicked. + if (MessageBox(hwndDlg,Translate("You are going to remove all the contacts associated with this MetaContact.\nThis will delete the MetaContact.\n\nProceed Anyway?"), + Translate("Delete MetaContact?"),MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON1)!=IDYES) + { + return TRUE; + } else { + Meta_Delete((WPARAM)changes.hMeta,(LPARAM)NULL); + DestroyWindow(hwndDlg); + return TRUE; + } + } + ApplyChanges(&changes); + } + EndDialog(hwndDlg, IDOK); + return TRUE; + case IDCANCEL: // Simply close the dialog + EndDialog(hwndDlg, IDCANCEL); + return TRUE; + case IDC_BTN_SETDEFAULT: + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + sel=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED|LVNI_SELECTED); // return item selected + InvalidateRect(hwnd, 0, TRUE); + changes.hDefaultContact = changes.hContact[sel]; + SendMessage(hwndDlg, WMU_SETTITLE, 0, (LPARAM)changes.hContact[sel]); + + FillContactList(hwndDlg, &changes); + SetListSelection(hwnd, sel); + // Disable set default button + EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_SETDEFAULT),FALSE); + // Enable the 'Apply' button. + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); + + // repaint list + return TRUE; + case IDC_BTN_SETOFFLINE: + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + sel=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED|LVNI_SELECTED); // return item selected + InvalidateRect(hwnd, 0, TRUE); + changes.hOfflineContact = changes.hContact[sel]; + + FillContactList(hwndDlg, &changes); + SetListSelection(hwnd, sel); + // Disable set offline button + EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_SETOFFLINE),FALSE); + // Enable the 'Apply' button. + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); + + // repaint list + return TRUE; + case IDC_BTN_REM: + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + sel=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED|LVNI_SELECTED); // return item selected + changes.num_contacts--; + changes.hDeletedContacts[changes.num_deleted++] = changes.hContact[sel]; + if (changes.hDefaultContact == changes.hContact[sel]) { + if (changes.num_contacts > 0) { + changes.hDefaultContact = changes.hContact[0]; + str = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)changes.hDefaultContact, 0); + SetWindowText(GetDlgItem(hwndDlg,IDC_ED_DEFAULT),str); + } else { + changes.hDefaultContact = 0; + SetWindowText(GetDlgItem(hwndDlg,IDC_ED_DEFAULT),"None"); + } + + } + + for (i = sel; i < changes.num_contacts; i++) + changes.hContact[i] = changes.hContact[i + 1]; + FillContactList(hwndDlg, &changes); + // disable buttons + hwnd = GetDlgItem(hwndDlg, IDC_BTN_REM); + EnableWindow(hwnd, FALSE); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_SETDEFAULT); + EnableWindow(hwnd, FALSE); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_SETOFFLINE); + EnableWindow(hwnd, FALSE); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_UP); + EnableWindow(hwnd, FALSE); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_DOWN); + EnableWindow(hwnd, FALSE); + // Enable the 'Apply' button. + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); + return TRUE; + case IDC_BTN_UP: + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + sel=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED|LVNI_SELECTED); // return item selected + + { + HANDLE temp = changes.hContact[sel]; + changes.hContact[sel] = changes.hContact[sel - 1]; + changes.hContact[sel - 1] = temp; + } + FillContactList(hwndDlg, &changes); + sel--; + SetListSelection(hwnd, sel); + + hwnd = GetDlgItem(hwndDlg, IDC_BTN_UP); + EnableWindow(hwnd, (sel > 0)); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_DOWN); + EnableWindow(hwnd, (sel < changes.num_contacts - 1)); + // Enable the 'Apply' button. + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); + return TRUE; + case IDC_BTN_DOWN: + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + sel=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED|LVNI_SELECTED); // return item selected + + { + HANDLE temp = changes.hContact[sel]; + changes.hContact[sel] = changes.hContact[sel + 1]; + changes.hContact[sel + 1] = temp; + } + FillContactList(hwndDlg, &changes); + sel++; + SetListSelection(hwnd, sel); + + hwnd = GetDlgItem(hwndDlg, IDC_BTN_UP); + EnableWindow(hwnd, (sel > 0)); + hwnd = GetDlgItem(hwndDlg, IDC_BTN_DOWN); + EnableWindow(hwnd, (sel < changes.num_contacts - 1)); + // Enable the 'Apply' button. + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); + return TRUE; + case IDC_CHK_FORCEDEFAULT: + changes.force_default = IsDlgButtonChecked(hwndDlg, IDC_CHK_FORCEDEFAULT); + // Enable the 'Apply' button. + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); + return TRUE; + } + } + break; + case WM_CLOSE: + DestroyWindow(hwndDlg); + return TRUE; + + case WM_DESTROY: + ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0)); + EndDialog(hwndDlg, IDCANCEL); + break; + } + + return FALSE; +} diff --git a/plugins/MetaContacts/icons.c b/plugins/MetaContacts/icons.c deleted file mode 100644 index 829636be1f..0000000000 --- a/plugins/MetaContacts/icons.c +++ /dev/null @@ -1,101 +0,0 @@ -#include "metacontacts.h" - -HANDLE hIcoLibIconsChanged = NULL; - - -typedef struct { - char* szDescr; - char* szName; - int defIconID; -} IconStruct; - -static IconStruct iconList[] = { - { "Toggle Off", "mc_off", IDI_MCMENUOFF }, - { "Toggle On", "mc_on", IDI_MCMENU }, - { "Convert to MetaContact", "mc_convert", IDI_MCCONVERT }, - { "Add to Existing", "mc_add", IDI_MCADD }, - { "Edit", "mc_edit", IDI_MCEDIT }, - { "Set to Default", "mc_default", IDI_MCSETDEFAULT }, - { "Remove", "mc_remove", IDI_MCREMOVE }, -}; - - -HICON LoadIconEx(IconIndex i) { - HICON hIcon; - - if (hIcoLibIconsChanged) - hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)iconList[(int)i].szName); - else - hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(iconList[(int)i].defIconID), IMAGE_ICON, 0, 0, 0); - - return hIcon; -} - - -void ReleaseIconEx(HICON hIcon) { - if (hIcoLibIconsChanged) - CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0); - else - DestroyIcon(hIcon); -} - -int ReloadIcons(WPARAM wParam, LPARAM lParam) { - // fix menu icons - CLISTMENUITEM menu = {0}; - - menu.cbSize = sizeof(menu); - menu.flags = CMIM_ICON; - - menu.hIcon = LoadIconEx(Meta_IsEnabled() ? I_MENUOFF : I_MENU); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuOnOff, (LPARAM)&menu); - ReleaseIconEx(menu.hIcon); - - menu.hIcon = LoadIconEx(I_CONVERT); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&menu); - ReleaseIconEx(menu.hIcon); - - menu.hIcon = LoadIconEx(I_ADD); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&menu); - ReleaseIconEx(menu.hIcon); - - menu.hIcon = LoadIconEx(I_EDIT); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&menu); - ReleaseIconEx(menu.hIcon); - - menu.hIcon = LoadIconEx(I_SETDEFAULT); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&menu); - ReleaseIconEx(menu.hIcon); - - menu.hIcon = LoadIconEx(I_REMOVE); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&menu); - ReleaseIconEx(menu.hIcon); - - return 0; -} - -void InitIcons(void) { - SKINICONDESC sid = {0}; - char path[MAX_PATH]; - int i; - - sid.cbSize = sizeof(SKINICONDESC); - sid.pszSection = META_PROTO; - sid.pszDefaultFile = path; - GetModuleFileName(hInstance, path, sizeof(path)); - - for (i = 0; i < sizeof(iconList) / sizeof(IconStruct); ++i) - { - sid.pszDescription = Translate(iconList[i].szDescr); - sid.pszName = iconList[i].szName; - sid.iDefaultIndex = -iconList[i].defIconID; - Skin_AddIcon(&sid); - } - - hIcoLibIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, ReloadIcons); - - ReloadIcons(0, 0); -} - -void DeinitIcons(void) { - if (hIcoLibIconsChanged) UnhookEvent(hIcoLibIconsChanged); -} diff --git a/plugins/MetaContacts/icons.cpp b/plugins/MetaContacts/icons.cpp new file mode 100644 index 0000000000..829636be1f --- /dev/null +++ b/plugins/MetaContacts/icons.cpp @@ -0,0 +1,101 @@ +#include "metacontacts.h" + +HANDLE hIcoLibIconsChanged = NULL; + + +typedef struct { + char* szDescr; + char* szName; + int defIconID; +} IconStruct; + +static IconStruct iconList[] = { + { "Toggle Off", "mc_off", IDI_MCMENUOFF }, + { "Toggle On", "mc_on", IDI_MCMENU }, + { "Convert to MetaContact", "mc_convert", IDI_MCCONVERT }, + { "Add to Existing", "mc_add", IDI_MCADD }, + { "Edit", "mc_edit", IDI_MCEDIT }, + { "Set to Default", "mc_default", IDI_MCSETDEFAULT }, + { "Remove", "mc_remove", IDI_MCREMOVE }, +}; + + +HICON LoadIconEx(IconIndex i) { + HICON hIcon; + + if (hIcoLibIconsChanged) + hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)iconList[(int)i].szName); + else + hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(iconList[(int)i].defIconID), IMAGE_ICON, 0, 0, 0); + + return hIcon; +} + + +void ReleaseIconEx(HICON hIcon) { + if (hIcoLibIconsChanged) + CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0); + else + DestroyIcon(hIcon); +} + +int ReloadIcons(WPARAM wParam, LPARAM lParam) { + // fix menu icons + CLISTMENUITEM menu = {0}; + + menu.cbSize = sizeof(menu); + menu.flags = CMIM_ICON; + + menu.hIcon = LoadIconEx(Meta_IsEnabled() ? I_MENUOFF : I_MENU); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuOnOff, (LPARAM)&menu); + ReleaseIconEx(menu.hIcon); + + menu.hIcon = LoadIconEx(I_CONVERT); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&menu); + ReleaseIconEx(menu.hIcon); + + menu.hIcon = LoadIconEx(I_ADD); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&menu); + ReleaseIconEx(menu.hIcon); + + menu.hIcon = LoadIconEx(I_EDIT); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&menu); + ReleaseIconEx(menu.hIcon); + + menu.hIcon = LoadIconEx(I_SETDEFAULT); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&menu); + ReleaseIconEx(menu.hIcon); + + menu.hIcon = LoadIconEx(I_REMOVE); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&menu); + ReleaseIconEx(menu.hIcon); + + return 0; +} + +void InitIcons(void) { + SKINICONDESC sid = {0}; + char path[MAX_PATH]; + int i; + + sid.cbSize = sizeof(SKINICONDESC); + sid.pszSection = META_PROTO; + sid.pszDefaultFile = path; + GetModuleFileName(hInstance, path, sizeof(path)); + + for (i = 0; i < sizeof(iconList) / sizeof(IconStruct); ++i) + { + sid.pszDescription = Translate(iconList[i].szDescr); + sid.pszName = iconList[i].szName; + sid.iDefaultIndex = -iconList[i].defIconID; + Skin_AddIcon(&sid); + } + + hIcoLibIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, ReloadIcons); + + ReloadIcons(0, 0); +} + +void DeinitIcons(void) { + if (hIcoLibIconsChanged) UnhookEvent(hIcoLibIconsChanged); +} diff --git a/plugins/MetaContacts/meta_api.c b/plugins/MetaContacts/meta_api.c deleted file mode 100644 index 331bdb55d5..0000000000 --- a/plugins/MetaContacts/meta_api.c +++ /dev/null @@ -1,245 +0,0 @@ -/* -MetaContacts Plugin for Miranda IM. - -Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. -Copyright © 2004 Scott Ellis (www.scottellis.com.au mail@scottellis.com.au) - -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 meta_api.c -* -* API functions needed to handle MetaContacts. -* Centralizes functions called by other plugins. -*/ - -#include "metacontacts.h" - -//get the handle for a contact's parent metacontact -//wParam=(HANDLE)hSubContact -//lParam=0 -//returns a handle to the parent metacontact, or null if this contact is not a subcontact -INT_PTR MetaAPI_GetMeta(WPARAM wParam, LPARAM lParam) { - return (int)(HANDLE)DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Handle", 0); -} - -//gets the handle for the default contact -//wParam=(HANDLE)hMetaContact -//lParam=0 -//returns a handle to the default contact, or null on failure -INT_PTR MetaAPI_GetDefault(WPARAM wParam, LPARAM lParam) { - DWORD default_contact_number = DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Default", -1); - if (default_contact_number != -1) { - return (int)Meta_GetContactHandle((HANDLE)wParam, default_contact_number); - } - return 0; -} - -//gets the contact number for the default contact -//wParam=(HANDLE)hMetaContact -//lParam=0 -//returns a DWORD contact number, or -1 on failure -INT_PTR MetaAPI_GetDefaultNum(WPARAM wParam, LPARAM lParam) { - return DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Default", -1); -} - -//gets the handle for the 'most online' contact -//wParam=(HANDLE)hMetaContact -//lParam=0 -//returns a handle to the 'most online' contact -INT_PTR MetaAPI_GetMostOnline(WPARAM wParam, LPARAM lParam) { - return (int)Meta_GetMostOnline((HANDLE)wParam); -} - -//gets the number of subcontacts for a metacontact -//wParam=(HANDLE)hMetaContact -//lParam=0 -//returns a DWORD representing the number of subcontacts for the given metacontact -INT_PTR MetaAPI_GetNumContacts(WPARAM wParam, LPARAM lParam) { - DWORD num_contacts = DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "NumContacts", -1); - return num_contacts; -} - -//gets the handle of a subcontact, using the subcontact's number -//wParam=(HANDLE)hMetaContact -//lParam=(DWORD)contact number -//returns a handle to the specified subcontact -INT_PTR MetaAPI_GetContact(WPARAM wParam, LPARAM lParam) { - return (int)Meta_GetContactHandle((HANDLE)wParam, (DWORD)lParam); -} - -//sets the default contact, using the subcontact's contact number -//wParam=(HANDLE)hMetaContact -//lParam=(DWORD)contact number -//returns 0 on success -INT_PTR MetaAPI_SetDefaultContactNum(WPARAM wParam, LPARAM lParam) { - DWORD num_contacts = DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "NumContacts", -1); - if (num_contacts == -1) - return 1; - if ((DWORD)lParam >= num_contacts || (DWORD)lParam < 0) - return 1; - if (DBWriteContactSettingDword((HANDLE)wParam, META_PROTO, "Default", (DWORD)lParam)) - return 1; - - NotifyEventHooks(hEventDefaultChanged, wParam, (LPARAM)Meta_GetContactHandle((HANDLE)wParam, (int)lParam)); - return 0; -} - -//sets the default contact, using the subcontact's handle -//wParam=(HANDLE)hMetaContact -//lParam=(HANDLE)hSubcontact -//returns 0 on success -INT_PTR MetaAPI_SetDefaultContact(WPARAM wParam, LPARAM lParam) { - HANDLE hMeta = (HANDLE)DBGetContactSettingDword((HANDLE)lParam, META_PROTO, "Handle", 0); - DWORD contact_number = Meta_GetContactNumber((HANDLE)lParam); - if (contact_number == -1 || !hMeta || hMeta != (HANDLE)wParam) - return 1; - if (DBWriteContactSettingDword(hMeta, META_PROTO, "Default", contact_number)) - return 1; - - NotifyEventHooks(hEventDefaultChanged, wParam, lParam); - return 0; -} - -//forces the metacontact to send using a specific subcontact, using the subcontact's contact number -//wParam=(HANDLE)hMetaContact -//lParam=(DWORD)contact number -//returns 0 on success -INT_PTR MetaAPI_ForceSendContactNum(WPARAM wParam, LPARAM lParam) { - HANDLE hContact = Meta_GetContactHandle((HANDLE)wParam, (int)lParam); - HANDLE hMeta = (HANDLE)DBGetContactSettingDword(hContact, META_PROTO, "Handle", 0); - if (!hContact || !hMeta || hMeta != (HANDLE)wParam || DBGetContactSettingByte(hMeta, META_PROTO, "ForceDefault", 0)) - return 1; - - DBWriteContactSettingDword(hMeta, META_PROTO, "ForceSend", (DWORD)hContact); - - NotifyEventHooks(hEventForceSend, wParam, (LPARAM)hContact); - return 0; -} - -//forces the metacontact to send using a specific subcontact, using the subcontact's handle -//wParam=(HANDLE)hMetaContact -//lParam=(HANDLE)hSubcontact -//returns 0 on success (will fail if 'force default' is in effect) -INT_PTR MetaAPI_ForceSendContact(WPARAM wParam, LPARAM lParam) { - HANDLE hContact = (HANDLE)lParam; - HANDLE hMeta = (HANDLE)DBGetContactSettingDword(hContact, META_PROTO, "Handle", 0); - if (!hContact || !hMeta || hMeta != (HANDLE)wParam || DBGetContactSettingByte(hMeta, META_PROTO, "ForceDefault", 0)) - return 1; - - DBWriteContactSettingDword(hMeta, META_PROTO, "ForceSend", (DWORD)hContact); - - NotifyEventHooks(hEventForceSend, wParam, lParam); - return 0; -} - -//'unforces' the metacontact to send using a specific subcontact -//wParam=(HANDLE)hMetaContact -//lParam=0 -//returns 0 on success (will fail if 'force default' is in effect) -INT_PTR MetaAPI_UnforceSendContact(WPARAM wParam, LPARAM lParam) { - if (DBGetContactSettingByte((HANDLE)wParam, META_PROTO, "ForceDefault", 0)) - return 1; - - DBWriteContactSettingDword((HANDLE)wParam, META_PROTO, "ForceSend", 0); - - NotifyEventHooks(hEventUnforceSend, wParam, lParam); - return 0; -} - - -//'forces' or 'unforces' (i.e. toggles) the metacontact to send using it's default contact -// overrides 'force send' above, and will even force use of offline contacts -// will send ME_MC_FORCESEND event -//wParam=(HANDLE)hMetaContact -//lParam=0 -//returns 1(true) or 0(false) representing new state of 'force default' -INT_PTR MetaAPI_ForceDefault(WPARAM wParam, LPARAM lParam) { - // forward to menu function - Meta_ForceDefault(wParam, lParam); - return DBGetContactSettingByte((HANDLE)wParam, META_PROTO, "ForceDefault", 0); -} - -// method to get state of 'force' for a metacontact -// wParam=(HANDLE)hMetaContact -// lParam= (DWORD)&contact_number or NULL -// if lparam supplied, the contact_number of the contatct 'in force' will be copied to the address it points to, -// or if none is in force, the value (DWORD)-1 will be copied -// (v0.8.0.8+ returns 1 if 'force default' is true with *lParam == default contact number, else returns 0 with *lParam as above) -INT_PTR MetaAPI_GetForceState(WPARAM wParam, LPARAM lParam) { - HANDLE hMeta = (HANDLE)wParam; - HANDLE hContact; - - if (!hMeta) return 0; - - if (DBGetContactSettingByte(hMeta, META_PROTO, "ForceDefault", 0)) { - if (lParam) *(DWORD *)lParam = DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Default", -1); - return 1; - } - - hContact = (HANDLE)DBGetContactSettingDword(hMeta, META_PROTO, "ForceSend", 0); - - if (!hContact) { - if (lParam) *(DWORD *)lParam = -1; - } else { - if (lParam) *(DWORD *)lParam = (DWORD)Meta_GetContactNumber(hContact); - } - - return 0; -} - -// method to get protocol name - used to be sure you're dealing with a "real" metacontacts plugin :) -// wParam=lParam=0 -INT_PTR MetaAPI_GetProtoName(WPARAM wParam, LPARAM lParam) { - return (int)META_PROTO; -} - -// added 0.9.5.0 (22/3/05) -// wParam=(HANDLE)hContact -// lParam=0 -// convert a given contact into a metacontact -INT_PTR MetaAPI_ConvertToMeta(WPARAM wParam, LPARAM lParam) { - return Meta_Convert(wParam, lParam); -} - -// added 0.9.5.0 (22/3/05) -// wParam=(HANDLE)hContact -// lParam=(HANDLE)hMeta -// add an existing contact to a metacontact -INT_PTR MetaAPI_AddToMeta(WPARAM wParam, LPARAM lParam) { - return Meta_Assign((HANDLE)wParam, (HANDLE)lParam, FALSE); -} - -// added 0.9.5.0 (22/3/05) -// wParam=0 -// lParam=(HANDLE)hContact -// remove a contact from a metacontact -INT_PTR MetaAPI_RemoveFromMeta(WPARAM wParam, LPARAM lParam) { - // notice we switch args - to keep the API function consistent with the others - return Meta_Delete((WPARAM)lParam, (LPARAM)wParam); -} - -// added 0.9.13.2 (6/10/05) -// wParam=(BOOL)disable -// lParam=0 -// enable/disable the 'hidden group hack' - for clists that support subcontact hiding using 'IsSubcontact' setting -// should be called once in your 'onmodulesloaded' event handler - -BOOL meta_group_hack_disabled = FALSE; // this global flag is used in utils 'SetGroup' function - -INT_PTR MetaAPI_DisableHiddenGroup(WPARAM wParam, LPARAM lParam) { - meta_group_hack_disabled = (BOOL)wParam; - return 0; -} diff --git a/plugins/MetaContacts/meta_api.cpp b/plugins/MetaContacts/meta_api.cpp new file mode 100644 index 0000000000..331bdb55d5 --- /dev/null +++ b/plugins/MetaContacts/meta_api.cpp @@ -0,0 +1,245 @@ +/* +MetaContacts Plugin for Miranda IM. + +Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. +Copyright © 2004 Scott Ellis (www.scottellis.com.au mail@scottellis.com.au) + +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 meta_api.c +* +* API functions needed to handle MetaContacts. +* Centralizes functions called by other plugins. +*/ + +#include "metacontacts.h" + +//get the handle for a contact's parent metacontact +//wParam=(HANDLE)hSubContact +//lParam=0 +//returns a handle to the parent metacontact, or null if this contact is not a subcontact +INT_PTR MetaAPI_GetMeta(WPARAM wParam, LPARAM lParam) { + return (int)(HANDLE)DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Handle", 0); +} + +//gets the handle for the default contact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a handle to the default contact, or null on failure +INT_PTR MetaAPI_GetDefault(WPARAM wParam, LPARAM lParam) { + DWORD default_contact_number = DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Default", -1); + if (default_contact_number != -1) { + return (int)Meta_GetContactHandle((HANDLE)wParam, default_contact_number); + } + return 0; +} + +//gets the contact number for the default contact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a DWORD contact number, or -1 on failure +INT_PTR MetaAPI_GetDefaultNum(WPARAM wParam, LPARAM lParam) { + return DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Default", -1); +} + +//gets the handle for the 'most online' contact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a handle to the 'most online' contact +INT_PTR MetaAPI_GetMostOnline(WPARAM wParam, LPARAM lParam) { + return (int)Meta_GetMostOnline((HANDLE)wParam); +} + +//gets the number of subcontacts for a metacontact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a DWORD representing the number of subcontacts for the given metacontact +INT_PTR MetaAPI_GetNumContacts(WPARAM wParam, LPARAM lParam) { + DWORD num_contacts = DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "NumContacts", -1); + return num_contacts; +} + +//gets the handle of a subcontact, using the subcontact's number +//wParam=(HANDLE)hMetaContact +//lParam=(DWORD)contact number +//returns a handle to the specified subcontact +INT_PTR MetaAPI_GetContact(WPARAM wParam, LPARAM lParam) { + return (int)Meta_GetContactHandle((HANDLE)wParam, (DWORD)lParam); +} + +//sets the default contact, using the subcontact's contact number +//wParam=(HANDLE)hMetaContact +//lParam=(DWORD)contact number +//returns 0 on success +INT_PTR MetaAPI_SetDefaultContactNum(WPARAM wParam, LPARAM lParam) { + DWORD num_contacts = DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "NumContacts", -1); + if (num_contacts == -1) + return 1; + if ((DWORD)lParam >= num_contacts || (DWORD)lParam < 0) + return 1; + if (DBWriteContactSettingDword((HANDLE)wParam, META_PROTO, "Default", (DWORD)lParam)) + return 1; + + NotifyEventHooks(hEventDefaultChanged, wParam, (LPARAM)Meta_GetContactHandle((HANDLE)wParam, (int)lParam)); + return 0; +} + +//sets the default contact, using the subcontact's handle +//wParam=(HANDLE)hMetaContact +//lParam=(HANDLE)hSubcontact +//returns 0 on success +INT_PTR MetaAPI_SetDefaultContact(WPARAM wParam, LPARAM lParam) { + HANDLE hMeta = (HANDLE)DBGetContactSettingDword((HANDLE)lParam, META_PROTO, "Handle", 0); + DWORD contact_number = Meta_GetContactNumber((HANDLE)lParam); + if (contact_number == -1 || !hMeta || hMeta != (HANDLE)wParam) + return 1; + if (DBWriteContactSettingDword(hMeta, META_PROTO, "Default", contact_number)) + return 1; + + NotifyEventHooks(hEventDefaultChanged, wParam, lParam); + return 0; +} + +//forces the metacontact to send using a specific subcontact, using the subcontact's contact number +//wParam=(HANDLE)hMetaContact +//lParam=(DWORD)contact number +//returns 0 on success +INT_PTR MetaAPI_ForceSendContactNum(WPARAM wParam, LPARAM lParam) { + HANDLE hContact = Meta_GetContactHandle((HANDLE)wParam, (int)lParam); + HANDLE hMeta = (HANDLE)DBGetContactSettingDword(hContact, META_PROTO, "Handle", 0); + if (!hContact || !hMeta || hMeta != (HANDLE)wParam || DBGetContactSettingByte(hMeta, META_PROTO, "ForceDefault", 0)) + return 1; + + DBWriteContactSettingDword(hMeta, META_PROTO, "ForceSend", (DWORD)hContact); + + NotifyEventHooks(hEventForceSend, wParam, (LPARAM)hContact); + return 0; +} + +//forces the metacontact to send using a specific subcontact, using the subcontact's handle +//wParam=(HANDLE)hMetaContact +//lParam=(HANDLE)hSubcontact +//returns 0 on success (will fail if 'force default' is in effect) +INT_PTR MetaAPI_ForceSendContact(WPARAM wParam, LPARAM lParam) { + HANDLE hContact = (HANDLE)lParam; + HANDLE hMeta = (HANDLE)DBGetContactSettingDword(hContact, META_PROTO, "Handle", 0); + if (!hContact || !hMeta || hMeta != (HANDLE)wParam || DBGetContactSettingByte(hMeta, META_PROTO, "ForceDefault", 0)) + return 1; + + DBWriteContactSettingDword(hMeta, META_PROTO, "ForceSend", (DWORD)hContact); + + NotifyEventHooks(hEventForceSend, wParam, lParam); + return 0; +} + +//'unforces' the metacontact to send using a specific subcontact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns 0 on success (will fail if 'force default' is in effect) +INT_PTR MetaAPI_UnforceSendContact(WPARAM wParam, LPARAM lParam) { + if (DBGetContactSettingByte((HANDLE)wParam, META_PROTO, "ForceDefault", 0)) + return 1; + + DBWriteContactSettingDword((HANDLE)wParam, META_PROTO, "ForceSend", 0); + + NotifyEventHooks(hEventUnforceSend, wParam, lParam); + return 0; +} + + +//'forces' or 'unforces' (i.e. toggles) the metacontact to send using it's default contact +// overrides 'force send' above, and will even force use of offline contacts +// will send ME_MC_FORCESEND event +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns 1(true) or 0(false) representing new state of 'force default' +INT_PTR MetaAPI_ForceDefault(WPARAM wParam, LPARAM lParam) { + // forward to menu function + Meta_ForceDefault(wParam, lParam); + return DBGetContactSettingByte((HANDLE)wParam, META_PROTO, "ForceDefault", 0); +} + +// method to get state of 'force' for a metacontact +// wParam=(HANDLE)hMetaContact +// lParam= (DWORD)&contact_number or NULL +// if lparam supplied, the contact_number of the contatct 'in force' will be copied to the address it points to, +// or if none is in force, the value (DWORD)-1 will be copied +// (v0.8.0.8+ returns 1 if 'force default' is true with *lParam == default contact number, else returns 0 with *lParam as above) +INT_PTR MetaAPI_GetForceState(WPARAM wParam, LPARAM lParam) { + HANDLE hMeta = (HANDLE)wParam; + HANDLE hContact; + + if (!hMeta) return 0; + + if (DBGetContactSettingByte(hMeta, META_PROTO, "ForceDefault", 0)) { + if (lParam) *(DWORD *)lParam = DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Default", -1); + return 1; + } + + hContact = (HANDLE)DBGetContactSettingDword(hMeta, META_PROTO, "ForceSend", 0); + + if (!hContact) { + if (lParam) *(DWORD *)lParam = -1; + } else { + if (lParam) *(DWORD *)lParam = (DWORD)Meta_GetContactNumber(hContact); + } + + return 0; +} + +// method to get protocol name - used to be sure you're dealing with a "real" metacontacts plugin :) +// wParam=lParam=0 +INT_PTR MetaAPI_GetProtoName(WPARAM wParam, LPARAM lParam) { + return (int)META_PROTO; +} + +// added 0.9.5.0 (22/3/05) +// wParam=(HANDLE)hContact +// lParam=0 +// convert a given contact into a metacontact +INT_PTR MetaAPI_ConvertToMeta(WPARAM wParam, LPARAM lParam) { + return Meta_Convert(wParam, lParam); +} + +// added 0.9.5.0 (22/3/05) +// wParam=(HANDLE)hContact +// lParam=(HANDLE)hMeta +// add an existing contact to a metacontact +INT_PTR MetaAPI_AddToMeta(WPARAM wParam, LPARAM lParam) { + return Meta_Assign((HANDLE)wParam, (HANDLE)lParam, FALSE); +} + +// added 0.9.5.0 (22/3/05) +// wParam=0 +// lParam=(HANDLE)hContact +// remove a contact from a metacontact +INT_PTR MetaAPI_RemoveFromMeta(WPARAM wParam, LPARAM lParam) { + // notice we switch args - to keep the API function consistent with the others + return Meta_Delete((WPARAM)lParam, (LPARAM)wParam); +} + +// added 0.9.13.2 (6/10/05) +// wParam=(BOOL)disable +// lParam=0 +// enable/disable the 'hidden group hack' - for clists that support subcontact hiding using 'IsSubcontact' setting +// should be called once in your 'onmodulesloaded' event handler + +BOOL meta_group_hack_disabled = FALSE; // this global flag is used in utils 'SetGroup' function + +INT_PTR MetaAPI_DisableHiddenGroup(WPARAM wParam, LPARAM lParam) { + meta_group_hack_disabled = (BOOL)wParam; + return 0; +} diff --git a/plugins/MetaContacts/meta_main.c b/plugins/MetaContacts/meta_main.c deleted file mode 100644 index dbe2f67224..0000000000 --- a/plugins/MetaContacts/meta_main.c +++ /dev/null @@ -1,266 +0,0 @@ -/* -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 meta_main.c -* -* Functions used by Miranda to launch the plugin. -* Centralizes functions needed by Miranda to get -* information about the plugin and to initialize it -* and to dispose of it properly. -*/ - -/*! \mainpage MetaContacts plugin - * \image html ulp.gif - * \section desc Description - * This library is a plugin for Miranda IM.\n - * It allows the user to group several contacts from different - * protocols (such as AIM or ICQ) into one unique metacontact.\n - * - * \section principle How does it work ? - * Only one protocol will be used at a time (the default protocol).\n - * This protocol is referenced in the proper field of the MetaContact - * section in the Database. - * - * \subsection send Emission of messages - * The plugin will search through the Database to get the default protocol - * (i.e. the protocol used to communicate with),\n and then call the Send function - * provided by this protocol. - * - * \subsection recv Reception of messages - * When a contact is converted to a metacontact, or when it is added to an existing - * metacontact, it gets a pseudo protocol \n (named "MetaContacts") in the protocol chain.\n - * Usually, when a message is received, all the protocols in the chain get this message, - * the real protocol (for example ICQ) at the end.\n But here, the message will be intercepted - * by the MetaContact protocol, which will inhibit the further reception.\n The message will - * then be redirected to the MetaContact, that will display it normally. - * - * \subsection handling Handling MetaContacts - * There are four functionnality for handling MetaContacts : - * \li Convert a contact to a MetaContact. - * \li Add a contact to an existing MetaContact. - * \li Edit a MetaContact. - * \li Delete a MetaContact. - * - * They all are accessible via the context-menu displayed when a right click has occured, - * but not at the same time : The 2 first will appear when the menu concerns a simple contact.\n - * whereas the 2 last are only accessible from a MetaContact.\n - * Those functions are self-explanatory, and a MessageBox is shown before any modification, so, for - * further information, take a look at the Dialogs shown when they are called.\n - * - * \section cvats Caveats - * Several functionnalities have not yet been developped : - * \li Assigning contacts by Drag'n'Drop - * \li Updating dynamically the status of the MetaContact - * \li Merging history of all the contacts attached to MetaContact - * \li Handling Files and URLs as well as Messages - * \li and some other little functionnalities... - * - * Some of those functionnalities will not be developped due to the architecture - * of Miranda (the 2 first, for example) - * - * \section mail Contact - * For any comment, suggestion or question, send a mail to shaalj@free.fr.\n - * This code is provided as-is, and I cannot be held responsible for any harm - * done to your database by this plugin.\n - * Test it first on a fake database before using it normally. - */ - -#include "metacontacts.h" - -// Use VersionNo.h to set the version number, and ensure resource file is not open -#include "version.h" - -struct MM_INTERFACE mmi; -BOOL os_unicode_enabled = FALSE; -int hLangpack; - -//! Information gathered by Miranda, displayed in the plugin pane of the Option Dialog -PLUGININFOEX pluginInfo={ - sizeof(PLUGININFOEX), - __PLUGIN_NAME, // altered here and on file listing, so as not to match original - PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), - __DESC, - __AUTHOR, - __AUTHOREMAIL, - __COPYRIGHT, - __AUTHORWEB, - 0, - 0, - { 0x4c4a27cf, 0x5e64, 0x4242, { 0xa3, 0x32, 0xb9, 0x8b, 0x8, 0x24, 0x3e, 0x89 } } // {4C4A27CF-5E64-4242-A332-B98B08243E89} -}; - -HINSTANCE hInstance; //!< Global reference to the application -PLUGINLINK *pluginLink; //!< Link between Miranda and this plugin - -/** Called by Miranda to get the information associated to this plugin. -* It only returns the PLUGININFO structure, without any test on the version -* @param mirandaVersion The version of the application calling this function -*/ -__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -static const MUUID interfaces[] = {MIID_PROTOCOL, MIID_METACONTACTS, MIID_LAST}; -__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} - - -/** DLL entry point -* Required to store the instance handle -*/ -BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) -{ - hInstance=hinstDLL; - DisableThreadLibraryCalls(hInstance); - return TRUE; -} - -/** Prepare the plugin to stop -* Called by Miranda when it will exit or when the plugin gets deselected -*/ -__declspec(dllexport)int Unload(void) -{ - // see also meta_services.c, Meta_PreShutdown - Meta_CloseHandles(); - //MessageBox(0, "Unload complete", "MC", MB_OK); - return 0; -} - -BOOL IsUnicodeOS() -{ - OSVERSIONINFOW os; - memset(&os, 0, sizeof(OSVERSIONINFOW)); - os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); - return (GetVersionExW(&os) != 0); -} - -/** Initializes the services provided and the link to those needed -* Called when the plugin is loaded into Miranda -*/ -int __declspec(dllexport)Load(PLUGINLINK *link) -{ - PROTOCOLDESCRIPTOR pd; - DBVARIANT dbv; - - pluginLink=link; - - mir_getMMI(&mmi); - mir_getLP(&pluginInfo); - - os_unicode_enabled = IsUnicodeOS(); - - if (ServiceExists(MS_DB_SETSETTINGRESIDENT)) { // 0.6+ - CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/Status")); - CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/IdleTS")); - CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/ContactCountCheck")); - CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/Handle")); - CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/WindowOpen")); - } - - //set all contacts to 'offline', and initialize subcontact counter for db consistency check - { - HANDLE hContact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0); - char *proto; - while(hContact != NULL) { - //proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - if (!DBGetContactSetting(hContact, "Protocol", "p", &dbv)) { - proto = dbv.pszVal; - if (proto && !lstrcmp( META_PROTO, proto)) { - DBWriteContactSettingWord(hContact, META_PROTO, "Status", ID_STATUS_OFFLINE); - DBWriteContactSettingDword(hContact, META_PROTO, "IdleTS", 0); - DBWriteContactSettingByte(hContact, META_PROTO, "ContactCountCheck", 0); - - // restore any saved defaults that might have remained if miranda was closed or crashed while a convo was happening - if (DBGetContactSettingDword(hContact, META_PROTO, "SavedDefault", (DWORD)-1) != (DWORD)-1) { - DBWriteContactSettingDword(hContact, META_PROTO, "Default", DBGetContactSettingDword(hContact, META_PROTO, "SavedDefault", 0)); - DBWriteContactSettingDword(hContact, META_PROTO, "SavedDefault", (DWORD)-1); - } - - } - DBFreeVariant(&dbv); - } - - hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 ); - } - } - - Meta_ReadOptions(&options); - - - // sets subcontact handles to metacontacts, and metacontact handles to subcontacts - // (since these handles are not necessarily the same from run to run of miranda) - - // also verifies that subcontacts: have metacontacts, and that contact numbers are reasonable, - // that metacontacts: have the correct number of subcontacts, and have reasonable defaults - if (Meta_SetHandles()) { - // error - db corruption - if (!DBGetContactSettingByte(0, META_PROTO, "DisabledMessageShown", 0)) { - MessageBox(0, Translate("Error - Database corruption.\nPlugin disabled."), Translate("MetaContacts"), MB_OK | MB_ICONERROR); - DBWriteContactSettingByte(0, META_PROTO, "DisabledMessageShown", 1); - } - //Meta_HideMetaContacts(TRUE); - return 1; - } - - DBDeleteContactSetting(0, META_PROTO, "DisabledMessageShown"); - - // add our modules to the KnownModules list - { - DBVARIANT dbv; - if (DBGetContactSetting(NULL, "KnownModules", META_PROTO, &dbv)) - DBWriteContactSettingString(NULL, "KnownModules", META_PROTO, META_PROTO); - else - DBFreeVariant(&dbv); - } - - ZeroMemory(&pd,sizeof(pd)); - pd.cbSize=PROTOCOLDESCRIPTOR_V3_SIZE;//sizeof(pd); - - pd.szName=META_FILTER; - pd.type=PROTOTYPE_FILTER; - CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd); - - ZeroMemory(&pd,sizeof(pd)); - pd.cbSize=PROTOCOLDESCRIPTOR_V3_SIZE;//sizeof(pd); - - pd.szName=META_PROTO; - pd.type = PROTOTYPE_PROTOCOL; - CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd); - - // further db setup done in modules loaded (nick [protocol string required] & clist display name) - - Meta_InitServices(); - - // moved to 'modules loaded' event handler (in meta_services.c) because we need to - // check protocol for jabber hack, and the proto modules must be loaded - //Meta_HideLinkedContactsAndSetHandles(); - - if (ServiceExists(MS_MSG_GETWINDOWAPI)) { - message_window_api_enabled = TRUE; - } - - // for clist_meta_mw - write hidden group name to DB - DBWriteContactSettingString(0, META_PROTO, "HiddenGroupName", META_HIDDEN_GROUP); - - return 0; -} diff --git a/plugins/MetaContacts/meta_main.cpp b/plugins/MetaContacts/meta_main.cpp new file mode 100644 index 0000000000..dbe2f67224 --- /dev/null +++ b/plugins/MetaContacts/meta_main.cpp @@ -0,0 +1,266 @@ +/* +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 meta_main.c +* +* Functions used by Miranda to launch the plugin. +* Centralizes functions needed by Miranda to get +* information about the plugin and to initialize it +* and to dispose of it properly. +*/ + +/*! \mainpage MetaContacts plugin + * \image html ulp.gif + * \section desc Description + * This library is a plugin for Miranda IM.\n + * It allows the user to group several contacts from different + * protocols (such as AIM or ICQ) into one unique metacontact.\n + * + * \section principle How does it work ? + * Only one protocol will be used at a time (the default protocol).\n + * This protocol is referenced in the proper field of the MetaContact + * section in the Database. + * + * \subsection send Emission of messages + * The plugin will search through the Database to get the default protocol + * (i.e. the protocol used to communicate with),\n and then call the Send function + * provided by this protocol. + * + * \subsection recv Reception of messages + * When a contact is converted to a metacontact, or when it is added to an existing + * metacontact, it gets a pseudo protocol \n (named "MetaContacts") in the protocol chain.\n + * Usually, when a message is received, all the protocols in the chain get this message, + * the real protocol (for example ICQ) at the end.\n But here, the message will be intercepted + * by the MetaContact protocol, which will inhibit the further reception.\n The message will + * then be redirected to the MetaContact, that will display it normally. + * + * \subsection handling Handling MetaContacts + * There are four functionnality for handling MetaContacts : + * \li Convert a contact to a MetaContact. + * \li Add a contact to an existing MetaContact. + * \li Edit a MetaContact. + * \li Delete a MetaContact. + * + * They all are accessible via the context-menu displayed when a right click has occured, + * but not at the same time : The 2 first will appear when the menu concerns a simple contact.\n + * whereas the 2 last are only accessible from a MetaContact.\n + * Those functions are self-explanatory, and a MessageBox is shown before any modification, so, for + * further information, take a look at the Dialogs shown when they are called.\n + * + * \section cvats Caveats + * Several functionnalities have not yet been developped : + * \li Assigning contacts by Drag'n'Drop + * \li Updating dynamically the status of the MetaContact + * \li Merging history of all the contacts attached to MetaContact + * \li Handling Files and URLs as well as Messages + * \li and some other little functionnalities... + * + * Some of those functionnalities will not be developped due to the architecture + * of Miranda (the 2 first, for example) + * + * \section mail Contact + * For any comment, suggestion or question, send a mail to shaalj@free.fr.\n + * This code is provided as-is, and I cannot be held responsible for any harm + * done to your database by this plugin.\n + * Test it first on a fake database before using it normally. + */ + +#include "metacontacts.h" + +// Use VersionNo.h to set the version number, and ensure resource file is not open +#include "version.h" + +struct MM_INTERFACE mmi; +BOOL os_unicode_enabled = FALSE; +int hLangpack; + +//! Information gathered by Miranda, displayed in the plugin pane of the Option Dialog +PLUGININFOEX pluginInfo={ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, // altered here and on file listing, so as not to match original + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESC, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + 0, + 0, + { 0x4c4a27cf, 0x5e64, 0x4242, { 0xa3, 0x32, 0xb9, 0x8b, 0x8, 0x24, 0x3e, 0x89 } } // {4C4A27CF-5E64-4242-A332-B98B08243E89} +}; + +HINSTANCE hInstance; //!< Global reference to the application +PLUGINLINK *pluginLink; //!< Link between Miranda and this plugin + +/** Called by Miranda to get the information associated to this plugin. +* It only returns the PLUGININFO structure, without any test on the version +* @param mirandaVersion The version of the application calling this function +*/ +__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +static const MUUID interfaces[] = {MIID_PROTOCOL, MIID_METACONTACTS, MIID_LAST}; +__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + + +/** DLL entry point +* Required to store the instance handle +*/ +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInstance=hinstDLL; + DisableThreadLibraryCalls(hInstance); + return TRUE; +} + +/** Prepare the plugin to stop +* Called by Miranda when it will exit or when the plugin gets deselected +*/ +__declspec(dllexport)int Unload(void) +{ + // see also meta_services.c, Meta_PreShutdown + Meta_CloseHandles(); + //MessageBox(0, "Unload complete", "MC", MB_OK); + return 0; +} + +BOOL IsUnicodeOS() +{ + OSVERSIONINFOW os; + memset(&os, 0, sizeof(OSVERSIONINFOW)); + os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); + return (GetVersionExW(&os) != 0); +} + +/** Initializes the services provided and the link to those needed +* Called when the plugin is loaded into Miranda +*/ +int __declspec(dllexport)Load(PLUGINLINK *link) +{ + PROTOCOLDESCRIPTOR pd; + DBVARIANT dbv; + + pluginLink=link; + + mir_getMMI(&mmi); + mir_getLP(&pluginInfo); + + os_unicode_enabled = IsUnicodeOS(); + + if (ServiceExists(MS_DB_SETSETTINGRESIDENT)) { // 0.6+ + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/Status")); + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/IdleTS")); + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/ContactCountCheck")); + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/Handle")); + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/WindowOpen")); + } + + //set all contacts to 'offline', and initialize subcontact counter for db consistency check + { + HANDLE hContact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0); + char *proto; + while(hContact != NULL) { + //proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if (!DBGetContactSetting(hContact, "Protocol", "p", &dbv)) { + proto = dbv.pszVal; + if (proto && !lstrcmp( META_PROTO, proto)) { + DBWriteContactSettingWord(hContact, META_PROTO, "Status", ID_STATUS_OFFLINE); + DBWriteContactSettingDword(hContact, META_PROTO, "IdleTS", 0); + DBWriteContactSettingByte(hContact, META_PROTO, "ContactCountCheck", 0); + + // restore any saved defaults that might have remained if miranda was closed or crashed while a convo was happening + if (DBGetContactSettingDword(hContact, META_PROTO, "SavedDefault", (DWORD)-1) != (DWORD)-1) { + DBWriteContactSettingDword(hContact, META_PROTO, "Default", DBGetContactSettingDword(hContact, META_PROTO, "SavedDefault", 0)); + DBWriteContactSettingDword(hContact, META_PROTO, "SavedDefault", (DWORD)-1); + } + + } + DBFreeVariant(&dbv); + } + + hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 ); + } + } + + Meta_ReadOptions(&options); + + + // sets subcontact handles to metacontacts, and metacontact handles to subcontacts + // (since these handles are not necessarily the same from run to run of miranda) + + // also verifies that subcontacts: have metacontacts, and that contact numbers are reasonable, + // that metacontacts: have the correct number of subcontacts, and have reasonable defaults + if (Meta_SetHandles()) { + // error - db corruption + if (!DBGetContactSettingByte(0, META_PROTO, "DisabledMessageShown", 0)) { + MessageBox(0, Translate("Error - Database corruption.\nPlugin disabled."), Translate("MetaContacts"), MB_OK | MB_ICONERROR); + DBWriteContactSettingByte(0, META_PROTO, "DisabledMessageShown", 1); + } + //Meta_HideMetaContacts(TRUE); + return 1; + } + + DBDeleteContactSetting(0, META_PROTO, "DisabledMessageShown"); + + // add our modules to the KnownModules list + { + DBVARIANT dbv; + if (DBGetContactSetting(NULL, "KnownModules", META_PROTO, &dbv)) + DBWriteContactSettingString(NULL, "KnownModules", META_PROTO, META_PROTO); + else + DBFreeVariant(&dbv); + } + + ZeroMemory(&pd,sizeof(pd)); + pd.cbSize=PROTOCOLDESCRIPTOR_V3_SIZE;//sizeof(pd); + + pd.szName=META_FILTER; + pd.type=PROTOTYPE_FILTER; + CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd); + + ZeroMemory(&pd,sizeof(pd)); + pd.cbSize=PROTOCOLDESCRIPTOR_V3_SIZE;//sizeof(pd); + + pd.szName=META_PROTO; + pd.type = PROTOTYPE_PROTOCOL; + CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd); + + // further db setup done in modules loaded (nick [protocol string required] & clist display name) + + Meta_InitServices(); + + // moved to 'modules loaded' event handler (in meta_services.c) because we need to + // check protocol for jabber hack, and the proto modules must be loaded + //Meta_HideLinkedContactsAndSetHandles(); + + if (ServiceExists(MS_MSG_GETWINDOWAPI)) { + message_window_api_enabled = TRUE; + } + + // for clist_meta_mw - write hidden group name to DB + DBWriteContactSettingString(0, META_PROTO, "HiddenGroupName", META_HIDDEN_GROUP); + + return 0; +} diff --git a/plugins/MetaContacts/meta_menu.c b/plugins/MetaContacts/meta_menu.c deleted file mode 100644 index e71e9357a5..0000000000 --- a/plugins/MetaContacts/meta_menu.c +++ /dev/null @@ -1,562 +0,0 @@ -/* -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 meta_menu.c -* -* Functions needed to handle MetaContacts. -* Centralizes functions called when the user chooses -* an option integrated in the context-menu of the \c CList. -*/ - -#include "metacontacts.h" - -/** Convert the contact chosen into a MetaContact. -* -* Create a new MetaContact, remove the selected contact from the \c CList -* and attach it to the MetaContact. -* -* @param wParam : \c HANDLE to the contact that has been chosen. -* @param lParam : Allways set to 0. -*/ -INT_PTR Meta_Convert(WPARAM wParam,LPARAM lParam) -{ - HANDLE hMetaContact; - DBVARIANT dbv; - char *group = 0;//, *proto; - - // Get some information about the selected contact. -// proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,wParam,0); - if (!DBGetContactSettingStringUtf((HANDLE)wParam,"CList","Group",&dbv)) { - group = _strdup(dbv.pszVal); - DBFreeVariant(&dbv); - } - - // Create a new metacontact - hMetaContact = (HANDLE)CallService(MS_DB_CONTACT_ADD,0,0); - - // Add the info for the metacontact - if (hMetaContact) - { - - DBWriteContactSettingDword(hMetaContact,META_PROTO,META_ID,nextMetaID); - DBWriteContactSettingDword(hMetaContact,META_PROTO,"NumContacts",0); - DBWriteContactSettingDword(NULL,META_PROTO,"NextMetaID",++nextMetaID); - - // Add the MetaContact protocol to the new meta contact - CallService( MS_PROTO_ADDTOCONTACT, ( WPARAM )hMetaContact, ( LPARAM )META_PROTO ); - - if (group) { - if (ServiceExists(MS_DB_CONTACT_GETSETTING_STR)) - DBWriteContactSettingStringUtf(hMetaContact,"CList","Group",group); - else - DBWriteContactSettingString(hMetaContact,"CList","Group",group); - } - - // Assign the contact to the MetaContact just created (and make default). - if (!Meta_Assign((HANDLE)wParam,hMetaContact,TRUE)) { - MessageBox(0,Translate("There was a problem in assigning the contact to the MetaContact"),Translate("Error"),MB_ICONEXCLAMATION); - CallService(MS_DB_CONTACT_DELETE, (WPARAM)hMetaContact, 0); - return 0; - } - - // hide the contact if clist groups disabled (shouldn't create one anyway since menus disabled) - if (!Meta_IsEnabled()) - DBWriteContactSettingByte(hMetaContact, "CList", "Hidden", 1); - - } - - // Update the graphics - CallService(MS_CLUI_SORTLIST,0,0); - - free(group); - return (int)hMetaContact; -} - -/** Display the 'Add to' Dialog -* -* Present a dialog in which the user can choose to which MetaContact this -* contact will be added -* -* @param wParam : \c HANDLE to the contact that has been chosen. -* @param lParam : Allways set to 0. -*/ -INT_PTR Meta_AddTo(WPARAM wParam, LPARAM lParam) -{ - HWND clui = (HWND)CallService(MS_CLUI_GETHWND,0,0); - DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_METASELECT),clui,&Meta_SelectDialogProc,(LPARAM)wParam); - return 0; -} - -/** Display the 'Edit' Dialog -* -* Present a dialog in which the user can edit some properties of the MetaContact. -* -* @param wParam : \c HANDLE to the MetaContact to be edited. -* @param lParam : Allways set to 0. -*/ -INT_PTR Meta_Edit(WPARAM wParam,LPARAM lParam) -{ - HWND clui = (HWND)CallService(MS_CLUI_GETHWND,0,0); - DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_METAEDIT),clui,Meta_EditDialogProc,(LPARAM)wParam); - return 0; -} - -/* DB/Contact/WriteSetting service -Change the value of, or create a new value with, a named setting for a specific -contact in the database to the given value - wParam=(WPARAM)(HANDLE)hContact - lParam=(LPARAM)(DBCONTACTWRITESETTING*)&dbcws -hContact should have been returned by find*contact or addcontact -Returns 0 on success or nonzero if hContact was invalid -Note that DBCONTACTGETSETTING takes a pointer to a DBVARIANT, whereas -DBCONTACTWRITESETTING contains a DBVARIANT. -Because this is such a common function there are some short helper function at -the bottom of this header that use it. -Triggers a db/contact/settingchanged event just before it returns. -*/ -//typedef struct { -// const char *szModule; // pointer to name of the module that wrote the -// // setting to get -// const char *szSetting; // pointer to name of the setting to get -// DBVARIANT value; // variant containing the value to set -//} DBCONTACTWRITESETTING; -//#define MS_DB_CONTACT_WRITESETTING "DB/Contact/WriteSetting" - -void Meta_RemoveContactNumber(HANDLE hMeta, int number) { - int i, num_contacts, default_contact; - HANDLE hContact;//, handle; - - char buffer[512], buffer2[512]; - - num_contacts = DBGetContactSettingDword(hMeta, META_PROTO, "NumContacts", 0); - default_contact = DBGetContactSettingDword(hMeta, META_PROTO, "Default", -1); - if (number >= 0 && number < num_contacts) { - - // get the handle - hContact = Meta_GetContactHandle(hMeta, number); - - // make sure this contact thinks it's part of this metacontact - if ((HANDLE)DBGetContactSettingDword(hContact,META_PROTO,"Handle", 0) == hMeta) { - - // remove link to meta contact - DBDeleteContactSetting(hContact,META_PROTO,"IsSubcontact"); - DBDeleteContactSetting(hContact,META_PROTO,META_LINK); - DBDeleteContactSetting(hContact,META_PROTO,"Handle"); - DBDeleteContactSetting(hContact,META_PROTO,"ContactNumber"); - // unhide - must be done after removing link (see meta_services.c:Meta_ChangeStatus) - Meta_RestoreGroup(hContact); - DBDeleteContactSetting(hContact,META_PROTO,"OldCListGroup"); - //CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)hContact,(LPARAM)META_PROTO); - CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)hContact,(LPARAM)META_FILTER); - // stop ignoring, if we were - if (options.suppress_status) - CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, (WPARAM)IGNOREEVENT_USERONLINE); - } - - // remove history from metacontact - //Meta_RemoveHistory(hMeta, hContact); - - // each contact from 'number' upwards will be moved down one - // and the last one will be deleted - for (i = number + 1; i < num_contacts; i++) { - Meta_SwapContacts(hMeta, i, i-1); - } - - // remove the last one - strcpy(buffer, "Protocol"); - strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); - DBDeleteContactSetting(hMeta, META_PROTO, buffer); - strcpy(buffer, "Status"); - strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); - DBDeleteContactSetting(hMeta, META_PROTO, buffer); - strcpy(buffer, "Handle"); - strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); - DBDeleteContactSetting(hMeta, META_PROTO, buffer); - strcpy(buffer, "StatusString"); - strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); - DBDeleteContactSetting(hMeta, META_PROTO, buffer); - strcpy(buffer, "Login"); - strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); - DBDeleteContactSetting(hMeta, META_PROTO, buffer); - strcpy(buffer, "Nick"); - strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); - DBDeleteContactSetting(hMeta, META_PROTO, buffer); - strcpy(buffer, "CListName"); - strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); - DBDeleteContactSetting(hMeta, META_PROTO, buffer); - - // if the default contact was equal to or greater than 'number', decrement it (and deal with ends) - if (default_contact >= number) { - default_contact--; - if (default_contact < 0) - default_contact = 0; - - DBWriteContactSettingDword(hMeta, META_PROTO, "Default", (DWORD)default_contact); - NotifyEventHooks(hEventDefaultChanged, (WPARAM)hMeta, (LPARAM)Meta_GetContactHandle(hMeta, default_contact)); - } - num_contacts--; - DBWriteContactSettingDword(hMeta, META_PROTO, "NumContacts", (DWORD)num_contacts); - - // fix nick - hContact = Meta_GetMostOnline(hMeta); - Meta_CopyContactNick(hMeta, hContact); - - // fix status - Meta_FixStatus(hMeta); - - // fix avatar - hContact = Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_4, PF4_AVATARS); - if (hContact) { - PROTO_AVATAR_INFORMATIONT AI; - - AI.cbSize = sizeof(AI); - AI.hContact = hMeta; - AI.format = PA_FORMAT_UNKNOWN; - _tcscpy(AI.filename, _T("X")); - - if ((int)CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) - DBWriteContactSettingTString(hMeta, "ContactPhoto", "File",AI.filename); - } - } -} - -/** Delete a MetaContact from the database -* -* Delete a MetaContact and remove all the information -* concerning this MetaContact in the contact linked to it. -* -* @param wParam : \c HANDLE to the MetaContact to be deleted, or to the subcontact to be removed from the MetaContact -* @param lParam : \c BOOL flag indicating whether to ask 'are you sure' when deleting a MetaContact -*/ -INT_PTR Meta_Delete(WPARAM wParam,LPARAM lParam) -{ - DWORD metaID; - HANDLE hContact; - - if ((metaID=DBGetContactSettingDword((HANDLE)wParam,META_PROTO,META_ID,(DWORD)-1))!=(DWORD)-1) - {// The wParam is a metacontact - if (!lParam) { // check from recursion - see second half of this function - if (MessageBox((HWND)CallService(MS_CLUI_GETHWND,0,0),Translate("This will remove the MetaContact permanently.\n\nProceed Anyway?"), - Translate("Are you sure?"),MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2)!=IDYES) - { - return 0; - } - } - - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); - while(hContact) - { // Scans the database to get all the contacts that have been previously linked to this MetaContact - if (DBGetContactSettingDword(hContact,META_PROTO,META_LINK,(DWORD)-1)==metaID) - { // This contact is assigned to the MetaContact that will be deleted, clear the "MetaContacts" information - DBDeleteContactSetting(hContact,META_PROTO,"IsSubcontact"); - DBDeleteContactSetting(hContact,META_PROTO,META_LINK); - DBDeleteContactSetting(hContact,META_PROTO,"Handle"); - DBDeleteContactSetting(hContact,META_PROTO,"ContactNumber"); - // unhide - must be done after removing link (see meta_services.c:Meta_ChangeStatus) - Meta_RestoreGroup(hContact); - DBDeleteContactSetting(hContact,META_PROTO,"OldCListGroup"); - - CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)hContact,(LPARAM)META_FILTER); - // stop ignoring, if we were - if (options.suppress_status) - CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, (WPARAM)IGNOREEVENT_USERONLINE); - } - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0); - } - //DBDeleteContactSetting((HANDLE)wParam, META_PROTO, META_ID); - //DBDeleteContactSetting((HANDLE)wParam, META_PROTO, "NumContacts"); - //CallService(MS_PROTO_REMOVEFROMCONTACT,wParam,(LPARAM)META_PROTO); - NotifyEventHooks(hSubcontactsChanged, (WPARAM)wParam, 0); - CallService(MS_DB_CONTACT_DELETE,wParam,0); - } - else - {// The wParam is a simple contact - //if (lParam == 0) - // return 1; // The function has been called by the menu of a simple contact. Should not happen. - //else - {// The function has been called by the edit dialog - HANDLE hMeta = (HANDLE)DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Handle", 0); - - - DWORD num_contacts = DBGetContactSettingDword(hMeta, META_PROTO, "NumContacts", -1); - - if (num_contacts == 1) { - if (MessageBox(0,Translate("You are going to remove all the contacts associated with this MetaContact.\nThis will delete the MetaContact.\n\nProceed Anyway?"), - Translate("Delete MetaContact?"),MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON1)==IDYES) - { - // recurse - once - Meta_Delete((WPARAM)hMeta,(LPARAM)1); - } - return 0; - } - - Meta_RemoveContactNumber(hMeta, DBGetContactSettingDword((HANDLE)wParam,META_PROTO,"ContactNumber", -1)); - - CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)wParam,(LPARAM)META_FILTER); - } - } - return 0; -} - -/** Set contact as MetaContact default -* -* Set the given contact to be the default one for the metacontact to which it is linked. -* -* @param wParam : \c HANDLE to the MetaContact to be set as default -* @param lParam : \c HWND to the clist window - (This means the function has been called via the contact menu). -*/ -INT_PTR Meta_Default(WPARAM wParam,LPARAM lParam) -{ - HANDLE hMeta; - - if ((hMeta = (HANDLE)DBGetContactSettingDword((HANDLE)wParam,META_PROTO,"Handle",0)) != 0) - { // the wParam is a subcontact - DBWriteContactSettingDword(hMeta, META_PROTO, "Default", (DWORD)Meta_GetContactNumber((HANDLE)wParam)); - NotifyEventHooks(hEventDefaultChanged, (WPARAM)hMeta, (LPARAM)(HANDLE)wParam); - } - return 0; -} - -/** Set/unset (i.e. toggle) contact to force use of default contact -* -* Set the given contact to be the default one for the metacontact to which it is linked. -* -* @param wParam : \c HANDLE to the MetaContact to be set as default -* @param lParam : \c HWND to the clist window - (This means the function has been called via the contact menu). -*/ -INT_PTR Meta_ForceDefault(WPARAM wParam,LPARAM lParam) -{ - if (DBGetContactSettingDword((HANDLE)wParam,META_PROTO, META_ID, (DWORD)-1) != (DWORD)-1) - { // the wParam is a MetaContact - - BOOL current = DBGetContactSettingByte((HANDLE)wParam, META_PROTO, "ForceDefault", 0); - current = !current; - DBWriteContactSettingByte((HANDLE)wParam, META_PROTO, "ForceDefault", (BYTE)current); - - DBWriteContactSettingDword((HANDLE)wParam, META_PROTO, "ForceSend", 0); - - if (current) NotifyEventHooks(hEventForceSend, wParam, (LPARAM)Meta_GetContactHandle((HANDLE)wParam, DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Default", -1))); - else NotifyEventHooks(hEventUnforceSend, wParam, 0); - } - return 0; -} - -INT_PTR MenuFunc0(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 0);} -INT_PTR MenuFunc1(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 1);} -INT_PTR MenuFunc2(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 2);} -INT_PTR MenuFunc3(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 3);} -INT_PTR MenuFunc4(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 4);} -INT_PTR MenuFunc5(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 5);} -INT_PTR MenuFunc6(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 6);} -INT_PTR MenuFunc7(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 7);} -INT_PTR MenuFunc8(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 8);} -INT_PTR MenuFunc9(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 9);} -INT_PTR MenuFunc10(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 10);} -INT_PTR MenuFunc11(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 11);} -INT_PTR MenuFunc12(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 12);} -INT_PTR MenuFunc13(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 13);} -INT_PTR MenuFunc14(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 14);} -INT_PTR MenuFunc15(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 15);} -INT_PTR MenuFunc16(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 16);} -INT_PTR MenuFunc17(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 17);} -INT_PTR MenuFunc18(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 18);} -INT_PTR MenuFunc19(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 19);} - -HANDLE hMenuContact[MAX_CONTACTS]; - -INT_PTR TranslateMenuFunc(HANDLE hMeta, int contact_number) { - return Meta_ContactMenuFunc((WPARAM)hMeta, (LPARAM) contact_number); -} - -/** Called when the context-menu of a contact is about to be displayed -* -* This will test which of the 4 menu item should be displayed, depending -* on which contact triggered the event -* -* @param wParam : \c HANDLE to the contact that triggered the event -* @param lParam : Always set to 0; -*/ -int Meta_ModifyMenu(WPARAM wParam, LPARAM lParam) -{ - CLISTMENUITEM mi; - DBVARIANT dbv; - HANDLE hContact; - char *proto; - char buf[512], buffer2[512]; - int i, iconIndex; - WORD status; - - mi.flags = CMIM_FLAGS; - mi.cbSize = sizeof(CLISTMENUITEM); - - if (DBGetContactSettingDword((HANDLE)wParam,META_PROTO,META_ID,-1) != (DWORD)-1) - { - int num_contacts, i; - - // save the mouse pos in case they open a subcontact menu - GetCursorPos(&menuMousePoint); - - // This is a MetaContact, show the edit, force default, and the delete menu, and hide the others - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&mi); - //mi.flags |= CMIM_NAME; - //if (DBGetContactSettingByte((HANDLE)wParam, META_PROTO, "ForceDefault", 0)) - // mi.pszName = Translate("Unforce Default"); - //else - // mi.pszName = Translate("Force Default"); - //CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuForceDefault, (LPARAM)&mi); - mi.flags = CMIM_FLAGS | CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); - mi.flags = CMIM_FLAGS | CMIM_NAME | CMIF_HIDDEN; // we don't need delete - already in contact menu - mi.pszName = Translate("Delete MetaContact"); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&mi); - - - //show subcontact menu items - num_contacts = DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "NumContacts", 0); - for (i = 0; i < MAX_CONTACTS; i++) { - if (i < num_contacts) { - hContact = Meta_GetContactHandle((HANDLE)wParam, i); - proto = _strdup((char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)); - - if (!proto) - status = ID_STATUS_OFFLINE; - else - status = DBGetContactSettingWord(hContact, proto, "Status", ID_STATUS_OFFLINE); - - if (options.menu_contact_label == DNT_UID) { - strcpy(buf, "Login"); - strcat(buf, _itoa(i, buffer2, 10)); - - DBGetContactSetting((HANDLE)wParam,META_PROTO,buf,&dbv); - switch(dbv.type) - { - case DBVT_ASCIIZ: - mir_snprintf(buf,512,"%s",dbv.pszVal); - break; - case DBVT_BYTE: - mir_snprintf(buf,512,"%d",dbv.bVal); - break; - case DBVT_WORD: - mir_snprintf(buf,512,"%d",dbv.wVal); - break; - case DBVT_DWORD: - mir_snprintf(buf,512,"%d",dbv.dVal); - break; - default: - buf[0] = 0; - } - DBFreeVariant(&dbv); - mi.pszName = buf; - mi.flags = 0; - } else { - char *name = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0); - char *wname = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_UNICODE); - - if (wname && strncmp(name, wname, strlen(name)) != 0) { - mi.pszName = wname; - mi.flags = CMIF_UNICODE; - } - else { - mi.pszName = name; - mi.flags = 0; - } - } - - mi.flags |= CMIM_FLAGS | CMIM_NAME | CMIM_ICON; - - //mi.hIcon = LoadSkinnedProtoIcon(proto, status); - iconIndex = (int)CallService(MS_CLIST_GETCONTACTICON, (WPARAM)hContact, 0); - mi.hIcon = ImageList_GetIcon((HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), iconIndex, 0);; - - free(proto); - - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); - DestroyIcon(mi.hIcon); - //CallService(MS_SKIN2_RELEASEICON, (WPARAM)mi.hIcon, 0); - } else { - mi.flags = CMIM_FLAGS | CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); - } - } - - // show hide nudge menu item -#define MS_NUDGE_SHOWMENU "NudgeShowMenu" -// wParam = char *szProto -// lParam = BOOL show - { - char serviceFunc[256]; - hContact = Meta_GetMostOnline((HANDLE)wParam); - mir_snprintf(serviceFunc, 256, "%s/SendNudge", (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)); - CallService(MS_NUDGE_SHOWMENU, (WPARAM)META_PROTO, (LPARAM)ServiceExists(serviceFunc)); - } - } - else - {// This is a simple contact - if (!Meta_IsEnabled()) - { - // groups disabled - all meta menu options hidden - mi.flags = CMIM_FLAGS | CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&mi); - for (i = 0; i < MAX_CONTACTS; i++) { - mi.flags = CMIM_FLAGS | CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); - } - - } else if (DBGetContactSettingDword((HANDLE)wParam,META_PROTO,META_LINK,(DWORD)-1)!=(DWORD)-1) { - // The contact is affected to a metacontact. - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); - mi.flags |= CMIM_NAME; - mi.pszName = (char *)Translate("Remove from MetaContact"); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&mi); - mi.flags = CMIM_FLAGS | CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&mi); - for (i = 0; i < MAX_CONTACTS; i++) { - mi.flags = CMIM_FLAGS | CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); - } - } else { - // The contact is neutral - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); - mi.flags |= CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); - for (i = 0; i < MAX_CONTACTS; i++) { - mi.flags = CMIM_FLAGS | CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); - } - } - } - return 0; -} - - - diff --git a/plugins/MetaContacts/meta_menu.cpp b/plugins/MetaContacts/meta_menu.cpp new file mode 100644 index 0000000000..e71e9357a5 --- /dev/null +++ b/plugins/MetaContacts/meta_menu.cpp @@ -0,0 +1,562 @@ +/* +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 meta_menu.c +* +* Functions needed to handle MetaContacts. +* Centralizes functions called when the user chooses +* an option integrated in the context-menu of the \c CList. +*/ + +#include "metacontacts.h" + +/** Convert the contact chosen into a MetaContact. +* +* Create a new MetaContact, remove the selected contact from the \c CList +* and attach it to the MetaContact. +* +* @param wParam : \c HANDLE to the contact that has been chosen. +* @param lParam : Allways set to 0. +*/ +INT_PTR Meta_Convert(WPARAM wParam,LPARAM lParam) +{ + HANDLE hMetaContact; + DBVARIANT dbv; + char *group = 0;//, *proto; + + // Get some information about the selected contact. +// proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,wParam,0); + if (!DBGetContactSettingStringUtf((HANDLE)wParam,"CList","Group",&dbv)) { + group = _strdup(dbv.pszVal); + DBFreeVariant(&dbv); + } + + // Create a new metacontact + hMetaContact = (HANDLE)CallService(MS_DB_CONTACT_ADD,0,0); + + // Add the info for the metacontact + if (hMetaContact) + { + + DBWriteContactSettingDword(hMetaContact,META_PROTO,META_ID,nextMetaID); + DBWriteContactSettingDword(hMetaContact,META_PROTO,"NumContacts",0); + DBWriteContactSettingDword(NULL,META_PROTO,"NextMetaID",++nextMetaID); + + // Add the MetaContact protocol to the new meta contact + CallService( MS_PROTO_ADDTOCONTACT, ( WPARAM )hMetaContact, ( LPARAM )META_PROTO ); + + if (group) { + if (ServiceExists(MS_DB_CONTACT_GETSETTING_STR)) + DBWriteContactSettingStringUtf(hMetaContact,"CList","Group",group); + else + DBWriteContactSettingString(hMetaContact,"CList","Group",group); + } + + // Assign the contact to the MetaContact just created (and make default). + if (!Meta_Assign((HANDLE)wParam,hMetaContact,TRUE)) { + MessageBox(0,Translate("There was a problem in assigning the contact to the MetaContact"),Translate("Error"),MB_ICONEXCLAMATION); + CallService(MS_DB_CONTACT_DELETE, (WPARAM)hMetaContact, 0); + return 0; + } + + // hide the contact if clist groups disabled (shouldn't create one anyway since menus disabled) + if (!Meta_IsEnabled()) + DBWriteContactSettingByte(hMetaContact, "CList", "Hidden", 1); + + } + + // Update the graphics + CallService(MS_CLUI_SORTLIST,0,0); + + free(group); + return (int)hMetaContact; +} + +/** Display the 'Add to' Dialog +* +* Present a dialog in which the user can choose to which MetaContact this +* contact will be added +* +* @param wParam : \c HANDLE to the contact that has been chosen. +* @param lParam : Allways set to 0. +*/ +INT_PTR Meta_AddTo(WPARAM wParam, LPARAM lParam) +{ + HWND clui = (HWND)CallService(MS_CLUI_GETHWND,0,0); + DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_METASELECT),clui,&Meta_SelectDialogProc,(LPARAM)wParam); + return 0; +} + +/** Display the 'Edit' Dialog +* +* Present a dialog in which the user can edit some properties of the MetaContact. +* +* @param wParam : \c HANDLE to the MetaContact to be edited. +* @param lParam : Allways set to 0. +*/ +INT_PTR Meta_Edit(WPARAM wParam,LPARAM lParam) +{ + HWND clui = (HWND)CallService(MS_CLUI_GETHWND,0,0); + DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_METAEDIT),clui,Meta_EditDialogProc,(LPARAM)wParam); + return 0; +} + +/* DB/Contact/WriteSetting service +Change the value of, or create a new value with, a named setting for a specific +contact in the database to the given value + wParam=(WPARAM)(HANDLE)hContact + lParam=(LPARAM)(DBCONTACTWRITESETTING*)&dbcws +hContact should have been returned by find*contact or addcontact +Returns 0 on success or nonzero if hContact was invalid +Note that DBCONTACTGETSETTING takes a pointer to a DBVARIANT, whereas +DBCONTACTWRITESETTING contains a DBVARIANT. +Because this is such a common function there are some short helper function at +the bottom of this header that use it. +Triggers a db/contact/settingchanged event just before it returns. +*/ +//typedef struct { +// const char *szModule; // pointer to name of the module that wrote the +// // setting to get +// const char *szSetting; // pointer to name of the setting to get +// DBVARIANT value; // variant containing the value to set +//} DBCONTACTWRITESETTING; +//#define MS_DB_CONTACT_WRITESETTING "DB/Contact/WriteSetting" + +void Meta_RemoveContactNumber(HANDLE hMeta, int number) { + int i, num_contacts, default_contact; + HANDLE hContact;//, handle; + + char buffer[512], buffer2[512]; + + num_contacts = DBGetContactSettingDword(hMeta, META_PROTO, "NumContacts", 0); + default_contact = DBGetContactSettingDword(hMeta, META_PROTO, "Default", -1); + if (number >= 0 && number < num_contacts) { + + // get the handle + hContact = Meta_GetContactHandle(hMeta, number); + + // make sure this contact thinks it's part of this metacontact + if ((HANDLE)DBGetContactSettingDword(hContact,META_PROTO,"Handle", 0) == hMeta) { + + // remove link to meta contact + DBDeleteContactSetting(hContact,META_PROTO,"IsSubcontact"); + DBDeleteContactSetting(hContact,META_PROTO,META_LINK); + DBDeleteContactSetting(hContact,META_PROTO,"Handle"); + DBDeleteContactSetting(hContact,META_PROTO,"ContactNumber"); + // unhide - must be done after removing link (see meta_services.c:Meta_ChangeStatus) + Meta_RestoreGroup(hContact); + DBDeleteContactSetting(hContact,META_PROTO,"OldCListGroup"); + //CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)hContact,(LPARAM)META_PROTO); + CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)hContact,(LPARAM)META_FILTER); + // stop ignoring, if we were + if (options.suppress_status) + CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, (WPARAM)IGNOREEVENT_USERONLINE); + } + + // remove history from metacontact + //Meta_RemoveHistory(hMeta, hContact); + + // each contact from 'number' upwards will be moved down one + // and the last one will be deleted + for (i = number + 1; i < num_contacts; i++) { + Meta_SwapContacts(hMeta, i, i-1); + } + + // remove the last one + strcpy(buffer, "Protocol"); + strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); + DBDeleteContactSetting(hMeta, META_PROTO, buffer); + strcpy(buffer, "Status"); + strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); + DBDeleteContactSetting(hMeta, META_PROTO, buffer); + strcpy(buffer, "Handle"); + strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); + DBDeleteContactSetting(hMeta, META_PROTO, buffer); + strcpy(buffer, "StatusString"); + strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); + DBDeleteContactSetting(hMeta, META_PROTO, buffer); + strcpy(buffer, "Login"); + strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); + DBDeleteContactSetting(hMeta, META_PROTO, buffer); + strcpy(buffer, "Nick"); + strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); + DBDeleteContactSetting(hMeta, META_PROTO, buffer); + strcpy(buffer, "CListName"); + strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); + DBDeleteContactSetting(hMeta, META_PROTO, buffer); + + // if the default contact was equal to or greater than 'number', decrement it (and deal with ends) + if (default_contact >= number) { + default_contact--; + if (default_contact < 0) + default_contact = 0; + + DBWriteContactSettingDword(hMeta, META_PROTO, "Default", (DWORD)default_contact); + NotifyEventHooks(hEventDefaultChanged, (WPARAM)hMeta, (LPARAM)Meta_GetContactHandle(hMeta, default_contact)); + } + num_contacts--; + DBWriteContactSettingDword(hMeta, META_PROTO, "NumContacts", (DWORD)num_contacts); + + // fix nick + hContact = Meta_GetMostOnline(hMeta); + Meta_CopyContactNick(hMeta, hContact); + + // fix status + Meta_FixStatus(hMeta); + + // fix avatar + hContact = Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_4, PF4_AVATARS); + if (hContact) { + PROTO_AVATAR_INFORMATIONT AI; + + AI.cbSize = sizeof(AI); + AI.hContact = hMeta; + AI.format = PA_FORMAT_UNKNOWN; + _tcscpy(AI.filename, _T("X")); + + if ((int)CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) + DBWriteContactSettingTString(hMeta, "ContactPhoto", "File",AI.filename); + } + } +} + +/** Delete a MetaContact from the database +* +* Delete a MetaContact and remove all the information +* concerning this MetaContact in the contact linked to it. +* +* @param wParam : \c HANDLE to the MetaContact to be deleted, or to the subcontact to be removed from the MetaContact +* @param lParam : \c BOOL flag indicating whether to ask 'are you sure' when deleting a MetaContact +*/ +INT_PTR Meta_Delete(WPARAM wParam,LPARAM lParam) +{ + DWORD metaID; + HANDLE hContact; + + if ((metaID=DBGetContactSettingDword((HANDLE)wParam,META_PROTO,META_ID,(DWORD)-1))!=(DWORD)-1) + {// The wParam is a metacontact + if (!lParam) { // check from recursion - see second half of this function + if (MessageBox((HWND)CallService(MS_CLUI_GETHWND,0,0),Translate("This will remove the MetaContact permanently.\n\nProceed Anyway?"), + Translate("Are you sure?"),MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2)!=IDYES) + { + return 0; + } + } + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + while(hContact) + { // Scans the database to get all the contacts that have been previously linked to this MetaContact + if (DBGetContactSettingDword(hContact,META_PROTO,META_LINK,(DWORD)-1)==metaID) + { // This contact is assigned to the MetaContact that will be deleted, clear the "MetaContacts" information + DBDeleteContactSetting(hContact,META_PROTO,"IsSubcontact"); + DBDeleteContactSetting(hContact,META_PROTO,META_LINK); + DBDeleteContactSetting(hContact,META_PROTO,"Handle"); + DBDeleteContactSetting(hContact,META_PROTO,"ContactNumber"); + // unhide - must be done after removing link (see meta_services.c:Meta_ChangeStatus) + Meta_RestoreGroup(hContact); + DBDeleteContactSetting(hContact,META_PROTO,"OldCListGroup"); + + CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)hContact,(LPARAM)META_FILTER); + // stop ignoring, if we were + if (options.suppress_status) + CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, (WPARAM)IGNOREEVENT_USERONLINE); + } + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0); + } + //DBDeleteContactSetting((HANDLE)wParam, META_PROTO, META_ID); + //DBDeleteContactSetting((HANDLE)wParam, META_PROTO, "NumContacts"); + //CallService(MS_PROTO_REMOVEFROMCONTACT,wParam,(LPARAM)META_PROTO); + NotifyEventHooks(hSubcontactsChanged, (WPARAM)wParam, 0); + CallService(MS_DB_CONTACT_DELETE,wParam,0); + } + else + {// The wParam is a simple contact + //if (lParam == 0) + // return 1; // The function has been called by the menu of a simple contact. Should not happen. + //else + {// The function has been called by the edit dialog + HANDLE hMeta = (HANDLE)DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Handle", 0); + + + DWORD num_contacts = DBGetContactSettingDword(hMeta, META_PROTO, "NumContacts", -1); + + if (num_contacts == 1) { + if (MessageBox(0,Translate("You are going to remove all the contacts associated with this MetaContact.\nThis will delete the MetaContact.\n\nProceed Anyway?"), + Translate("Delete MetaContact?"),MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON1)==IDYES) + { + // recurse - once + Meta_Delete((WPARAM)hMeta,(LPARAM)1); + } + return 0; + } + + Meta_RemoveContactNumber(hMeta, DBGetContactSettingDword((HANDLE)wParam,META_PROTO,"ContactNumber", -1)); + + CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)wParam,(LPARAM)META_FILTER); + } + } + return 0; +} + +/** Set contact as MetaContact default +* +* Set the given contact to be the default one for the metacontact to which it is linked. +* +* @param wParam : \c HANDLE to the MetaContact to be set as default +* @param lParam : \c HWND to the clist window + (This means the function has been called via the contact menu). +*/ +INT_PTR Meta_Default(WPARAM wParam,LPARAM lParam) +{ + HANDLE hMeta; + + if ((hMeta = (HANDLE)DBGetContactSettingDword((HANDLE)wParam,META_PROTO,"Handle",0)) != 0) + { // the wParam is a subcontact + DBWriteContactSettingDword(hMeta, META_PROTO, "Default", (DWORD)Meta_GetContactNumber((HANDLE)wParam)); + NotifyEventHooks(hEventDefaultChanged, (WPARAM)hMeta, (LPARAM)(HANDLE)wParam); + } + return 0; +} + +/** Set/unset (i.e. toggle) contact to force use of default contact +* +* Set the given contact to be the default one for the metacontact to which it is linked. +* +* @param wParam : \c HANDLE to the MetaContact to be set as default +* @param lParam : \c HWND to the clist window + (This means the function has been called via the contact menu). +*/ +INT_PTR Meta_ForceDefault(WPARAM wParam,LPARAM lParam) +{ + if (DBGetContactSettingDword((HANDLE)wParam,META_PROTO, META_ID, (DWORD)-1) != (DWORD)-1) + { // the wParam is a MetaContact + + BOOL current = DBGetContactSettingByte((HANDLE)wParam, META_PROTO, "ForceDefault", 0); + current = !current; + DBWriteContactSettingByte((HANDLE)wParam, META_PROTO, "ForceDefault", (BYTE)current); + + DBWriteContactSettingDword((HANDLE)wParam, META_PROTO, "ForceSend", 0); + + if (current) NotifyEventHooks(hEventForceSend, wParam, (LPARAM)Meta_GetContactHandle((HANDLE)wParam, DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Default", -1))); + else NotifyEventHooks(hEventUnforceSend, wParam, 0); + } + return 0; +} + +INT_PTR MenuFunc0(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 0);} +INT_PTR MenuFunc1(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 1);} +INT_PTR MenuFunc2(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 2);} +INT_PTR MenuFunc3(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 3);} +INT_PTR MenuFunc4(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 4);} +INT_PTR MenuFunc5(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 5);} +INT_PTR MenuFunc6(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 6);} +INT_PTR MenuFunc7(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 7);} +INT_PTR MenuFunc8(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 8);} +INT_PTR MenuFunc9(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 9);} +INT_PTR MenuFunc10(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 10);} +INT_PTR MenuFunc11(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 11);} +INT_PTR MenuFunc12(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 12);} +INT_PTR MenuFunc13(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 13);} +INT_PTR MenuFunc14(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 14);} +INT_PTR MenuFunc15(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 15);} +INT_PTR MenuFunc16(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 16);} +INT_PTR MenuFunc17(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 17);} +INT_PTR MenuFunc18(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 18);} +INT_PTR MenuFunc19(WPARAM wParam, LPARAM lParam) {return TranslateMenuFunc((HANDLE)wParam, 19);} + +HANDLE hMenuContact[MAX_CONTACTS]; + +INT_PTR TranslateMenuFunc(HANDLE hMeta, int contact_number) { + return Meta_ContactMenuFunc((WPARAM)hMeta, (LPARAM) contact_number); +} + +/** Called when the context-menu of a contact is about to be displayed +* +* This will test which of the 4 menu item should be displayed, depending +* on which contact triggered the event +* +* @param wParam : \c HANDLE to the contact that triggered the event +* @param lParam : Always set to 0; +*/ +int Meta_ModifyMenu(WPARAM wParam, LPARAM lParam) +{ + CLISTMENUITEM mi; + DBVARIANT dbv; + HANDLE hContact; + char *proto; + char buf[512], buffer2[512]; + int i, iconIndex; + WORD status; + + mi.flags = CMIM_FLAGS; + mi.cbSize = sizeof(CLISTMENUITEM); + + if (DBGetContactSettingDword((HANDLE)wParam,META_PROTO,META_ID,-1) != (DWORD)-1) + { + int num_contacts, i; + + // save the mouse pos in case they open a subcontact menu + GetCursorPos(&menuMousePoint); + + // This is a MetaContact, show the edit, force default, and the delete menu, and hide the others + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&mi); + //mi.flags |= CMIM_NAME; + //if (DBGetContactSettingByte((HANDLE)wParam, META_PROTO, "ForceDefault", 0)) + // mi.pszName = Translate("Unforce Default"); + //else + // mi.pszName = Translate("Force Default"); + //CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuForceDefault, (LPARAM)&mi); + mi.flags = CMIM_FLAGS | CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); + mi.flags = CMIM_FLAGS | CMIM_NAME | CMIF_HIDDEN; // we don't need delete - already in contact menu + mi.pszName = Translate("Delete MetaContact"); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&mi); + + + //show subcontact menu items + num_contacts = DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "NumContacts", 0); + for (i = 0; i < MAX_CONTACTS; i++) { + if (i < num_contacts) { + hContact = Meta_GetContactHandle((HANDLE)wParam, i); + proto = _strdup((char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)); + + if (!proto) + status = ID_STATUS_OFFLINE; + else + status = DBGetContactSettingWord(hContact, proto, "Status", ID_STATUS_OFFLINE); + + if (options.menu_contact_label == DNT_UID) { + strcpy(buf, "Login"); + strcat(buf, _itoa(i, buffer2, 10)); + + DBGetContactSetting((HANDLE)wParam,META_PROTO,buf,&dbv); + switch(dbv.type) + { + case DBVT_ASCIIZ: + mir_snprintf(buf,512,"%s",dbv.pszVal); + break; + case DBVT_BYTE: + mir_snprintf(buf,512,"%d",dbv.bVal); + break; + case DBVT_WORD: + mir_snprintf(buf,512,"%d",dbv.wVal); + break; + case DBVT_DWORD: + mir_snprintf(buf,512,"%d",dbv.dVal); + break; + default: + buf[0] = 0; + } + DBFreeVariant(&dbv); + mi.pszName = buf; + mi.flags = 0; + } else { + char *name = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0); + char *wname = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_UNICODE); + + if (wname && strncmp(name, wname, strlen(name)) != 0) { + mi.pszName = wname; + mi.flags = CMIF_UNICODE; + } + else { + mi.pszName = name; + mi.flags = 0; + } + } + + mi.flags |= CMIM_FLAGS | CMIM_NAME | CMIM_ICON; + + //mi.hIcon = LoadSkinnedProtoIcon(proto, status); + iconIndex = (int)CallService(MS_CLIST_GETCONTACTICON, (WPARAM)hContact, 0); + mi.hIcon = ImageList_GetIcon((HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), iconIndex, 0);; + + free(proto); + + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); + DestroyIcon(mi.hIcon); + //CallService(MS_SKIN2_RELEASEICON, (WPARAM)mi.hIcon, 0); + } else { + mi.flags = CMIM_FLAGS | CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); + } + } + + // show hide nudge menu item +#define MS_NUDGE_SHOWMENU "NudgeShowMenu" +// wParam = char *szProto +// lParam = BOOL show + { + char serviceFunc[256]; + hContact = Meta_GetMostOnline((HANDLE)wParam); + mir_snprintf(serviceFunc, 256, "%s/SendNudge", (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)); + CallService(MS_NUDGE_SHOWMENU, (WPARAM)META_PROTO, (LPARAM)ServiceExists(serviceFunc)); + } + } + else + {// This is a simple contact + if (!Meta_IsEnabled()) + { + // groups disabled - all meta menu options hidden + mi.flags = CMIM_FLAGS | CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&mi); + for (i = 0; i < MAX_CONTACTS; i++) { + mi.flags = CMIM_FLAGS | CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); + } + + } else if (DBGetContactSettingDword((HANDLE)wParam,META_PROTO,META_LINK,(DWORD)-1)!=(DWORD)-1) { + // The contact is affected to a metacontact. + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); + mi.flags |= CMIM_NAME; + mi.pszName = (char *)Translate("Remove from MetaContact"); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&mi); + mi.flags = CMIM_FLAGS | CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&mi); + for (i = 0; i < MAX_CONTACTS; i++) { + mi.flags = CMIM_FLAGS | CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); + } + } else { + // The contact is neutral + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); + mi.flags |= CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuEdit, (LPARAM)&mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDelete, (LPARAM)&mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); + for (i = 0; i < MAX_CONTACTS; i++) { + mi.flags = CMIM_FLAGS | CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[i], (LPARAM)&mi); + } + } + } + return 0; +} + + + diff --git a/plugins/MetaContacts/meta_options.c b/plugins/MetaContacts/meta_options.c deleted file mode 100644 index cceb484f6f..0000000000 --- a/plugins/MetaContacts/meta_options.c +++ /dev/null @@ -1,640 +0,0 @@ -/* -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 meta_menu.c -* -* Functions needed to handle MetaContacts. -* Centralizes functions called when the user chooses -* an option integrated in the context-menu of the \c CList. -*/ - -#include "metacontacts.h" - -MetaOptions options; -MetaOptions options_changes; - -INT_PTR CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HWND hw; - char buff[512]; - - switch ( msg ) { - case WM_INITDIALOG: { - TranslateDialogDefault( hwndDlg ); - options_changes = options; - - CheckDlgButton(hwndDlg, IDC_CHK_SETDEFAULTRECV, options_changes.set_default_on_recv ? TRUE : FALSE); - hw = GetDlgItem(hwndDlg, IDC_CHK_TEMPDEFAULT); - EnableWindow(hw, options_changes.set_default_on_recv); - CheckDlgButton(hwndDlg, IDC_CHK_TEMPDEFAULT, options_changes.temp_default ? TRUE : FALSE); - - CheckDlgButton(hwndDlg, IDC_CHK_ALWAYSUSEDEFAULT, options_changes.always_use_default ? TRUE : FALSE); - CheckDlgButton(hwndDlg, IDC_CHK_SUPPRESSSTATUS, options_changes.suppress_status ? TRUE : FALSE); - CheckDlgButton(hwndDlg, IDC_CHK_SUPPRESSPROTO, options_changes.suppress_proto ? TRUE : FALSE); - - CheckDlgButton(hwndDlg, IDC_RAD_UID, options_changes.menu_contact_label == DNT_UID); - CheckDlgButton(hwndDlg, IDC_RAD_DID, options_changes.menu_contact_label == DNT_DID); - - CheckDlgButton(hwndDlg, IDC_RAD_MSG, options_changes.menu_function == FT_MSG); - CheckDlgButton(hwndDlg, IDC_RAD_MENU, options_changes.menu_function == FT_MENU); - CheckDlgButton(hwndDlg, IDC_RAD_INFO, options_changes.menu_function == FT_INFO); - - CheckDlgButton(hwndDlg, IDC_RAD_NICK, options_changes.clist_contact_name == CNNT_NICK); - CheckDlgButton(hwndDlg, IDC_RAD_NAME, options_changes.clist_contact_name == CNNT_DISPLAYNAME); - CheckDlgButton(hwndDlg, IDC_CHK_LOCKHANDLE, options_changes.lockHandle ? TRUE : FALSE); - CheckDlgButton(hwndDlg, IDC_CHK_SUBWINDOW, options_changes.subcontact_windows ? TRUE : FALSE); - - CheckDlgButton(hwndDlg, IDC_CHK_METAHISTORY, options_changes.metahistory ? TRUE : FALSE); - CheckDlgButton(hwndDlg, IDC_CHK_SUBHISTORY, options_changes.subhistory ? TRUE : FALSE); - CheckDlgButton(hwndDlg, IDC_CHK_COPYDATA, options_changes.copydata ? TRUE : FALSE); - - if (!options_changes.subcontact_windows) { - hw = GetDlgItem(hwndDlg, IDC_CHK_METAHISTORY); - EnableWindow(hw, FALSE); - } else { - hw = GetDlgItem(hwndDlg, IDC_CHK_SUBHISTORY); - EnableWindow(hw, FALSE); - } - - CheckDlgButton(hwndDlg, IDC_CHK_COPYHISTORY, options_changes.copy_subcontact_history ? TRUE : FALSE); - hw = GetDlgItem(hwndDlg, IDC_ED_DAYS); - _itoa(options_changes.days_history, buff, 10); - SetWindowText(hw, buff); - - return TRUE; - } - case WM_COMMAND: - if ( HIWORD( wParam ) == BN_CLICKED ) { - switch( LOWORD( wParam )) { - case IDC_CHK_SETDEFAULTRECV: - options_changes.set_default_on_recv = IsDlgButtonChecked(hwndDlg, IDC_CHK_SETDEFAULTRECV); - hw = GetDlgItem(hwndDlg, IDC_CHK_TEMPDEFAULT); - EnableWindow(hw, options_changes.set_default_on_recv); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_CHK_TEMPDEFAULT: - hw = GetDlgItem(hwndDlg, IDC_CHK_TEMPDEFAULT); - options_changes.temp_default = IsDlgButtonChecked(hwndDlg, IDC_CHK_TEMPDEFAULT); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_CHK_ALWAYSUSEDEFAULT: - hw = GetDlgItem(hwndDlg, IDC_CHK_ALWAYSUSEDEFAULT); - options_changes.always_use_default = IsDlgButtonChecked(hwndDlg, IDC_CHK_ALWAYSUSEDEFAULT); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_CHK_SUPPRESSSTATUS: - hw = GetDlgItem(hwndDlg, IDC_CHK_SUPPRESSSTATUS); - options_changes.suppress_status = IsDlgButtonChecked(hwndDlg, IDC_CHK_SUPPRESSSTATUS); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_CHK_SUPPRESSPROTO: - hw = GetDlgItem(hwndDlg, IDC_CHK_SUPPRESSPROTO); - options_changes.suppress_proto = IsDlgButtonChecked(hwndDlg, IDC_CHK_SUPPRESSPROTO); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_CHK_COPYHISTORY: - hw = GetDlgItem(hwndDlg, IDC_CHK_COPYHISTORY); - options_changes.copy_subcontact_history = IsDlgButtonChecked(hwndDlg, IDC_CHK_COPYHISTORY); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_CHK_METAHISTORY: - hw = GetDlgItem(hwndDlg, IDC_CHK_METAHISTORY); - options_changes.metahistory = IsDlgButtonChecked(hwndDlg, IDC_CHK_METAHISTORY); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_CHK_SUBHISTORY: - hw = GetDlgItem(hwndDlg, IDC_CHK_SUBHISTORY); - options_changes.subhistory = IsDlgButtonChecked(hwndDlg, IDC_CHK_SUBHISTORY); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_CHK_COPYDATA: - hw = GetDlgItem(hwndDlg, IDC_CHK_COPYDATA); - options_changes.copydata = IsDlgButtonChecked(hwndDlg, IDC_CHK_COPYDATA); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_RAD_UID: - hw = GetDlgItem(hwndDlg, IDC_RAD_UID); - if (IsDlgButtonChecked(hwndDlg, IDC_RAD_UID)) { - options_changes.menu_contact_label = DNT_UID; - CheckDlgButton(hwndDlg, IDC_RAD_DID, FALSE); - } - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_RAD_DID: - hw = GetDlgItem(hwndDlg, IDC_RAD_DID); - if (IsDlgButtonChecked(hwndDlg, IDC_RAD_DID)) { - options_changes.menu_contact_label = DNT_DID; - CheckDlgButton(hwndDlg, IDC_RAD_UID, FALSE); - } - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_RAD_MSG: - hw = GetDlgItem(hwndDlg, IDC_RAD_MSG); - if (IsDlgButtonChecked(hwndDlg, IDC_RAD_MSG)) { - options_changes.menu_function = FT_MSG; - CheckDlgButton(hwndDlg, IDC_RAD_MENU, FALSE); - CheckDlgButton(hwndDlg, IDC_RAD_INFO, FALSE); - } - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_RAD_MENU: - hw = GetDlgItem(hwndDlg, IDC_RAD_MENU); - if (IsDlgButtonChecked(hwndDlg, IDC_RAD_MENU)) { - options_changes.menu_function = FT_MENU; - CheckDlgButton(hwndDlg, IDC_RAD_MSG, FALSE); - CheckDlgButton(hwndDlg, IDC_RAD_INFO, FALSE); - } - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_RAD_INFO: - hw = GetDlgItem(hwndDlg, IDC_RAD_INFO); - if (IsDlgButtonChecked(hwndDlg, IDC_RAD_INFO)) { - options_changes.menu_function = FT_INFO; - CheckDlgButton(hwndDlg, IDC_RAD_MSG, FALSE); - CheckDlgButton(hwndDlg, IDC_RAD_MENU, FALSE); - } - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_RAD_NICK: - hw = GetDlgItem(hwndDlg, IDC_RAD_NICK); - if (IsDlgButtonChecked(hwndDlg, IDC_RAD_NICK)) { - options_changes.clist_contact_name = CNNT_NICK; - CheckDlgButton(hwndDlg, IDC_RAD_NAME, FALSE); - } - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_RAD_NAME: - hw = GetDlgItem(hwndDlg, IDC_RAD_NAME); - if (IsDlgButtonChecked(hwndDlg, IDC_RAD_NAME)) { - options_changes.clist_contact_name = CNNT_DISPLAYNAME; - CheckDlgButton(hwndDlg, IDC_RAD_NICK, FALSE); - } - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_CHK_SUBWINDOW: - hw = GetDlgItem(hwndDlg, IDC_CHK_SUBWINDOW); - options_changes.subcontact_windows = IsDlgButtonChecked(hwndDlg, IDC_CHK_SUBWINDOW); - - if (options_changes.subcontact_windows) { - hw = GetDlgItem(hwndDlg, IDC_CHK_METAHISTORY); - EnableWindow(hw, TRUE); - hw = GetDlgItem(hwndDlg, IDC_CHK_SUBHISTORY); - CheckDlgButton(hwndDlg, IDC_CHK_SUBHISTORY, TRUE); - EnableWindow(hw, FALSE); - options_changes.subhistory = TRUE; - } else { - hw = GetDlgItem(hwndDlg, IDC_CHK_SUBHISTORY); - EnableWindow(hw, TRUE); - hw = GetDlgItem(hwndDlg, IDC_CHK_METAHISTORY); - CheckDlgButton(hwndDlg, IDC_CHK_METAHISTORY, TRUE); - EnableWindow(hw, FALSE); - options_changes.metahistory = TRUE; - } - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - case IDC_CHK_LOCKHANDLE: - options_changes.lockHandle = IsDlgButtonChecked(hwndDlg, IDC_CHK_LOCKHANDLE); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - } - } else if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) { - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - } - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->code == PSN_APPLY ) { - hw = GetDlgItem(hwndDlg, IDC_ED_DAYS); - GetWindowText(hw, buff, 512); - if (strlen(buff) > 0) - options_changes.days_history = atoi(buff); - - options = options_changes; - Meta_WriteOptions(&options); - - Meta_SuppressStatus(options.suppress_status); - Meta_SetAllNicks(); - return TRUE; - } - break; - } - - return FALSE; -} - -int Meta_WriteOptions(MetaOptions *opt) { - DBWriteContactSettingByte(NULL, META_PROTO, "SetDefaultOnRecv", (BYTE)(opt->set_default_on_recv ? 1 : 0)); - DBWriteContactSettingByte(NULL, META_PROTO, "TempDefault", (BYTE)(opt->temp_default ? 1 : 0)); - DBWriteContactSettingByte(NULL, META_PROTO, "AlwaysUseDefault", (BYTE)(opt->always_use_default ? 1 : 0)); - DBWriteContactSettingByte(NULL, META_PROTO, "SuppressStatus", (BYTE)(opt->suppress_status ? 1 : 0)); - DBWriteContactSettingWord(NULL, META_PROTO, "MenuContactLabel", (WORD)opt->menu_contact_label); - DBWriteContactSettingWord(NULL, META_PROTO, "MenuContactFunction", (WORD)opt->menu_function); - DBWriteContactSettingWord(NULL, META_PROTO, "CListContactName", (WORD)opt->clist_contact_name); - DBWriteContactSettingByte(NULL, META_PROTO, "SuppressProto", (BYTE)(opt->suppress_proto ? 1 : 0)); - DBWriteContactSettingByte(NULL, META_PROTO, "CopyHistory", (BYTE)(opt->copy_subcontact_history ? 1 : 0)); - DBWriteContactSettingDword(NULL, META_PROTO, "DaysHistory", (DWORD)(opt->days_history)); - DBWriteContactSettingDword(NULL, META_PROTO, "SetStatusFromOfflineDelay", (DWORD)(opt->set_status_from_offline_delay)); - DBWriteContactSettingByte(NULL, META_PROTO, "SubcontactWindows", (BYTE)(opt->subcontact_windows ? 1 : 0)); - DBWriteContactSettingByte(NULL, META_PROTO, "CopyData", (BYTE)(opt->copydata ? 1 : 0)); - DBWriteContactSettingByte(NULL, META_PROTO, "LockHandle", (BYTE)(opt->lockHandle ? 1 : 0)); - DBWriteContactSettingByte(NULL, META_PROTO, "MetaMessageIcon", (BYTE)(opt->flash_meta_message_icon ? 1 : 0)); - DBWriteContactSettingByte(NULL, META_PROTO, "CopyUserInfo", (BYTE)(opt->copy_userinfo ? 1 : 0)); - - if (!opt->subcontact_windows) - DBWriteContactSettingByte(NULL, META_PROTO, "MetaHistory", 1); - else - DBWriteContactSettingByte(NULL, META_PROTO, "MetaHistory", (BYTE)(opt->metahistory ? 1 : 0)); - - if (opt->subcontact_windows) - DBWriteContactSettingByte(NULL, META_PROTO, "SubcontactHistory", 1); - else - DBWriteContactSettingByte(NULL, META_PROTO, "SubcontactHistory", (BYTE)(opt->subhistory ? 1 : 0)); - return 0; - - DBWriteContactSettingByte(NULL, META_PROTO, "UseProtoRecv", (BYTE)(opt->use_proto_recv ? 1 : 0)); -} - -int Meta_ReadOptions(MetaOptions *opt) { - opt->set_default_on_recv = (DBGetContactSettingByte(NULL, META_PROTO, "SetDefaultOnRecv", 1) == 1 ? TRUE : FALSE); - opt->temp_default = (DBGetContactSettingByte(NULL, META_PROTO, "TempDefault", 0) == 1 ? TRUE : FALSE); - opt->always_use_default = (DBGetContactSettingByte(NULL, META_PROTO, "AlwaysUseDefault", 0) == 1 ? TRUE : FALSE); - opt->suppress_status = (DBGetContactSettingByte(NULL, META_PROTO, "SuppressStatus", 1) == 1 ? TRUE : FALSE); - opt->menu_contact_label = (int)DBGetContactSettingWord(NULL, META_PROTO, "MenuContactLabel", DNT_UID); - opt->menu_function = (int)DBGetContactSettingWord(NULL, META_PROTO, "MenuContactFunction", FT_MENU); - opt->clist_contact_name = (int)DBGetContactSettingWord(NULL, META_PROTO, "CListContactName", CNNT_NICK); - opt->suppress_proto = (DBGetContactSettingByte(NULL, META_PROTO, "SuppressProto", 0) == 1 ? TRUE : FALSE); - opt->copy_subcontact_history = (DBGetContactSettingByte(NULL, META_PROTO, "CopyHistory", 1) == 1 ? TRUE : FALSE); - opt->days_history = (int)DBGetContactSettingDword(NULL, META_PROTO, "DaysHistory", 14); - opt->set_status_from_offline_delay = (int)DBGetContactSettingDword(NULL, META_PROTO, "SetStatusFromOfflineDelay", DEFAULT_SET_STATUS_SLEEP_TIME); - opt->subcontact_windows = (DBGetContactSettingByte(NULL, META_PROTO, "SubcontactWindows", 0) == 1 ? TRUE : FALSE); - opt->copydata = (DBGetContactSettingByte(NULL, META_PROTO, "CopyData", 1) == 1 ? TRUE : FALSE); - opt->lockHandle = (DBGetContactSettingByte(NULL, META_PROTO, "LockHandle", 0) == 1 ? TRUE : FALSE); - opt->flash_meta_message_icon = (DBGetContactSettingByte(NULL, META_PROTO, "MetaMessageIcon", 1) == 1 ? TRUE : FALSE); - opt->copy_userinfo = (DBGetContactSettingByte(NULL, META_PROTO, "CopyUserInfo", 1) == 1 ? TRUE : FALSE); - - if (!opt->subcontact_windows) - opt->metahistory = TRUE; - else - opt->metahistory = (DBGetContactSettingByte(NULL, META_PROTO, "MetaHistory", 1) == 1 ? TRUE : FALSE); - - if (opt->subcontact_windows) - opt->subhistory = TRUE; - else - opt->subhistory = (DBGetContactSettingByte(NULL, META_PROTO, "SubcontactHistory", 1) == 1 ? TRUE : FALSE); - - opt->use_proto_recv = (DBGetContactSettingByte(NULL, META_PROTO, "UseProtoRecv", 1) == 1 ? TRUE : FALSE); - return 0; -} - -/* -#define ID_STATUS_OFFLINE 40071 ->8 -#define ID_STATUS_ONLINE 40072 ->0 -#define ID_STATUS_AWAY 40073 ->4 -#define ID_STATUS_DND 40074 ->7 -#define ID_STATUS_NA 40075 ->6 -#define ID_STATUS_OCCUPIED 40076 ->5 -#define ID_STATUS_FREECHAT 40077 ->1 -#define ID_STATUS_INVISIBLE 40078 ->0 -#define ID_STATUS_ONTHEPHONE 40079 ->2 -#define ID_STATUS_OUTTOLUNCH 40080 ->3 -*/ - -int GetDefaultPrio(int status) { - switch( status ) { - case ID_STATUS_OFFLINE: return 8; - case ID_STATUS_AWAY: return 4; - case ID_STATUS_DND: return 7; - case ID_STATUS_NA: return 6; - case ID_STATUS_OCCUPIED: return 5; - case ID_STATUS_FREECHAT: return 1; - case ID_STATUS_ONTHEPHONE: return 2; - case ID_STATUS_OUTTOLUNCH: return 3; - } - - return 0; -} - -typedef struct { - int prio[10]; // priority for each status - BOOL def[10]; // use default for this one? -} ProtoStatusPrio; - -ProtoStatusPrio *priorities = 0; - -int GetRealPriority(char *proto, int status) { - char szSetting[256]; - if (!proto) { - mir_snprintf(szSetting, 256, "DefaultPrio_%d", status); - return DBGetContactSettingWord(0, META_PROTO, szSetting, GetDefaultPrio(status)); - } else { - int prio; - mir_snprintf(szSetting, 256, "ProtoPrio_%s%d", proto, status); - prio = DBGetContactSettingWord(0, META_PROTO, szSetting, 0xFFFF); - if (prio == 0xFFFF) { - mir_snprintf(szSetting, 256, "DefaultPrio_%d", status); - return DBGetContactSettingWord(0, META_PROTO, szSetting, GetDefaultPrio(status)); - } else - return prio; - } - return 0xFFFF; -} - -void ReadPriorities() { - int num_protocols; - PROTOCOLDESCRIPTOR **pppDesc; - char szSetting[256]; - ProtoStatusPrio * current; - int i, j; - - CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&num_protocols, (WPARAM)&pppDesc); - - current = priorities = (ProtoStatusPrio *)malloc((num_protocols + 1) * sizeof(ProtoStatusPrio)); - for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { - mir_snprintf(szSetting, 256, "DefaultPrio_%d", i); - current->def[i - ID_STATUS_OFFLINE] = TRUE; - current->prio[i - ID_STATUS_OFFLINE] = DBGetContactSettingWord(0, META_PROTO, szSetting, GetDefaultPrio(i)); - } - for (i = 0; i < num_protocols; i++) { - current = priorities + (i + 1); - for (j = ID_STATUS_OFFLINE; j <= ID_STATUS_OUTTOLUNCH; j++) { - mir_snprintf(szSetting, 256, "ProtoPrio_%s%d", pppDesc[i]->szName, j); - current->prio[j - ID_STATUS_OFFLINE] = DBGetContactSettingWord(0, META_PROTO, szSetting, 0xFFFF); - current->def[j - ID_STATUS_OFFLINE] = (current->prio[j - ID_STATUS_OFFLINE] == 0xFFFF); - } - } -} - -void WritePriorities() { - int num_protocols; - PROTOCOLDESCRIPTOR **pppDesc; - char szSetting[256]; - ProtoStatusPrio * current = priorities; - int i, j; - - CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&num_protocols, (WPARAM)&pppDesc); - - for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { - mir_snprintf(szSetting, 256, "DefaultPrio_%d", i); - if (current->prio[i - ID_STATUS_OFFLINE] != GetDefaultPrio(i)) - DBWriteContactSettingWord(0, META_PROTO, szSetting, (WORD)current->prio[i - ID_STATUS_OFFLINE]); - else - DBDeleteContactSetting(0, META_PROTO, szSetting); - } - for (i = 0; i < num_protocols; i++) { - current = priorities + (i + 1); - for (j = ID_STATUS_OFFLINE; j <= ID_STATUS_OUTTOLUNCH; j++) { - mir_snprintf(szSetting, 256, "ProtoPrio_%s%d", pppDesc[i]->szName, j); - if (!current->def[j - ID_STATUS_OFFLINE]) - DBWriteContactSettingWord(0, META_PROTO, szSetting, (WORD)current->prio[j - ID_STATUS_OFFLINE]); - else - DBDeleteContactSetting(0, META_PROTO, szSetting); - } - } -} - -int GetIsDefault(int proto_index, int status) { - return (priorities + (proto_index + 1))->def[status - ID_STATUS_OFFLINE]; -} - -BOOL GetPriority(int proto_index, int status) { - ProtoStatusPrio * current; - if (proto_index == -1) { - current = priorities; - return current->prio[status - ID_STATUS_OFFLINE]; - } else { - current = priorities + (proto_index + 1); - if (current->def[status - ID_STATUS_OFFLINE]) { - current = priorities; - } - return current->prio[status - ID_STATUS_OFFLINE]; - } - return 0xFFFF; -} - -void SetPriority(int proto_index, int status, BOOL def, int prio) { - ProtoStatusPrio * current; - if (prio < 0) prio = 0; - if (prio > 500) prio = 500; - if (proto_index == -1) { - current = priorities; - current->prio[status - ID_STATUS_OFFLINE] = prio; - } else { - current = priorities + (proto_index + 1); - current->def[status - ID_STATUS_OFFLINE] = def; - if (!def) { - current->prio[status - ID_STATUS_OFFLINE] = prio; - } - } -} - -void ResetPriorities() { - int num_protocols; - PROTOCOLDESCRIPTOR **pppDesc; - ProtoStatusPrio * current; - int i, j; - - CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&num_protocols, (WPARAM)&pppDesc); - - current = priorities; - for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { - current->def[i - ID_STATUS_OFFLINE] = TRUE; - current->prio[i - ID_STATUS_OFFLINE] = GetDefaultPrio(i); - } - for (i = 0; i < num_protocols; i++) { - current = priorities + (i + 1); - for (j = ID_STATUS_OFFLINE; j <= ID_STATUS_OUTTOLUNCH; j++) { - current->def[j - ID_STATUS_OFFLINE] = TRUE; - } - } -} - -#define WMU_FILLSTATUSCMB (WM_USER + 0x100) -#define WMU_FILLPRIODATA (WM_USER + 0x101) - -INT_PTR CALLBACK DlgProcOptsPriorities(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HWND hw; - - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - SendMessage(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), UDM_SETRANGE, 0, (LPARAM)MAKELONG(500, 0)); - ReadPriorities(); - { - int num_protocols; - PROTOCOLDESCRIPTOR **pppDesc; - int i, index; - - CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&num_protocols, (WPARAM)&pppDesc); - hw = GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL); - index = SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)Translate("")); - SendMessage(hw, CB_SETITEMDATA, (WPARAM)index, -1); - for (i = 0; i < num_protocols; i++) { - if (pppDesc[i]->type == PROTOTYPE_PROTOCOL) { - if (strcmp(pppDesc[i]->szName, META_PROTO) != 0) { - index = SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)pppDesc[i]->szName); - SendMessage(hw, CB_SETITEMDATA, (WPARAM)index, i); - } - } - } - - SendMessage(hw, CB_SETCURSEL, 0, 0); - SendMessage(hwndDlg, WMU_FILLSTATUSCMB, 0, 0); - SendMessage(hwndDlg, WMU_FILLPRIODATA, 0, 0); - } - return FALSE; - case WMU_FILLPRIODATA: - { - int sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETCURSEL, 0, 0); - if (sel != -1) { - int index = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETITEMDATA, (WPARAM)sel, 0); - sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETCURSEL, 0, 0); - if (sel != -1) { - int status = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETITEMDATA, (WPARAM)sel, 0); - SetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, GetPriority(index, status), FALSE); - if (index == -1) { - EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PRIORITY), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), TRUE); - CheckDlgButton(hwndDlg, IDC_CHK_DEFAULT, TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_DEFAULT), FALSE); - } else { - if (GetIsDefault(index, status)) { - CheckDlgButton(hwndDlg, IDC_CHK_DEFAULT, TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PRIORITY), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), FALSE); - } else { - CheckDlgButton(hwndDlg, IDC_CHK_DEFAULT, FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PRIORITY), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), TRUE); - } - - EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_DEFAULT), TRUE); - } - } - } - } - return TRUE; - case WMU_FILLSTATUSCMB: - { - int sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETCURSEL, 0, 0); - if (sel != -1) { - int index = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETITEMDATA, (WPARAM)sel, 0); - HWND hw = GetDlgItem(hwndDlg, IDC_CMB_STATUS); - SendMessage(hw, CB_RESETCONTENT, 0, 0); - if (index == -1) { - int i; - for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { - index = SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)(char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, i, 0)); - SendMessage(hw, CB_SETITEMDATA, (WPARAM)index, i); - } - } else { - int num_protocols, caps, i; - PROTOCOLDESCRIPTOR **pppDesc; - CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&num_protocols, (WPARAM)&pppDesc); - - caps = CallProtoService(pppDesc[index]->szName, PS_GETCAPS, PFLAGNUM_2, 0); - - for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { - if (caps & Proto_Status2Flag(i)) { - index = SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)(char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, i, 0)); - SendMessage(hw, CB_SETITEMDATA, (WPARAM)index, i); - } - } - } - SendMessage(hw, CB_SETCURSEL, 0, 0); - SendMessage(hwndDlg, WMU_FILLPRIODATA, 0, 0); - } - } - return TRUE; - case WM_COMMAND: - if ( HIWORD( wParam ) == BN_CLICKED ) { - switch( LOWORD( wParam )) { - case IDC_CHK_DEFAULT: - { - int sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETCURSEL, 0, 0); - if (sel != -1) { - int index = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETITEMDATA, (WPARAM)sel, 0); - sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETCURSEL, 0, 0); - if (sel != -1) { - BOOL checked = IsDlgButtonChecked(hwndDlg, IDC_CHK_DEFAULT); - int status = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETITEMDATA, (WPARAM)sel, 0); - if (checked) { - SetPriority(index, status, TRUE, 0); - SetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, GetPriority(index, status), FALSE); - } else { - SetPriority(index, status, FALSE, GetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, 0, FALSE)); - } - EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PRIORITY), !checked); - EnableWindow(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), !checked); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - } - } - } - break; - case IDC_BTN_RESET: - ResetPriorities(); - SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_SETCURSEL, 0, 0); - SendMessage(hwndDlg, WMU_FILLSTATUSCMB, 0, 0); - SendMessage(hwndDlg, WMU_FILLPRIODATA, 0, 0); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - break; - } - } - if ( HIWORD( wParam ) == EN_CHANGE && LOWORD(wParam) == IDC_ED_PRIORITY && ( HWND )lParam == GetFocus()) { - int sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETCURSEL, 0, 0); - if (sel != -1) { - int index = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETITEMDATA, (WPARAM)sel, 0); - sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETCURSEL, 0, 0); - if (sel != -1) { - int status = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETITEMDATA, (WPARAM)sel, 0); - int prio = GetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, 0, FALSE); - SetPriority(index, status, FALSE, prio); - if (prio != GetPriority(index, status)) - SetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, GetPriority(index, status), FALSE); - SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); - } - } - } - if ( HIWORD( wParam ) == CBN_SELCHANGE) { - switch( LOWORD( wParam )) { - case IDC_CMB_STATUS: - SendMessage(hwndDlg, WMU_FILLPRIODATA, 0, 0); - break; - case IDC_CMB_PROTOCOL: - SendMessage(hwndDlg, WMU_FILLSTATUSCMB, 0, 0); - break; - } - } - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->code == PSN_APPLY ) { - WritePriorities(); - return TRUE; - } - break; - case WM_DESTROY: - free(priorities); - priorities = 0; - break; - } - - return FALSE; -} diff --git a/plugins/MetaContacts/meta_options.cpp b/plugins/MetaContacts/meta_options.cpp new file mode 100644 index 0000000000..9b113def92 --- /dev/null +++ b/plugins/MetaContacts/meta_options.cpp @@ -0,0 +1,640 @@ +/* +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 meta_menu.c +* +* Functions needed to handle MetaContacts. +* Centralizes functions called when the user chooses +* an option integrated in the context-menu of the \c CList. +*/ + +#include "metacontacts.h" + +MetaOptions options; +MetaOptions options_changes; + +INT_PTR CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hw; + char buff[512]; + + switch ( msg ) { + case WM_INITDIALOG: { + TranslateDialogDefault( hwndDlg ); + options_changes = options; + + CheckDlgButton(hwndDlg, IDC_CHK_SETDEFAULTRECV, options_changes.set_default_on_recv ? TRUE : FALSE); + hw = GetDlgItem(hwndDlg, IDC_CHK_TEMPDEFAULT); + EnableWindow(hw, options_changes.set_default_on_recv); + CheckDlgButton(hwndDlg, IDC_CHK_TEMPDEFAULT, options_changes.temp_default ? TRUE : FALSE); + + CheckDlgButton(hwndDlg, IDC_CHK_ALWAYSUSEDEFAULT, options_changes.always_use_default ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_SUPPRESSSTATUS, options_changes.suppress_status ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_SUPPRESSPROTO, options_changes.suppress_proto ? TRUE : FALSE); + + CheckDlgButton(hwndDlg, IDC_RAD_UID, options_changes.menu_contact_label == DNT_UID); + CheckDlgButton(hwndDlg, IDC_RAD_DID, options_changes.menu_contact_label == DNT_DID); + + CheckDlgButton(hwndDlg, IDC_RAD_MSG, options_changes.menu_function == FT_MSG); + CheckDlgButton(hwndDlg, IDC_RAD_MENU, options_changes.menu_function == FT_MENU); + CheckDlgButton(hwndDlg, IDC_RAD_INFO, options_changes.menu_function == FT_INFO); + + CheckDlgButton(hwndDlg, IDC_RAD_NICK, options_changes.clist_contact_name == CNNT_NICK); + CheckDlgButton(hwndDlg, IDC_RAD_NAME, options_changes.clist_contact_name == CNNT_DISPLAYNAME); + CheckDlgButton(hwndDlg, IDC_CHK_LOCKHANDLE, options_changes.lockHandle ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_SUBWINDOW, options_changes.subcontact_windows ? TRUE : FALSE); + + CheckDlgButton(hwndDlg, IDC_CHK_METAHISTORY, options_changes.metahistory ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_SUBHISTORY, options_changes.subhistory ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_COPYDATA, options_changes.copydata ? TRUE : FALSE); + + if (!options_changes.subcontact_windows) { + hw = GetDlgItem(hwndDlg, IDC_CHK_METAHISTORY); + EnableWindow(hw, FALSE); + } else { + hw = GetDlgItem(hwndDlg, IDC_CHK_SUBHISTORY); + EnableWindow(hw, FALSE); + } + + CheckDlgButton(hwndDlg, IDC_CHK_COPYHISTORY, options_changes.copy_subcontact_history ? TRUE : FALSE); + hw = GetDlgItem(hwndDlg, IDC_ED_DAYS); + _itoa(options_changes.days_history, buff, 10); + SetWindowText(hw, buff); + + return TRUE; + } + case WM_COMMAND: + if ( HIWORD( wParam ) == BN_CLICKED ) { + switch( LOWORD( wParam )) { + case IDC_CHK_SETDEFAULTRECV: + options_changes.set_default_on_recv = IsDlgButtonChecked(hwndDlg, IDC_CHK_SETDEFAULTRECV); + hw = GetDlgItem(hwndDlg, IDC_CHK_TEMPDEFAULT); + EnableWindow(hw, options_changes.set_default_on_recv); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_CHK_TEMPDEFAULT: + hw = GetDlgItem(hwndDlg, IDC_CHK_TEMPDEFAULT); + options_changes.temp_default = IsDlgButtonChecked(hwndDlg, IDC_CHK_TEMPDEFAULT); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_CHK_ALWAYSUSEDEFAULT: + hw = GetDlgItem(hwndDlg, IDC_CHK_ALWAYSUSEDEFAULT); + options_changes.always_use_default = IsDlgButtonChecked(hwndDlg, IDC_CHK_ALWAYSUSEDEFAULT); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_CHK_SUPPRESSSTATUS: + hw = GetDlgItem(hwndDlg, IDC_CHK_SUPPRESSSTATUS); + options_changes.suppress_status = IsDlgButtonChecked(hwndDlg, IDC_CHK_SUPPRESSSTATUS); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_CHK_SUPPRESSPROTO: + hw = GetDlgItem(hwndDlg, IDC_CHK_SUPPRESSPROTO); + options_changes.suppress_proto = IsDlgButtonChecked(hwndDlg, IDC_CHK_SUPPRESSPROTO); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_CHK_COPYHISTORY: + hw = GetDlgItem(hwndDlg, IDC_CHK_COPYHISTORY); + options_changes.copy_subcontact_history = IsDlgButtonChecked(hwndDlg, IDC_CHK_COPYHISTORY); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_CHK_METAHISTORY: + hw = GetDlgItem(hwndDlg, IDC_CHK_METAHISTORY); + options_changes.metahistory = IsDlgButtonChecked(hwndDlg, IDC_CHK_METAHISTORY); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_CHK_SUBHISTORY: + hw = GetDlgItem(hwndDlg, IDC_CHK_SUBHISTORY); + options_changes.subhistory = IsDlgButtonChecked(hwndDlg, IDC_CHK_SUBHISTORY); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_CHK_COPYDATA: + hw = GetDlgItem(hwndDlg, IDC_CHK_COPYDATA); + options_changes.copydata = IsDlgButtonChecked(hwndDlg, IDC_CHK_COPYDATA); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_RAD_UID: + hw = GetDlgItem(hwndDlg, IDC_RAD_UID); + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_UID)) { + options_changes.menu_contact_label = DNT_UID; + CheckDlgButton(hwndDlg, IDC_RAD_DID, FALSE); + } + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_RAD_DID: + hw = GetDlgItem(hwndDlg, IDC_RAD_DID); + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_DID)) { + options_changes.menu_contact_label = DNT_DID; + CheckDlgButton(hwndDlg, IDC_RAD_UID, FALSE); + } + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_RAD_MSG: + hw = GetDlgItem(hwndDlg, IDC_RAD_MSG); + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_MSG)) { + options_changes.menu_function = FT_MSG; + CheckDlgButton(hwndDlg, IDC_RAD_MENU, FALSE); + CheckDlgButton(hwndDlg, IDC_RAD_INFO, FALSE); + } + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_RAD_MENU: + hw = GetDlgItem(hwndDlg, IDC_RAD_MENU); + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_MENU)) { + options_changes.menu_function = FT_MENU; + CheckDlgButton(hwndDlg, IDC_RAD_MSG, FALSE); + CheckDlgButton(hwndDlg, IDC_RAD_INFO, FALSE); + } + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_RAD_INFO: + hw = GetDlgItem(hwndDlg, IDC_RAD_INFO); + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_INFO)) { + options_changes.menu_function = FT_INFO; + CheckDlgButton(hwndDlg, IDC_RAD_MSG, FALSE); + CheckDlgButton(hwndDlg, IDC_RAD_MENU, FALSE); + } + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_RAD_NICK: + hw = GetDlgItem(hwndDlg, IDC_RAD_NICK); + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_NICK)) { + options_changes.clist_contact_name = CNNT_NICK; + CheckDlgButton(hwndDlg, IDC_RAD_NAME, FALSE); + } + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_RAD_NAME: + hw = GetDlgItem(hwndDlg, IDC_RAD_NAME); + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_NAME)) { + options_changes.clist_contact_name = CNNT_DISPLAYNAME; + CheckDlgButton(hwndDlg, IDC_RAD_NICK, FALSE); + } + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_CHK_SUBWINDOW: + hw = GetDlgItem(hwndDlg, IDC_CHK_SUBWINDOW); + options_changes.subcontact_windows = IsDlgButtonChecked(hwndDlg, IDC_CHK_SUBWINDOW); + + if (options_changes.subcontact_windows) { + hw = GetDlgItem(hwndDlg, IDC_CHK_METAHISTORY); + EnableWindow(hw, TRUE); + hw = GetDlgItem(hwndDlg, IDC_CHK_SUBHISTORY); + CheckDlgButton(hwndDlg, IDC_CHK_SUBHISTORY, TRUE); + EnableWindow(hw, FALSE); + options_changes.subhistory = TRUE; + } else { + hw = GetDlgItem(hwndDlg, IDC_CHK_SUBHISTORY); + EnableWindow(hw, TRUE); + hw = GetDlgItem(hwndDlg, IDC_CHK_METAHISTORY); + CheckDlgButton(hwndDlg, IDC_CHK_METAHISTORY, TRUE); + EnableWindow(hw, FALSE); + options_changes.metahistory = TRUE; + } + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + case IDC_CHK_LOCKHANDLE: + options_changes.lockHandle = IsDlgButtonChecked(hwndDlg, IDC_CHK_LOCKHANDLE); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + } + } else if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) { + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + } + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->code == PSN_APPLY ) { + hw = GetDlgItem(hwndDlg, IDC_ED_DAYS); + GetWindowText(hw, buff, 512); + if (strlen(buff) > 0) + options_changes.days_history = atoi(buff); + + options = options_changes; + Meta_WriteOptions(&options); + + Meta_SuppressStatus(options.suppress_status); + Meta_SetAllNicks(); + return TRUE; + } + break; + } + + return FALSE; +} + +int Meta_WriteOptions(MetaOptions *opt) { + DBWriteContactSettingByte(NULL, META_PROTO, "SetDefaultOnRecv", (BYTE)(opt->set_default_on_recv ? 1 : 0)); + DBWriteContactSettingByte(NULL, META_PROTO, "TempDefault", (BYTE)(opt->temp_default ? 1 : 0)); + DBWriteContactSettingByte(NULL, META_PROTO, "AlwaysUseDefault", (BYTE)(opt->always_use_default ? 1 : 0)); + DBWriteContactSettingByte(NULL, META_PROTO, "SuppressStatus", (BYTE)(opt->suppress_status ? 1 : 0)); + DBWriteContactSettingWord(NULL, META_PROTO, "MenuContactLabel", (WORD)opt->menu_contact_label); + DBWriteContactSettingWord(NULL, META_PROTO, "MenuContactFunction", (WORD)opt->menu_function); + DBWriteContactSettingWord(NULL, META_PROTO, "CListContactName", (WORD)opt->clist_contact_name); + DBWriteContactSettingByte(NULL, META_PROTO, "SuppressProto", (BYTE)(opt->suppress_proto ? 1 : 0)); + DBWriteContactSettingByte(NULL, META_PROTO, "CopyHistory", (BYTE)(opt->copy_subcontact_history ? 1 : 0)); + DBWriteContactSettingDword(NULL, META_PROTO, "DaysHistory", (DWORD)(opt->days_history)); + DBWriteContactSettingDword(NULL, META_PROTO, "SetStatusFromOfflineDelay", (DWORD)(opt->set_status_from_offline_delay)); + DBWriteContactSettingByte(NULL, META_PROTO, "SubcontactWindows", (BYTE)(opt->subcontact_windows ? 1 : 0)); + DBWriteContactSettingByte(NULL, META_PROTO, "CopyData", (BYTE)(opt->copydata ? 1 : 0)); + DBWriteContactSettingByte(NULL, META_PROTO, "LockHandle", (BYTE)(opt->lockHandle ? 1 : 0)); + DBWriteContactSettingByte(NULL, META_PROTO, "MetaMessageIcon", (BYTE)(opt->flash_meta_message_icon ? 1 : 0)); + DBWriteContactSettingByte(NULL, META_PROTO, "CopyUserInfo", (BYTE)(opt->copy_userinfo ? 1 : 0)); + + if (!opt->subcontact_windows) + DBWriteContactSettingByte(NULL, META_PROTO, "MetaHistory", 1); + else + DBWriteContactSettingByte(NULL, META_PROTO, "MetaHistory", (BYTE)(opt->metahistory ? 1 : 0)); + + if (opt->subcontact_windows) + DBWriteContactSettingByte(NULL, META_PROTO, "SubcontactHistory", 1); + else + DBWriteContactSettingByte(NULL, META_PROTO, "SubcontactHistory", (BYTE)(opt->subhistory ? 1 : 0)); + return 0; + + DBWriteContactSettingByte(NULL, META_PROTO, "UseProtoRecv", (BYTE)(opt->use_proto_recv ? 1 : 0)); +} + +int Meta_ReadOptions(MetaOptions *opt) { + opt->set_default_on_recv = (DBGetContactSettingByte(NULL, META_PROTO, "SetDefaultOnRecv", 1) == 1 ? TRUE : FALSE); + opt->temp_default = (DBGetContactSettingByte(NULL, META_PROTO, "TempDefault", 1) == 1 ? TRUE : FALSE); + opt->always_use_default = (DBGetContactSettingByte(NULL, META_PROTO, "AlwaysUseDefault", 1) == 1 ? TRUE : FALSE); + opt->suppress_status = (DBGetContactSettingByte(NULL, META_PROTO, "SuppressStatus", 1) == 1 ? TRUE : FALSE); + opt->menu_contact_label = (int)DBGetContactSettingWord(NULL, META_PROTO, "MenuContactLabel", DNT_UID); + opt->menu_function = (int)DBGetContactSettingWord(NULL, META_PROTO, "MenuContactFunction", FT_MENU); + opt->clist_contact_name = (int)DBGetContactSettingWord(NULL, META_PROTO, "CListContactName", CNNT_NICK); + opt->suppress_proto = (DBGetContactSettingByte(NULL, META_PROTO, "SuppressProto", 0) == 1 ? TRUE : FALSE); + opt->copy_subcontact_history = (DBGetContactSettingByte(NULL, META_PROTO, "CopyHistory", 1) == 1 ? TRUE : FALSE); + opt->days_history = (int)DBGetContactSettingDword(NULL, META_PROTO, "DaysHistory", 0); + opt->set_status_from_offline_delay = (int)DBGetContactSettingDword(NULL, META_PROTO, "SetStatusFromOfflineDelay", DEFAULT_SET_STATUS_SLEEP_TIME); + opt->subcontact_windows = (DBGetContactSettingByte(NULL, META_PROTO, "SubcontactWindows", 0) == 1 ? TRUE : FALSE); + opt->copydata = (DBGetContactSettingByte(NULL, META_PROTO, "CopyData", 1) == 1 ? TRUE : FALSE); + opt->lockHandle = (DBGetContactSettingByte(NULL, META_PROTO, "LockHandle", 0) == 1 ? TRUE : FALSE); + opt->flash_meta_message_icon = (DBGetContactSettingByte(NULL, META_PROTO, "MetaMessageIcon", 1) == 1 ? TRUE : FALSE); + opt->copy_userinfo = (DBGetContactSettingByte(NULL, META_PROTO, "CopyUserInfo", 1) == 1 ? TRUE : FALSE); + + if (!opt->subcontact_windows) + opt->metahistory = TRUE; + else + opt->metahistory = (DBGetContactSettingByte(NULL, META_PROTO, "MetaHistory", 1) == 1 ? TRUE : FALSE); + + if (opt->subcontact_windows) + opt->subhistory = TRUE; + else + opt->subhistory = (DBGetContactSettingByte(NULL, META_PROTO, "SubcontactHistory", 1) == 1 ? TRUE : FALSE); + + opt->use_proto_recv = (DBGetContactSettingByte(NULL, META_PROTO, "UseProtoRecv", 1) == 1 ? TRUE : FALSE); + return 0; +} + +/* +#define ID_STATUS_OFFLINE 40071 ->8 +#define ID_STATUS_ONLINE 40072 ->0 +#define ID_STATUS_AWAY 40073 ->4 +#define ID_STATUS_DND 40074 ->7 +#define ID_STATUS_NA 40075 ->6 +#define ID_STATUS_OCCUPIED 40076 ->5 +#define ID_STATUS_FREECHAT 40077 ->1 +#define ID_STATUS_INVISIBLE 40078 ->0 +#define ID_STATUS_ONTHEPHONE 40079 ->2 +#define ID_STATUS_OUTTOLUNCH 40080 ->3 +*/ + +int GetDefaultPrio(int status) { + switch( status ) { + case ID_STATUS_OFFLINE: return 8; + case ID_STATUS_AWAY: return 4; + case ID_STATUS_DND: return 7; + case ID_STATUS_NA: return 6; + case ID_STATUS_OCCUPIED: return 5; + case ID_STATUS_FREECHAT: return 1; + case ID_STATUS_ONTHEPHONE: return 2; + case ID_STATUS_OUTTOLUNCH: return 3; + } + + return 0; +} + +typedef struct { + int prio[10]; // priority for each status + BOOL def[10]; // use default for this one? +} ProtoStatusPrio; + +ProtoStatusPrio *priorities = 0; + +int GetRealPriority(char *proto, int status) { + char szSetting[256]; + if (!proto) { + mir_snprintf(szSetting, 256, "DefaultPrio_%d", status); + return DBGetContactSettingWord(0, META_PROTO, szSetting, GetDefaultPrio(status)); + } else { + int prio; + mir_snprintf(szSetting, 256, "ProtoPrio_%s%d", proto, status); + prio = DBGetContactSettingWord(0, META_PROTO, szSetting, 0xFFFF); + if (prio == 0xFFFF) { + mir_snprintf(szSetting, 256, "DefaultPrio_%d", status); + return DBGetContactSettingWord(0, META_PROTO, szSetting, GetDefaultPrio(status)); + } else + return prio; + } + return 0xFFFF; +} + +void ReadPriorities() { + int num_protocols; + PROTOCOLDESCRIPTOR **pppDesc; + char szSetting[256]; + ProtoStatusPrio * current; + int i, j; + + CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&num_protocols, (WPARAM)&pppDesc); + + current = priorities = (ProtoStatusPrio *)malloc((num_protocols + 1) * sizeof(ProtoStatusPrio)); + for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { + mir_snprintf(szSetting, 256, "DefaultPrio_%d", i); + current->def[i - ID_STATUS_OFFLINE] = TRUE; + current->prio[i - ID_STATUS_OFFLINE] = DBGetContactSettingWord(0, META_PROTO, szSetting, GetDefaultPrio(i)); + } + for (i = 0; i < num_protocols; i++) { + current = priorities + (i + 1); + for (j = ID_STATUS_OFFLINE; j <= ID_STATUS_OUTTOLUNCH; j++) { + mir_snprintf(szSetting, 256, "ProtoPrio_%s%d", pppDesc[i]->szName, j); + current->prio[j - ID_STATUS_OFFLINE] = DBGetContactSettingWord(0, META_PROTO, szSetting, 0xFFFF); + current->def[j - ID_STATUS_OFFLINE] = (current->prio[j - ID_STATUS_OFFLINE] == 0xFFFF); + } + } +} + +void WritePriorities() { + int num_protocols; + PROTOCOLDESCRIPTOR **pppDesc; + char szSetting[256]; + ProtoStatusPrio * current = priorities; + int i, j; + + CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&num_protocols, (WPARAM)&pppDesc); + + for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { + mir_snprintf(szSetting, 256, "DefaultPrio_%d", i); + if (current->prio[i - ID_STATUS_OFFLINE] != GetDefaultPrio(i)) + DBWriteContactSettingWord(0, META_PROTO, szSetting, (WORD)current->prio[i - ID_STATUS_OFFLINE]); + else + DBDeleteContactSetting(0, META_PROTO, szSetting); + } + for (i = 0; i < num_protocols; i++) { + current = priorities + (i + 1); + for (j = ID_STATUS_OFFLINE; j <= ID_STATUS_OUTTOLUNCH; j++) { + mir_snprintf(szSetting, 256, "ProtoPrio_%s%d", pppDesc[i]->szName, j); + if (!current->def[j - ID_STATUS_OFFLINE]) + DBWriteContactSettingWord(0, META_PROTO, szSetting, (WORD)current->prio[j - ID_STATUS_OFFLINE]); + else + DBDeleteContactSetting(0, META_PROTO, szSetting); + } + } +} + +int GetIsDefault(int proto_index, int status) { + return (priorities + (proto_index + 1))->def[status - ID_STATUS_OFFLINE]; +} + +BOOL GetPriority(int proto_index, int status) { + ProtoStatusPrio * current; + if (proto_index == -1) { + current = priorities; + return current->prio[status - ID_STATUS_OFFLINE]; + } else { + current = priorities + (proto_index + 1); + if (current->def[status - ID_STATUS_OFFLINE]) { + current = priorities; + } + return current->prio[status - ID_STATUS_OFFLINE]; + } + return 0xFFFF; +} + +void SetPriority(int proto_index, int status, BOOL def, int prio) { + ProtoStatusPrio * current; + if (prio < 0) prio = 0; + if (prio > 500) prio = 500; + if (proto_index == -1) { + current = priorities; + current->prio[status - ID_STATUS_OFFLINE] = prio; + } else { + current = priorities + (proto_index + 1); + current->def[status - ID_STATUS_OFFLINE] = def; + if (!def) { + current->prio[status - ID_STATUS_OFFLINE] = prio; + } + } +} + +void ResetPriorities() { + int num_protocols; + PROTOCOLDESCRIPTOR **pppDesc; + ProtoStatusPrio * current; + int i, j; + + CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&num_protocols, (WPARAM)&pppDesc); + + current = priorities; + for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { + current->def[i - ID_STATUS_OFFLINE] = TRUE; + current->prio[i - ID_STATUS_OFFLINE] = GetDefaultPrio(i); + } + for (i = 0; i < num_protocols; i++) { + current = priorities + (i + 1); + for (j = ID_STATUS_OFFLINE; j <= ID_STATUS_OUTTOLUNCH; j++) { + current->def[j - ID_STATUS_OFFLINE] = TRUE; + } + } +} + +#define WMU_FILLSTATUSCMB (WM_USER + 0x100) +#define WMU_FILLPRIODATA (WM_USER + 0x101) + +INT_PTR CALLBACK DlgProcOptsPriorities(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hw; + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + SendMessage(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), UDM_SETRANGE, 0, (LPARAM)MAKELONG(500, 0)); + ReadPriorities(); + { + int num_protocols; + PROTOCOLDESCRIPTOR **pppDesc; + int i, index; + + CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&num_protocols, (WPARAM)&pppDesc); + hw = GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL); + index = SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)Translate("")); + SendMessage(hw, CB_SETITEMDATA, (WPARAM)index, -1); + for (i = 0; i < num_protocols; i++) { + if (pppDesc[i]->type == PROTOTYPE_PROTOCOL) { + if (strcmp(pppDesc[i]->szName, META_PROTO) != 0) { + index = SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)pppDesc[i]->szName); + SendMessage(hw, CB_SETITEMDATA, (WPARAM)index, i); + } + } + } + + SendMessage(hw, CB_SETCURSEL, 0, 0); + SendMessage(hwndDlg, WMU_FILLSTATUSCMB, 0, 0); + SendMessage(hwndDlg, WMU_FILLPRIODATA, 0, 0); + } + return FALSE; + case WMU_FILLPRIODATA: + { + int sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETCURSEL, 0, 0); + if (sel != -1) { + int index = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETITEMDATA, (WPARAM)sel, 0); + sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETCURSEL, 0, 0); + if (sel != -1) { + int status = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETITEMDATA, (WPARAM)sel, 0); + SetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, GetPriority(index, status), FALSE); + if (index == -1) { + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PRIORITY), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), TRUE); + CheckDlgButton(hwndDlg, IDC_CHK_DEFAULT, TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_DEFAULT), FALSE); + } else { + if (GetIsDefault(index, status)) { + CheckDlgButton(hwndDlg, IDC_CHK_DEFAULT, TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PRIORITY), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), FALSE); + } else { + CheckDlgButton(hwndDlg, IDC_CHK_DEFAULT, FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PRIORITY), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), TRUE); + } + + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_DEFAULT), TRUE); + } + } + } + } + return TRUE; + case WMU_FILLSTATUSCMB: + { + int sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETCURSEL, 0, 0); + if (sel != -1) { + int index = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETITEMDATA, (WPARAM)sel, 0); + HWND hw = GetDlgItem(hwndDlg, IDC_CMB_STATUS); + SendMessage(hw, CB_RESETCONTENT, 0, 0); + if (index == -1) { + int i; + for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { + index = SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)(char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, i, 0)); + SendMessage(hw, CB_SETITEMDATA, (WPARAM)index, i); + } + } else { + int num_protocols, caps, i; + PROTOCOLDESCRIPTOR **pppDesc; + CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&num_protocols, (WPARAM)&pppDesc); + + caps = CallProtoService(pppDesc[index]->szName, PS_GETCAPS, PFLAGNUM_2, 0); + + for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { + if (caps & Proto_Status2Flag(i)) { + index = SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)(char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, i, 0)); + SendMessage(hw, CB_SETITEMDATA, (WPARAM)index, i); + } + } + } + SendMessage(hw, CB_SETCURSEL, 0, 0); + SendMessage(hwndDlg, WMU_FILLPRIODATA, 0, 0); + } + } + return TRUE; + case WM_COMMAND: + if ( HIWORD( wParam ) == BN_CLICKED ) { + switch( LOWORD( wParam )) { + case IDC_CHK_DEFAULT: + { + int sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETCURSEL, 0, 0); + if (sel != -1) { + int index = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETITEMDATA, (WPARAM)sel, 0); + sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETCURSEL, 0, 0); + if (sel != -1) { + BOOL checked = IsDlgButtonChecked(hwndDlg, IDC_CHK_DEFAULT); + int status = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETITEMDATA, (WPARAM)sel, 0); + if (checked) { + SetPriority(index, status, TRUE, 0); + SetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, GetPriority(index, status), FALSE); + } else { + SetPriority(index, status, FALSE, GetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, 0, FALSE)); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PRIORITY), !checked); + EnableWindow(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), !checked); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + } + } + } + break; + case IDC_BTN_RESET: + ResetPriorities(); + SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_SETCURSEL, 0, 0); + SendMessage(hwndDlg, WMU_FILLSTATUSCMB, 0, 0); + SendMessage(hwndDlg, WMU_FILLPRIODATA, 0, 0); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + break; + } + } + if ( HIWORD( wParam ) == EN_CHANGE && LOWORD(wParam) == IDC_ED_PRIORITY && ( HWND )lParam == GetFocus()) { + int sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETCURSEL, 0, 0); + if (sel != -1) { + int index = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETITEMDATA, (WPARAM)sel, 0); + sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETCURSEL, 0, 0); + if (sel != -1) { + int status = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETITEMDATA, (WPARAM)sel, 0); + int prio = GetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, 0, FALSE); + SetPriority(index, status, FALSE, prio); + if (prio != GetPriority(index, status)) + SetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, GetPriority(index, status), FALSE); + SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 ); + } + } + } + if ( HIWORD( wParam ) == CBN_SELCHANGE) { + switch( LOWORD( wParam )) { + case IDC_CMB_STATUS: + SendMessage(hwndDlg, WMU_FILLPRIODATA, 0, 0); + break; + case IDC_CMB_PROTOCOL: + SendMessage(hwndDlg, WMU_FILLSTATUSCMB, 0, 0); + break; + } + } + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->code == PSN_APPLY ) { + WritePriorities(); + return TRUE; + } + break; + case WM_DESTROY: + free(priorities); + priorities = 0; + break; + } + + return FALSE; +} diff --git a/plugins/MetaContacts/meta_services.c b/plugins/MetaContacts/meta_services.c deleted file mode 100644 index 8f570773b1..0000000000 --- a/plugins/MetaContacts/meta_services.c +++ /dev/null @@ -1,2104 +0,0 @@ -/* -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 meta_services.c -* -* Functions specific to the protocol part of the plugin. -* Centralizes all the functions called by Miranda to make -* the plugin work as a protocol. -*/ - -#include "metacontacts.h" - -#define NB_SERVICES 62 //!< Number of services registered in Miranda (see Meta_CloseHandles()). -#define NB_HOOKS 17 //!< Number of hooks set up (see Meta_CloseHandles()). - -#define PREF_METANODB 0x2000 //!< Flag to indicate message should not be added to db by filter when sending - -char *pendingACK = 0; //!< Name of the protocol in which an ACK is about to come. - -int previousMode, //!< Previous status of the MetaContacts Protocol - mcStatus; //!< Current status of the MetaContacts Protocol - -HANDLE hServices[NB_SERVICES] = {0}, //!< list of all the services registered (see Meta_CloseHandles()). -hHooks[NB_HOOKS] = {0}; //!< list of all hooks set up (see Meta_CloseHandles()). - -HANDLE *hNudgeEvents = 0; -int iNudgeProtos = 0; - -HGENMENU - hMenuConvert, //!< \c HANDLE to the convert menu item. - hMenuAdd, //!< \c HANDLE to the add to menu item. - hMenuEdit, //!< \c HANDLE to the edit menu item. - hMenuDelete, //!< \c HANDLE to the delete menu item. - hMenuDefault, //!< \c HANDLE to the delete menu item. - hMenuForceDefault, //!< \c HANDLE to the delete menu item. - hMenuOnOff; //!< \c HANDLE to the enable/disable menu item. - -HANDLE - hEventDefaultChanged, //!< \c HANDLE to the 'default changed' event - hEventForceSend, //!< \c HANDLE to the 'force send' event - hEventUnforceSend, //!< \c HANDLE to the 'unforce send' event - hSubcontactsChanged, //!< \c HANDLE to the 'contacts changed' event - hEventNudge; - - -DWORD nextMetaID; //!< Global variable specifying the ID value the next MetaContact will have. - -BOOL message_window_api_enabled = FALSE; //!< Global variable specifying whether the message window api ver 0.0.0.1+ is available - -// stuff for mw_clist extra icon -int proto_count = 0; -HANDLE hExtraImage[MAX_PROTOCOLS * 2]; // online and offline icons -char proto_names[MAX_PROTOCOLS * 128]; -HANDLE hProtoIcons[MAX_PROTOCOLS * 2]; // online and offline icons - -UINT_PTR setStatusTimerId = 0; -BOOL firstSetOnline = TRUE; // see Meta_SetStatus function - -/** Get the capabilities of the "MetaContacts" protocol. -* -* @param wParam : equals to one of the following values :\n - PFLAGNUM_1 | PFLAGNUM_2 | PFLAGNUM_3 | PFLAGNUM_4 | PFLAG_UNIQUEIDTEXT | PFLAG_MAXLENOFMESSAGE | PFLAG_UNIQUEIDSETTING . -* @param lParam : Allways set to 0. -* -* @return Depending on the \c WPARAM. -*/ -INT_PTR Meta_GetCaps(WPARAM wParam,LPARAM lParam) -{ - int ret = 0; - switch (wParam) { - case PFLAGNUM_1: - //ret = PF1_IM | PF1_URL | PF1_FILE | PF1_MODEMSG | PF1_AUTHREQ | PF1_ADDED; - //ret = PF1_IMSEND | PF1_URLSEND | PF1_FILESEND | PF1_MODEMSGSEND; - ret = PF1_IM | PF1_CHAT | PF1_FILESEND | PF1_MODEMSGRECV | PF1_NUMERICUSERID; - break; - case PFLAGNUM_2: - if (!options.suppress_proto) { - ret = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND - | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE; - } - //ret = PF2_ONLINE; - break; - case PFLAGNUM_3: - //ret = PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND; - ret = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND - | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE; - break; - case PFLAGNUM_4: - //ret = PF4_FORCEAUTH; - ret = PF4_SUPPORTTYPING | PF4_AVATARS; - break; - case PFLAGNUM_5: - ret = PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND - | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE; - break; - case PFLAG_UNIQUEIDTEXT: - ret = (INT_PTR) Translate("Meta ID"); - break; - case PFLAG_MAXLENOFMESSAGE: - ret = 2000; - break; - case PFLAG_UNIQUEIDSETTING: - ret = (INT_PTR) META_ID; - break; - } - return ret; -} - -/** Copy the name of the protocole into lParam -* @param wParam : max size of the name -* @param lParam : reference to a char *, which will hold the name -*/ -INT_PTR Meta_GetName(WPARAM wParam,LPARAM lParam) -{ - char *name = (char *)Translate(META_PROTO); - size_t size = min(strlen(name),wParam-1); // copy only the first size bytes. - if (strncpy((char *)lParam,name,size)==NULL) - return 1; - ((char *)lParam)[size]='\0'; - return 0; -} - -/** Loads the icon corresponding to the status -* Called by the CList when the status changes. -* @param wParam : one of the following values : \n - PLI_PROTOCOL | PLI_ONLINE | PLI_OFFLINE -* @return an \c HICON in which the icon has been loaded. -*/ -INT_PTR Meta_LoadIcon(WPARAM wParam,LPARAM lParam) -{ - UINT id; - switch (wParam & 0xFFFF) - { - case PLI_PROTOCOL: - id = IDI_MCMENU; - break; - case PLI_ONLINE: - id = IDI_MCMENU; - break; - case PLI_OFFLINE: - id = IDI_MCMENU; - break; - default: - return 0; - } - - return (INT_PTR) LoadImage(hInstance, MAKEINTRESOURCE(id), IMAGE_ICON, - GetSystemMetrics(wParam & PLIF_SMALL ? SM_CXSMICON : SM_CXICON), - GetSystemMetrics(wParam & PLIF_SMALL ? SM_CYSMICON : SM_CYICON), 0); - -} - - -//static DWORD CALLBACK SetStatusThread( LPVOID param ) -void CALLBACK SetStatusThread(HWND hWnd, UINT msg, UINT_PTR id, DWORD dw) -{ - - previousMode = mcStatus; - - //Sleep(options.set_status_from_offline_delay); - - mcStatus = (int)ID_STATUS_ONLINE; - ProtoBroadcastAck(META_PROTO,NULL,ACKTYPE_STATUS,ACKRESULT_SUCCESS, (HANDLE)previousMode, mcStatus); - - //return 0; - KillTimer(0, setStatusTimerId); -} - -/** Changes the status and notifies everybody -* @param wParam : The new mode -* @param lParam : Allways set to 0. -*/ -INT_PTR Meta_SetStatus(WPARAM wParam,LPARAM lParam) -{ - // firstSetOnline starts out true - used to delay metacontact's 'onlineness' to prevent double status notifications on startup - if (mcStatus == ID_STATUS_OFFLINE && firstSetOnline) { - // causes crash on exit if miranda is closed in under options.set_status_from_offline milliseconds! - //CloseHandle( CreateThread( NULL, 0, SetStatusThread, (void *)wParam, 0, 0 )); - setStatusTimerId = SetTimer(0, 0, options.set_status_from_offline_delay, SetStatusThread); - firstSetOnline = FALSE; - } else { - previousMode = mcStatus; - mcStatus = (int)wParam; - ProtoBroadcastAck(META_PROTO,NULL,ACKTYPE_STATUS,ACKRESULT_SUCCESS, (HANDLE)previousMode, mcStatus); - } - return 0; -} - -/** Returns the current status -*/ -INT_PTR Meta_GetStatus(WPARAM wParam,LPARAM lParam) -{ - return mcStatus; -} - -////////////////////////////////////////////////////////// -/// Copied from MSN plugin - sent acks need to be from different thread :( -////////////////////////////////////////////////////////// -typedef struct tag_TFakeAckParams -{ - HANDLE hEvent; - HANDLE hContact; - LONG id; - char msg[512]; -} TFakeAckParams; - -/* -static DWORD CALLBACK sttFakeAckSuccess( LPVOID param ) -{ - TFakeAckParams *tParam = ( TFakeAckParams* )param; - WaitForSingleObject( tParam->hEvent, INFINITE ); - - Sleep( 100 ); - ProtoBroadcastAck(META_PROTO, tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, ( HANDLE )tParam->id, 0 ); - - CloseHandle( tParam->hEvent ); - free(tParam); - return 0; -} -*/ - -static DWORD CALLBACK sttFakeAckFail( LPVOID param ) -{ - TFakeAckParams *tParam = ( TFakeAckParams* )param; - WaitForSingleObject( tParam->hEvent, INFINITE ); - - Sleep( 100 ); - ProtoBroadcastAck(META_PROTO, tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, ( HANDLE )tParam->id, (WPARAM)tParam->msg ); - - CloseHandle( tParam->hEvent ); - mir_free(tParam); - return 0; -} - -/** Filter messages sent by subcontacts -* -* When groups are disabled, add an event to the DB for the metacontact to maintain history -* -* @param wParam : index of the protocol in the protocol chain. -* @param lParam : \c CCSDATA structure holding all the information about the message. -* -* @return 0 on success, 1 otherwise. -*/ - -INT_PTR MetaFilter_SendMessage(WPARAM wParam,LPARAM lParam) -{ - DBEVENTINFO dbei; - CCSDATA *ccs = (CCSDATA *) lParam; - HANDLE hMeta; - - if ((hMeta = (HANDLE)DBGetContactSettingDword(ccs->hContact,META_PROTO, "Handle", (DWORD)0)) == (DWORD)0) { - return CallService(MS_PROTO_CHAINSEND, wParam, lParam); // Can't find the MetaID of the metacontact linked to - } - - // if subcontact sending, add db event to keep metacontact history correct - if (options.metahistory && !(ccs->wParam & PREF_METANODB)) { - - // reject "file As Message" messages - if (strlen((char *)ccs->lParam) > 5 && strncmp((char *)ccs->lParam, "<%fAM", 5) == 0) - return CallService(MS_PROTO_CHAINSEND, wParam, lParam); // continue processing - - // reject "data As Message" messages - if (strlen((char *)ccs->lParam) > 5 && strncmp((char *)ccs->lParam, "<%dAM", 5) == 0) - return CallService(MS_PROTO_CHAINSEND, wParam, lParam); // continue processing - - // reject "OTR" messages - if (strlen((char *)ccs->lParam) > 5 && strncmp((char *)ccs->lParam, "?OTR", 4) == 0) - return CallService(MS_PROTO_CHAINSEND, wParam, lParam); // continue processing - - ZeroMemory(&dbei, sizeof(dbei)); - dbei.cbSize = sizeof(dbei); - dbei.szModule = META_PROTO; - dbei.flags = DBEF_SENT; - dbei.timestamp = time(NULL); - dbei.eventType = EVENTTYPE_MESSAGE; - if (ccs->wParam & PREF_RTL) dbei.flags |= DBEF_RTL; - if (ccs->wParam & PREF_UTF) dbei.flags |= DBEF_UTF; - dbei.cbBlob = (DWORD)strlen((char *)ccs->lParam) + 1; - if ( ccs->wParam & PREF_UNICODE ) - dbei.cbBlob *= ( sizeof( wchar_t )+1 ); - dbei.pBlob = (PBYTE)ccs->lParam; - - CallService(MS_DB_EVENT_ADD, (WPARAM) hMeta, (LPARAM)&dbei); - } - - return CallService(MS_PROTO_CHAINSEND, wParam, lParam); -} - -INT_PTR Meta_SendNudge(WPARAM wParam,LPARAM lParam) -{ - HANDLE hMeta = (HANDLE)wParam, - hSubContact = Meta_GetMostOnline(hMeta); - - char servicefunction[ 100 ]; - char *protoName = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hSubContact, 0); - sprintf(servicefunction, "%s/SendNudge", protoName); - - return CallService(servicefunction, (WPARAM)hSubContact, lParam); - - //return CallService("NUDGE/Send", (WPARAM)hSubContact, lParam); -} - -///////////////////////////////////////////////////////////////// - -/** Send a message to the protocol specific network. -* -* Call the function specific to the protocol that belongs -* to the contact chosen to send the message. -* -* @param wParam : index of the protocol in the protocol chain. -* @param lParam : \c CCSDATA structure holding all the information abour rhe message. -* -* @return 0 on success, 1 otherwise. -*/ -INT_PTR Meta_SendMessage(WPARAM wParam,LPARAM lParam) -{ - DBEVENTINFO dbei; - CCSDATA *ccs = (CCSDATA *) lParam; - char *proto = 0; - DWORD default_contact_number; - - - if ((default_contact_number = DBGetContactSettingDword(ccs->hContact,META_PROTO,"Default",(DWORD)-1)) == (DWORD)-1) - { - // This is a simple contact, let through the stack of protocols - // (this should normally not happen, since linked contacts do not appear on the list.) - return CallService(MS_PROTO_CHAINSEND, wParam, lParam); - } - else - { - char szServiceName[100]; - HANDLE most_online; - - most_online = Meta_GetMostOnline(ccs->hContact); - //DBEVENTINFO dbei; - - if (!most_online) { - DWORD dwThreadId; - HANDLE hEvent; - TFakeAckParams *tfap; - - // send failure to notify user of reason - hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); - - tfap = (TFakeAckParams *)mir_alloc(sizeof(TFakeAckParams)); - tfap->hContact = ccs->hContact; - tfap->hEvent = hEvent; - tfap->id = 10; - strcpy(tfap->msg, Translate("No online contacts found.")); - - CloseHandle( CreateThread( NULL, 0, sttFakeAckFail, tfap, 0, &dwThreadId )); - SetEvent( hEvent ); - - return 10; - } - - Meta_CopyContactNick(ccs->hContact, most_online); - - ccs->hContact = most_online; - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online, 0); - Meta_SetNick(proto); // (no matter what was there before) - - // don't bypass filters etc - strncpy(szServiceName, PSS_MESSAGE, sizeof(szServiceName)); - - if (ccs->wParam & PREF_UNICODE) { - char szTemp[100]; - _snprintf(szTemp, sizeof(szTemp), "%s%sW", proto, PSS_MESSAGE); - if (ServiceExists(szTemp)) - strncpy(szServiceName, PSS_MESSAGE "W", sizeof(szServiceName)); - } - - if (options.subhistory && !(ccs->wParam & PREF_METANODB)) { - // add sent event to subcontact - ZeroMemory(&dbei, sizeof(dbei)); - dbei.cbSize = sizeof(dbei); - dbei.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ccs->hContact, 0); - dbei.flags = DBEF_SENT; - dbei.timestamp = time(NULL); - dbei.eventType = EVENTTYPE_MESSAGE; - if (ccs->wParam & PREF_RTL) dbei.flags |= DBEF_RTL; - if (ccs->wParam & PREF_UTF) dbei.flags |= DBEF_UTF; - dbei.cbBlob = (DWORD)strlen((char *)ccs->lParam) + 1; - if ( ccs->wParam & PREF_UNICODE ) - dbei.cbBlob *= ( sizeof( wchar_t )+1 ); - dbei.pBlob = (PBYTE)ccs->lParam; - - CallService(MS_DB_EVENT_ADD, (WPARAM) ccs->hContact, (LPARAM)&dbei); - } - - // prevent send filter from adding another copy of this send event to the db - ccs->wParam |= PREF_METANODB; - - return CallContactService(ccs->hContact, szServiceName, ccs->wParam, ccs->lParam); - } -} - -/** Transmit a message received by a contact. -* -* Forward the message received by a contact linked to a MetaContact -* to that MetaContact and inhibit the further reception of this message -* by the standard protocol of the contact. -* -* @param wParam : index of the protocol in the protocol chain. -* @param lParam : \c CCSDATA structure holding all the information about the message. -* -* @return 0 on success, 1 otherwise. -*/ -INT_PTR MetaFilter_RecvMessage(WPARAM wParam,LPARAM lParam) -{ - DBEVENTINFO dbei; - CCSDATA *ccs = (CCSDATA *) lParam; - PROTORECVEVENT *pre = (PROTORECVEVENT *) ccs->lParam; - HANDLE hMeta; - - if ((hMeta = (HANDLE)DBGetContactSettingDword(ccs->hContact,META_PROTO, "Handle", (DWORD)0)) == (DWORD)0) { - CallService(MS_PROTO_CHAINRECV, wParam, (LPARAM)ccs); // Can't find the MetaID of the metacontact linked to - // this contact, let through the protocol chain - return 0; - } - - if (options.set_default_on_recv) { - if (options.temp_default && DBGetContactSettingDword(hMeta, META_PROTO, "SavedDefault", (DWORD)-1) == (DWORD)-1) - DBWriteContactSettingDword(hMeta, META_PROTO, "SavedDefault", DBGetContactSettingDword(hMeta, META_PROTO, "Default", 0)); - DBWriteContactSettingDword(hMeta, META_PROTO, "Default", DBGetContactSettingDword(ccs->hContact, META_PROTO, "ContactNumber", 0)); - NotifyEventHooks(hEventDefaultChanged, (WPARAM)hMeta, (LPARAM)ccs->hContact); // nick set in event handler - } - - // if meta disabled (now message api) or window open (message api), or using subcontact windows, - // let through but add db event for metacontact history - if (!Meta_IsEnabled() - || DBGetContactSettingByte(ccs->hContact, META_PROTO, "WindowOpen", 0) == 1 - || options.subcontact_windows) - { - - // add a clist event, so that e.g. there is an icon flashing - // (only add it when message api available, 'cause then we can remove the event when the message window is opened) - if (message_window_api_enabled - && DBGetContactSettingByte(ccs->hContact, META_PROTO, "WindowOpen", 0) == 0 - && DBGetContactSettingByte(hMeta, META_PROTO, "WindowOpen", 0) == 0 - && options.flash_meta_message_icon) - { - CLISTEVENT cle; - char toolTip[256], *contactName; - ZeroMemory(&cle, sizeof(cle)); - - cle.cbSize = sizeof(cle); - cle.hContact = hMeta; - cle.hDbEvent = ccs->hContact; // use subcontact handle as key - then we can remove all events if the subcontact window is opened - cle.hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE); - cle.pszService = "MetaContacts/CListMessageEvent"; - contactName = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hMeta, 0); - _snprintf(toolTip, sizeof(toolTip), Translate("Message from %s"), contactName); - cle.pszTooltip = toolTip; - CallService(MS_CLIST_ADDEVENT, 0, (LPARAM) & cle); - } - - if (options.metahistory) { - - BOOL added = FALSE; - - // should be able to do this, but some protos mess with the memory - if (options.use_proto_recv) - { - // use the subcontact's protocol 'recv' service to add the meta's history (AIMOSCAR removes HTML here!) if possible - char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ccs->hContact, 0); - if (proto) { - char service[256]; - HANDLE hSub = ccs->hContact; - DWORD flags = pre->flags; - mir_snprintf(service, 256, "%s%s", proto, PSR_MESSAGE); - ccs->hContact = hMeta; - pre->flags |= (DBGetContactSettingByte(hMeta, META_PROTO, "WindowOpen", 0) ? 0 : PREF_CREATEREAD); - if (ServiceExists(service) && !CallService(service, 0, (LPARAM)ccs)) - added = TRUE; - ccs->hContact = hSub; - pre->flags = flags; - } - } - - if (!added) { - // otherwise add raw db event - ZeroMemory(&dbei, sizeof(dbei)); - dbei.cbSize = sizeof(dbei); - dbei.szModule = META_PROTO; - dbei.timestamp = pre->timestamp; - dbei.flags = (DBGetContactSettingByte(hMeta, META_PROTO, "WindowOpen", 0) ? 0 : DBEF_READ); - if (pre->flags & PREF_RTL) dbei.flags |= DBEF_RTL; - if (pre->flags & PREF_UTF) dbei.flags |= DBEF_UTF; - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = (DWORD)strlen(pre->szMessage) + 1; - if ( pre->flags & PREF_UNICODE ) { - dbei.cbBlob *= ( sizeof( wchar_t )+1 ); - } - dbei.pBlob = (PBYTE) pre->szMessage; - - CallService(MS_DB_EVENT_ADD, (WPARAM) hMeta, (LPARAM)&dbei); - } - } - - CallService(MS_PROTO_CHAINRECV, wParam, (LPARAM)ccs); - return 0; - } // else: - - /* - // add event to subcontact history (would do it in meta_recvmessage, but here we have the hcontact) - // should be able to use the method below, except some protos can mess with the memory - if (options.subhistory) { - ZeroMemory(&dbei, sizeof(dbei)); - dbei.cbSize = sizeof(dbei); - dbei.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ccs->hContact, 0); - dbei.timestamp = pre->timestamp; - dbei.flags = (DBGetContactSettingByte(ccs->hContact, META_PROTO, "WindowOpen", 0) ? 0 : DBEF_READ); - if (pre->flags & PREF_RTL) dbei.flags |= DBEF_RTL; - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = strlen(pre->szMessage) + 1; - if ( pre->flags & PREF_UNICODE ) - dbei.cbBlob *= ( sizeof( wchar_t )+1 ); - dbei.pBlob = (PBYTE) pre->szMessage; - - CallService(MS_DB_EVENT_ADD, (WPARAM) ccs->hContact, (LPARAM)&dbei); - } - */ - - - { - HANDLE hSub = ccs->hContact; - ccs->hContact = hMeta; // Forward to the associated MetaContact. - CallService(MS_PROTO_CHAINRECV, 0, (LPARAM)ccs); - ccs->hContact = hSub; - } - - if (options.subhistory && !(ccs->wParam & PREF_METANODB)) { - // allow event pass through and thereby be added to subcontact history - pre->flags |= (DBGetContactSettingByte(ccs->hContact, META_PROTO, "WindowOpen", 0) ? 0 : PREF_CREATEREAD); - CallService(MS_PROTO_CHAINRECV, wParam, (LPARAM)ccs); // pass through as normal - return 0; - } - - return 1; // Stop further processing. -} - -/** Receive a message for a MetaContact -* -* @return 0 -*/ -INT_PTR Meta_RecvMessage(WPARAM wParam, LPARAM lParam) -{ - DBEVENTINFO dbei; - CCSDATA *ccs = (CCSDATA *) lParam; - PROTORECVEVENT *pre = (PROTORECVEVENT *) ccs->lParam; - - char *proto; - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ccs->hContact, 0); - - // contact is not a meta proto contact - just leave it - if (!proto || strcmp(proto, META_PROTO)) { - return 0; - } - - if (options.use_proto_recv) - { - // use the subcontact's protocol to add the db if possible (AIMOSCAR removes HTML here!) - HANDLE most_online = Meta_GetMostOnline(ccs->hContact); - char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online, 0); - if (proto) { - char service[256]; - mir_snprintf(service, 256, "%s%s", proto, PSR_MESSAGE); - if (CallService(service, wParam, lParam) != CALLSERVICE_NOTFOUND) - return 0; - } - } - - - // otherwise, add event to db directly - ZeroMemory(&dbei, sizeof(dbei)); - dbei.cbSize = sizeof(dbei); - dbei.szModule = META_PROTO; - dbei.timestamp = pre->timestamp; - dbei.flags = (pre->flags & PREF_CREATEREAD ? DBEF_READ : 0); - if (pre->flags & PREF_RTL) dbei.flags |= DBEF_RTL; - if (pre->flags & PREF_UTF) dbei.flags |= DBEF_UTF; - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = (DWORD)strlen(pre->szMessage) + 1; - if ( pre->flags & PREF_UNICODE ) - dbei.cbBlob *= ( sizeof( wchar_t )+1 ); - dbei.pBlob = (PBYTE) pre->szMessage; - - CallService(MS_DB_EVENT_ADD, (WPARAM) ccs->hContact, (LPARAM)&dbei); - - return 0; -} - - - -/** Called when an ACK is received. -* -* Retransmit the ACK sent by a simple contact so that it -* looks like it was the MetaContact that sends the ACK. -* -* @param wParam : Allways set to 0. -* @param lParam : Reference to a ACKDATA that contains - information about the ACK. -* @return 0 on success, 1 otherwise. -*/ -int Meta_HandleACK(WPARAM wParam, LPARAM lParam) -{ - ACKDATA *ack = (ACKDATA*) lParam; - HANDLE hUser; - - if (ack->hContact == 0 || (hUser = (HANDLE)DBGetContactSettingDword(ack->hContact,META_PROTO,"Handle",0)) == 0) - return 0; // Can't find the MetaID, let through the protocol chain - - - if (!strcmp(ack->szModule, META_PROTO)) { - return 0; // don't rebroadcast our own acks - } - - // if it's for something we don't support, ignore - if (ack->type != ACKTYPE_MESSAGE && ack->type != ACKTYPE_CHAT && ack->type != ACKTYPE_FILE && ack->type != ACKTYPE_AWAYMSG - && ack->type != ACKTYPE_AVATAR && ack->type != ACKTYPE_GETINFO) - - { - return 0; - } - - // change the hContact in the avatar info struct, if it's the avatar we're using - else drop it - if (ack->type == ACKTYPE_AVATAR) { - if (ack->result == ACKRESULT_SUCCESS || ack->result == ACKRESULT_FAILED || ack->result == ACKRESULT_STATUS) { - HANDLE most_online; - DBVARIANT dbv; - - // change avatar if the most online supporting avatars changes, or if we don't have one - most_online = Meta_GetMostOnlineSupporting(hUser, PFLAGNUM_4, PF4_AVATARS); - //if (AI.hContact == 0 || AI.hContact != most_online) { - if (ack->hContact == 0 || ack->hContact != most_online) { - return 0; - } - - //if (!DBGetContactSetting(AI.hContact, "ContactPhoto", "File", &dbv)) { - if (!DBGetContactSetting(ack->hContact, "ContactPhoto", "File", &dbv)) { - DBWriteContactSettingTString(hUser, "ContactPhoto", "File", dbv.ptszVal); - DBFreeVariant(&dbv); - } - - if (ack->hProcess) { - PROTO_AVATAR_INFORMATIONT AI; - memcpy(&AI, (PROTO_AVATAR_INFORMATIONT *)ack->hProcess, sizeof(PROTO_AVATAR_INFORMATIONT)); - if (AI.hContact) - AI.hContact = hUser; - - return ProtoBroadcastAck(META_PROTO,hUser,ack->type,ack->result, (HANDLE)&AI, ack->lParam); - } else - return ProtoBroadcastAck(META_PROTO,hUser,ack->type,ack->result, 0, ack->lParam); - } - } - - return ProtoBroadcastAck(META_PROTO,hUser,ack->type,ack->result,ack->hProcess,ack->lParam); -} - -// hiding contacts on "CList/UseGroups" setting changed can cause a crash - do it in a seperate thread during idle time -static DWORD sttHideContacts( BOOL param ) -{ - Meta_HideMetaContacts((int)param); - return 0; -} - -/** Call whenever a contact changes one of its settings (for example, the status) -** -* @param wParam \c HANDLE to the contact that has change of its setting. -* @param lParam Reference to a structure that contains the setting that has changed (not used) -*/ -int Meta_SettingChanged(WPARAM wParam, LPARAM lParam) -{ - DBCONTACTWRITESETTING *dcws = (DBCONTACTWRITESETTING *)lParam; - char buffer[512], buffer2[512]; - int contact_number; - HANDLE hMeta, most_online; - - - // hide metacontacts when groups disabled - if (wParam == 0 - && ((strcmp(dcws->szModule, "CList") == 0 && strcmp(dcws->szSetting, "UseGroups") == 0) - || (strcmp(dcws->szModule, META_PROTO) == 0 && strcmp(dcws->szSetting, "Enabled") == 0))) - { - sttHideContacts(!Meta_IsEnabled()); - return 0; - } - - if (wParam == 0 - && strcmp(dcws->szModule, "Import") == 0 && strcmp(dcws->szSetting, "Completed") == 0) - { - // import process has just been run...call startup routines... - Meta_SetHandles(); - { - HANDLE hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 ); - int meta_id; - while ( hContact != NULL ) { - if ((meta_id = DBGetContactSettingDword(hContact,META_PROTO,META_ID,(DWORD)-1))!=(DWORD)-1) { - Meta_CopyData(hContact); - } - hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 ); - } - } - - Meta_HideLinkedContacts(); - Meta_SuppressStatus(options.suppress_status); - } - - if (wParam == 0 - && strcmp(dcws->szModule, "CListGroups") == 0 && dcws->value.type != DBVT_DELETED && strcmp(dcws->value.pszVal, META_HIDDEN_GROUP) == 0) - { - // someone is creating our hidden group!! - - } - - // from here on, we're just interested in contact settings - if (wParam == 0) return 0; - - if ((hMeta=(HANDLE)DBGetContactSettingDword((HANDLE)wParam,META_PROTO,"Handle",0))!=0 - && CallService(MS_DB_CONTACT_IS, (WPARAM)hMeta, 0)) // just to be safe - - { // This contact is attached to a MetaContact. - - contact_number = Meta_GetContactNumber((HANDLE)wParam); - if (contact_number == -1) return 0; // exit - db corruption - - if (!meta_group_hack_disabled && !strcmp(dcws->szModule, "CList") && !strcmp(dcws->szSetting, "Group") && - Meta_IsEnabled() && DBGetContactSettingByte((HANDLE)wParam, META_PROTO, "Hidden", 0) == 0 && !Miranda_Terminated()) { - if ((dcws->value.type == DBVT_ASCIIZ || dcws->value.type == DBVT_UTF8) && !Meta_IsHiddenGroup(dcws->value.pszVal)) { - // subcontact group reassigned - copy to saved group - MyDBWriteContactSetting((HANDLE)wParam, META_PROTO, "OldCListGroup", &dcws->value); - DBWriteContactSettingString((HANDLE)wParam, "CList", "Group", META_HIDDEN_GROUP); - } else if (dcws->value.type == DBVT_DELETED) { - DBDeleteContactSetting((HANDLE)wParam, META_PROTO, "OldCListGroup"); - DBWriteContactSettingString((HANDLE)wParam, "CList", "Group", META_HIDDEN_GROUP); - } - } else - - // copy IP - if (!strcmp(dcws->szSetting, "IP")) { - if (dcws->value.type == DBVT_DWORD) - DBWriteContactSettingDword(hMeta, META_PROTO, "IP", dcws->value.dVal); - else - DBDeleteContactSetting(hMeta, META_PROTO, "IP"); - } else - - // copy RealIP - if (!strcmp(dcws->szSetting, "RealIP")) { - if (dcws->value.type == DBVT_DWORD) - DBWriteContactSettingDword(hMeta, META_PROTO, "RealIP", dcws->value.dVal); - else - DBDeleteContactSetting(hMeta, META_PROTO, "RealIP"); - - } else - // copy ListeningTo - if (!strcmp(dcws->szSetting, "ListeningTo")) { - switch(dcws->value.type) { - case DBVT_ASCIIZ: - DBWriteContactSettingString(hMeta, META_PROTO, "ListeningTo", dcws->value.pszVal); - break; - case DBVT_UTF8: - DBWriteContactSettingStringUtf(hMeta, META_PROTO, "ListeningTo", dcws->value.pszVal); - break; - case DBVT_WCHAR: - DBWriteContactSettingWString(hMeta, META_PROTO, "ListeningTo", dcws->value.pwszVal); - break; - case DBVT_DELETED: - DBDeleteContactSetting(hMeta, META_PROTO, "ListeningTo"); - break; - } - } else - - if (!strcmp(dcws->szSetting, "Nick") && !dcws->value.type == DBVT_DELETED) { - DBVARIANT dbv; - HANDLE most_online; - - // subcontact nick has changed - update metacontact - strcpy(buffer, "Nick"); - strcat(buffer, _itoa(contact_number, buffer2, 10)); - MyDBWriteContactSetting(hMeta, META_PROTO, buffer, &dcws->value); - - if (MyDBGetContactSetting((HANDLE)wParam, "CList", "MyHandle", &dbv)) { - strcpy(buffer, "CListName"); - strcat(buffer, _itoa(contact_number, buffer2, 10)); - MyDBWriteContactSetting(hMeta, META_PROTO, buffer, &dcws->value); - } else { - DBFreeVariant(&dbv); - } - - // copy nick to metacontact, if it's the most online - most_online = Meta_GetMostOnline(hMeta); - Meta_CopyContactNick(hMeta, most_online); - - return 0; - } else - - if (!strcmp(dcws->szSetting, "IdleTS")) { - if (dcws->value.type == DBVT_DWORD) - DBWriteContactSettingDword(hMeta, META_PROTO, "IdleTS", dcws->value.dVal); - else if (dcws->value.type == DBVT_DELETED) - DBWriteContactSettingDword(hMeta, META_PROTO, "IdleTS", 0); - } else - - if (!strcmp(dcws->szSetting, "LogonTS")) { - if (dcws->value.type == DBVT_DWORD) - DBWriteContactSettingDword(hMeta, META_PROTO, "LogonTS", dcws->value.dVal); - else if (dcws->value.type == DBVT_DELETED) - DBWriteContactSettingDword(hMeta, META_PROTO, "LogonTS", 0); - } else - - if (!strcmp(dcws->szModule, "CList") && !strcmp(dcws->szSetting, "MyHandle")) { - HANDLE most_online; - - if (dcws->value.type == DBVT_DELETED) { - DBVARIANT dbv; - - char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); - strcpy(buffer, "CListName"); - strcat(buffer, _itoa(contact_number, buffer2, 10)); - if (proto && !MyDBGetContactSetting((HANDLE)wParam, proto, "Nick", &dbv)) { - MyDBWriteContactSetting(hMeta, META_PROTO, buffer, &dbv); - DBFreeVariant(&dbv); - } else { - DBDeleteContactSetting(hMeta, META_PROTO, buffer); - } - } else { - // subcontact clist displayname has changed - update metacontact - strcpy(buffer, "CListName"); - strcat(buffer, _itoa(contact_number, buffer2, 10)); - - MyDBWriteContactSetting(hMeta, META_PROTO, buffer, &dcws->value); - } - - // copy nick to metacontact, if it's the most online - most_online = Meta_GetMostOnline(hMeta); - Meta_CopyContactNick(hMeta, most_online); - - return 0; - } else - - if (!strcmp(dcws->szSetting, "Status") && !dcws->value.type == DBVT_DELETED) { - // subcontact changing status - - // update subcontact status setting - strcpy(buffer, "Status"); - strcat(buffer, _itoa(contact_number, buffer2, 10)); - DBWriteContactSettingWord(hMeta, META_PROTO, buffer, dcws->value.wVal); - strcpy(buffer, "StatusString"); - strcat(buffer, _itoa(contact_number, buffer2, 10)); - Meta_GetStatusString(dcws->value.wVal, buffer2, 512); - DBWriteContactSettingString(hMeta, META_PROTO, buffer, buffer2); - - // if the contact was forced, unforce it (which updates status) - if ((HANDLE)DBGetContactSettingDword(hMeta, META_PROTO, "ForceSend", 0) == (HANDLE)wParam) { - MetaAPI_UnforceSendContact((WPARAM)hMeta, 0); - } else { - // set status to that of most online contact - most_online = Meta_GetMostOnline(hMeta); - Meta_CopyContactNick(hMeta, most_online); - - Meta_FixStatus(hMeta); - - Meta_CopyData(hMeta); - } - - // most online contact with avatar support might have changed - update avatar - most_online = Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_4, PF4_AVATARS); - if (most_online) { - PROTO_AVATAR_INFORMATIONT AI; - - AI.cbSize = sizeof(AI); - AI.hContact = hMeta; - AI.format = PA_FORMAT_UNKNOWN; - _tcscpy(AI.filename, _T("X")); - - if ((int)CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) - DBWriteContactSettingTString(hMeta, "ContactPhoto", "File",AI.filename); - } - } else - - if (strcmp(dcws->szSetting, "XStatusId") == 0 || strcmp(dcws->szSetting, "XStatusMsg") == 0 || strcmp(dcws->szSetting, "XStatusName") == 0 || strcmp(dcws->szSetting, "StatusMsg") == 0) { - Meta_CopyData(hMeta); - } else - - if (strcmp(dcws->szSetting, "MirVer") == 0) { - Meta_CopyData(hMeta); - } else - - if (!meta_group_hack_disabled && !strcmp(dcws->szModule, "CList") && !strcmp(dcws->szSetting, "Hidden")) { - if ((dcws->value.type == DBVT_DELETED || DBGetContactSettingByte((HANDLE)wParam, "CList", "Hidden", 0) == 0) - && DBGetContactSettingByte((HANDLE)wParam, META_PROTO, "Hidden", 0) == 1) - { - // a subcontact we hid (e.g. jabber) has been unhidden - hide it again :( - DBWriteContactSettingByte((HANDLE)wParam, "CList", "Hidden", 1); - } - } - } - - return 0; -} - -int Meta_ContactDeleted(WPARAM wParam, LPARAM lParam) { - HANDLE hMeta; - - // is a subcontact - update meta contact - hMeta = (HANDLE)DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "Handle", 0); - if (hMeta) { - Meta_RemoveContactNumber(hMeta, DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "ContactNumber", -1)); - NotifyEventHooks(hSubcontactsChanged, (WPARAM)hMeta, 0); - return 0; - } else { - // not a subcontact - is it a metacontact? - int num_contacts = DBGetContactSettingDword((HANDLE)wParam, META_PROTO, "NumContacts", 0); - int i; - HANDLE hContact; - - if (num_contacts) NotifyEventHooks(hSubcontactsChanged, (WPARAM)wParam, 0); - - // remove & restore all subcontacts - for (i = 0; i < num_contacts; i++) { - hContact = Meta_GetContactHandle((HANDLE)wParam, i); - - if (hContact && (HANDLE)DBGetContactSettingDword(hContact, META_PROTO, "Handle", 0) == (HANDLE)wParam) { - if (DBGetContactSettingByte(hContact, META_PROTO, "IsSubcontact", 0) == 1) - DBDeleteContactSetting(hContact,META_PROTO,"IsSubcontact"); - DBDeleteContactSetting(hContact,META_PROTO,META_LINK); - DBDeleteContactSetting(hContact,META_PROTO,"Handle"); - DBDeleteContactSetting(hContact,META_PROTO,"ContactNumber"); - Meta_RestoreGroup(hContact); - DBDeleteContactSetting(hContact,META_PROTO,"OldCListGroup"); - - CallService(MS_PROTO_REMOVEFROMCONTACT, (WPARAM)hContact, (LPARAM)META_FILTER); - // stop ignoring, if we were - if (options.suppress_status) - CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, (WPARAM)IGNOREEVENT_USERONLINE); - } - } - return 0; - } - - - return 0; -} - -/** Call when we want to send a user is typing message -* -* @param wParam \c HANDLE to the contact that we are typing to -* @param lParam either PROTOTYPE_SELFTYPING_ON or PROTOTYPE_SELFTYPING_OFF -*/ -INT_PTR Meta_UserIsTyping(WPARAM wParam, LPARAM lParam) -{ - char *proto; - char buff[512]; - - if (DBGetContactSettingDword((HANDLE)wParam,META_PROTO,META_ID,(DWORD)-1) == (DWORD)-1) - { - // This is a simple contact, let through the stack of protocols - return 0; - } - else - { - // forward to sending protocol, if supported - - HANDLE most_online = Meta_GetMostOnline((HANDLE)wParam); - Meta_CopyContactNick((HANDLE)wParam, most_online); - - if (!most_online) return 0; - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online, 0); - if (proto) { - strncpy(buff, proto, 512); - strncpy(buff + strlen(proto), PSS_USERISTYPING, 512 - strlen(proto)); - - if (ServiceExists(buff)) { - CallService(buff, (WPARAM)most_online, (LPARAM)lParam); - } - } - } - - return 0; -} - -/** Call when we want to receive a user is typing message -* -* @param wParam \c HANDLE to the contact that is typing or not -* @param lParam either PROTOTYPE_SELFTYPING_ON or PROTOTYPE_SELFTYPING_OFF -*/ -int Meta_ContactIsTyping(WPARAM wParam, LPARAM lParam) -{ - HANDLE hMeta; - - if ((hMeta = (HANDLE)DBGetContactSettingDword((HANDLE)wParam,META_PROTO,"Handle",(DWORD)0)) != 0 - // check metacontacts enabled - && Meta_IsEnabled() - ) - { // This contact is attached to a MetaContact. - if (!options.subcontact_windows) { // we don't want clicking on the clist notification icon to open the metacontact message window - - // try to remove any clist events we added for subcontact - CallServiceSync(MS_CLIST_REMOVEEVENT, wParam, (LPARAM) 1); - - CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hMeta, lParam); - - // stop processing of event - return 1; - } - } - - return 0; -} - -/** Called when user info is about to be shown -* -* Returns 1 to stop event processing and opens page for metacontact default contact (returning 1 to stop it doesn't work!) -* -*/ -int Meta_UserInfo(WPARAM wParam, LPARAM lParam) -{ - DWORD default_contact_number = DBGetContactSettingDword((HANDLE)lParam, META_PROTO, "Default", (DWORD)-1); - - if (default_contact_number == -1) // not a meta contact - return 0; - - CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)Meta_GetContactHandle((HANDLE)lParam, default_contact_number), 0); - - return 1; -} - -// handle message window api ver 0.0.0.1+ events - record window open/close status for subcontacts, so we know whether to -// let received messages through and add db history to metacontact, or vice versa -int Meta_MessageWindowEvent(WPARAM wParam, LPARAM lParam) { - MessageWindowEventData *mwed = (MessageWindowEventData *)lParam; - HANDLE hMeta = 0; - - message_window_api_enabled = TRUE; - - if ((hMeta = (HANDLE)DBGetContactSettingDword(mwed->hContact, META_PROTO, "Handle", 0)) != 0 - || DBGetContactSettingDword(mwed->hContact, META_PROTO, META_ID, (DWORD)-1) != (DWORD)-1) - { - // contact is subcontact of metacontact, or an actual metacontact - record whether window is open or closed - if (mwed->uType == MSG_WINDOW_EVT_OPEN || mwed->uType == MSG_WINDOW_EVT_OPENING) { - DBWriteContactSettingByte(mwed->hContact, META_PROTO, "WindowOpen", 1); - - if (hMeta) { // subcontact window opened - remove clist events we added for metacontact - while(!CallService(MS_CLIST_REMOVEEVENT, (WPARAM)hMeta, (LPARAM)mwed->hContact)); - } - } else if (mwed->uType == MSG_WINDOW_EVT_CLOSE || mwed->uType == MSG_WINDOW_EVT_CLOSING) { - DBWriteContactSettingByte(mwed->hContact, META_PROTO, "WindowOpen", 0); - if (!hMeta) { // hMeta is 0 for metacontact (sorry) - DWORD saved_def; - - MetaAPI_UnforceSendContact((WPARAM)mwed->hContact, 0); - - // restore saved default contact - if (options.set_default_on_recv) { - saved_def = DBGetContactSettingDword(mwed->hContact, META_PROTO, "SavedDefault", -1); - if (options.temp_default && saved_def != (DWORD)-1) { - DBWriteContactSettingDword(mwed->hContact, META_PROTO, "Default", saved_def); - DBWriteContactSettingDword(mwed->hContact, META_PROTO, "SavedDefault", (DWORD)-1); - NotifyEventHooks(hEventDefaultChanged, (WPARAM)mwed->hContact, (LPARAM)Meta_GetContactHandle(hMeta, saved_def)); // nick set in event handler - } - } - } - } - - } - - return 0; -} -/* -int Meta_LoadIcons(WPARAM wParam, LPARAM lParam) { - PROTOCOLDESCRIPTOR **protos; - - //MessageBox(0, "LoadIcons", "Event", MB_OK); - - if (ServiceExists(MS_CLIST_EXTRA_ADD_ICON)) { - int index = 0, i; - - CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&proto_count,(LPARAM)&protos); - for (i = 0; i < proto_count && i < MAX_PROTOCOLS; i++) { - if (protos[i]->type!=PROTOTYPE_PROTOCOL || CallProtoService(protos[i]->szName,PS_GETCAPS,PFLAGNUM_2,0)==0) - continue; - - strncpy(proto_names + (index * 128), protos[i]->szName, 128); - hProtoIcons[index * 2] = LoadSkinnedProtoIcon(protos[i]->szName,ID_STATUS_ONLINE); - hProtoIcons[index * 2 + 1] = LoadSkinnedProtoIcon(protos[i]->szName,ID_STATUS_OFFLINE); - hExtraImage[index * 2] = 0; - hExtraImage[index * 2 + 1] = 0; - - //sprintf(buff, "Added icon (hIcon = %d, hImage = %d) for protocol %s.", hProtoIcons[index], hExtraImage[index], protos[i]->szName); - //MessageBox(0, buff, "Added Extra Icon", MB_OK); - - index++; - } - proto_count = index; - - //Meta_CListMW_ExtraIconsRebuild(0, 0); - - } - - - return 0; -} - -int Meta_CListMW_ExtraIconsRebuild(WPARAM wParam, LPARAM lParam) { - int i; - - //MessageBox(0, "IconsRebuild", "Event", MB_OK); - Meta_LoadIcons(0, 0); - - if (ServiceExists(MS_CLIST_EXTRA_ADD_ICON)) { - for (i = 0; i < proto_count; i++) { - hExtraImage[i * 2] = (HANDLE)CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM)hProtoIcons[i * 2], 0); - hExtraImage[i * 2 + 1] = (HANDLE)CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM)hProtoIcons[i * 2 + 1], 0); - } - } - - return 0; -} - -int Meta_CListMW_ExtraIconsApply(WPARAM wParam, LPARAM lParam) { - - //MessageBox(0, "IconsApply", "Event", MB_OK); - - if (DBGetContactSettingDword((HANDLE)wParam, META_PROTO, META_ID, (DWORD)-1) != (DWORD)-1) { - if (ServiceExists(MS_CLIST_EXTRA_SET_ICON)) { - IconExtraColumn iec; - HANDLE most_online_im = Meta_GetMostOnline((HANDLE)wParam); - int i; - - if (most_online_im) { - char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online_im, 0); - if (proto) { - WORD status = DBGetContactSettingWord(most_online_im, proto, "Status", ID_STATUS_OFFLINE); - iec.cbSize = sizeof(iec); - for (i = 0; i < proto_count; i++) { - if (!strcmp((proto_names + i * 128), proto)) { - if (hExtraImage[i * 2 + (status == ID_STATUS_OFFLINE ? 1 : 0)]) { - iec.hImage = hExtraImage[i * 2 + (status == ID_STATUS_OFFLINE ? 1 : 0)]; - iec.ColumnType = EXTRA_ICON_ADV2; - CallService(MS_CLIST_EXTRA_SET_ICON, (WPARAM)wParam, (LPARAM)&iec); - iec.ColumnType = EXTRA_ICON_PROTO; - CallService(MS_CLIST_EXTRA_SET_ICON, (WPARAM)wParam, (LPARAM)&iec); - } - break; - } - } - } - } - } - } - return 0; -} -*/ -int Meta_ClistDoubleClicked(WPARAM wParam, LPARAM lParam) { - - if (DBGetContactSettingDword((HANDLE)wParam,META_PROTO,"Default",(WORD)-1) == (WORD)-1) - { - // This is a simple contact - return 0; - } - else - { - // -1 indicates no specific capability but respect 'ForceDefault' - HANDLE most_online = Meta_GetMostOnlineSupporting((HANDLE)wParam, PFLAGNUM_1, -1); - //DBEVENTINFO dbei; - char *proto; - char buffer[512]; - int caps; - - if (!most_online) - return 0; - - if (options.subcontact_windows) { - if (lParam) { - // contact from incoming message in lParam via (at this point) clist message event - CallService(MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM)lParam, 0); - } else { - // simulate double click on most_online contact and stop event processing - CallService(MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM)most_online, 0); - } - return 1; - } else { - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online, 0); - - if (proto) { - strcpy(buffer, proto); - strcat(buffer, PS_GETCAPS); - - // get the contacts messaging capabilities - caps = CallService(buffer, (WPARAM)PFLAGNUM_1, 0); - - if ((caps & PF1_IMSEND) || (caps & PF1_CHAT) || (proto && strcmp(proto, "IRC") == 0)) - // let event process normally - return 0; - else { - // simulate double click on most_online contact and stop event processing - CallService(MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM)most_online, 0); - return 1; - } - } else - return 0; - } - } - - return 0; -} - -INT_PTR Meta_ClistMessageEventClicked(WPARAM wParam, LPARAM lParam) { - - HANDLE hContact = ((CLISTEVENT *)lParam)->hContact; - - // hdbevent contains the id of the subcontact - return Meta_ClistDoubleClicked((WPARAM)hContact, (LPARAM)((CLISTEVENT *)lParam)->hDbEvent); -} - - -int NudgeRecieved(WPARAM wParam, LPARAM lParam) { - /* - // already being forwarded by someone - HANDLE hMeta = (HANDLE)DBGetContactSettingDword((HANDLE)wParam,META_PROTO, "Handle", (DWORD)0); - if (hMeta) - NotifyEventHooks(hEventNudge, (WPARAM)hMeta, 0); - */ - return 0; -} - -/** Called when all the plugin are loaded into Miranda. -* -* Initializes the 4 menus present in the context-menu -* and the initial value of nextMetaID -*/ -int Meta_ModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - CLISTMENUITEM mi = {0}; - char buffer[512], buffer2[512], buffer3[512]; - int i; - - if (ServiceExists(MS_MSG_GETWINDOWAPI)) - message_window_api_enabled = TRUE; - - if (ServiceExists(MS_UPDATE_REGISTER)) { - // register with updater - Update update = {0}; - char szVersion[16]; - - update.cbSize = sizeof(Update); - - update.szComponentName = pluginInfo.shortName; - update.pbVersion = (BYTE *)CreateVersionString(pluginInfo.version, szVersion); - update.cpbVersion = (int)strlen((char *)update.pbVersion); - update.szBetaChangelogURL = "https://server.scottellis.com.au/wsvn/mim_plugs/metacontacts/?op=log&rev=0&sc=0&isdir=1"; - - update.szUpdateURL = UPDATER_AUTOREGISTER; - - // these are the three lines that matter - the archive, the page containing the version string, and the text (or data) - // before the version that we use to locate it on the page - // (note that if the update URL and the version URL point to standard file listing entries, the backend xml - // data will be used to check for updates rather than the actual web page - this is not true for beta urls) - update.szBetaUpdateURL = "http://www.scottellis.com.au/miranda_plugins/MetaContacts.zip"; - update.szBetaVersionURL = "http://www.scottellis.com.au/miranda_plugins/ver_MetaContacts.html"; - update.pbBetaVersionPrefix = (BYTE *)"MetaContacts Plugin, version "; - - update.cpbBetaVersionPrefix = (int)strlen((char *)update.pbBetaVersionPrefix); - - CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); - } - - // disable group hack for older nicer versions without the fix - if (ServiceExists(MS_CLUI_GETVERSION)) { - char *version = (char *)CallService(MS_CLUI_GETVERSION, 0, 0); - if (version && strlen(version) >= strlen("CList Nicer+") && strncmp(version, "CList Nicer+", strlen("CList Nicer+")) == 0) - meta_group_hack_disabled = TRUE; - } - - // for database editor++ ver 3+ - if (ServiceExists("DBEditorpp/RegisterSingleModule")) - CallService("DBEditorpp/RegisterSingleModule",(WPARAM)META_PROTO,0); - - hHooks[11] = (HANDLE)HookEvent(ME_CLIST_PREBUILDCONTACTMENU, Meta_ModifyMenu); - hHooks[12] = (HANDLE)HookEvent(ME_CLIST_DOUBLECLICKED, Meta_ClistDoubleClicked ); - //hHooks[13] = (HANDLE)HookEvent(ME_CLIST_EXTRA_LIST_REBUILD, Meta_CListMW_ExtraIconsRebuild); - //hHooks[14] = (HANDLE)HookEvent(ME_CLIST_EXTRA_IMAGE_APPLY, Meta_CListMW_ExtraIconsApply); - - // icons are erased on this event... - // (BUT, the me_clist_extra_list_rebuild is send FIRST...so, we ignore this one...) - hHooks[15] = 0;//(HANDLE)HookEvent(ME_SKIN_ICONSCHANGED, Meta_LoadIcons); - - mi.cbSize = sizeof(mi); - mi.flags = CMIM_ALL; - - // main menu item - mi.pszName = "Toggle MetaContacts Off"; - mi.pszService = "MetaContacts/OnOff"; - mi.position = 500010000; - hMenuOnOff = Menu_AddMainMenuItem(&mi); - - // contact menu items - mi.position = -200010; - mi.pszName = "Convert to MetaContact"; - mi.pszService = "MetaContacts/Convert"; - hMenuConvert = Menu_AddContactMenuItem(&mi); - - mi.position = -200009; - mi.pszName = "Add to existing MetaContact..."; - mi.pszService = "MetaContacts/AddTo"; - hMenuAdd = Menu_AddContactMenuItem(&mi); - - mi.position = -200010; - mi.pszName = "Edit MetaContact..."; - mi.pszService = "MetaContacts/Edit"; - hMenuEdit = Menu_AddContactMenuItem(&mi); - - mi.position = -200009; - mi.pszName = "Set as MetaContact default"; - mi.pszService = "MetaContacts/Default"; - hMenuDefault = Menu_AddContactMenuItem(&mi); - - mi.position = -200008; - mi.pszName = "Delete MetaContact"; - mi.pszService = "MetaContacts/Delete"; - hMenuDelete = Menu_AddContactMenuItem(&mi); - - //mi.pszName = "Force Default"; - //mi.pszService = "MetaContacts/ForceDefault"; - //hMenuForceDefault = Menu_AddContactMenuItem(&mi); - - mi.flags |= CMIF_HIDDEN; - mi.pszContactOwner = META_PROTO; - - mi.position = -99000; - for (i = 0; i < MAX_CONTACTS; i++) { - mi.position--; - strcpy(buffer3, (char *)Translate("Context")); - strcat(buffer3, _itoa(i, buffer2, 10)); - mi.pszName = buffer3; - - strcpy(buffer, "MetaContacts/MenuFunc"); - strcat(buffer, _itoa(i, buffer2, 10)); - mi.pszService= buffer; - - hMenuContact[i] = Menu_AddContactMenuItem(&mi); - } - - nextMetaID = DBGetContactSettingDword(NULL,META_PROTO,"NextMetaID",(DWORD)0); - - // attemp to subsume userinfo...(returning 1 does not prevent dialog - so disabled) - //hHooks[] = (HANDLE)HookEvent(ME_USERINFO_INITIALISE, Meta_UserInfo); - - // loop and copy data from subcontacts - if (options.copydata) { - HANDLE hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 ); - int meta_id; - while ( hContact != NULL ) { - if ((meta_id = DBGetContactSettingDword(hContact,META_PROTO,META_ID,(DWORD)-1))!=(DWORD)-1) { - Meta_CopyData(hContact); - } - hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 ); - } - } - - Meta_HideLinkedContacts(); - - InitIcons(); - - if (!Meta_IsEnabled()) - { - // modify main menu item - mi.flags = CMIM_NAME; - mi.pszName = "Toggle MetaContacts On"; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuOnOff, (LPARAM)&mi); - - Meta_HideMetaContacts(TRUE); - } else { - Meta_SuppressStatus(options.suppress_status); - } - - // hook srmm window close/open events - message api ver 0.0.0.1+ - hHooks[16] = (HANDLE)HookEvent(ME_MSG_WINDOWEVENT, Meta_MessageWindowEvent); - if (hHooks[16]) // message api available - message_window_api_enabled = TRUE; - - // hook protocol nudge events to forward to subcontacts - { - int i, numberOfProtocols,ret; - char str[MAXMODULELABELLENGTH + 10]; - HANDLE hNudgeEvent = NULL; - PROTOCOLDESCRIPTOR ** ppProtocolDescriptors; - ret = CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM) &numberOfProtocols,(LPARAM)&ppProtocolDescriptors); - if (ret == 0) - { - for (i = 0; i < numberOfProtocols ; i++) - { - if (ppProtocolDescriptors[i]->type == PROTOTYPE_PROTOCOL) - { - if (strcmp(ppProtocolDescriptors[i]->szName, META_PROTO)) { - sprintf(str,"%s/Nudge",ppProtocolDescriptors[i]->szName); - hNudgeEvent = HookEvent(str, NudgeRecieved); - if (hNudgeEvent != NULL) { - ++iNudgeProtos; - hNudgeEvents = realloc(hNudgeEvents, sizeof(HANDLE) * iNudgeProtos); - hNudgeEvents[iNudgeProtos - 1] = hNudgeEvent; - } - } - } - } - - } - } - return 0; -} - -static VOID CALLBACK sttMenuThread( PVOID param ) -{ - HMENU hMenu; - TPMPARAMS tpmp; - BOOL menuRet; - - hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)param, 0); - - ZeroMemory(&tpmp, sizeof(tpmp)); - tpmp.cbSize = sizeof(tpmp); - - menuRet = TrackPopupMenuEx(hMenu, TPM_RETURNCMD, menuMousePoint.x, menuMousePoint.y, (HWND)CallService(MS_CLUI_GETHWND, 0, 0), &tpmp); - - CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(menuRet), MPCF_CONTACTMENU), (LPARAM)param); - - DestroyMenu(hMenu); -} - -INT_PTR Meta_ContactMenuFunc(WPARAM wParam, LPARAM lParam) { - HANDLE hContact; - hContact = Meta_GetContactHandle((HANDLE)wParam, (int)lParam); - - if (options.menu_function == FT_MSG) { - // open message window if protocol supports message sending or chat, else simulate double click - - int caps; - char *proto; - char buffer[512]; - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - - if (proto) { - strcpy(buffer, proto); - strcat(buffer, PS_GETCAPS); - - caps = CallService(buffer, (WPARAM)PFLAGNUM_1, 0); - - if ((caps & PF1_IMSEND) || (caps & PF1_CHAT) || (proto && strcmp(proto, "IRC") == 0)) { - // set default contact for sending/status and open message window - DBWriteContactSettingDword((HANDLE)wParam, META_PROTO, "Default", (DWORD)(int)lParam); - NotifyEventHooks(hEventDefaultChanged, wParam, (LPARAM)hContact); - CallService(MS_MSG_SENDMESSAGE, wParam, 0); - } else - // protocol does not support messaging - simulate double click - CallService(MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM)hContact, 0); - } else - // protocol does not support messaging - simulate double click - CallService(MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM)hContact, 0); - - } else if (options.menu_function == FT_MENU) { - // show contact's context menu - CallFunctionAsync(sttMenuThread, hContact); - } else if (options.menu_function == FT_INFO) { - // show user info for subcontact - CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0); - } - - return 0; -} - -//////////////////// -// file transfer support - mostly not required, since subcontacts do the receiving -//////////////////// -/* -INT_PTR Meta_FileResume(WPARAM wParam, LPARAM lParam) -{ - DBVARIANT dbv; - CCSDATA *ccs = (CCSDATA *) lParam; - char *proto = 0; - - if (DBGetContactSetting(ccs->hContact,META_PROTO,"Default",&dbv)) - { - // This is a simple contact - // (this should normally not happen, since linked contacts do not appear on the list.) - return 1; - } - else - { - HANDLE most_online = Meta_GetMostOnlineSupporting(ccs->hContact, PFLAGNUM_1, PF1_FILERESUME); - //DBEVENTINFO dbei; - char szServiceName[100]; - - DBFreeVariant(&dbv); - - if (!most_online) - return 0; - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online, 0); - - ccs->hContact = most_online; - Meta_SetNick(proto); - - _snprintf(szServiceName, sizeof(szServiceName), "%s%s", proto, PS_FILERESUME); - if (ServiceExists(szServiceName)) { - strncpy(szServiceName, PS_FILERESUME, sizeof(szServiceName)); - return (int)(CallContactService(ccs->hContact, szServiceName, ccs->wParam, ccs->lParam)); - } - } - return 1; // fail -} - -INT_PTR Meta_FileAllow(WPARAM wParam, LPARAM lParam) -{ - DBVARIANT dbv; - CCSDATA *ccs = (CCSDATA *) lParam; - char *proto = 0; - - if (DBGetContactSetting(ccs->hContact,META_PROTO,"Default",&dbv)) - { - // This is a simple contact - // (this should normally not happen, since linked contacts do not appear on the list.) - return 0; - } - else - { - HANDLE most_online = Meta_GetMostOnlineSupporting(ccs->hContact, PFLAGNUM_1, PF1_FILE); - char szServiceName[100]; - - DBFreeVariant(&dbv); - - if (!most_online) - return 0; - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online, 0); - - ccs->hContact = most_online; - Meta_SetNick(proto); - - _snprintf(szServiceName, sizeof(szServiceName), "%s%s", proto, PSS_FILEALLOW); - if (ServiceExists(szServiceName)) { - strncpy(szServiceName, PSS_FILEALLOW, sizeof(szServiceName)); - return (int)(CallContactService(ccs->hContact, szServiceName, ccs->wParam, ccs->lParam)); - } - } - return 0; // fail -} - -INT_PTR Meta_FileDeny(WPARAM wParam, LPARAM lParam) -{ - DBVARIANT dbv; - CCSDATA *ccs = (CCSDATA *) lParam; - char *proto = 0; - - if (DBGetContactSetting(ccs->hContact,META_PROTO,"Default",&dbv)) - { - // This is a simple contact - // (this should normally not happen, since linked contacts do not appear on the list.) - return 1; - } - else - { - HANDLE most_online = Meta_GetMostOnlineSupporting(ccs->hContact, PFLAGNUM_1, PF1_FILE); - //DBEVENTINFO dbei; - char szServiceName[100]; - - DBFreeVariant(&dbv); - - if (!most_online) - return 1; - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online, 0); - - ccs->hContact = most_online; - Meta_SetNick(proto); - - _snprintf(szServiceName, sizeof(szServiceName), "%s%s", proto, PSS_FILEDENY); - if (ServiceExists(szServiceName)) { - strncpy(szServiceName, PSS_FILEDENY, sizeof(szServiceName)); - return (int)(CallContactService(ccs->hContact, szServiceName, ccs->wParam, ccs->lParam)); - } - } - return 1; // fail -} - -INT_PTR Meta_FileRecv(WPARAM wParam, LPARAM lParam) -{ - DBVARIANT dbv; - CCSDATA *ccs = (CCSDATA *) lParam; - char *proto = 0; - - if (DBGetContactSetting(ccs->hContact,META_PROTO,"Default",&dbv)) - { - // This is a simple contact - // (this should normally not happen, since linked contacts do not appear on the list.) - return 0; - } - else - { - HANDLE most_online = Meta_GetMostOnlineSupporting(ccs->hContact, PFLAGNUM_1, PF1_FILE); - //DBEVENTINFO dbei; - char szServiceName[100]; - - DBFreeVariant(&dbv); - - if (!most_online) - return 0; - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online, 0); - - ccs->hContact = most_online; - Meta_SetNick(proto); - - _snprintf(szServiceName, sizeof(szServiceName), "%s%s", proto, PSR_FILE); - if (ServiceExists(szServiceName)) { - strncpy(szServiceName, PSR_FILE, sizeof(szServiceName)); - return (int)(CallContactService(ccs->hContact, szServiceName, ccs->wParam, ccs->lParam)); - } - } - - return 0; -} - -int Meta_FileCancel(WPARAM wParam, LPARAM lParam) -{ - DBVARIANT dbv; - CCSDATA *ccs = (CCSDATA *) lParam; - char *proto = 0; - - if (DBGetContactSetting(ccs->hContact,META_PROTO,"Default",&dbv)) - { - // This is a simple contact - // (this should normally not happen, since linked contacts do not appear on the list.) - return 0; - } - else - { - HANDLE most_online = Meta_GetMostOnlineSupporting(ccs->hContact, PFLAGNUM_1, PF1_FILE); - //DBEVENTINFO dbei; - char szServiceName[100]; - - DBFreeVariant(&dbv); - - if (!most_online) - return 0; - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online, 0); - - ccs->hContact = most_online; - Meta_SetNick(proto); - - _snprintf(szServiceName, sizeof(szServiceName), "%s%s", proto, PSS_FILECANCEL); - if (ServiceExists(szServiceName)) { - strncpy(szServiceName, PSS_FILECANCEL, sizeof(szServiceName)); - return (int)(CallContactService(ccs->hContact, szServiceName, ccs->wParam, ccs->lParam)); - } - } - return 0; -} -*/ - -INT_PTR Meta_FileSend(WPARAM wParam, LPARAM lParam) -{ - CCSDATA *ccs = (CCSDATA *) lParam; - char *proto = 0; - DWORD default_contact_number; - - if ((default_contact_number = DBGetContactSettingDword(ccs->hContact,META_PROTO,"Default",(DWORD)-1)) == (DWORD)-1) - { - // This is a simple contact - // (this should normally not happen, since linked contacts do not appear on the list.) - //PUShowMessage("meta has no default", SM_NOTIFY); - return 0; - } - else - { - HANDLE most_online; - //DBEVENTINFO dbei; - //char szServiceName[100]; - - most_online = Meta_GetMostOnlineSupporting(ccs->hContact, PFLAGNUM_1, PF1_FILESEND); - - if (!most_online) { - //PUShowMessage("no most online for ft", SM_NOTIFY); - return 0; - } - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online, 0); - //Meta_CopyContactNick(ccs->hContact, most_online, proto); - - if (proto) { - //ccs->hContact = most_online; - //Meta_SetNick(proto); - - // don't check for existence of service - 'accounts' based protos don't have them! - //_snprintf(szServiceName, sizeof(szServiceName), "%s%s", proto, PSS_FILE); - //if (ServiceExists(szServiceName)) { - // PUShowMessage("sending to subcontact", SM_NOTIFY); - return (int)(CallContactService(most_online, PSS_FILE, ccs->wParam, ccs->lParam)); - //} else - // PUShowMessage("no service", SM_NOTIFY); - } //else - //PUShowMessage("no proto for subcontact", SM_NOTIFY); - } - return 0; // fail -} - -INT_PTR Meta_GetAwayMsg(WPARAM wParam, LPARAM lParam) { - CCSDATA *ccs = (CCSDATA *) lParam; - char *proto = 0; - DWORD default_contact_number; - - if ((default_contact_number = DBGetContactSettingDword(ccs->hContact,META_PROTO,"Default",(DWORD)-1)) == (DWORD)-1) - { - // This is a simple contact - // (this should normally not happen, since linked contacts do not appear on the list.) - return 0; - } - else - { - HANDLE most_online; - - most_online = Meta_GetMostOnlineSupporting(ccs->hContact, PFLAGNUM_1, PF1_MODEMSGRECV); - - if (!most_online) - return 0; - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online, 0); - if (!proto) return 0; - - //Meta_CopyContactNick(ccs->hContact, most_online, proto); - - ccs->hContact = most_online; - //Meta_SetNick(proto); - - return (int)(CallContactService(ccs->hContact, PSS_GETAWAYMSG, ccs->wParam, ccs->lParam)); - } - return 0; // fail -} - -INT_PTR Meta_GetAvatarInfo(WPARAM wParam, LPARAM lParam) { - PROTO_AVATAR_INFORMATIONT *AI = (PROTO_AVATAR_INFORMATIONT *) lParam; - char *proto = 0; - DWORD default_contact_number; - - if ((default_contact_number = DBGetContactSettingDword(AI->hContact,META_PROTO,"Default",(DWORD)-1)) == (DWORD)-1) - { - // This is a simple contact - // (this should normally not happen, since linked contacts do not appear on the list.) - return 0; - } - else - { - HANDLE hSub, hMeta; - char szServiceName[100]; - int result; - - hMeta = AI->hContact; - hSub = Meta_GetMostOnlineSupporting(AI->hContact, PFLAGNUM_4, PF4_AVATARS); - - if (!hSub) - return GAIR_NOAVATAR; - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hSub, 0); - if (!proto) return GAIR_NOAVATAR; - - AI->hContact = hSub; - - mir_snprintf(szServiceName, sizeof(szServiceName), "%s%s", proto, PS_GETAVATARINFOT); - result = CallService(szServiceName, wParam, lParam); - AI->hContact = hMeta; - if (result != CALLSERVICE_NOTFOUND) return result; - } - return GAIR_NOAVATAR; // fail -} - -INT_PTR Meta_GetInfo(WPARAM wParam, LPARAM lParam) { - CCSDATA *ccs = (CCSDATA *) lParam; - char *proto = 0; - DWORD default_contact_number; - - if ((default_contact_number = DBGetContactSettingDword(ccs->hContact,META_PROTO,"Default",(DWORD)-1)) == (DWORD)-1) - { - // This is a simple contact - // (this should normally not happen, since linked contacts do not appear on the list.) - return 0; - } - else - { - HANDLE most_online; - PROTO_AVATAR_INFORMATIONT AI; - char szServiceName[100]; - - most_online = Meta_GetMostOnlineSupporting(ccs->hContact, PFLAGNUM_4, PF4_AVATARS); - - if (!most_online) - return 0; - - proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)most_online, 0); - if (!proto) return 0; - - AI.cbSize = sizeof(AI); - AI.hContact = ccs->hContact; - AI.format = PA_FORMAT_UNKNOWN; - _tcscpy(AI.filename, _T("X")); - if ((int)CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) - DBWriteContactSettingTString(ccs->hContact, "ContactPhoto", "File",AI.filename); - - most_online = Meta_GetMostOnline(ccs->hContact); - Meta_CopyContactNick(ccs->hContact, most_online); - - if (!most_online) - return 0; - - //Meta_CopyContactNick(ccs->hContact, most_online, proto); - - ccs->hContact = most_online; - //Meta_SetNick(proto); - - _snprintf(szServiceName, sizeof(szServiceName), "%s%s", proto, PSS_GETINFO); - if (ServiceExists(szServiceName)) { - strncpy(szServiceName, PSS_GETINFO, sizeof(szServiceName)); - return (int)(CallContactService(ccs->hContact, szServiceName, ccs->wParam, ccs->lParam)); - } - } - return 0; // fail -} - -int Meta_OptInit(WPARAM wParam, LPARAM lParam) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.cbSize = sizeof(odp); - odp.position = -790000000; - odp.hInstance = hInstance; - odp.flags = ODPF_BOLDGROUPS; - - odp.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONS); - odp.pszTitle = LPGEN("MetaContacts"); - odp.pszGroup = LPGEN("Contact List"); - odp.pszTab = LPGEN("General"); - odp.pfnDlgProc = DlgProcOpts; - Options_AddPage(wParam, &odp); - - odp.pszTemplate = MAKEINTRESOURCE(IDD_PRIORITIES); - odp.pszTab = LPGEN("Priorities"); - odp.pfnDlgProc = DlgProcOptsPriorities; - Options_AddPage(wParam, &odp); - - odp.pszTemplate = MAKEINTRESOURCE(IDD_HISTORY); - odp.pszTab = LPGEN("History"); - odp.pfnDlgProc = DlgProcOpts; - Options_AddPage(wParam, &odp); - return 0; -} - -int Meta_CallMostOnline(WPARAM wParam, LPARAM lParam) { - HANDLE most_online_im = Meta_GetMostOnline((HANDLE)wParam); - - // fix nick - Meta_CopyContactNick((HANDLE)wParam, most_online_im); - - // fix status - Meta_FixStatus((HANDLE)wParam); - - // copy all other data - Meta_CopyData((HANDLE) wParam); - - return 0; -} - - -INT_PTR Meta_OnOff(WPARAM wParam, LPARAM lParam) { - CLISTMENUITEM mi; - mi.cbSize = sizeof(CLISTMENUITEM); - // just write to db - the rest is handled in the Meta_SettingChanged function - if (DBGetContactSettingByte(0, META_PROTO, "Enabled", 1)) { - DBWriteContactSettingByte(0, META_PROTO, "Enabled", 0); - // modify main mi item - mi.flags = CMIM_NAME | CMIM_ICON; - mi.hIcon = LoadIconEx(I_MENU); - mi.pszName = "Toggle MetaContacts On"; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuOnOff, (LPARAM)&mi); - } else { - DBWriteContactSettingByte(0, META_PROTO, "Enabled", 1); - // modify main mi item - mi.flags = CMIM_NAME | CMIM_ICON; - mi.hIcon = LoadIconEx(I_MENUOFF); - mi.pszName = "Toggle MetaContacts Off"; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuOnOff, (LPARAM)&mi); - } - ReleaseIconEx(mi.hIcon); - - return 0; -} - - -int Meta_PreShutdown(WPARAM wParam, LPARAM lParam) { - //MessageBox(0, "Preshutdown called", "MC", MB_OK); - Meta_SetStatus((WPARAM)ID_STATUS_OFFLINE, 0); - Meta_UnhideLinkedContacts(); - Meta_SuppressStatus(FALSE); - //MessageBox(0, "Status is OFFLINE", "MC", MB_OK); - //MessageBox(0, "Preshutdown complete", "MC", MB_OK); - - if (setStatusTimerId) KillTimer(0, setStatusTimerId); - - return 0; -} - -int Meta_OkToExit(WPARAM wParam, LPARAM lParam) { - Meta_SetStatus((WPARAM)ID_STATUS_OFFLINE, 0); - return 0; -} - -int Meta_OnIdleChanged(WPARAM wParam, LPARAM lParam) { - return 0; -} - -/** Initializes all services provided by the plugin -* -* Creates every function and hooks the event desired. -*/ -void Meta_InitServices() -{ - int i; - - previousMode = mcStatus = ID_STATUS_OFFLINE; - - // set hooks pointers and services pointers to zero - in case we do not initialize them all correctly - for (i=0;i