From 1ca120b165c2f2d9f521a04bfc31c7956d2ce422 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 17 Jul 2012 06:57:55 +0000 Subject: ContactsPlus, CountryFlags, CrashDumper: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@1000 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/ContactsPlus/contacts.cpp | 31 - plugins/ContactsPlus/contacts.h | 77 -- plugins/ContactsPlus/contacts.rc | 191 ----- plugins/ContactsPlus/contacts.vcxproj | 22 +- plugins/ContactsPlus/contacts.vcxproj.filters | 22 +- plugins/ContactsPlus/contactsplus-translation.txt | 30 - .../ContactsPlus/docs/contactsplus-translation.txt | 30 + plugins/ContactsPlus/docs/readme_contacts.txt | 158 ++++ plugins/ContactsPlus/main.cpp | 317 -------- plugins/ContactsPlus/readme_contacts.txt | 158 ---- plugins/ContactsPlus/receive.cpp | 522 ------------- plugins/ContactsPlus/receive.h | 65 -- plugins/ContactsPlus/res/contacts.rc | 191 +++++ plugins/ContactsPlus/resource.h | 44 -- plugins/ContactsPlus/send.cpp | 609 --------------- plugins/ContactsPlus/send.h | 110 --- plugins/ContactsPlus/src/contacts.cpp | 31 + plugins/ContactsPlus/src/contacts.h | 77 ++ plugins/ContactsPlus/src/main.cpp | 317 ++++++++ plugins/ContactsPlus/src/receive.cpp | 522 +++++++++++++ plugins/ContactsPlus/src/receive.h | 65 ++ plugins/ContactsPlus/src/resource.h | 44 ++ plugins/ContactsPlus/src/send.cpp | 609 +++++++++++++++ plugins/ContactsPlus/src/send.h | 110 +++ plugins/ContactsPlus/src/utils.cpp | 832 +++++++++++++++++++++ plugins/ContactsPlus/src/utils.h | 86 +++ plugins/ContactsPlus/utils.cpp | 832 --------------------- plugins/ContactsPlus/utils.h | 86 --- 28 files changed, 3094 insertions(+), 3094 deletions(-) delete mode 100644 plugins/ContactsPlus/contacts.cpp delete mode 100644 plugins/ContactsPlus/contacts.h delete mode 100644 plugins/ContactsPlus/contacts.rc delete mode 100644 plugins/ContactsPlus/contactsplus-translation.txt create mode 100644 plugins/ContactsPlus/docs/contactsplus-translation.txt create mode 100644 plugins/ContactsPlus/docs/readme_contacts.txt delete mode 100644 plugins/ContactsPlus/main.cpp delete mode 100644 plugins/ContactsPlus/readme_contacts.txt delete mode 100644 plugins/ContactsPlus/receive.cpp delete mode 100644 plugins/ContactsPlus/receive.h create mode 100644 plugins/ContactsPlus/res/contacts.rc delete mode 100644 plugins/ContactsPlus/resource.h delete mode 100644 plugins/ContactsPlus/send.cpp delete mode 100644 plugins/ContactsPlus/send.h create mode 100644 plugins/ContactsPlus/src/contacts.cpp create mode 100644 plugins/ContactsPlus/src/contacts.h create mode 100644 plugins/ContactsPlus/src/main.cpp create mode 100644 plugins/ContactsPlus/src/receive.cpp create mode 100644 plugins/ContactsPlus/src/receive.h create mode 100644 plugins/ContactsPlus/src/resource.h create mode 100644 plugins/ContactsPlus/src/send.cpp create mode 100644 plugins/ContactsPlus/src/send.h create mode 100644 plugins/ContactsPlus/src/utils.cpp create mode 100644 plugins/ContactsPlus/src/utils.h delete mode 100644 plugins/ContactsPlus/utils.cpp delete mode 100644 plugins/ContactsPlus/utils.h (limited to 'plugins/ContactsPlus') diff --git a/plugins/ContactsPlus/contacts.cpp b/plugins/ContactsPlus/contacts.cpp deleted file mode 100644 index a7ba2cdfbb..0000000000 --- a/plugins/ContactsPlus/contacts.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// -------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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. -// -// ----------------------------------------------------------------------------- - -#include "contacts.h" - - -bool WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - hInst = hinstDLL; - return TRUE; -} diff --git a/plugins/ContactsPlus/contacts.h b/plugins/ContactsPlus/contacts.h deleted file mode 100644 index 742f577924..0000000000 --- a/plugins/ContactsPlus/contacts.h +++ /dev/null @@ -1,77 +0,0 @@ -// --------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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. -// -// --------------------------------------------------------------------------- - -#define _CRT_SECURE_NO_WARNINGS -#define _CRT_NONSTDC_NO_WARNINGS - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -//!!this is fake - this plugin maintains backward compatibility internally -#define MIRANDA_VER 0x0A00 - -#include "newpluginapi.h" -#include "m_system.h" -#include "m_protocols.h" -#include "m_protosvc.h" -#include "m_database.h" -#include "m_utils.h" -#include "m_langpack.h" -#include "m_skin.h" -#include "m_clist.h" -#include "m_clc.h" -#include "m_clui.h" -#include "m_addcontact.h" -#include "m_history.h" -#include "m_userinfo.h" -#include "m_button.h" -#include "m_contacts.h" -#include "m_message.h" -#include "statusmodes.h" -#include "win2k.h" - -#include "resource.h" - -#include "utils.h" -#include "send.h" -#include "receive.h" - -#define MODULENAME "SendReceiveContacts" - - -#define MS_CONTACTS_SEND "ContactsTransfer/SendContacts" -#define MS_CONTACTS_RECEIVE "ContactsTransfer/ReceiveContacts" - -// Global Variables -extern int g_UnicodeCore; -extern int g_NewProtoAPI; -extern int g_SendAckSupported; -extern int g_Utf8EventsSupported; diff --git a/plugins/ContactsPlus/contacts.rc b/plugins/ContactsPlus/contacts.rc deleted file mode 100644 index 3edfca49c4..0000000000 --- a/plugins/ContactsPlus/contacts.rc +++ /dev/null @@ -1,191 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(1250) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_SEND DIALOGEX 0, 0, 308, 242 -STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_VISIBLE | WS_CAPTION | - WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Send contacts" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - CONTROL "",IDC_PROTOCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,5,7, - 12,12 - LTEXT "",IDC_NAME,19,7,118,9,SS_NOPREFIX | SS_CENTERIMAGE - CONTROL "&A",IDC_ADD,"MButtonClass",WS_TABSTOP,231,5,16,14, - 0x18000000L - CONTROL "6",IDC_USERMENU,"MButtonClass",WS_TABSTOP,249,5,16,14, - 0x18000000L - CONTROL "&D",IDC_DETAILS,"MButtonClass",WS_TABSTOP,267,5,16,14, - 0x18000000L - CONTROL "&H",IDC_HISTORY,"MButtonClass",WS_TABSTOP,285,5,16,14, - 0x18000000L - CONTROL "Choose contacts to be send:",IDC_STATIC,"Static", - SS_SIMPLE | WS_GROUP,5,20,300,10,WS_EX_TRANSPARENT - DEFPUSHBUTTON "&Send",IDOK,195,220,50,14 - PUSHBUTTON "Cancel",IDCANCEL,249,220,50,14 - CONTROL "",IDC_LIST,"CListControl",WS_TABSTOP | 0x3da,5,30,298, - 185,WS_EX_CLIENTEDGE - PUSHBUTTON "&Select All",ID_SELECTALL,5,220,50,14 -END - -IDD_RECEIVE DIALOGEX 0, 0, 320, 225 -STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | - WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | - WS_SYSMENU | WS_THICKFRAME -CAPTION "Received contacts" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "",IDC_PROTOCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,5,7, - 12,12 - LTEXT "",IDC_NAME,19,7,118,9,SS_NOPREFIX | SS_CENTERIMAGE - CONTROL "&A",IDC_ADD,"MButtonClass",WS_TABSTOP,243,5,16,14, - 0x18000000L - CONTROL "6",IDC_USERMENU,"MButtonClass",WS_TABSTOP,261,5,16,14, - 0x18000000L - CONTROL "&D",IDC_DETAILS,"MButtonClass",WS_TABSTOP,279,5,16,14, - 0x18000000L - CONTROL "&H",IDC_HISTORY,"MButtonClass",WS_TABSTOP,297,5,16,14, - 0x18000000L - CONTROL "",IDC_CONTACTS,"SysListView32",LVS_REPORT | - LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | - WS_BORDER | WS_TABSTOP,5,22,310,178 - CONTROL "Add to &group:",IDC_ENABLEGROUPS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,205,80,12 - COMBOBOX IDC_GROUPS,90,205,72,140,CBS_DROPDOWNLIST | CBS_SORT | - WS_VSCROLL | WS_TABSTOP | 0x8000 - PUSHBUTTON "&Add",IDOK,169,204,46,14,WS_DISABLED - PUSHBUTTON "&Details",IDDETAILS,215,204,46,14,WS_DISABLED - PUSHBUTTON "Close",IDCANCEL,261,204,52,14 -END - -IDD_MSGSENDERROR DIALOGEX 0, 0, 187, 97 -STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | - WS_VISIBLE | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Contacts send error" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "An error has occured. The protocol reported the following error:", - IDC_STATIC,5,5,177,28 - DEFPUSHBUTTON "Try again",IDOK,22,78,63,14 - PUSHBUTTON "Cancel",IDCANCEL,104,78,61,14 - EDITTEXT IDC_ERRORTEXT,5,37,177,35,ES_MULTILINE | ES_READONLY | - WS_VSCROLL -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO MOVEABLE PURE -BEGIN - IDD_SEND, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 235 - END - - IDD_RECEIVE, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 313 - TOPMARGIN, 7 - BOTTOMMARGIN, 218 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_CONTACTMENU MENUEX DISCARDABLE -BEGIN - POPUP "Popup", 0,MFT_STRING,MFS_ENABLED - BEGIN - MENUITEM "Add to List", 111,MFT_STRING,MFS_ENABLED - MENUITEM "User Details", 113,MFT_STRING, - MFS_ENABLED | MFS_UNCHECKED | MFS_UNHILITE | MFS_DEFAULT - MENUITEM MFT_SEPARATOR - MENUITEM "Send Message", 112,MFT_STRING,MFS_ENABLED - END -END - - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,2,0 - PRODUCTVERSION 0,8,0,0 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "Requires Miranda 0.3+; Recommended Miranda 0.4+\0" - VALUE "CompanyName", "Jokusoftware, Dusk Horizon\0" - VALUE "FileDescription", "Send/Receive Contacts plugin for Miranda (Unicode 2in1)\0" - VALUE "FileVersion", "1, 5, 2, 0\0" - VALUE "InternalName", "contacts+\0" - VALUE "LegalCopyright", "Copyright (C) 2004-2008 Jokusoftware, Original code (C) 2002 Dominus Procellarum\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "contacts.dll\0" - VALUE "ProductName", "Send/Receive Contacts plugin for Miranda\0" - VALUE "ProductVersion", "0, 8, 0, 0\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // !_MAC - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_CONTACTS ICON DISCARDABLE "res\\SendContacts.ico" -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// diff --git a/plugins/ContactsPlus/contacts.vcxproj b/plugins/ContactsPlus/contacts.vcxproj index 57d0cfbacb..1ebfa955a2 100644 --- a/plugins/ContactsPlus/contacts.vcxproj +++ b/plugins/ContactsPlus/contacts.vcxproj @@ -173,23 +173,23 @@ - - + + Create - - - + + + - - - - - + + + + + - + diff --git a/plugins/ContactsPlus/contacts.vcxproj.filters b/plugins/ContactsPlus/contacts.vcxproj.filters index 8270d92a72..f0fb5d4da0 100644 --- a/plugins/ContactsPlus/contacts.vcxproj.filters +++ b/plugins/ContactsPlus/contacts.vcxproj.filters @@ -15,41 +15,41 @@ - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Resource Files diff --git a/plugins/ContactsPlus/contactsplus-translation.txt b/plugins/ContactsPlus/contactsplus-translation.txt deleted file mode 100644 index 373fe04d50..0000000000 --- a/plugins/ContactsPlus/contactsplus-translation.txt +++ /dev/null @@ -1,30 +0,0 @@ -; Common strings that belong to many files -;[] - -; ../../plugins/ContactsPlus/contacts.rc -;[&A] -;[&Add] -;[&D] -;[&Details] -;[&H] -;[&Select All] -;[&Send] -;[Add to &group:] -;[Add to List] -;[An error has occured. The protocol reported the following error:] -;[Cancel] -;[Choose contacts to be send:] -;[Close] -;[Contacts send error] -;[Popup] -;[Received contacts] -;[Send Message] -;[Send contacts] -;[Try again] -;[User Details] - -; ../../plugins/ContactsPlus/main.cpp -;[Contacts] -;[Contacts received from] -;[Incoming Contacts] -;[Outgoing Contacts] diff --git a/plugins/ContactsPlus/docs/contactsplus-translation.txt b/plugins/ContactsPlus/docs/contactsplus-translation.txt new file mode 100644 index 0000000000..373fe04d50 --- /dev/null +++ b/plugins/ContactsPlus/docs/contactsplus-translation.txt @@ -0,0 +1,30 @@ +; Common strings that belong to many files +;[] + +; ../../plugins/ContactsPlus/contacts.rc +;[&A] +;[&Add] +;[&D] +;[&Details] +;[&H] +;[&Select All] +;[&Send] +;[Add to &group:] +;[Add to List] +;[An error has occured. The protocol reported the following error:] +;[Cancel] +;[Choose contacts to be send:] +;[Close] +;[Contacts send error] +;[Popup] +;[Received contacts] +;[Send Message] +;[Send contacts] +;[Try again] +;[User Details] + +; ../../plugins/ContactsPlus/main.cpp +;[Contacts] +;[Contacts received from] +;[Incoming Contacts] +;[Outgoing Contacts] diff --git a/plugins/ContactsPlus/docs/readme_contacts.txt b/plugins/ContactsPlus/docs/readme_contacts.txt new file mode 100644 index 0000000000..f3ae933be3 --- /dev/null +++ b/plugins/ContactsPlus/docs/readme_contacts.txt @@ -0,0 +1,158 @@ +About +----- + +Send and receive contacts ui +Version 1.5.2.0 +by Joe Kucera aka Jokusoftware +Original Code by Todor Totev aka Dominus Procellarum +for use with Miranda IM 0.3.3+ +Best for Miranda IM 0.4+ + + +Description +----------- + +This plugin allows you to send and receive contacts. +It is protocol independent, although currently the only +protocol supporting contacts transfer is ICQ. + + +Installation +------------ + +For the contactsp.zip zip archive - + Extract contacts.dll to Miranda plugin folder - + usually this is C:\Program Files\Miranda\Plugins. + All other files are not mandatory and can go to Miranda folder. + + +Source +------ + +The source code for this plugin can be downloaded from Miranda IM +website http://addons.miranda-im.org. + + +License +------- + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. +3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. +4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +For more information, e-mail jokusoftware@miranda-im.org + + +Version history +--------------- +1.0.11.0 + initial release - working ui, but M is still crashing +1.0.12.0 + 20-may night build of M - underlying code is OK, so i can continue this plugin + remove inverse logic in MirandaPluginInfo() + removed #include "win2k.h" for cleaner build + attempt to show more user info on receive contacts +1.0.13.0 + cleaned main.cpp + added icon to dialogue windows +1.0.14.0 + Nick / UIN swapped upon showing received contacts /silly me/ + bigger size of nick string allowed to accomodate non-english nicks /cyrrilic letters requires 2 times more bytes/ + added icon for menu item +1.0.15.0 + list columns default size is more convinient + save restore window position / size +1.0.16.0 + receive dlg is resizable one /thanks to WTL there was virtually no code to write/ +1.0.17.0 + add button is enabled only when at least one item in the list view is checked-in +1.0.18.0 + more translate()-friendly + at last contacts are permanently added to DB +1.0.19.0 + receive window is now being put on top + lots of big-fixes +1.1.0.0 + source beautify + receive user iface and internal dependancies re-design + now only contacts which details are requested are being added to the DB + std::vector is used instead of std::deque for 10KB smaller dll + this should be the official release build + you can get detailed info about contacts being sent to you + more bug fixes +1.2.0.0 + bugfix - contacts are always being added outside any group /forget actually writing to the DB/ + sending contacts is now a Miranda service, accessible via m_contacts.h + implemented contactlist event, no more popup windows + NOTE: the langpack is modified, because my english is at least questionable and some items are now obsolete + +1.4.0.0 (New developer: Joe @ Whale, jokusoftware@miranda-im.org) + now fully protocol independent + made sending with full acknowledgement (needs miranda 0.3.4alpha) & improved Send Dialog + now sent contacts are added to history (can be viewed by e.g. History++) + improved Receive Dialog - added popup & some convenient functions, display more info (like ICQ) + many fixes +1.4.1.3 + fixed multipacket sending (if 15 contacts, do not try to send empty packet) + optimisations (reimplemented many structures, size cut by 20kB) + when contact gets deleted close his send window + redesigned Send dialog - more nice & effective (show only contacts of the same protocol + many more) + grouplist on receive dialog now gets updated +1.4.1.7 + redesigned and improved Received dialog (get rid of WTL & MFC) + empty groups in send dialog are hidden according to clui setting + fixed multi-packet error handling + fixed crashes on exit (thanks to Ghazan) + small fixes +1.4.1.8 + fixed received dialog not showed on some systems + other small fixes +1.4.2.0 + fixed memory leak on any event received (thx to Ghazan) + fixed other small memory leaks + popup menu on Received dialog gets translated now + added DBE3++ Known Modules support +1.5.0.0 + many internal optimisations + added Unicode 2in1 support + added support for Unicode ready DB contacts events + added Updater plug-in support +1.5.1.0 + added support for per-contact contacts API capabilities + improved compatibility with unicode database API + added support for new clist groups API + several internal fixes & improvements +1.5.2.0 + fixed possible crash during contacts send (with older Miranda IM) + fixed compatibility with the new Account API introduced in Miranda IM 0.8 + + +Translation +----------- + +Contacts plugin can be translated via the Miranda language files. +The required strings are provided in langpack_contacts.txt file. diff --git a/plugins/ContactsPlus/main.cpp b/plugins/ContactsPlus/main.cpp deleted file mode 100644 index da43554c29..0000000000 --- a/plugins/ContactsPlus/main.cpp +++ /dev/null @@ -1,317 +0,0 @@ -// -------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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. -// -// ----------------------------------------------------------------------------- - -#include "contacts.h" - - -HINSTANCE hInst; - -int hLangpack; - -int g_NewProtoAPI = TRUE; - -int g_SendAckSupported = TRUE; -int g_Utf8EventsSupported = TRUE; - -HANDLE ghSendWindowList; -HANDLE ghRecvWindowList; -gAckList gaAckData; - -HANDLE hServiceSend; -HANDLE hServiceReceive; - -HANDLE hHookModulesLoaded = NULL; -HANDLE hHookDBEventAdded = NULL; -HANDLE hHookContactDeleted = NULL; -HANDLE hHookContactSettingChanged = NULL; -HANDLE hHookPreBuildContactMenu = NULL; - -HANDLE hContactMenuItem = NULL; - -int g_UnicodeCore; - -PLUGININFOEX pluginInfo = { - sizeof(PLUGININFOEX), - "Send/Receive Contacts+", - PLUGIN_MAKE_VERSION(1,5,2,0), - "Allows you to send and receive contacts", - "Joe Kucera, Todor Totev", - "jokusoftware@miranda-im.org", - "(C) 2004-2008 Joe Kucera, Original Code (C) 2002 Dominus Procellarum", - "http://addons.miranda-im.org/details.php?action=viewfile&id=1253", - UNICODE_AWARE, - {0x0324785E, 0x74CE, 0x4600, {0xB7, 0x81, 0x85, 0x17, 0x73, 0xB3, 0xEF, 0xC5 } } // {0324785E-74CE-4600-B781-851773B3EFC5} -}; - - -static int HookDBEventAdded(WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact = (HANDLE)wParam; - HANDLE hDbEvent = (HANDLE)lParam; - //process the event - DBEVENTINFO dbe = {0}; - - dbe.cbSize = sizeof(DBEVENTINFO); - //get event details - CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe); - //check if we should process the event - if (dbe.flags & (DBEF_SENT|DBEF_READ) || dbe.eventType != EVENTTYPE_CONTACTS) return 0; - //get event contents - dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0); - if (dbe.cbBlob != -1) - dbe.pBlob = (PBYTE)_alloca(dbe.cbBlob); - CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe); - //play received sound - SkinPlaySound("RecvContacts"); - { //add event to the contact list - CLISTEVENT cle = {0}; - TCHAR caToolTip[128]; - - cle.cbSize = sizeof(cle); - cle.hContact = hContact; - cle.hDbEvent = hDbEvent; - cle.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS)); - cle.pszService = MS_CONTACTS_RECEIVE; - - WCHAR tmp[MAX_PATH]; - _snprintfT(caToolTip, 64, "%s %s", SRCTranslateT("Contacts received from", tmp), (TCHAR*)GetContactDisplayNameT(hContact)); - - cle.ptszTooltip = caToolTip; - if (g_UnicodeCore) - cle.flags |= CLEF_UNICODE; - CallService(MS_CLIST_ADDEVENT, 0, (LPARAM)&cle); - } - return 0; //continue processing by other hooks -} - - -static void ProcessUnreadEvents(void) -{ - DBEVENTINFO dbei = {0}; - HANDLE hDbEvent,hContact; - - dbei.cbSize = sizeof(dbei); - - hContact = SRCFindFirstContact(); - while (hContact) - { - hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDFIRSTUNREAD,(WPARAM)hContact,0); - - while (hDbEvent) - { - dbei.cbBlob=0; - CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei); - if (!(dbei.flags&(DBEF_SENT|DBEF_READ)) && dbei.eventType==EVENTTYPE_CONTACTS) - { //process the event - HookDBEventAdded((WPARAM)hContact, (LPARAM)hDbEvent); - } - hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0); - } - hContact = SRCFindNextContact(hContact); - } -} - - -static bool CheckContactsServiceSupport(const char* szProto) -{ - if (g_NewProtoAPI) - { // there is no way to determine if the service exists (only proto_interface call is supported by 0.8+) - if (CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_CONTACTSEND) - return true; - } - else - { // check the real send service (only 0.7.x and older) - char serstr[MAX_PATH+30]; - - strcpy(serstr, szProto); - strcat(serstr, PSS_CONTACTS); - if (ServiceExists(serstr)) - return true; - } - return false; -} - - -static int HookPreBuildContactMenu(WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact = (HANDLE)wParam; - char* szProto = GetContactProto(hContact); - int bVisible = FALSE; - - if (szProto && CheckContactsServiceSupport(szProto)) - { // known protocol, protocol supports contacts sending - // check the selected contact if it supports contacts receive - if (CallProtoService(szProto, PS_GETCAPS, PFLAG_MAXCONTACTSPERPACKET, (LPARAM)hContact)) - bVisible = TRUE; - } - - { // update contact menu item's visibility - CLISTMENUITEM mi = {0}; - - mi.cbSize = sizeof(mi); - if (bVisible) - mi.flags = CMIM_FLAGS; - else - mi.flags = CMIM_FLAGS | CMIF_HIDDEN; - - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hContactMenuItem, (LPARAM)&mi); - } - - return 0; -} - - -static int HookModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - char* modules[2] = {0}; - WCHAR tmp[MAX_PATH]; - - modules[0] = MODULENAME; - CallService("DBEditorpp/RegisterModule",(WPARAM)modules,(LPARAM)1); - - CLISTMENUITEM mi = {0}; - mi.cbSize = sizeof(mi); - mi.ptszName = SRCTranslateT("Contacts", tmp); - mi.position = -2000009990; //position in menu - mi.flags = CMIF_KEEPUNTRANSLATED; - if (g_UnicodeCore) - mi.flags |= CMIF_UNICODE; - mi.pszService = MS_CONTACTS_SEND; - mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS)); - hContactMenuItem = Menu_AddContactMenuItem(&mi); - - hHookPreBuildContactMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, HookPreBuildContactMenu); - - ghSendWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); // no need to destroy this - ghRecvWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); // no need to destroy this - - - ProcessUnreadEvents(); - return 0; -} - - -static int HookContactSettingChanged(WPARAM wParam, LPARAM lParam) -{ - DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam; - char *szProto = GetContactProto((HANDLE)wParam); - - if (strcmpnull(cws->szModule,"CList") && strcmpnull(cws->szModule, szProto)) return 0; - - WindowList_Broadcast(ghSendWindowList,DM_UPDATETITLE,0,0); - WindowList_Broadcast(ghRecvWindowList,DM_UPDATETITLE,0,0); - - return 0; -} - - -static int HookContactDeleted(WPARAM wParam, LPARAM lParam) -{ // if our contact gets deleted close his window - HWND h = WindowList_Find(ghSendWindowList,(HANDLE)wParam); - - if (h) - { - SendMessageT(h,WM_CLOSE,0,0); - } - - while (h = WindowList_Find(ghRecvWindowList, (HANDLE)wParam)) - { // since we hack the window list - more windows for one contact, we need to close them all - SendMessageT(h, WM_CLOSE,0,0); - } - return 0; -} - - -static INT_PTR ServiceSendCommand(WPARAM wParam, LPARAM lParam) -{ - HWND hWnd; - //find window for hContact - hWnd = WindowList_Find(ghSendWindowList, (HANDLE)wParam); - - if (!hWnd) - CreateDialogParamT(hInst, MAKEINTRESOURCE(IDD_SEND), NULL, SendDlgProc, (LPARAM)(HANDLE)wParam); - else - { - SetForegroundWindow(hWnd); - SetFocus(hWnd); - } - return 0; -} - -static INT_PTR ServiceReceiveCommand(WPARAM wParam, LPARAM lParam) -{ - CLISTEVENT* pcle = (CLISTEVENT*)lParam; - - CreateDialogParamT(hInst, MAKEINTRESOURCE(IDD_RECEIVE), NULL, RecvDlgProc, (LPARAM)pcle); - - return 0; -} - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_SRCONTACTS, MIID_LAST}; - -extern "C" __declspec(dllexport) int Load(void) -{ - mir_getLP(&pluginInfo); - InitCommonControls(); - InitI18N(); - - { // Are we running under unicode Miranda core ? - char szVer[MAX_PATH]; - - CallService(MS_SYSTEM_GETVERSIONTEXT, MAX_PATH, (LPARAM)szVer); - _strlwr(szVer); - g_UnicodeCore = (strstr(szVer, "unicode") != NULL); - } - //init hooks - hHookModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, HookModulesLoaded); - hHookDBEventAdded = HookEvent(ME_DB_EVENT_ADDED, HookDBEventAdded); - hHookContactDeleted = HookEvent(ME_DB_CONTACT_DELETED, HookContactDeleted); - hHookContactSettingChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, HookContactSettingChanged); - //create services - hServiceSend = CreateServiceFunction(MS_CONTACTS_SEND, ServiceSendCommand); - hServiceReceive = CreateServiceFunction(MS_CONTACTS_RECEIVE, ServiceReceiveCommand); - //define event sounds - SkinAddNewSound("RecvContacts", LPGEN("Incoming Contacts"), "contacts.wav"); - SkinAddNewSound("SentContacts", LPGEN("Outgoing Contacts"), "ocontacts.wav"); - - return 0; -} - -extern "C" __declspec(dllexport) int Unload(void) -{ - UnhookEvent(hHookModulesLoaded); - UnhookEvent(hHookDBEventAdded); - UnhookEvent(hHookContactDeleted); - UnhookEvent(hHookContactSettingChanged); - UnhookEvent(hHookPreBuildContactMenu); - - DestroyServiceFunction(hServiceSend); - DestroyServiceFunction(hServiceReceive); - - return 0; -} diff --git a/plugins/ContactsPlus/readme_contacts.txt b/plugins/ContactsPlus/readme_contacts.txt deleted file mode 100644 index f3ae933be3..0000000000 --- a/plugins/ContactsPlus/readme_contacts.txt +++ /dev/null @@ -1,158 +0,0 @@ -About ------ - -Send and receive contacts ui -Version 1.5.2.0 -by Joe Kucera aka Jokusoftware -Original Code by Todor Totev aka Dominus Procellarum -for use with Miranda IM 0.3.3+ -Best for Miranda IM 0.4+ - - -Description ------------ - -This plugin allows you to send and receive contacts. -It is protocol independent, although currently the only -protocol supporting contacts transfer is ICQ. - - -Installation ------------- - -For the contactsp.zip zip archive - - Extract contacts.dll to Miranda plugin folder - - usually this is C:\Program Files\Miranda\Plugins. - All other files are not mandatory and can go to Miranda folder. - - -Source ------- - -The source code for this plugin can be downloaded from Miranda IM -website http://addons.miranda-im.org. - - -License -------- - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the copyright - notice, this list of conditions and the following disclaimer. -2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. -3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. -4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS -OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -For more information, e-mail jokusoftware@miranda-im.org - - -Version history ---------------- -1.0.11.0 - initial release - working ui, but M is still crashing -1.0.12.0 - 20-may night build of M - underlying code is OK, so i can continue this plugin - remove inverse logic in MirandaPluginInfo() - removed #include "win2k.h" for cleaner build - attempt to show more user info on receive contacts -1.0.13.0 - cleaned main.cpp - added icon to dialogue windows -1.0.14.0 - Nick / UIN swapped upon showing received contacts /silly me/ - bigger size of nick string allowed to accomodate non-english nicks /cyrrilic letters requires 2 times more bytes/ - added icon for menu item -1.0.15.0 - list columns default size is more convinient - save restore window position / size -1.0.16.0 - receive dlg is resizable one /thanks to WTL there was virtually no code to write/ -1.0.17.0 - add button is enabled only when at least one item in the list view is checked-in -1.0.18.0 - more translate()-friendly - at last contacts are permanently added to DB -1.0.19.0 - receive window is now being put on top - lots of big-fixes -1.1.0.0 - source beautify - receive user iface and internal dependancies re-design - now only contacts which details are requested are being added to the DB - std::vector is used instead of std::deque for 10KB smaller dll - this should be the official release build - you can get detailed info about contacts being sent to you - more bug fixes -1.2.0.0 - bugfix - contacts are always being added outside any group /forget actually writing to the DB/ - sending contacts is now a Miranda service, accessible via m_contacts.h - implemented contactlist event, no more popup windows - NOTE: the langpack is modified, because my english is at least questionable and some items are now obsolete - -1.4.0.0 (New developer: Joe @ Whale, jokusoftware@miranda-im.org) - now fully protocol independent - made sending with full acknowledgement (needs miranda 0.3.4alpha) & improved Send Dialog - now sent contacts are added to history (can be viewed by e.g. History++) - improved Receive Dialog - added popup & some convenient functions, display more info (like ICQ) - many fixes -1.4.1.3 - fixed multipacket sending (if 15 contacts, do not try to send empty packet) - optimisations (reimplemented many structures, size cut by 20kB) - when contact gets deleted close his send window - redesigned Send dialog - more nice & effective (show only contacts of the same protocol + many more) - grouplist on receive dialog now gets updated -1.4.1.7 - redesigned and improved Received dialog (get rid of WTL & MFC) - empty groups in send dialog are hidden according to clui setting - fixed multi-packet error handling - fixed crashes on exit (thanks to Ghazan) - small fixes -1.4.1.8 - fixed received dialog not showed on some systems - other small fixes -1.4.2.0 - fixed memory leak on any event received (thx to Ghazan) - fixed other small memory leaks - popup menu on Received dialog gets translated now - added DBE3++ Known Modules support -1.5.0.0 - many internal optimisations - added Unicode 2in1 support - added support for Unicode ready DB contacts events - added Updater plug-in support -1.5.1.0 - added support for per-contact contacts API capabilities - improved compatibility with unicode database API - added support for new clist groups API - several internal fixes & improvements -1.5.2.0 - fixed possible crash during contacts send (with older Miranda IM) - fixed compatibility with the new Account API introduced in Miranda IM 0.8 - - -Translation ------------ - -Contacts plugin can be translated via the Miranda language files. -The required strings are provided in langpack_contacts.txt file. diff --git a/plugins/ContactsPlus/receive.cpp b/plugins/ContactsPlus/receive.cpp deleted file mode 100644 index 3d3fb2f773..0000000000 --- a/plugins/ContactsPlus/receive.cpp +++ /dev/null @@ -1,522 +0,0 @@ -// -------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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. -// -// ----------------------------------------------------------------------------- - -#include "contacts.h" - - -/* TRecvContactsData */ - -TReceivedItem* TRecvContactsData::AddReceivedItem() { - int iItem = cbReceived; - - cbReceived++; - maReceived = (TReceivedItem**)realloc(maReceived, cbReceived*sizeof(TReceivedItem*)); - maReceived[iItem] = new TReceivedItem(); - - return maReceived[iItem]; -} - - -static int RecvDlg_Resize(HWND hwndDlg,LPARAM lParam,UTILRESIZECONTROL *urc) -{ - switch (urc->wId) - { - case IDC_CONTACTS: - return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; - break; - case IDOK: - case IDDETAILS: - case IDC_ENABLEGROUPS: - case IDC_GROUPS: - return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; - break; - case IDC_ADD: - case IDC_HISTORY: - case IDC_USERMENU: - case IDC_DETAILS: - return RD_ANCHORX_RIGHT | RD_ANCHORY_TOP; - break; - case IDCANCEL: - return RD_ANCHORY_BOTTOM | RD_ANCHORX_RIGHT; - break; - } - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; // default -} - - -static char* ListView_GetItemTextEx(HWND hLV, int iItem, int iSubItem) -{ - LVITEM lvi = {0}; - - lvi.mask = LVIF_TEXT; - lvi.iSubItem = iSubItem; - lvi.cchTextMax = 64; - lvi.pszText = (char*)malloc(lvi.cchTextMax); - while (SendMessageT(hLV, LVM_GETITEMTEXT, iItem, (LPARAM)&lvi) == lvi.cchTextMax - 1) - { // loop until the returned size is smaller than buffer size - SAFE_FREE((void**)&lvi.pszText); - lvi.cchTextMax += 64; - lvi.pszText = (char*)malloc(lvi.cchTextMax); - } - return lvi.pszText; -} - - -static void EnableGroupCombo(HWND hwndDlg) -{ - EnableDlgItem(hwndDlg, IDC_GROUPS, SendMessageT(GetDlgItem(hwndDlg, IDC_ENABLEGROUPS), BM_GETCHECK, 0, 0)); -} - - -static void RebuildGroupCombo(HWND hwndDlg) -{ - DBVARIANT dbv = {0}; - char caGroupId[33]; - int bHasGroups = !DBGetContactSettingT(NULL, "CListGroups", "0", &dbv); - HWND hGroupsCombo = GetDlgItem(hwndDlg, IDC_GROUPS); - - DBFreeVariant(&dbv); - if (bHasGroups) - { - int curs = SendMessageT(hGroupsCombo, CB_GETCURSEL, 0, 0); - TCHAR* curst; - - EnableDlgItem(hwndDlg, IDC_ENABLEGROUPS, TRUE); - EnableGroupCombo(hwndDlg); - - if (curs != CB_ERR) - { - curst = (char*)_alloca((SendMessageT(hGroupsCombo, CB_GETLBTEXTLEN, curs, 0) + 1) * sizeof(WCHAR)); - SendMessageT(hGroupsCombo, CB_GETLBTEXT, curs, (LPARAM)curst); - } - SendMessageT(hGroupsCombo, CB_RESETCONTENT, 0, 0); - - for (int groupId=0; ; groupId++) - { - itoa(groupId, caGroupId, 10); - TCHAR* szGroup = DBGetContactSettingStringT(NULL, "CListGroups", caGroupId, NULL); - int nPrefix = g_UnicodeCore ? sizeof(WCHAR) : sizeof(char); - if (!szGroup) break; - int nIndex = SendMessageT(hGroupsCombo, CB_ADDSTRING, 0, (LPARAM)szGroup + nPrefix); - SendMessageT(hGroupsCombo, CB_SETITEMDATA, nIndex, groupId+1); - SAFE_FREE((void**)&szGroup); - } - if (curs != CB_ERR) - SendMessageT(hGroupsCombo, CB_SELECTSTRING, -1, (LPARAM)curst); - else - SendMessageT(hGroupsCombo, CB_SETCURSEL, 0, 0); - } - else - { // no groups available - EnableDlgItem(hwndDlg, IDC_ENABLEGROUPS, FALSE); - EnableDlgItem(hwndDlg, IDC_GROUPS, FALSE); - } -} - - -static HANDLE CreateTemporaryContactForItem(HWND hwndDlg, TRecvContactsData* wndData, int iItem) -{ - char* caUIN = ListView_GetItemTextEx(GetDlgItem(hwndDlg, IDC_CONTACTS), iItem, 0); - char* szProto = GetContactProto(wndData->mhContact); - wndData->rhSearch = (HANDLE)CallProtoService(szProto, PS_BASICSEARCH, 0, (LPARAM)caUIN); // find it - SAFE_FREE((void**)&wndData->haUin); - wndData->haUin = caUIN; - for (int j = 0; j < wndData->cbReceived; j++) - if (!strcmpnull(wndData->maReceived[j]->mcaUIN, caUIN)) - return (HANDLE)CallProtoService(szProto, PS_ADDTOLISTBYEVENT, MAKEWPARAM(PALF_TEMPORARY, j), (LPARAM)wndData->mhDbEvent); - return NULL; -} - - -void RecvListView_AddColumn(HWND hList, int nWidth, const char* szTitle, int nTranslate, int nItem) { - LVCOLUMN col; - WCHAR tmp[MAX_PATH]; - - - col.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; - col.fmt = LVCFMT_LEFT; - col.cx = nWidth; - if (nTranslate) { - col.pszText = SRCTranslateT(szTitle, tmp); - } - else { - if (!szTitle) szTitle = "UID"; - col.pszText = ansi_to_tchar(szTitle, CallService(MS_LANGPACK_GETCODEPAGE, 0, 0)); - } - col.iSubItem = nItem; - ListView_InsertColumnT(hList, nItem, &col); - if (!nTranslate) - SAFE_FREE((void**)&col.pszText); -} - - -INT_PTR CALLBACK RecvDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TRecvContactsData* wndData = (TRecvContactsData*)GetWindowLongPtr(hwndDlg, DWLP_USER); - - switch (msg) - { - case WM_INITDIALOG: - { - CLISTEVENT* pcle = (CLISTEVENT*)lParam; /// got it - - TranslateDialogDefault(hwndDlg); - WindowList_Add(ghRecvWindowList, hwndDlg, pcle->hContact); - SendMessageT(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); - EnableDlgItem(hwndDlg, IDOK, FALSE); - EnableDlgItem(hwndDlg, IDDETAILS, FALSE); - wndData = new TRecvContactsData(pcle->hContact); - SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)wndData); - wndData->mhDbEvent = pcle->hDbEvent; /// initialized, pcle not needed anymore - wndData->mhListIcon = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLORDDB|ILC_MASK, 0, 1); - wndData->mhPopup = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTACTMENU)); - TranslateMenu(wndData->mhPopup); - wndData->hHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_EVENTSENT); - - char *szProto = GetContactProto(wndData->mhContact); - - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); - ListView_SetExtendedListViewStyle(hLV, LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT); - // add columns - RecvListView_AddColumn(hLV, 120, (char*)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDTEXT, 0), FALSE, 0); - RecvListView_AddColumn(hLV, 100, "Nick", TRUE, 1); - RecvListView_AddColumn(hLV, 100, "First Name", TRUE, 2); - RecvListView_AddColumn(hLV, 100, "Last Name", TRUE, 3); - - // fill in groups - SendMessageT(GetDlgItem(hwndDlg, IDC_ENABLEGROUPS), BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); - RebuildGroupCombo(hwndDlg); - - { // fill listview with received contacts - DBEVENTINFO dbe = {0}; - - dbe.cbSize = sizeof(DBEVENTINFO); - dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)wndData->mhDbEvent, 0); - if (dbe.cbBlob != -1) // this marks an invalid hDbEvent - all smashed anyway... - dbe.pBlob = (PBYTE)_alloca(dbe.cbBlob); - CallService(MS_DB_EVENT_GET, (WPARAM)wndData->mhDbEvent, (LPARAM)&dbe); - char* pcBlob = (char*)dbe.pBlob; - char* pcEnd = (char*)dbe.pBlob + dbe.cbBlob; - - HICON hiProto = LoadContactProtoIcon(wndData->mhContact); - ImageList_AddIcon(wndData->mhListIcon, hiProto); - DestroyIcon(hiProto); // imagelist copied the resource - ListView_SetImageList(hLV, wndData->mhListIcon, LVSIL_SMALL); - LVITEM lvi = {0}; - lvi.iImage = 0; - lvi.mask = LVIF_TEXT | LVIF_IMAGE; - - for (int nItem = 0; ; nItem++) - { // Nick - int strsize = (int)strlennull(pcBlob); - TReceivedItem* pItem = wndData->AddReceivedItem(); - - if (dbe.flags & DBEF_UTF) - pItem->mcaNick = utf8_to_tchar((unsigned char*)pcBlob); - else - pItem->mcaNick = ansi_to_tchar(pcBlob); - pcBlob += strsize + 1; - // UIN - strsize = (int)strlennull(pcBlob); - pItem->mcaUIN = null_strdup(pcBlob); - pcBlob += strsize + 1; - // add to listview - lvi.iItem = nItem; - lvi.pszText = pItem->mcaUIN; - ListView_InsertItem(hLV, &lvi); // with image - ListView_SetItemTextT(hLV, nItem, 1, pItem->mcaNick); - // check for end of contacts - if (pcBlob >= pcEnd) - break; - } - } - // new dlg init - wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), "Add Contact Permanently to List"); - wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), "View User's Details"); - wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), "View User's History"); - wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), "User Menu"); - - SendMessageT(hwndDlg,DM_UPDATETITLE,0,0); - // new dialog init done - Utils_RestoreWindowPosition(hwndDlg, NULL, MODULENAME, ""); - return TRUE; - } - case WM_NOTIFY: - if (((LPNMHDR)lParam)->idFrom == IDC_CONTACTS) - { - switch (((LPNMHDR)lParam)->code) - { - case NM_DBLCLK: - { - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); - if (ListView_GetSelectedCount(hLV) != 1) break; // if not clicking on item, bye - wndData->iPopupItem = ListView_GetNextItem(hLV, -1, LVNI_ALL|LVNI_SELECTED); - if (wndData->iPopupItem == -1) break; // if no item selected no user details available - return SendMessageT(hwndDlg, WM_COMMAND, ID_POPUP_USERDETAILS, 0); // show user details - } - case LVN_ITEMCHANGED: - { - LPNMLISTVIEW pNMLV = (LPNMLISTVIEW)lParam; - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); // optimisation, for FOR-Cycle - bool bExistsCheckedItem = false; // there must be no checked items to disable "Add" button - - if (ListView_GetCheckState(hLV, pNMLV->iItem)) - { // the user has checked this item - bExistsCheckedItem = true; // enable "Add" button - } - else - { // loop thru items and check if at least one is checked - for (int i = 0; i < ListView_GetItemCount(hLV); i++) - if (ListView_GetCheckState(hLV, i)) - { // we found checked item, enable add, exit loop - bExistsCheckedItem = true; - break; - } - } - EnableDlgItem(hwndDlg, IDOK, bExistsCheckedItem); - EnableDlgItem(hwndDlg, IDDETAILS, ListView_GetSelectedCount(hLV) > 0); - break; - } - } - } - break; - - case WM_COMMAND: - { - if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->mhContact)) - break; - - switch(LOWORD(wParam)) - { - case IDOK: // "Add Selected" button click - { // for each selected item, find its index in the hDbEvent - // and after that add this item to the DB permanently - char* caUIN; - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); - HWND hGroupsCombo = GetDlgItem(hwndDlg, IDC_GROUPS); - HWND hGroupsCheck = GetDlgItem(hwndDlg, IDC_ENABLEGROUPS); - int curs = SendMessageT(hGroupsCombo, CB_GETCURSEL, 0, 0); - TCHAR* caGroup = NULL; - int nGroupId = -1; - if (curs != CB_ERR && IsWindowEnabled(hGroupsCheck) && SendMessageT(hGroupsCheck, BM_GETCHECK, 0, 0)) - { //got groups, get the one selected in combo - TCHAR* caGroup = (TCHAR*)_alloca((SendMessageT(hGroupsCombo, CB_GETLBTEXTLEN, curs, 0) + 1) * sizeof(WCHAR)); - SendMessageT(hGroupsCombo, CB_GETLBTEXT, curs, (LPARAM)caGroup); - nGroupId = SendMessageT(hGroupsCombo, CB_GETITEMDATA, curs, 0); - } - - for (int i = 0; i < ListView_GetItemCount(hLV); i++) - if (ListView_GetCheckState(hLV, i)) - { // found checked contact item, add it - caUIN = ListView_GetItemTextEx(hLV, i, 0); - for (int j = 0; j < wndData->cbReceived; j++) // determine item index in packet - if (!strcmpnull(wndData->maReceived[j]->mcaUIN, caUIN)) - { - char* szProto = GetContactProto(wndData->mhContact); - HANDLE hContact = (HANDLE)CallProtoService(szProto, PS_ADDTOLISTBYEVENT, MAKEWPARAM(0, j), (LPARAM)wndData->mhDbEvent); - if (hContact && caGroup) - { // use newest group API if available - if (ServiceExists(MS_CLIST_CONTACTCHANGEGROUP)) - CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)hContact, (LPARAM)nGroupId); - else - DBWriteContactSettingStringT(hContact, "CList", "Group", caGroup); - } - break; - } - SAFE_FREE((void**)&caUIN); - } // move to next item - break; - } - case IDDETAILS: - { // for each selected item, find its index in the hDbEvent - // and after that add this item to the DB - // finally, request Details window for this hContact - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); - for (int i = 0; i < ListView_GetItemCount(hLV); i++) - if (ListView_GetItemState(hLV, i, LVIS_SELECTED)) - { - HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, i); - if (hContact) - CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0); - } - break; - } - case IDCANCEL: - { - SendMessageT(hwndDlg, WM_CLOSE, 0, 0); - break; - } - case IDC_ENABLEGROUPS: - { - EnableGroupCombo(hwndDlg); - break; - } - case IDC_GROUPS: - { // rebuild group list on popup - if (HIWORD(wParam) == CBN_DROPDOWN) - RebuildGroupCombo(hwndDlg); - break; - } - case ID_POPUP_ADDUSER: - { - HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); - - if (hContact) - DialogAddContactExecute(hwndDlg, hContact); - break; - } - case ID_POPUP_USERDETAILS: - { - HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); - - if (hContact) - CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0 ); - break; - } - case ID_POPUP_SENDMESSAGE: - { - HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); - - if (hContact) - CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0); - break; - } - case IDC_USERMENU: - { - RECT rc; - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)wndData->mhContact, 0); - GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU), &rc); - TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); - DestroyMenu(hMenu); - break; - } - case IDC_HISTORY: - CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->mhContact,0); - break; - case IDC_DETAILS: - CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->mhContact,0); - break; - case IDC_ADD: - DialogAddContactExecute(hwndDlg, wndData->mhContact); - break; - } - break; - } - case WM_CONTEXTMENU: - { - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); - LVHITTESTINFO lvh; - RECT rt; - - wndData->iPopupItem = -1; - if ((HWND)wParam != hLV) break; // if not our ListView go away - lvh.pt.x = LOWORD(lParam); - lvh.pt.y = HIWORD(lParam); - if (GetWindowRect(hLV, &rt)==0) return FALSE; // ?? why this, some check ?? - ScreenToClient(hLV, &lvh.pt); // convert to ListView local coordinates - int ci = ListView_HitTest(hLV, &lvh); - if (ci==-1) break; // mouse is not over any item - wndData->iPopupItem = ci; - TrackPopupMenu(GetSubMenu(wndData->mhPopup, 0), TPM_LEFTALIGN|TPM_TOPALIGN, LOWORD(lParam), HIWORD(lParam), 0, hwndDlg, NULL); - break; - } - case HM_EVENTSENT: - { - ACKDATA *ack=(ACKDATA*)lParam; - if (ack->type!=ACKTYPE_SEARCH) break; // not search ack, go away - if (ack->hProcess!=wndData->rhSearch) break; //not our search, go away - if (ack->result==ACKRESULT_DATA) - { - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); - PROTOSEARCHRESULT* psr = (PROTOSEARCHRESULT*)ack->lParam; - LVFINDINFO fi; - fi.flags = LVFI_STRING; - fi.psz = wndData->haUin; - int iLPos = ListView_FindItem(hLV, -1, &fi); - if (iLPos==-1) iLPos=0; -// ListView_SetItemText(hLV, iLPos, 0, psr->email); // not sent by ICQ, and currently unsupported either - if (strcmpnull(psr->nick, "") && psr->nick) ListView_SetItemText(hLV, iLPos, 1, psr->nick); - ListView_SetItemText(hLV, iLPos, 2, psr->firstName); - ListView_SetItemText(hLV, iLPos, 3, psr->lastName); - break; - } - SAFE_FREE((void**)&wndData->haUin); - break; - } - case WM_CLOSE: // user closed window, so destroy it - { - WindowList_Remove(ghRecvWindowList, hwndDlg); - DestroyWindow(hwndDlg); - break; - } - case WM_DESTROY: // last message received by this dialog, cleanup - { - CallService(MS_DB_EVENT_MARKREAD, (WPARAM)wndData->mhContact, (LPARAM)wndData->mhDbEvent); - Utils_SaveWindowPosition(hwndDlg, NULL, MODULENAME, ""); - ImageList_Destroy(wndData->mhListIcon); - UnhookEvent(wndData->hHook); - DestroyMenu(wndData->mhPopup); - for (int i=0; i < SIZEOF(wndData->hIcons); i++) - DestroyIcon(wndData->hIcons[i]); - delete wndData; // automatically calls destructor - break; - } - case WM_MEASUREITEM: - return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); - - case WM_DRAWITEM: - { - DrawProtocolIcon(hwndDlg, lParam, wndData->mhContact); - return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); - } - case WM_SIZE: - { // make the dlg resizeable - UTILRESIZEDIALOG urd = {0}; - - if (IsIconic(hwndDlg)) break; - urd.cbSize = sizeof(urd); - urd.hInstance = hInst; - urd.hwndDlg = hwndDlg; - urd.lParam = 0; // user-defined - urd.lpTemplate = MAKEINTRESOURCEA(IDD_RECEIVE); - urd.pfnResizer = RecvDlg_Resize; - CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM) & urd); - break; - } - case WM_GETMINMAXINFO: - { - MINMAXINFO* mmi=(MINMAXINFO*)lParam; - mmi->ptMinTrackSize.x = 480+2*GetSystemMetrics(SM_CXSIZEFRAME); - mmi->ptMinTrackSize.y = 130+2*GetSystemMetrics(SM_CYSIZEFRAME); - break; - } - case DM_UPDATETITLE: - { - UpdateDialogTitle(hwndDlg, wndData?wndData->mhContact:NULL, "Contacts from"); - if (wndData) - UpdateDialogAddButton(hwndDlg, wndData->mhContact); - break; - } - } - return FALSE; -} diff --git a/plugins/ContactsPlus/receive.h b/plugins/ContactsPlus/receive.h deleted file mode 100644 index fe35d94be6..0000000000 --- a/plugins/ContactsPlus/receive.h +++ /dev/null @@ -1,65 +0,0 @@ -// --------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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. -// -// --------------------------------------------------------------------------- - -#ifndef __RECEIVE_H -#define __RECEIVE_H - - -#define HM_EVENTSENT (WM_USER+10) - -#define DM_UPDATETITLE (WM_USER+11) - -#define IDI_ADDCONTACT 210 -#define IDI_USERDETAILS 160 -#define IDI_HISTORY 174 -#define IDI_DOWNARROW 264 - -struct TReceivedItem { - char* mcaUIN; - TCHAR* mcaNick; - ~TReceivedItem() { SAFE_FREE((void**)&mcaUIN); SAFE_FREE((void**)&mcaNick); } - TReceivedItem() { mcaUIN = NULL; mcaNick = NULL; } -}; - -struct TRecvContactsData { - HANDLE mhDbEvent; // handle to recv DB event - HANDLE mhContact; // from whom we received this - HIMAGELIST mhListIcon;// icons for listview - HMENU mhPopup; // popup menu for listview - HANDLE hHook; // hook to event - HANDLE rhSearch; // handle to uin-search - char* haUin; - int iPopupItem; - TReceivedItem** maReceived;// received contacts - int cbReceived; - TReceivedItem* AddReceivedItem(); - HICON hIcons[4]; // icons for dialog - TRecvContactsData(HANDLE contact) { mhContact = contact; hHook = NULL; cbReceived = 0; maReceived = NULL; haUin = NULL; }; - ~TRecvContactsData() { if (cbReceived) { for(int i=0;inContacts = nContacts; - ackData->aContacts = (HANDLE*)malloc(nContacts*sizeof(HANDLE)); - memmove(ackData->aContacts, phContacts, nContacts*sizeof(HANDLE)); // copy the array of hContact for ack array - EnableDlgItem(hwndDlg, IDOK, FALSE); - EnableDlgItem(hwndDlg, IDC_LIST, FALSE); - - return TRUE; // Success -} - - -int TSendContactsData::SendContacts(HWND hwndDlg) { - char* szProto = GetContactProto(hContact); - int nMaxContacts = CallProtoService(szProto, PS_GETCAPS, PFLAG_MAXCONTACTSPERPACKET, (LPARAM)hContact); - - if (!nMaxContacts) { - ShowErrorDlg(hwndDlg, "The selected contact does not support receiving contacts.", FALSE); - return FALSE; - } - // hook event - we want to receive protocol acknowledgements - HookProtoAck(hwndDlg); - - for (int j = 0; j < nContacts / nMaxContacts; j++ ) - { // send in packets, each of nMaxContacts contacts - if (!SendContactsPacket(hwndDlg, aContacts + j*nMaxContacts, nMaxContacts)) - return FALSE; - } - if (nContacts%nMaxContacts!=0) - { - if (!SendContactsPacket(hwndDlg, aContacts + nContacts/nMaxContacts*nMaxContacts, nContacts%nMaxContacts)) - return FALSE; - } - return TRUE; -} - - -/* Send Dialog Implementation */ - -static void ResetListOptions(HWND hwndList) -{ - COLORREF bgColour,fgColour; - - SendMessageT(hwndList,CLM_SETBKBITMAP,0,(LPARAM)(HBITMAP)NULL); - bgColour=GetSysColor(COLOR_WINDOW); - SendMessageT(hwndList,CLM_SETBKCOLOR,bgColour,0); - SendMessageT(hwndList,CLM_SETGREYOUTFLAGS,0,0); - SendMessageT(hwndList,CLM_SETLEFTMARGIN,4,0); - SendMessageT(hwndList,CLM_SETINDENT,10,0); - for(int i=0; i<=FONTID_MAX; i++) - { - fgColour=(COLORREF)SendMessageT(hwndList,CLM_GETTEXTCOLOR,i,0); - if(abs(GetRValue(fgColour)-GetRValue(bgColour))<10 && - abs(GetGValue(fgColour)-GetGValue(bgColour))<10 && - abs(GetBValue(fgColour)-GetBValue(bgColour))<10) - SendMessageT(hwndList,CLM_SETTEXTCOLOR,i,GetSysColor(COLOR_WINDOWTEXT)); - } -} - - -static HANDLE FindNextClistContact(HWND hList, HANDLE hContact, HANDLE *phItem) -{ - HANDLE hNextContact = SRCFindNextContact(hContact); - HANDLE hNextItem = NULL; - - while (hNextContact && !(hNextItem = (HANDLE)SendMessageT(hList, CLM_FINDCONTACT, (WPARAM)hNextContact,0))) - hNextContact = SRCFindNextContact(hNextContact); - - if (phItem) - *phItem = hNextItem; - - return hNextContact; -} - - -static HANDLE FindFirstClistContact(HWND hList, HANDLE *phItem) -{ - HANDLE hContact = SRCFindFirstContact(); - HANDLE hItem = (HANDLE)SendMessageT(hList, CLM_FINDCONTACT, (WPARAM)hContact, 0); - - if (hContact && !hItem) - return FindNextClistContact(hList, hContact, phItem); - - if (phItem) - *phItem = hItem; - - return hContact; -} - - -bool binListEvent = FALSE; - -static void SetAllContactChecks(HWND hwndList, HANDLE hReceiver) // doubtful name -{ - HANDLE hContact, hItem; - - if (binListEvent) return; - binListEvent = TRUE; - char* szProto = GetContactProto(hReceiver); - if (szProto == NULL) return; - - if (CallService(MS_CLUI_GETCAPS, 0, 0) & CLUIF_HIDEEMPTYGROUPS && DBGetContactSettingByte(NULL, "CList", "HideEmptyGroups", SETTING_USEGROUPS_DEFAULT)) - SendMessageT(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM) TRUE, 0); - else - SendMessageT(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM) FALSE, 0); - - hContact = FindFirstClistContact(hwndList, &hItem); - while (hContact) - { - char* szProto2 = GetContactProto(hContact); - - if (strcmpnull(szProto, szProto2)) - { // different protocols or protocol undefined, remove contact, useless anyway - SendMessageT(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0); - } - else // otherwise uncheck - SendMessageT(hwndList, CLM_SETCHECKMARK,(WPARAM)hItem, 0); - - hContact = FindNextClistContact(hwndList, hContact, &hItem); - } - - binListEvent = FALSE; -} - - -INT_PTR CALLBACK SendDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TSendContactsData* wndData = (TSendContactsData*)GetWindowLongPtr(hwndDlg, DWLP_USER); - - switch (msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - SendMessageT(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); - ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST)); - SetAllContactChecks(GetDlgItem(hwndDlg,IDC_LIST), (HANDLE)lParam); - WindowList_Add(ghSendWindowList, hwndDlg, (HANDLE)lParam); - wndData = new TSendContactsData((HANDLE)lParam); - SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)wndData); - // new dlg init - wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), "Add Contact Permanently to List"); - wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), "View User's Details"); - wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), "View User's History"); - wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), "User Menu"); - - SendMessageT(hwndDlg,DM_UPDATETITLE,0,0); - // new dialog init done - return TRUE; - } - - case WM_SETFOCUS: - SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->idFrom == IDC_LIST) - { - switch (((LPNMHDR)lParam)->code) - { - case CLN_NEWCONTACT: - case CLN_LISTREBUILT: // rebuild list - if (wndData) SetAllContactChecks(GetDlgItem(hwndDlg,IDC_LIST), wndData->hContact); - case CLN_OPTIONSCHANGED: - ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST)); - break; - } - } - break; - - case WM_TIMER: - if (wParam == TIMERID_MSGSEND) - { - if (!g_SendAckSupported) - { // old Miranda has this ack unimplemented, we need to send it by ourselves - ACKDATA ack = {0}; - - ack.cbSize = sizeof(ACKDATA); - ack.type = ACKTYPE_CONTACTS; - ack.result = ACKRESULT_SUCCESS; - ack.hContact = wndData->hContact; - while (wndData->uacklist.Count) - { // the uack gets empty after processing all messages :) - ack.hProcess = wndData->uacklist.Items[0]; - SendMessageT(hwndDlg, HM_EVENTSENT, NULL, (WPARAM)&ack); // this removes the ack from our array - } - break; - } - KillTimer(hwndDlg,wParam); - wndData->ShowErrorDlg(hwndDlg, "The contacts send timed out.", TRUE); - } - break; - - case DM_ERRORDECIDED: - { - EnableWindow(hwndDlg,TRUE); - wndData->hError = NULL; - switch(wParam) - { - case MSGERROR_CANCEL: - { - wndData->UnhookProtoAck(); - if (wndData->uacklist.Count) - { - for (int i=0; iuacklist.Count; i++) - { - delete gaAckData.Remove(wndData->uacklist.Items[i]); // remove our ackdata & release structure - } - SAFE_FREE((void**)&wndData->uacklist.Items); - wndData->uacklist.Count = 0; - } - EnableDlgItem(hwndDlg,IDOK,TRUE); - EnableDlgItem(hwndDlg,IDC_LIST,TRUE); - ShowWindow(hwndDlg,SW_SHOWNORMAL); - SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); - break; - } - case MSGERROR_DONE: - // contacts were delivered succesfully after timeout - SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); - wndData->UnhookProtoAck(); - break; - - case MSGERROR_RETRY:// resend timeouted packets - - for (int i=0; iuacklist.Count; i++) - { - TAckData* lla = gaAckData.Remove(wndData->uacklist.Items[i]); - HANDLE hProcc = (HANDLE)CallContactService(wndData->hContact, PSS_CONTACTS, MAKEWPARAM(0, lla->nContacts), (LPARAM)lla->aContacts); - - if (!hProcc) // if fatal do not include - { - wndData->uacklist.Remove(wndData->uacklist.Items[i]); - delete lla; // release the structure - continue; - } - else - { // update process code - wndData->uacklist.Items[i] = hProcc; - gaAckData.Add(hProcc, lla); - } - }// collect TAckData for our window, resend - break; - } - break; - } - - case WM_COMMAND: - { - if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->hContact)) - break; - - switch(LOWORD(wParam)) - { - case IDOK: - { - if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDOK))) break; - HANDLE hContact, hItem; - wndData->ClearContacts(); // do not include contacts twice - - HWND hList = GetDlgItem(hwndDlg, IDC_LIST); - hContact = FindFirstClistContact(hList, &hItem); - while (hContact) - { - if (SendMessageT(hList, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) - { // build list of contacts to send - wndData->AddContact(hContact); - } - hContact = FindNextClistContact(hList, hContact, &hItem); - } - /* send contacts */ - if (!wndData->SendContacts(hwndDlg)) - break; - - if (g_SendAckSupported) - SetTimer(hwndDlg,TIMERID_MSGSEND,DBGetContactSettingDword(NULL,"SRMsg","MessageTimeout",TIMEOUT_MSGSEND),NULL); - else - SetTimer(hwndDlg,TIMERID_MSGSEND,1000,NULL); // wait one second - if no error occures - - break; - } - case IDCANCEL: - { - DestroyWindow(hwndDlg); - break; - } - case ID_SELECTALL: - { // select all contacts - HANDLE hContact, hItem; - HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST); - - hContact = FindFirstClistContact(hwndList, &hItem); - while (hContact) { - SendMessageT(hwndList,CLM_SETCHECKMARK,(WPARAM)hItem, 1); - hContact = FindNextClistContact(hwndList, hContact, &hItem); - }; - break; - } - case IDC_USERMENU: - { - RECT rc; - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)wndData->hContact,0); - - GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU),&rc); - TrackPopupMenu(hMenu,0,rc.left,rc.bottom,0,hwndDlg,NULL); - DestroyMenu(hMenu); - break; - } - case IDC_HISTORY: - CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->hContact,0); - break; - - case IDC_DETAILS: - CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->hContact,0); - break; - - case IDC_ADD: - DialogAddContactExecute(hwndDlg, wndData->hContact); - break; - } - break; - } - case HM_EVENTSENT: - { - ACKDATA *ack=(ACKDATA*)lParam; - DBEVENTINFO dbei={0}; - - if (ack->type != ACKTYPE_CONTACTS) break; - - TAckData* ackData = gaAckData.Get(ack->hProcess); - - if (ackData == NULL) break; // on unknown hprocc go away - - if (ackData->hContact != ack->hContact) break; // this is not ours, strange - - if (ack->result == ACKRESULT_FAILED) - { // some process failed, show error dialog - KillTimer(hwndDlg, TIMERID_MSGSEND); - wndData->ShowErrorDlg(hwndDlg, (char *)ack->lParam, TRUE); - // ackData get used in error handling, released there - break; - } - - dbei.cbSize = sizeof(dbei); - dbei.szModule = GetContactProto(ackData->hContact); - dbei.eventType = EVENTTYPE_CONTACTS; - dbei.flags = DBEF_SENT; - if (g_UnicodeCore && g_Utf8EventsSupported) - dbei.flags |= DBEF_UTF; - dbei.timestamp = time(NULL); - //make blob - TCTSend* maSend = (TCTSend*)_alloca(ackData->nContacts*sizeof(TCTSend)); - ZeroMemory(maSend, ackData->nContacts*sizeof(TCTSend)); - dbei.cbBlob=0; - char* pBlob; - int i; - for (i=0; inContacts; i++) - { // prepare data & count size - if (g_UnicodeCore && g_Utf8EventsSupported) - maSend[i].mcaNick = make_utf8_string((WCHAR*)GetContactDisplayNameT(ackData->aContacts[i])); - else - maSend[i].mcaNick = (unsigned char*)null_strdup((char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ackData->aContacts[i], 0)); - maSend[i].mcaUIN = GetContactUID(ackData->aContacts[i], FALSE); - dbei.cbBlob += (DWORD)strlennull(maSend[i].mcaUIN) + (DWORD)strlennull((char*)maSend[i].mcaNick) + 2; - } - dbei.pBlob = (PBYTE)_alloca(dbei.cbBlob); - for (i=0, pBlob=(char*)dbei.pBlob; i < ackData->nContacts; i++) - { - strcpy(pBlob, (char*)maSend[i].mcaNick); - pBlob += strlennull(pBlob) + 1; - strcpy(pBlob, maSend[i].mcaUIN); - pBlob += strlennull(pBlob) + 1; - } - CallService(MS_DB_EVENT_ADD, (WPARAM)ackData->hContact,(LPARAM)&dbei); - gaAckData.Remove(ack->hProcess); // do not release here, still needed - wndData->uacklist.Remove(ack->hProcess); // packet confirmed - for (i=0; inContacts; i++) - { - SAFE_FREE((void**)&maSend[i].mcaUIN); - SAFE_FREE((void**)&maSend[i].mcaNick); - } - delete ackData; // all done, release structure - if (!wndData->uacklist.Count) - { - SkinPlaySound("SentContacts"); - KillTimer(hwndDlg, TIMERID_MSGSEND); - - if (wndData->hError) - SendMessageT(wndData->hError, DM_ERRORDECIDED, MSGERROR_DONE, 0); - - SendMessageT(hwndDlg, WM_CLOSE, 0, 0); // all packets confirmed, close the dialog - } - break; - } - - case WM_CLOSE: - { - wndData->UnhookProtoAck(); - DestroyWindow(hwndDlg); - break; - } - case WM_DESTROY: - { - int i; - for (i = 0; i < SIZEOF(wndData->hIcons); i++) - DestroyIcon(wndData->hIcons[i]); - WindowList_Remove(ghSendWindowList, hwndDlg); - delete wndData; - break; - } - case WM_MEASUREITEM: - return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam); - - case WM_DRAWITEM: - { - DrawProtocolIcon(hwndDlg, lParam, wndData->hContact); - return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam); - } - case DM_UPDATETITLE: - { - UpdateDialogTitle(hwndDlg, wndData?wndData->hContact:NULL, "Send Contacts to"); - if (wndData) - UpdateDialogAddButton(hwndDlg, wndData->hContact); - break; - } - } - - return FALSE; -} - - -// Error Dialog - -INT_PTR CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_INITDIALOG: - { - RECT rc, rcParent; - - TranslateDialogDefault(hwndDlg); - - if (lParam) - { - WCHAR tmp[MAX_PATH]; - - SetDlgItemTextT(hwndDlg, IDC_ERRORTEXT, SRCTranslateT((char*)lParam, tmp)); - } - GetWindowRect(hwndDlg, &rc); - GetWindowRect(GetParent(hwndDlg), &rcParent); - SetWindowPos(hwndDlg, 0, - (rcParent.left+rcParent.right-(rc.right-rc.left))/2, - (rcParent.top+rcParent.bottom-(rc.bottom-rc.top))/2, - 0, 0, SWP_NOZORDER|SWP_NOSIZE); - } - return TRUE; - - case WM_COMMAND: - switch(LOWORD(wParam)) - { - case IDOK: - SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_RETRY, 0); - DestroyWindow(hwndDlg); - break; - - case IDCANCEL: - SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_CANCEL, 0); - DestroyWindow(hwndDlg); - break; - } - break; - case DM_ERRORDECIDED: - if (wParam!=MSGERROR_DONE) break; - SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_DONE, 0); - DestroyWindow(hwndDlg); - break; - } - - return FALSE; -} diff --git a/plugins/ContactsPlus/send.h b/plugins/ContactsPlus/send.h deleted file mode 100644 index c8580a4eb1..0000000000 --- a/plugins/ContactsPlus/send.h +++ /dev/null @@ -1,110 +0,0 @@ -// --------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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. -// -// --------------------------------------------------------------------------- - -#ifndef __SEND_H -#define __SEND_H - - -#define TIMERID_MSGSEND 1024 -#define TIMEOUT_MSGSEND 9000 //ms -#define HM_EVENTSENT (WM_USER+10) -#define DM_ERRORDECIDED (WM_USER+18) -#define DM_UPDATETITLE (WM_USER+11) -#define MSGERROR_CANCEL 0 -#define MSGERROR_RETRY 1 -#define MSGERROR_DONE 2 - -#define IDI_ADDCONTACT 210 -#define IDI_USERDETAILS 160 -#define IDI_HISTORY 174 -#define IDI_DOWNARROW 264 - -struct TSendProcessList { - int Count; - HANDLE* Items; - CRITICAL_SECTION lock; - void Add(HANDLE hProcc); - void Remove(HANDLE hProcc); - TSendProcessList(); - ~TSendProcessList(); -}; - -struct TSendContactsData { // hope uack is released automaticly, static property - HANDLE hHook; // hook to event - void HookProtoAck(HWND hwndDlg); - void UnhookProtoAck(); - HANDLE* aContacts; // contacts to be sent - int nContacts; // now many UIDs shall we send? - void ClearContacts(); - void AddContact(HANDLE hContact); - HANDLE hContact; // to whom shall we send? - TSendProcessList uacklist;// ackdata - necessary for errorbox - HWND hError; // handle of error box, if any - void ShowErrorDlg(HWND hwndDlg, char* szMsg, bool bAllowRetry); - int SendContactsPacket(HWND hwndDlg, HANDLE *phContacts, int nContacts); - int SendContacts(HWND hwndDlg); - HICON hIcons[4]; // icons for dialog - TSendContactsData(HANDLE contact); - ~TSendContactsData(); -}; - -struct TAckData { - HANDLE hContact; // to whom was it sent - HANDLE* aContacts; // obj - int nContacts; // how many - TAckData(HANDLE contact) { hContact = contact; aContacts = NULL; nContacts = 0;}; - ~TAckData() { if (nContacts) SAFE_FREE((void**)&aContacts); } -}; - -typedef TAckData* PAckData; - -struct TCTSend { - char* mcaUIN; - unsigned char* mcaNick; -}; - -struct gAckItem { // some shit here - HANDLE hProcc; - PAckData ackData; - gAckItem(HANDLE procC, PAckData aData) { ackData=aData; hProcc=procC; }; - ~gAckItem() { /*delete ackData;*/ }; -}; - -struct gAckList { - gAckItem** Items; - int Count; - TAckData* Get(HANDLE hProcc) { for (int i=0; ihProcc==hProcc) { return Items[i]->ackData; }; return NULL; }; - TAckData* Add(HANDLE hProcc, TAckData* ackData) { Items=(gAckItem**)realloc(Items, (Count+1)*sizeof(gAckItem*)); Items[Count]=new gAckItem(hProcc, ackData); Count++; return ackData; }; - TAckData* Remove(HANDLE hProcc) { for (int i=0; ihProcc==hProcc) { TAckData* data=Items[i]->ackData; delete Items[i]; memmove(Items+i, Items+i+1, (Count-i-1)*sizeof(gAckItem*)); Count--; return data; }; return NULL; }; - gAckList() { Count = 0; Items = NULL; } - ~gAckList() { if (Count) { for (int i=0; i +#include + +#include +#include +#include +#include +#include +#include +#include + +//!!this is fake - this plugin maintains backward compatibility internally +#define MIRANDA_VER 0x0A00 + +#include "newpluginapi.h" +#include "m_system.h" +#include "m_protocols.h" +#include "m_protosvc.h" +#include "m_database.h" +#include "m_utils.h" +#include "m_langpack.h" +#include "m_skin.h" +#include "m_clist.h" +#include "m_clc.h" +#include "m_clui.h" +#include "m_addcontact.h" +#include "m_history.h" +#include "m_userinfo.h" +#include "m_button.h" +#include "m_contacts.h" +#include "m_message.h" +#include "statusmodes.h" +#include "win2k.h" + +#include "resource.h" + +#include "utils.h" +#include "send.h" +#include "receive.h" + +#define MODULENAME "SendReceiveContacts" + + +#define MS_CONTACTS_SEND "ContactsTransfer/SendContacts" +#define MS_CONTACTS_RECEIVE "ContactsTransfer/ReceiveContacts" + +// Global Variables +extern int g_UnicodeCore; +extern int g_NewProtoAPI; +extern int g_SendAckSupported; +extern int g_Utf8EventsSupported; diff --git a/plugins/ContactsPlus/src/main.cpp b/plugins/ContactsPlus/src/main.cpp new file mode 100644 index 0000000000..da43554c29 --- /dev/null +++ b/plugins/ContactsPlus/src/main.cpp @@ -0,0 +1,317 @@ +// -------------------------------------------------------------------------- +// Contacts+ for Miranda Instant Messenger +// _______________________________________ +// +// Copyright © 2002 Dominus Procellarum +// Copyright © 2004-2008 Joe Kucera +// +// 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. +// +// ----------------------------------------------------------------------------- + +#include "contacts.h" + + +HINSTANCE hInst; + +int hLangpack; + +int g_NewProtoAPI = TRUE; + +int g_SendAckSupported = TRUE; +int g_Utf8EventsSupported = TRUE; + +HANDLE ghSendWindowList; +HANDLE ghRecvWindowList; +gAckList gaAckData; + +HANDLE hServiceSend; +HANDLE hServiceReceive; + +HANDLE hHookModulesLoaded = NULL; +HANDLE hHookDBEventAdded = NULL; +HANDLE hHookContactDeleted = NULL; +HANDLE hHookContactSettingChanged = NULL; +HANDLE hHookPreBuildContactMenu = NULL; + +HANDLE hContactMenuItem = NULL; + +int g_UnicodeCore; + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + "Send/Receive Contacts+", + PLUGIN_MAKE_VERSION(1,5,2,0), + "Allows you to send and receive contacts", + "Joe Kucera, Todor Totev", + "jokusoftware@miranda-im.org", + "(C) 2004-2008 Joe Kucera, Original Code (C) 2002 Dominus Procellarum", + "http://addons.miranda-im.org/details.php?action=viewfile&id=1253", + UNICODE_AWARE, + {0x0324785E, 0x74CE, 0x4600, {0xB7, 0x81, 0x85, 0x17, 0x73, 0xB3, 0xEF, 0xC5 } } // {0324785E-74CE-4600-B781-851773B3EFC5} +}; + + +static int HookDBEventAdded(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + HANDLE hDbEvent = (HANDLE)lParam; + //process the event + DBEVENTINFO dbe = {0}; + + dbe.cbSize = sizeof(DBEVENTINFO); + //get event details + CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe); + //check if we should process the event + if (dbe.flags & (DBEF_SENT|DBEF_READ) || dbe.eventType != EVENTTYPE_CONTACTS) return 0; + //get event contents + dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0); + if (dbe.cbBlob != -1) + dbe.pBlob = (PBYTE)_alloca(dbe.cbBlob); + CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe); + //play received sound + SkinPlaySound("RecvContacts"); + { //add event to the contact list + CLISTEVENT cle = {0}; + TCHAR caToolTip[128]; + + cle.cbSize = sizeof(cle); + cle.hContact = hContact; + cle.hDbEvent = hDbEvent; + cle.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS)); + cle.pszService = MS_CONTACTS_RECEIVE; + + WCHAR tmp[MAX_PATH]; + _snprintfT(caToolTip, 64, "%s %s", SRCTranslateT("Contacts received from", tmp), (TCHAR*)GetContactDisplayNameT(hContact)); + + cle.ptszTooltip = caToolTip; + if (g_UnicodeCore) + cle.flags |= CLEF_UNICODE; + CallService(MS_CLIST_ADDEVENT, 0, (LPARAM)&cle); + } + return 0; //continue processing by other hooks +} + + +static void ProcessUnreadEvents(void) +{ + DBEVENTINFO dbei = {0}; + HANDLE hDbEvent,hContact; + + dbei.cbSize = sizeof(dbei); + + hContact = SRCFindFirstContact(); + while (hContact) + { + hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDFIRSTUNREAD,(WPARAM)hContact,0); + + while (hDbEvent) + { + dbei.cbBlob=0; + CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei); + if (!(dbei.flags&(DBEF_SENT|DBEF_READ)) && dbei.eventType==EVENTTYPE_CONTACTS) + { //process the event + HookDBEventAdded((WPARAM)hContact, (LPARAM)hDbEvent); + } + hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0); + } + hContact = SRCFindNextContact(hContact); + } +} + + +static bool CheckContactsServiceSupport(const char* szProto) +{ + if (g_NewProtoAPI) + { // there is no way to determine if the service exists (only proto_interface call is supported by 0.8+) + if (CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_CONTACTSEND) + return true; + } + else + { // check the real send service (only 0.7.x and older) + char serstr[MAX_PATH+30]; + + strcpy(serstr, szProto); + strcat(serstr, PSS_CONTACTS); + if (ServiceExists(serstr)) + return true; + } + return false; +} + + +static int HookPreBuildContactMenu(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + char* szProto = GetContactProto(hContact); + int bVisible = FALSE; + + if (szProto && CheckContactsServiceSupport(szProto)) + { // known protocol, protocol supports contacts sending + // check the selected contact if it supports contacts receive + if (CallProtoService(szProto, PS_GETCAPS, PFLAG_MAXCONTACTSPERPACKET, (LPARAM)hContact)) + bVisible = TRUE; + } + + { // update contact menu item's visibility + CLISTMENUITEM mi = {0}; + + mi.cbSize = sizeof(mi); + if (bVisible) + mi.flags = CMIM_FLAGS; + else + mi.flags = CMIM_FLAGS | CMIF_HIDDEN; + + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hContactMenuItem, (LPARAM)&mi); + } + + return 0; +} + + +static int HookModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + char* modules[2] = {0}; + WCHAR tmp[MAX_PATH]; + + modules[0] = MODULENAME; + CallService("DBEditorpp/RegisterModule",(WPARAM)modules,(LPARAM)1); + + CLISTMENUITEM mi = {0}; + mi.cbSize = sizeof(mi); + mi.ptszName = SRCTranslateT("Contacts", tmp); + mi.position = -2000009990; //position in menu + mi.flags = CMIF_KEEPUNTRANSLATED; + if (g_UnicodeCore) + mi.flags |= CMIF_UNICODE; + mi.pszService = MS_CONTACTS_SEND; + mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS)); + hContactMenuItem = Menu_AddContactMenuItem(&mi); + + hHookPreBuildContactMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, HookPreBuildContactMenu); + + ghSendWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); // no need to destroy this + ghRecvWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); // no need to destroy this + + + ProcessUnreadEvents(); + return 0; +} + + +static int HookContactSettingChanged(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam; + char *szProto = GetContactProto((HANDLE)wParam); + + if (strcmpnull(cws->szModule,"CList") && strcmpnull(cws->szModule, szProto)) return 0; + + WindowList_Broadcast(ghSendWindowList,DM_UPDATETITLE,0,0); + WindowList_Broadcast(ghRecvWindowList,DM_UPDATETITLE,0,0); + + return 0; +} + + +static int HookContactDeleted(WPARAM wParam, LPARAM lParam) +{ // if our contact gets deleted close his window + HWND h = WindowList_Find(ghSendWindowList,(HANDLE)wParam); + + if (h) + { + SendMessageT(h,WM_CLOSE,0,0); + } + + while (h = WindowList_Find(ghRecvWindowList, (HANDLE)wParam)) + { // since we hack the window list - more windows for one contact, we need to close them all + SendMessageT(h, WM_CLOSE,0,0); + } + return 0; +} + + +static INT_PTR ServiceSendCommand(WPARAM wParam, LPARAM lParam) +{ + HWND hWnd; + //find window for hContact + hWnd = WindowList_Find(ghSendWindowList, (HANDLE)wParam); + + if (!hWnd) + CreateDialogParamT(hInst, MAKEINTRESOURCE(IDD_SEND), NULL, SendDlgProc, (LPARAM)(HANDLE)wParam); + else + { + SetForegroundWindow(hWnd); + SetFocus(hWnd); + } + return 0; +} + +static INT_PTR ServiceReceiveCommand(WPARAM wParam, LPARAM lParam) +{ + CLISTEVENT* pcle = (CLISTEVENT*)lParam; + + CreateDialogParamT(hInst, MAKEINTRESOURCE(IDD_RECEIVE), NULL, RecvDlgProc, (LPARAM)pcle); + + return 0; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_SRCONTACTS, MIID_LAST}; + +extern "C" __declspec(dllexport) int Load(void) +{ + mir_getLP(&pluginInfo); + InitCommonControls(); + InitI18N(); + + { // Are we running under unicode Miranda core ? + char szVer[MAX_PATH]; + + CallService(MS_SYSTEM_GETVERSIONTEXT, MAX_PATH, (LPARAM)szVer); + _strlwr(szVer); + g_UnicodeCore = (strstr(szVer, "unicode") != NULL); + } + //init hooks + hHookModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, HookModulesLoaded); + hHookDBEventAdded = HookEvent(ME_DB_EVENT_ADDED, HookDBEventAdded); + hHookContactDeleted = HookEvent(ME_DB_CONTACT_DELETED, HookContactDeleted); + hHookContactSettingChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, HookContactSettingChanged); + //create services + hServiceSend = CreateServiceFunction(MS_CONTACTS_SEND, ServiceSendCommand); + hServiceReceive = CreateServiceFunction(MS_CONTACTS_RECEIVE, ServiceReceiveCommand); + //define event sounds + SkinAddNewSound("RecvContacts", LPGEN("Incoming Contacts"), "contacts.wav"); + SkinAddNewSound("SentContacts", LPGEN("Outgoing Contacts"), "ocontacts.wav"); + + return 0; +} + +extern "C" __declspec(dllexport) int Unload(void) +{ + UnhookEvent(hHookModulesLoaded); + UnhookEvent(hHookDBEventAdded); + UnhookEvent(hHookContactDeleted); + UnhookEvent(hHookContactSettingChanged); + UnhookEvent(hHookPreBuildContactMenu); + + DestroyServiceFunction(hServiceSend); + DestroyServiceFunction(hServiceReceive); + + return 0; +} diff --git a/plugins/ContactsPlus/src/receive.cpp b/plugins/ContactsPlus/src/receive.cpp new file mode 100644 index 0000000000..3d3fb2f773 --- /dev/null +++ b/plugins/ContactsPlus/src/receive.cpp @@ -0,0 +1,522 @@ +// -------------------------------------------------------------------------- +// Contacts+ for Miranda Instant Messenger +// _______________________________________ +// +// Copyright © 2002 Dominus Procellarum +// Copyright © 2004-2008 Joe Kucera +// +// 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. +// +// ----------------------------------------------------------------------------- + +#include "contacts.h" + + +/* TRecvContactsData */ + +TReceivedItem* TRecvContactsData::AddReceivedItem() { + int iItem = cbReceived; + + cbReceived++; + maReceived = (TReceivedItem**)realloc(maReceived, cbReceived*sizeof(TReceivedItem*)); + maReceived[iItem] = new TReceivedItem(); + + return maReceived[iItem]; +} + + +static int RecvDlg_Resize(HWND hwndDlg,LPARAM lParam,UTILRESIZECONTROL *urc) +{ + switch (urc->wId) + { + case IDC_CONTACTS: + return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; + break; + case IDOK: + case IDDETAILS: + case IDC_ENABLEGROUPS: + case IDC_GROUPS: + return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; + break; + case IDC_ADD: + case IDC_HISTORY: + case IDC_USERMENU: + case IDC_DETAILS: + return RD_ANCHORX_RIGHT | RD_ANCHORY_TOP; + break; + case IDCANCEL: + return RD_ANCHORY_BOTTOM | RD_ANCHORX_RIGHT; + break; + } + return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; // default +} + + +static char* ListView_GetItemTextEx(HWND hLV, int iItem, int iSubItem) +{ + LVITEM lvi = {0}; + + lvi.mask = LVIF_TEXT; + lvi.iSubItem = iSubItem; + lvi.cchTextMax = 64; + lvi.pszText = (char*)malloc(lvi.cchTextMax); + while (SendMessageT(hLV, LVM_GETITEMTEXT, iItem, (LPARAM)&lvi) == lvi.cchTextMax - 1) + { // loop until the returned size is smaller than buffer size + SAFE_FREE((void**)&lvi.pszText); + lvi.cchTextMax += 64; + lvi.pszText = (char*)malloc(lvi.cchTextMax); + } + return lvi.pszText; +} + + +static void EnableGroupCombo(HWND hwndDlg) +{ + EnableDlgItem(hwndDlg, IDC_GROUPS, SendMessageT(GetDlgItem(hwndDlg, IDC_ENABLEGROUPS), BM_GETCHECK, 0, 0)); +} + + +static void RebuildGroupCombo(HWND hwndDlg) +{ + DBVARIANT dbv = {0}; + char caGroupId[33]; + int bHasGroups = !DBGetContactSettingT(NULL, "CListGroups", "0", &dbv); + HWND hGroupsCombo = GetDlgItem(hwndDlg, IDC_GROUPS); + + DBFreeVariant(&dbv); + if (bHasGroups) + { + int curs = SendMessageT(hGroupsCombo, CB_GETCURSEL, 0, 0); + TCHAR* curst; + + EnableDlgItem(hwndDlg, IDC_ENABLEGROUPS, TRUE); + EnableGroupCombo(hwndDlg); + + if (curs != CB_ERR) + { + curst = (char*)_alloca((SendMessageT(hGroupsCombo, CB_GETLBTEXTLEN, curs, 0) + 1) * sizeof(WCHAR)); + SendMessageT(hGroupsCombo, CB_GETLBTEXT, curs, (LPARAM)curst); + } + SendMessageT(hGroupsCombo, CB_RESETCONTENT, 0, 0); + + for (int groupId=0; ; groupId++) + { + itoa(groupId, caGroupId, 10); + TCHAR* szGroup = DBGetContactSettingStringT(NULL, "CListGroups", caGroupId, NULL); + int nPrefix = g_UnicodeCore ? sizeof(WCHAR) : sizeof(char); + if (!szGroup) break; + int nIndex = SendMessageT(hGroupsCombo, CB_ADDSTRING, 0, (LPARAM)szGroup + nPrefix); + SendMessageT(hGroupsCombo, CB_SETITEMDATA, nIndex, groupId+1); + SAFE_FREE((void**)&szGroup); + } + if (curs != CB_ERR) + SendMessageT(hGroupsCombo, CB_SELECTSTRING, -1, (LPARAM)curst); + else + SendMessageT(hGroupsCombo, CB_SETCURSEL, 0, 0); + } + else + { // no groups available + EnableDlgItem(hwndDlg, IDC_ENABLEGROUPS, FALSE); + EnableDlgItem(hwndDlg, IDC_GROUPS, FALSE); + } +} + + +static HANDLE CreateTemporaryContactForItem(HWND hwndDlg, TRecvContactsData* wndData, int iItem) +{ + char* caUIN = ListView_GetItemTextEx(GetDlgItem(hwndDlg, IDC_CONTACTS), iItem, 0); + char* szProto = GetContactProto(wndData->mhContact); + wndData->rhSearch = (HANDLE)CallProtoService(szProto, PS_BASICSEARCH, 0, (LPARAM)caUIN); // find it + SAFE_FREE((void**)&wndData->haUin); + wndData->haUin = caUIN; + for (int j = 0; j < wndData->cbReceived; j++) + if (!strcmpnull(wndData->maReceived[j]->mcaUIN, caUIN)) + return (HANDLE)CallProtoService(szProto, PS_ADDTOLISTBYEVENT, MAKEWPARAM(PALF_TEMPORARY, j), (LPARAM)wndData->mhDbEvent); + return NULL; +} + + +void RecvListView_AddColumn(HWND hList, int nWidth, const char* szTitle, int nTranslate, int nItem) { + LVCOLUMN col; + WCHAR tmp[MAX_PATH]; + + + col.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; + col.fmt = LVCFMT_LEFT; + col.cx = nWidth; + if (nTranslate) { + col.pszText = SRCTranslateT(szTitle, tmp); + } + else { + if (!szTitle) szTitle = "UID"; + col.pszText = ansi_to_tchar(szTitle, CallService(MS_LANGPACK_GETCODEPAGE, 0, 0)); + } + col.iSubItem = nItem; + ListView_InsertColumnT(hList, nItem, &col); + if (!nTranslate) + SAFE_FREE((void**)&col.pszText); +} + + +INT_PTR CALLBACK RecvDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TRecvContactsData* wndData = (TRecvContactsData*)GetWindowLongPtr(hwndDlg, DWLP_USER); + + switch (msg) + { + case WM_INITDIALOG: + { + CLISTEVENT* pcle = (CLISTEVENT*)lParam; /// got it + + TranslateDialogDefault(hwndDlg); + WindowList_Add(ghRecvWindowList, hwndDlg, pcle->hContact); + SendMessageT(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); + EnableDlgItem(hwndDlg, IDOK, FALSE); + EnableDlgItem(hwndDlg, IDDETAILS, FALSE); + wndData = new TRecvContactsData(pcle->hContact); + SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)wndData); + wndData->mhDbEvent = pcle->hDbEvent; /// initialized, pcle not needed anymore + wndData->mhListIcon = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLORDDB|ILC_MASK, 0, 1); + wndData->mhPopup = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTACTMENU)); + TranslateMenu(wndData->mhPopup); + wndData->hHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_EVENTSENT); + + char *szProto = GetContactProto(wndData->mhContact); + + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); + ListView_SetExtendedListViewStyle(hLV, LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT); + // add columns + RecvListView_AddColumn(hLV, 120, (char*)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDTEXT, 0), FALSE, 0); + RecvListView_AddColumn(hLV, 100, "Nick", TRUE, 1); + RecvListView_AddColumn(hLV, 100, "First Name", TRUE, 2); + RecvListView_AddColumn(hLV, 100, "Last Name", TRUE, 3); + + // fill in groups + SendMessageT(GetDlgItem(hwndDlg, IDC_ENABLEGROUPS), BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); + RebuildGroupCombo(hwndDlg); + + { // fill listview with received contacts + DBEVENTINFO dbe = {0}; + + dbe.cbSize = sizeof(DBEVENTINFO); + dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)wndData->mhDbEvent, 0); + if (dbe.cbBlob != -1) // this marks an invalid hDbEvent - all smashed anyway... + dbe.pBlob = (PBYTE)_alloca(dbe.cbBlob); + CallService(MS_DB_EVENT_GET, (WPARAM)wndData->mhDbEvent, (LPARAM)&dbe); + char* pcBlob = (char*)dbe.pBlob; + char* pcEnd = (char*)dbe.pBlob + dbe.cbBlob; + + HICON hiProto = LoadContactProtoIcon(wndData->mhContact); + ImageList_AddIcon(wndData->mhListIcon, hiProto); + DestroyIcon(hiProto); // imagelist copied the resource + ListView_SetImageList(hLV, wndData->mhListIcon, LVSIL_SMALL); + LVITEM lvi = {0}; + lvi.iImage = 0; + lvi.mask = LVIF_TEXT | LVIF_IMAGE; + + for (int nItem = 0; ; nItem++) + { // Nick + int strsize = (int)strlennull(pcBlob); + TReceivedItem* pItem = wndData->AddReceivedItem(); + + if (dbe.flags & DBEF_UTF) + pItem->mcaNick = utf8_to_tchar((unsigned char*)pcBlob); + else + pItem->mcaNick = ansi_to_tchar(pcBlob); + pcBlob += strsize + 1; + // UIN + strsize = (int)strlennull(pcBlob); + pItem->mcaUIN = null_strdup(pcBlob); + pcBlob += strsize + 1; + // add to listview + lvi.iItem = nItem; + lvi.pszText = pItem->mcaUIN; + ListView_InsertItem(hLV, &lvi); // with image + ListView_SetItemTextT(hLV, nItem, 1, pItem->mcaNick); + // check for end of contacts + if (pcBlob >= pcEnd) + break; + } + } + // new dlg init + wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), "Add Contact Permanently to List"); + wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), "View User's Details"); + wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), "View User's History"); + wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), "User Menu"); + + SendMessageT(hwndDlg,DM_UPDATETITLE,0,0); + // new dialog init done + Utils_RestoreWindowPosition(hwndDlg, NULL, MODULENAME, ""); + return TRUE; + } + case WM_NOTIFY: + if (((LPNMHDR)lParam)->idFrom == IDC_CONTACTS) + { + switch (((LPNMHDR)lParam)->code) + { + case NM_DBLCLK: + { + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); + if (ListView_GetSelectedCount(hLV) != 1) break; // if not clicking on item, bye + wndData->iPopupItem = ListView_GetNextItem(hLV, -1, LVNI_ALL|LVNI_SELECTED); + if (wndData->iPopupItem == -1) break; // if no item selected no user details available + return SendMessageT(hwndDlg, WM_COMMAND, ID_POPUP_USERDETAILS, 0); // show user details + } + case LVN_ITEMCHANGED: + { + LPNMLISTVIEW pNMLV = (LPNMLISTVIEW)lParam; + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); // optimisation, for FOR-Cycle + bool bExistsCheckedItem = false; // there must be no checked items to disable "Add" button + + if (ListView_GetCheckState(hLV, pNMLV->iItem)) + { // the user has checked this item + bExistsCheckedItem = true; // enable "Add" button + } + else + { // loop thru items and check if at least one is checked + for (int i = 0; i < ListView_GetItemCount(hLV); i++) + if (ListView_GetCheckState(hLV, i)) + { // we found checked item, enable add, exit loop + bExistsCheckedItem = true; + break; + } + } + EnableDlgItem(hwndDlg, IDOK, bExistsCheckedItem); + EnableDlgItem(hwndDlg, IDDETAILS, ListView_GetSelectedCount(hLV) > 0); + break; + } + } + } + break; + + case WM_COMMAND: + { + if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->mhContact)) + break; + + switch(LOWORD(wParam)) + { + case IDOK: // "Add Selected" button click + { // for each selected item, find its index in the hDbEvent + // and after that add this item to the DB permanently + char* caUIN; + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); + HWND hGroupsCombo = GetDlgItem(hwndDlg, IDC_GROUPS); + HWND hGroupsCheck = GetDlgItem(hwndDlg, IDC_ENABLEGROUPS); + int curs = SendMessageT(hGroupsCombo, CB_GETCURSEL, 0, 0); + TCHAR* caGroup = NULL; + int nGroupId = -1; + if (curs != CB_ERR && IsWindowEnabled(hGroupsCheck) && SendMessageT(hGroupsCheck, BM_GETCHECK, 0, 0)) + { //got groups, get the one selected in combo + TCHAR* caGroup = (TCHAR*)_alloca((SendMessageT(hGroupsCombo, CB_GETLBTEXTLEN, curs, 0) + 1) * sizeof(WCHAR)); + SendMessageT(hGroupsCombo, CB_GETLBTEXT, curs, (LPARAM)caGroup); + nGroupId = SendMessageT(hGroupsCombo, CB_GETITEMDATA, curs, 0); + } + + for (int i = 0; i < ListView_GetItemCount(hLV); i++) + if (ListView_GetCheckState(hLV, i)) + { // found checked contact item, add it + caUIN = ListView_GetItemTextEx(hLV, i, 0); + for (int j = 0; j < wndData->cbReceived; j++) // determine item index in packet + if (!strcmpnull(wndData->maReceived[j]->mcaUIN, caUIN)) + { + char* szProto = GetContactProto(wndData->mhContact); + HANDLE hContact = (HANDLE)CallProtoService(szProto, PS_ADDTOLISTBYEVENT, MAKEWPARAM(0, j), (LPARAM)wndData->mhDbEvent); + if (hContact && caGroup) + { // use newest group API if available + if (ServiceExists(MS_CLIST_CONTACTCHANGEGROUP)) + CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)hContact, (LPARAM)nGroupId); + else + DBWriteContactSettingStringT(hContact, "CList", "Group", caGroup); + } + break; + } + SAFE_FREE((void**)&caUIN); + } // move to next item + break; + } + case IDDETAILS: + { // for each selected item, find its index in the hDbEvent + // and after that add this item to the DB + // finally, request Details window for this hContact + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); + for (int i = 0; i < ListView_GetItemCount(hLV); i++) + if (ListView_GetItemState(hLV, i, LVIS_SELECTED)) + { + HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, i); + if (hContact) + CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0); + } + break; + } + case IDCANCEL: + { + SendMessageT(hwndDlg, WM_CLOSE, 0, 0); + break; + } + case IDC_ENABLEGROUPS: + { + EnableGroupCombo(hwndDlg); + break; + } + case IDC_GROUPS: + { // rebuild group list on popup + if (HIWORD(wParam) == CBN_DROPDOWN) + RebuildGroupCombo(hwndDlg); + break; + } + case ID_POPUP_ADDUSER: + { + HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); + + if (hContact) + DialogAddContactExecute(hwndDlg, hContact); + break; + } + case ID_POPUP_USERDETAILS: + { + HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); + + if (hContact) + CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0 ); + break; + } + case ID_POPUP_SENDMESSAGE: + { + HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); + + if (hContact) + CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0); + break; + } + case IDC_USERMENU: + { + RECT rc; + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)wndData->mhContact, 0); + GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU), &rc); + TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); + DestroyMenu(hMenu); + break; + } + case IDC_HISTORY: + CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->mhContact,0); + break; + case IDC_DETAILS: + CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->mhContact,0); + break; + case IDC_ADD: + DialogAddContactExecute(hwndDlg, wndData->mhContact); + break; + } + break; + } + case WM_CONTEXTMENU: + { + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); + LVHITTESTINFO lvh; + RECT rt; + + wndData->iPopupItem = -1; + if ((HWND)wParam != hLV) break; // if not our ListView go away + lvh.pt.x = LOWORD(lParam); + lvh.pt.y = HIWORD(lParam); + if (GetWindowRect(hLV, &rt)==0) return FALSE; // ?? why this, some check ?? + ScreenToClient(hLV, &lvh.pt); // convert to ListView local coordinates + int ci = ListView_HitTest(hLV, &lvh); + if (ci==-1) break; // mouse is not over any item + wndData->iPopupItem = ci; + TrackPopupMenu(GetSubMenu(wndData->mhPopup, 0), TPM_LEFTALIGN|TPM_TOPALIGN, LOWORD(lParam), HIWORD(lParam), 0, hwndDlg, NULL); + break; + } + case HM_EVENTSENT: + { + ACKDATA *ack=(ACKDATA*)lParam; + if (ack->type!=ACKTYPE_SEARCH) break; // not search ack, go away + if (ack->hProcess!=wndData->rhSearch) break; //not our search, go away + if (ack->result==ACKRESULT_DATA) + { + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); + PROTOSEARCHRESULT* psr = (PROTOSEARCHRESULT*)ack->lParam; + LVFINDINFO fi; + fi.flags = LVFI_STRING; + fi.psz = wndData->haUin; + int iLPos = ListView_FindItem(hLV, -1, &fi); + if (iLPos==-1) iLPos=0; +// ListView_SetItemText(hLV, iLPos, 0, psr->email); // not sent by ICQ, and currently unsupported either + if (strcmpnull(psr->nick, "") && psr->nick) ListView_SetItemText(hLV, iLPos, 1, psr->nick); + ListView_SetItemText(hLV, iLPos, 2, psr->firstName); + ListView_SetItemText(hLV, iLPos, 3, psr->lastName); + break; + } + SAFE_FREE((void**)&wndData->haUin); + break; + } + case WM_CLOSE: // user closed window, so destroy it + { + WindowList_Remove(ghRecvWindowList, hwndDlg); + DestroyWindow(hwndDlg); + break; + } + case WM_DESTROY: // last message received by this dialog, cleanup + { + CallService(MS_DB_EVENT_MARKREAD, (WPARAM)wndData->mhContact, (LPARAM)wndData->mhDbEvent); + Utils_SaveWindowPosition(hwndDlg, NULL, MODULENAME, ""); + ImageList_Destroy(wndData->mhListIcon); + UnhookEvent(wndData->hHook); + DestroyMenu(wndData->mhPopup); + for (int i=0; i < SIZEOF(wndData->hIcons); i++) + DestroyIcon(wndData->hIcons[i]); + delete wndData; // automatically calls destructor + break; + } + case WM_MEASUREITEM: + return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); + + case WM_DRAWITEM: + { + DrawProtocolIcon(hwndDlg, lParam, wndData->mhContact); + return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); + } + case WM_SIZE: + { // make the dlg resizeable + UTILRESIZEDIALOG urd = {0}; + + if (IsIconic(hwndDlg)) break; + urd.cbSize = sizeof(urd); + urd.hInstance = hInst; + urd.hwndDlg = hwndDlg; + urd.lParam = 0; // user-defined + urd.lpTemplate = MAKEINTRESOURCEA(IDD_RECEIVE); + urd.pfnResizer = RecvDlg_Resize; + CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM) & urd); + break; + } + case WM_GETMINMAXINFO: + { + MINMAXINFO* mmi=(MINMAXINFO*)lParam; + mmi->ptMinTrackSize.x = 480+2*GetSystemMetrics(SM_CXSIZEFRAME); + mmi->ptMinTrackSize.y = 130+2*GetSystemMetrics(SM_CYSIZEFRAME); + break; + } + case DM_UPDATETITLE: + { + UpdateDialogTitle(hwndDlg, wndData?wndData->mhContact:NULL, "Contacts from"); + if (wndData) + UpdateDialogAddButton(hwndDlg, wndData->mhContact); + break; + } + } + return FALSE; +} diff --git a/plugins/ContactsPlus/src/receive.h b/plugins/ContactsPlus/src/receive.h new file mode 100644 index 0000000000..fe35d94be6 --- /dev/null +++ b/plugins/ContactsPlus/src/receive.h @@ -0,0 +1,65 @@ +// --------------------------------------------------------------------------- +// Contacts+ for Miranda Instant Messenger +// _______________________________________ +// +// Copyright © 2002 Dominus Procellarum +// Copyright © 2004-2008 Joe Kucera +// +// 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. +// +// --------------------------------------------------------------------------- + +#ifndef __RECEIVE_H +#define __RECEIVE_H + + +#define HM_EVENTSENT (WM_USER+10) + +#define DM_UPDATETITLE (WM_USER+11) + +#define IDI_ADDCONTACT 210 +#define IDI_USERDETAILS 160 +#define IDI_HISTORY 174 +#define IDI_DOWNARROW 264 + +struct TReceivedItem { + char* mcaUIN; + TCHAR* mcaNick; + ~TReceivedItem() { SAFE_FREE((void**)&mcaUIN); SAFE_FREE((void**)&mcaNick); } + TReceivedItem() { mcaUIN = NULL; mcaNick = NULL; } +}; + +struct TRecvContactsData { + HANDLE mhDbEvent; // handle to recv DB event + HANDLE mhContact; // from whom we received this + HIMAGELIST mhListIcon;// icons for listview + HMENU mhPopup; // popup menu for listview + HANDLE hHook; // hook to event + HANDLE rhSearch; // handle to uin-search + char* haUin; + int iPopupItem; + TReceivedItem** maReceived;// received contacts + int cbReceived; + TReceivedItem* AddReceivedItem(); + HICON hIcons[4]; // icons for dialog + TRecvContactsData(HANDLE contact) { mhContact = contact; hHook = NULL; cbReceived = 0; maReceived = NULL; haUin = NULL; }; + ~TRecvContactsData() { if (cbReceived) { for(int i=0;inContacts = nContacts; + ackData->aContacts = (HANDLE*)malloc(nContacts*sizeof(HANDLE)); + memmove(ackData->aContacts, phContacts, nContacts*sizeof(HANDLE)); // copy the array of hContact for ack array + EnableDlgItem(hwndDlg, IDOK, FALSE); + EnableDlgItem(hwndDlg, IDC_LIST, FALSE); + + return TRUE; // Success +} + + +int TSendContactsData::SendContacts(HWND hwndDlg) { + char* szProto = GetContactProto(hContact); + int nMaxContacts = CallProtoService(szProto, PS_GETCAPS, PFLAG_MAXCONTACTSPERPACKET, (LPARAM)hContact); + + if (!nMaxContacts) { + ShowErrorDlg(hwndDlg, "The selected contact does not support receiving contacts.", FALSE); + return FALSE; + } + // hook event - we want to receive protocol acknowledgements + HookProtoAck(hwndDlg); + + for (int j = 0; j < nContacts / nMaxContacts; j++ ) + { // send in packets, each of nMaxContacts contacts + if (!SendContactsPacket(hwndDlg, aContacts + j*nMaxContacts, nMaxContacts)) + return FALSE; + } + if (nContacts%nMaxContacts!=0) + { + if (!SendContactsPacket(hwndDlg, aContacts + nContacts/nMaxContacts*nMaxContacts, nContacts%nMaxContacts)) + return FALSE; + } + return TRUE; +} + + +/* Send Dialog Implementation */ + +static void ResetListOptions(HWND hwndList) +{ + COLORREF bgColour,fgColour; + + SendMessageT(hwndList,CLM_SETBKBITMAP,0,(LPARAM)(HBITMAP)NULL); + bgColour=GetSysColor(COLOR_WINDOW); + SendMessageT(hwndList,CLM_SETBKCOLOR,bgColour,0); + SendMessageT(hwndList,CLM_SETGREYOUTFLAGS,0,0); + SendMessageT(hwndList,CLM_SETLEFTMARGIN,4,0); + SendMessageT(hwndList,CLM_SETINDENT,10,0); + for(int i=0; i<=FONTID_MAX; i++) + { + fgColour=(COLORREF)SendMessageT(hwndList,CLM_GETTEXTCOLOR,i,0); + if(abs(GetRValue(fgColour)-GetRValue(bgColour))<10 && + abs(GetGValue(fgColour)-GetGValue(bgColour))<10 && + abs(GetBValue(fgColour)-GetBValue(bgColour))<10) + SendMessageT(hwndList,CLM_SETTEXTCOLOR,i,GetSysColor(COLOR_WINDOWTEXT)); + } +} + + +static HANDLE FindNextClistContact(HWND hList, HANDLE hContact, HANDLE *phItem) +{ + HANDLE hNextContact = SRCFindNextContact(hContact); + HANDLE hNextItem = NULL; + + while (hNextContact && !(hNextItem = (HANDLE)SendMessageT(hList, CLM_FINDCONTACT, (WPARAM)hNextContact,0))) + hNextContact = SRCFindNextContact(hNextContact); + + if (phItem) + *phItem = hNextItem; + + return hNextContact; +} + + +static HANDLE FindFirstClistContact(HWND hList, HANDLE *phItem) +{ + HANDLE hContact = SRCFindFirstContact(); + HANDLE hItem = (HANDLE)SendMessageT(hList, CLM_FINDCONTACT, (WPARAM)hContact, 0); + + if (hContact && !hItem) + return FindNextClistContact(hList, hContact, phItem); + + if (phItem) + *phItem = hItem; + + return hContact; +} + + +bool binListEvent = FALSE; + +static void SetAllContactChecks(HWND hwndList, HANDLE hReceiver) // doubtful name +{ + HANDLE hContact, hItem; + + if (binListEvent) return; + binListEvent = TRUE; + char* szProto = GetContactProto(hReceiver); + if (szProto == NULL) return; + + if (CallService(MS_CLUI_GETCAPS, 0, 0) & CLUIF_HIDEEMPTYGROUPS && DBGetContactSettingByte(NULL, "CList", "HideEmptyGroups", SETTING_USEGROUPS_DEFAULT)) + SendMessageT(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM) TRUE, 0); + else + SendMessageT(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM) FALSE, 0); + + hContact = FindFirstClistContact(hwndList, &hItem); + while (hContact) + { + char* szProto2 = GetContactProto(hContact); + + if (strcmpnull(szProto, szProto2)) + { // different protocols or protocol undefined, remove contact, useless anyway + SendMessageT(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0); + } + else // otherwise uncheck + SendMessageT(hwndList, CLM_SETCHECKMARK,(WPARAM)hItem, 0); + + hContact = FindNextClistContact(hwndList, hContact, &hItem); + } + + binListEvent = FALSE; +} + + +INT_PTR CALLBACK SendDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TSendContactsData* wndData = (TSendContactsData*)GetWindowLongPtr(hwndDlg, DWLP_USER); + + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + SendMessageT(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); + ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST)); + SetAllContactChecks(GetDlgItem(hwndDlg,IDC_LIST), (HANDLE)lParam); + WindowList_Add(ghSendWindowList, hwndDlg, (HANDLE)lParam); + wndData = new TSendContactsData((HANDLE)lParam); + SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)wndData); + // new dlg init + wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), "Add Contact Permanently to List"); + wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), "View User's Details"); + wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), "View User's History"); + wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), "User Menu"); + + SendMessageT(hwndDlg,DM_UPDATETITLE,0,0); + // new dialog init done + return TRUE; + } + + case WM_SETFOCUS: + SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->idFrom == IDC_LIST) + { + switch (((LPNMHDR)lParam)->code) + { + case CLN_NEWCONTACT: + case CLN_LISTREBUILT: // rebuild list + if (wndData) SetAllContactChecks(GetDlgItem(hwndDlg,IDC_LIST), wndData->hContact); + case CLN_OPTIONSCHANGED: + ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST)); + break; + } + } + break; + + case WM_TIMER: + if (wParam == TIMERID_MSGSEND) + { + if (!g_SendAckSupported) + { // old Miranda has this ack unimplemented, we need to send it by ourselves + ACKDATA ack = {0}; + + ack.cbSize = sizeof(ACKDATA); + ack.type = ACKTYPE_CONTACTS; + ack.result = ACKRESULT_SUCCESS; + ack.hContact = wndData->hContact; + while (wndData->uacklist.Count) + { // the uack gets empty after processing all messages :) + ack.hProcess = wndData->uacklist.Items[0]; + SendMessageT(hwndDlg, HM_EVENTSENT, NULL, (WPARAM)&ack); // this removes the ack from our array + } + break; + } + KillTimer(hwndDlg,wParam); + wndData->ShowErrorDlg(hwndDlg, "The contacts send timed out.", TRUE); + } + break; + + case DM_ERRORDECIDED: + { + EnableWindow(hwndDlg,TRUE); + wndData->hError = NULL; + switch(wParam) + { + case MSGERROR_CANCEL: + { + wndData->UnhookProtoAck(); + if (wndData->uacklist.Count) + { + for (int i=0; iuacklist.Count; i++) + { + delete gaAckData.Remove(wndData->uacklist.Items[i]); // remove our ackdata & release structure + } + SAFE_FREE((void**)&wndData->uacklist.Items); + wndData->uacklist.Count = 0; + } + EnableDlgItem(hwndDlg,IDOK,TRUE); + EnableDlgItem(hwndDlg,IDC_LIST,TRUE); + ShowWindow(hwndDlg,SW_SHOWNORMAL); + SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); + break; + } + case MSGERROR_DONE: + // contacts were delivered succesfully after timeout + SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); + wndData->UnhookProtoAck(); + break; + + case MSGERROR_RETRY:// resend timeouted packets + + for (int i=0; iuacklist.Count; i++) + { + TAckData* lla = gaAckData.Remove(wndData->uacklist.Items[i]); + HANDLE hProcc = (HANDLE)CallContactService(wndData->hContact, PSS_CONTACTS, MAKEWPARAM(0, lla->nContacts), (LPARAM)lla->aContacts); + + if (!hProcc) // if fatal do not include + { + wndData->uacklist.Remove(wndData->uacklist.Items[i]); + delete lla; // release the structure + continue; + } + else + { // update process code + wndData->uacklist.Items[i] = hProcc; + gaAckData.Add(hProcc, lla); + } + }// collect TAckData for our window, resend + break; + } + break; + } + + case WM_COMMAND: + { + if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->hContact)) + break; + + switch(LOWORD(wParam)) + { + case IDOK: + { + if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDOK))) break; + HANDLE hContact, hItem; + wndData->ClearContacts(); // do not include contacts twice + + HWND hList = GetDlgItem(hwndDlg, IDC_LIST); + hContact = FindFirstClistContact(hList, &hItem); + while (hContact) + { + if (SendMessageT(hList, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) + { // build list of contacts to send + wndData->AddContact(hContact); + } + hContact = FindNextClistContact(hList, hContact, &hItem); + } + /* send contacts */ + if (!wndData->SendContacts(hwndDlg)) + break; + + if (g_SendAckSupported) + SetTimer(hwndDlg,TIMERID_MSGSEND,DBGetContactSettingDword(NULL,"SRMsg","MessageTimeout",TIMEOUT_MSGSEND),NULL); + else + SetTimer(hwndDlg,TIMERID_MSGSEND,1000,NULL); // wait one second - if no error occures + + break; + } + case IDCANCEL: + { + DestroyWindow(hwndDlg); + break; + } + case ID_SELECTALL: + { // select all contacts + HANDLE hContact, hItem; + HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST); + + hContact = FindFirstClistContact(hwndList, &hItem); + while (hContact) { + SendMessageT(hwndList,CLM_SETCHECKMARK,(WPARAM)hItem, 1); + hContact = FindNextClistContact(hwndList, hContact, &hItem); + }; + break; + } + case IDC_USERMENU: + { + RECT rc; + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)wndData->hContact,0); + + GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU),&rc); + TrackPopupMenu(hMenu,0,rc.left,rc.bottom,0,hwndDlg,NULL); + DestroyMenu(hMenu); + break; + } + case IDC_HISTORY: + CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->hContact,0); + break; + + case IDC_DETAILS: + CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->hContact,0); + break; + + case IDC_ADD: + DialogAddContactExecute(hwndDlg, wndData->hContact); + break; + } + break; + } + case HM_EVENTSENT: + { + ACKDATA *ack=(ACKDATA*)lParam; + DBEVENTINFO dbei={0}; + + if (ack->type != ACKTYPE_CONTACTS) break; + + TAckData* ackData = gaAckData.Get(ack->hProcess); + + if (ackData == NULL) break; // on unknown hprocc go away + + if (ackData->hContact != ack->hContact) break; // this is not ours, strange + + if (ack->result == ACKRESULT_FAILED) + { // some process failed, show error dialog + KillTimer(hwndDlg, TIMERID_MSGSEND); + wndData->ShowErrorDlg(hwndDlg, (char *)ack->lParam, TRUE); + // ackData get used in error handling, released there + break; + } + + dbei.cbSize = sizeof(dbei); + dbei.szModule = GetContactProto(ackData->hContact); + dbei.eventType = EVENTTYPE_CONTACTS; + dbei.flags = DBEF_SENT; + if (g_UnicodeCore && g_Utf8EventsSupported) + dbei.flags |= DBEF_UTF; + dbei.timestamp = time(NULL); + //make blob + TCTSend* maSend = (TCTSend*)_alloca(ackData->nContacts*sizeof(TCTSend)); + ZeroMemory(maSend, ackData->nContacts*sizeof(TCTSend)); + dbei.cbBlob=0; + char* pBlob; + int i; + for (i=0; inContacts; i++) + { // prepare data & count size + if (g_UnicodeCore && g_Utf8EventsSupported) + maSend[i].mcaNick = make_utf8_string((WCHAR*)GetContactDisplayNameT(ackData->aContacts[i])); + else + maSend[i].mcaNick = (unsigned char*)null_strdup((char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ackData->aContacts[i], 0)); + maSend[i].mcaUIN = GetContactUID(ackData->aContacts[i], FALSE); + dbei.cbBlob += (DWORD)strlennull(maSend[i].mcaUIN) + (DWORD)strlennull((char*)maSend[i].mcaNick) + 2; + } + dbei.pBlob = (PBYTE)_alloca(dbei.cbBlob); + for (i=0, pBlob=(char*)dbei.pBlob; i < ackData->nContacts; i++) + { + strcpy(pBlob, (char*)maSend[i].mcaNick); + pBlob += strlennull(pBlob) + 1; + strcpy(pBlob, maSend[i].mcaUIN); + pBlob += strlennull(pBlob) + 1; + } + CallService(MS_DB_EVENT_ADD, (WPARAM)ackData->hContact,(LPARAM)&dbei); + gaAckData.Remove(ack->hProcess); // do not release here, still needed + wndData->uacklist.Remove(ack->hProcess); // packet confirmed + for (i=0; inContacts; i++) + { + SAFE_FREE((void**)&maSend[i].mcaUIN); + SAFE_FREE((void**)&maSend[i].mcaNick); + } + delete ackData; // all done, release structure + if (!wndData->uacklist.Count) + { + SkinPlaySound("SentContacts"); + KillTimer(hwndDlg, TIMERID_MSGSEND); + + if (wndData->hError) + SendMessageT(wndData->hError, DM_ERRORDECIDED, MSGERROR_DONE, 0); + + SendMessageT(hwndDlg, WM_CLOSE, 0, 0); // all packets confirmed, close the dialog + } + break; + } + + case WM_CLOSE: + { + wndData->UnhookProtoAck(); + DestroyWindow(hwndDlg); + break; + } + case WM_DESTROY: + { + int i; + for (i = 0; i < SIZEOF(wndData->hIcons); i++) + DestroyIcon(wndData->hIcons[i]); + WindowList_Remove(ghSendWindowList, hwndDlg); + delete wndData; + break; + } + case WM_MEASUREITEM: + return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam); + + case WM_DRAWITEM: + { + DrawProtocolIcon(hwndDlg, lParam, wndData->hContact); + return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam); + } + case DM_UPDATETITLE: + { + UpdateDialogTitle(hwndDlg, wndData?wndData->hContact:NULL, "Send Contacts to"); + if (wndData) + UpdateDialogAddButton(hwndDlg, wndData->hContact); + break; + } + } + + return FALSE; +} + + +// Error Dialog + +INT_PTR CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + RECT rc, rcParent; + + TranslateDialogDefault(hwndDlg); + + if (lParam) + { + WCHAR tmp[MAX_PATH]; + + SetDlgItemTextT(hwndDlg, IDC_ERRORTEXT, SRCTranslateT((char*)lParam, tmp)); + } + GetWindowRect(hwndDlg, &rc); + GetWindowRect(GetParent(hwndDlg), &rcParent); + SetWindowPos(hwndDlg, 0, + (rcParent.left+rcParent.right-(rc.right-rc.left))/2, + (rcParent.top+rcParent.bottom-(rc.bottom-rc.top))/2, + 0, 0, SWP_NOZORDER|SWP_NOSIZE); + } + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDOK: + SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_RETRY, 0); + DestroyWindow(hwndDlg); + break; + + case IDCANCEL: + SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_CANCEL, 0); + DestroyWindow(hwndDlg); + break; + } + break; + case DM_ERRORDECIDED: + if (wParam!=MSGERROR_DONE) break; + SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_DONE, 0); + DestroyWindow(hwndDlg); + break; + } + + return FALSE; +} diff --git a/plugins/ContactsPlus/src/send.h b/plugins/ContactsPlus/src/send.h new file mode 100644 index 0000000000..c8580a4eb1 --- /dev/null +++ b/plugins/ContactsPlus/src/send.h @@ -0,0 +1,110 @@ +// --------------------------------------------------------------------------- +// Contacts+ for Miranda Instant Messenger +// _______________________________________ +// +// Copyright © 2002 Dominus Procellarum +// Copyright © 2004-2008 Joe Kucera +// +// 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. +// +// --------------------------------------------------------------------------- + +#ifndef __SEND_H +#define __SEND_H + + +#define TIMERID_MSGSEND 1024 +#define TIMEOUT_MSGSEND 9000 //ms +#define HM_EVENTSENT (WM_USER+10) +#define DM_ERRORDECIDED (WM_USER+18) +#define DM_UPDATETITLE (WM_USER+11) +#define MSGERROR_CANCEL 0 +#define MSGERROR_RETRY 1 +#define MSGERROR_DONE 2 + +#define IDI_ADDCONTACT 210 +#define IDI_USERDETAILS 160 +#define IDI_HISTORY 174 +#define IDI_DOWNARROW 264 + +struct TSendProcessList { + int Count; + HANDLE* Items; + CRITICAL_SECTION lock; + void Add(HANDLE hProcc); + void Remove(HANDLE hProcc); + TSendProcessList(); + ~TSendProcessList(); +}; + +struct TSendContactsData { // hope uack is released automaticly, static property + HANDLE hHook; // hook to event + void HookProtoAck(HWND hwndDlg); + void UnhookProtoAck(); + HANDLE* aContacts; // contacts to be sent + int nContacts; // now many UIDs shall we send? + void ClearContacts(); + void AddContact(HANDLE hContact); + HANDLE hContact; // to whom shall we send? + TSendProcessList uacklist;// ackdata - necessary for errorbox + HWND hError; // handle of error box, if any + void ShowErrorDlg(HWND hwndDlg, char* szMsg, bool bAllowRetry); + int SendContactsPacket(HWND hwndDlg, HANDLE *phContacts, int nContacts); + int SendContacts(HWND hwndDlg); + HICON hIcons[4]; // icons for dialog + TSendContactsData(HANDLE contact); + ~TSendContactsData(); +}; + +struct TAckData { + HANDLE hContact; // to whom was it sent + HANDLE* aContacts; // obj + int nContacts; // how many + TAckData(HANDLE contact) { hContact = contact; aContacts = NULL; nContacts = 0;}; + ~TAckData() { if (nContacts) SAFE_FREE((void**)&aContacts); } +}; + +typedef TAckData* PAckData; + +struct TCTSend { + char* mcaUIN; + unsigned char* mcaNick; +}; + +struct gAckItem { // some shit here + HANDLE hProcc; + PAckData ackData; + gAckItem(HANDLE procC, PAckData aData) { ackData=aData; hProcc=procC; }; + ~gAckItem() { /*delete ackData;*/ }; +}; + +struct gAckList { + gAckItem** Items; + int Count; + TAckData* Get(HANDLE hProcc) { for (int i=0; ihProcc==hProcc) { return Items[i]->ackData; }; return NULL; }; + TAckData* Add(HANDLE hProcc, TAckData* ackData) { Items=(gAckItem**)realloc(Items, (Count+1)*sizeof(gAckItem*)); Items[Count]=new gAckItem(hProcc, ackData); Count++; return ackData; }; + TAckData* Remove(HANDLE hProcc) { for (int i=0; ihProcc==hProcc) { TAckData* data=Items[i]->ackData; delete Items[i]; memmove(Items+i, Items+i+1, (Count-i-1)*sizeof(gAckItem*)); Count--; return data; }; return NULL; }; + gAckList() { Count = 0; Items = NULL; } + ~gAckList() { if (Count) { for (int i=0; ihwndItem==GetDlgItem(hwndDlg, IDC_PROTOCOL)) + { + HICON hIcon = LoadContactProtoIcon(hContact); + if (hIcon) + { + DrawIconEx(dis->hDC,dis->rcItem.left,dis->rcItem.top,hIcon,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL); + DestroyIcon(hIcon); + } + } +} + + +void UpdateDialogTitle(HWND hwndDlg, HANDLE hContact, char* pszTitleStart) +{ + TCHAR newtitle[512]; + WCHAR str[MAX_PATH]; + TCHAR *oldTitle; + TCHAR *szStatus; + char *szProto; + + if (hContact) + { + szProto = GetContactProto(hContact); + if (szProto) + { + TCHAR *uid = GetContactUID(hContact, TRUE); + TCHAR *contactName = GetContactDisplayNameT(hContact); + + oldTitle = GetDlgItemTextT(hwndDlg, IDC_NAME); + + if (strcmpT(uid?uid:contactName, oldTitle)) + SetDlgItemTextT(hwndDlg, IDC_NAME, uid?uid:contactName); + + szStatus = MirandaStatusToStringT(szProto==NULL ? ID_STATUS_OFFLINE:DBGetContactSettingWord(hContact,szProto,"Status",ID_STATUS_OFFLINE)); + _snprintfT(newtitle, 256, "%s %s (%s)", SRCTranslateT(pszTitleStart, str), contactName, szStatus); + + SAFE_FREE((void**)&uid); + SAFE_FREE((void**)&oldTitle); + } + else + strncpyT(newtitle, SRCTranslateT(pszTitleStart, str), 256); + } + else + strncpyT(newtitle, SRCTranslateT(pszTitleStart, str), 256); + + oldTitle = GetWindowTextT(hwndDlg); + + if (strcmpT(newtitle, oldTitle)) + SetWindowTextT(hwndDlg, newtitle); + + SAFE_FREE((void**)&oldTitle); +} + + +void UpdateDialogAddButton(HWND hwndDlg, HANDLE hContact) +{ + int bVisible = DBGetContactSettingByte(hContact,"CList","NotOnList",0); + + ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), bVisible?SW_SHOW:SW_HIDE); +} + + +HICON InitMButton(HWND hDlg, int idButton, LPCSTR szIcon, char* szTip) +{ + HWND hButton = GetDlgItem(hDlg, idButton); + HICON hIcon = (HICON)LoadImage(GetModuleHandle(NULL),szIcon,IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0); + + SendMessageT(hButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + SendMessageT(hButton, BUTTONSETASFLATBTN, TRUE, 0); + SendMessageT(hButton, BUTTONADDTOOLTIP, (WPARAM)Translate(szTip), 0); + + return hIcon; +} + + +HICON LoadContactProtoIcon(HANDLE hContact) +{ + char* szProto = GetContactProto(hContact); + if (szProto) + return (HICON)CallProtoService(szProto, PS_LOADICON, PLI_PROTOCOL|PLIF_SMALL, 0); + return NULL; +} + + +void EnableDlgItem(HWND hwndDlg, UINT control, int state) +{ + EnableWindow(GetDlgItem(hwndDlg, control), state); +} + + +LRESULT SendMessageT(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + if (g_UnicodeCore) + return SendMessageW(hWnd, Msg, wParam, lParam); + else + return SendMessageA(hWnd, Msg, wParam, lParam); +} + +TCHAR* GetWindowTextT(HWND hWnd) +{ + if (g_UnicodeCore) + { + int len = GetWindowTextLengthW(hWnd) + 1; + WCHAR* txt = (WCHAR*)malloc(len * sizeof(WCHAR)); + if (txt) { + txt[0] = 0; + GetWindowTextW(hWnd, txt, len); + } + return (TCHAR*)txt; + } + else + { + int len = GetWindowTextLengthA(hWnd) + 1; + char* txt = (char*)malloc(len * sizeof(char)); + if (txt) { + txt[0] = 0; + GetWindowTextA(hWnd, txt, len); + } + return (TCHAR*)txt; + } +} + +BOOL SetWindowTextT(HWND hWnd, TCHAR* lpString) +{ + if (g_UnicodeCore) + return SetWindowTextW(hWnd, (WCHAR*)lpString); + else + return SetWindowTextA(hWnd, lpString); +} + +TCHAR* GetDlgItemTextT(HWND hDlg, int nIDDlgItem) +{ + return GetWindowTextT(GetDlgItem(hDlg, nIDDlgItem)); +} + +BOOL SetDlgItemTextT(HWND hDlg, int nIDDlgItem, TCHAR* lpString) +{ + return SetWindowTextT(GetDlgItem(hDlg, nIDDlgItem), lpString); +} + +HWND CreateDialogParamT(HINSTANCE hInstance, const char* szTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) +{ + if (g_UnicodeCore) + return CreateDialogParamW(hInstance, (LPCWSTR)szTemplate, hWndParent, lpDialogFunc, dwInitParam); + else + return CreateDialogParamA(hInstance, szTemplate, hWndParent, lpDialogFunc, dwInitParam); +} + +int ListView_InsertColumnT(HWND hwnd, int iCol, const LPLVCOLUMN pcol) +{ + return SendMessageT(hwnd, g_UnicodeCore ? LVM_INSERTCOLUMNW : LVM_INSERTCOLUMNA, (WPARAM)iCol, (LPARAM)pcol); +} + +void ListView_SetItemTextT(HWND hwnd, int i, int iSubItem, TCHAR* pszText) +{ + LV_ITEM lvi = {0}; + + lvi.iSubItem = iSubItem; + lvi.pszText = pszText; + SendMessageT(hwnd, g_UnicodeCore ? LVM_SETITEMTEXTW : LVM_SETITEMTEXTA, (WPARAM)i, (LPARAM)&lvi); +} + + + +size_t __fastcall strlenT(const TCHAR *string) +{ + if (string) + { + if (g_UnicodeCore) + return wcslen((WCHAR*)string); + else + return strlen((char*)string); + } + return 0; +} + +TCHAR* __fastcall strdupT(const TCHAR *string) +{ + if (string) + { + if (g_UnicodeCore) + return (TCHAR*)wcsdup((WCHAR*)string); + else + return (TCHAR*)strdup((char*)string); + } + return NULL; +} + +int __fastcall strcmpT(const TCHAR *string1, const TCHAR *string2) +{ + if (!string1 || !string2) return 1; + + if (g_UnicodeCore) + return wcscmp((WCHAR*)string1, (WCHAR*)string2); + else + return strcmp((char*)string1, (char*)string2); +} + +TCHAR* __fastcall strcpyT(TCHAR* dest, const TCHAR* src) +{ + if (src) + { + if (g_UnicodeCore) + return (TCHAR*)wcscpy((WCHAR*)dest, (WCHAR*)src); + else + return (TCHAR*)strcpy((char*)dest, (char*)src); + } + return dest; +} + +TCHAR* __fastcall strncpyT(TCHAR* dest, const TCHAR* src, size_t len) +{ + if (src) + { + if (g_UnicodeCore) + return (TCHAR*)wcsncpy((WCHAR*)dest, (WCHAR*)src, len); + else + return (TCHAR*)strncpy((char*)dest, (char*)src, len); + } + return dest; +} + +TCHAR* __fastcall strcatT(TCHAR* dest, const TCHAR* src) +{ + if (src) + { + if (g_UnicodeCore) + return (TCHAR*)wcscat((WCHAR*)dest, (WCHAR*)src); + else + return (TCHAR*)strcat((char*)dest, (char*)src); + } + return dest; +} + +int _snprintfT(TCHAR *buffer, size_t count, const char* fmt, ...) +{ + va_list va; + int len; + + va_start(va, fmt); + if (g_UnicodeCore) + { + TCHAR* wfmt = ansi_to_tchar(fmt); + + len = _vsnwprintf((WCHAR*)buffer, count-1, (WCHAR*)wfmt, va); + ((WCHAR*)buffer)[count-1] = 0; + SAFE_FREE((void**)&wfmt); + } + else + { + len = _vsnprintf((char*)buffer, count-1, fmt, va); + ((char*)buffer)[count-1] = 0; + } + va_end(va); + return len; +} + +TCHAR* __fastcall SRCTranslateT(const char* src, const WCHAR* unibuf) +{ // this takes Ascii strings only!!! + char* szRes = NULL; + + if (!strlennull(src)) + { // for the case of empty strings + return ""; + } + + if (g_UnicodeCore) + { // we give WCHAR + WCHAR *unicode; + int wchars, err; + + wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, + (int)strlennull(src), NULL, 0); + + if (wchars == 0) return NULL; // Failure + + unicode = (WCHAR*)unibuf; + if (!unicode) + unicode = (WCHAR*)malloc((wchars + 1) * sizeof(WCHAR)); + + unicode[wchars] = 0; + + err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, + (int)strlennull(src), unicode, wchars); + if (err != wchars) return NULL; // Failure + + return (TCHAR*)TranslateW(unicode); + } + else + return (TCHAR*)Translate(src); +} + +static BOOL bHasCP_UTF8 = FALSE; + + +void InitI18N(void) +{ + CPINFO CPInfo; + + + bHasCP_UTF8 = GetCPInfo(CP_UTF8, &CPInfo); +} + + +// Scans a string encoded in UTF-8 to verify that it contains +// only valid sequences. It will return 1 if the string contains +// only legitimate encoding sequences; otherwise it will return 0; +// From 'Secure Programming Cookbook', John Viega & Matt Messier, 2003 +int UTF8_IsValid(const unsigned char* pszInput) +{ + int nb, i; + const unsigned char* c = pszInput; + + if (!pszInput) return 0; + + for (c = pszInput; *c; c += (nb + 1)) + { + if (!(*c & 0x80)) + nb = 0; + else if ((*c & 0xc0) == 0x80) return 0; + else if ((*c & 0xe0) == 0xc0) nb = 1; + else if ((*c & 0xf0) == 0xe0) nb = 2; + else if ((*c & 0xf8) == 0xf0) nb = 3; + else if ((*c & 0xfc) == 0xf8) nb = 4; + else if ((*c & 0xfe) == 0xfc) nb = 5; + + for (i = 1; i<=nb; i++) // we this forward, do not cross end of string + if ((*(c + i) & 0xc0) != 0x80) + return 0; + } + + return 1; +} + + +/* + * The following UTF8 routines are + * + * Copyright (C) 2001 Peter Harris + * Copyright (C) 2001 Edmund Grimley Evans + * + * under a GPL license + * + * -------------------------------------------------------------- + * Convert a string between UTF-8 and the locale's charset. + * Invalid bytes are replaced by '#', and characters that are + * not available in the target encoding are replaced by '?'. + * + * If the locale's charset is not set explicitly then it is + * obtained using nl_langinfo(CODESET), where available, the + * environment variable CHARSET, or assumed to be US-ASCII. + * + * Return value of conversion functions: + * + * -1 : memory allocation failed + * 0 : data was converted exactly + * 1 : valid data was converted approximately (using '?') + * 2 : input was invalid (but still converted, using '#') + * 3 : unknown encoding (but still converted, using '?') + */ + + + +/* + * Convert a string between UTF-8 and the locale's charset. + */ +unsigned char *make_utf8_string(const wchar_t *unicode) +{ + int size = 0; + int index = 0; + int out_index = 0; + unsigned char* out; + unsigned short c; + + if (!unicode) return NULL; + + /* first calculate the size of the target string */ + c = unicode[index++]; + while (c) + { + if (c < 0x0080) + size += 1; + else if (c < 0x0800) + size += 2; + else + size += 3; + c = unicode[index++]; + } + + out = (unsigned char*)malloc(size + 1); + if (out == NULL) + return NULL; + index = 0; + + c = unicode[index++]; + while (c) + { + if (c < 0x080) + { + out[out_index++] = (unsigned char)c; + } + else if (c < 0x800) + { + out[out_index++] = 0xc0 | (c >> 6); + out[out_index++] = 0x80 | (c & 0x3f); + } + else + { + out[out_index++] = 0xe0 | (c >> 12); + out[out_index++] = 0x80 | ((c >> 6) & 0x3f); + out[out_index++] = 0x80 | (c & 0x3f); + } + c = unicode[index++]; + } + out[out_index] = 0x00; + + return out; +} + + + +WCHAR *make_unicode_string(const unsigned char *utf8) +{ + int size = 0, index = 0, out_index = 0; + wchar_t *out; + unsigned char c; + + if (!utf8) return NULL; + + /* first calculate the size of the target string */ + c = utf8[index++]; + while (c) + { + if ((c & 0x80) == 0) + { + index += 0; + } + else if ((c & 0xe0) == 0xe0) + { + index += 2; + } + else + { + index += 1; + } + size += 1; + c = utf8[index++]; + } + + out = (wchar_t*)malloc((size + 1) * sizeof(wchar_t)); + if (out == NULL) + return NULL; + index = 0; + + c = utf8[index++]; + while (c) + { + if ((c & 0x80) == 0) + { + out[out_index++] = c; + } + else if ((c & 0xe0) == 0xe0) + { + out[out_index] = (c & 0x1F) << 12; + c = utf8[index++]; + out[out_index] |= (c & 0x3F) << 6; + c = utf8[index++]; + out[out_index++] |= (c & 0x3F); + } + else + { + out[out_index] = (c & 0x3F) << 6; + c = utf8[index++]; + out[out_index++] |= (c & 0x3F); + } + c = utf8[index++]; + } + out[out_index] = 0; + + return out; +} + + +// Returns 0 on error, 1 on success +static int utf8_decode(const unsigned char *from, char **to) +{ + int nResult = 0; + +// _ASSERTE(!(*to)); // You passed a non-zero pointer, make sure it doesnt point to unfreed memory + + // Validate the string + if (!UTF8_IsValid(from)) + return 0; + + // Use the native conversion routines when available + if (bHasCP_UTF8) + { + WCHAR *wszTemp = NULL; + int inlen = (int)strlennull((char*)from); + + wszTemp = (WCHAR *)_alloca(sizeof(WCHAR) * (inlen + 1)); + + // Convert the UTF-8 string to UCS + if (MultiByteToWideChar(CP_UTF8, 0, (char*)from, -1, wszTemp, inlen + 1)) + { + // Convert the UCS string to local ANSI codepage + *to = (char*)malloc(inlen+1); + if (WideCharToMultiByte(CP_ACP, 0, wszTemp, -1, *to, inlen+1, NULL, NULL)) + { + nResult = 1; + } + else + { + SAFE_FREE((void**)to); + } + } + } + else + { + wchar_t *unicode; + int chars; + int err; + + unicode = make_unicode_string(from); + if (unicode == NULL) + { +// fprintf(stderr, "Out of memory processing string from UTF8 to UNICODE16\n"); + return 0; + } + + chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); + + if(chars == 0) + { +// fprintf(stderr, "Unicode translation error %d\n", GetLastError()); + SAFE_FREE((void**)&unicode); + return 0; + } + + *to = (char*)malloc((chars + 1)*sizeof(unsigned char)); + if (*to == NULL) + { +// fprintf(stderr, "Out of memory processing string to local charset\n"); + SAFE_FREE((void**)&unicode); + return 0; + } + + err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); + if (err != chars) + { +// fprintf(stderr, "Unicode translation error %d\n", GetLastError()); + SAFE_FREE((void**)&unicode); + SAFE_FREE((void**)to); + return 0; + } + + SAFE_FREE((void**)&unicode); + + nResult = 1; + } + + return nResult; +} + + + +TCHAR* ansi_to_tchar(const char* src, int codepage) +{ + if (g_UnicodeCore) + { + WCHAR *unicode; + int wchars, err; + + wchars = MultiByteToWideChar(codepage, MB_PRECOMPOSED, src, (int)strlennull(src), NULL, 0); + + if (wchars == 0) return NULL; // Failure + + unicode = (WCHAR*)malloc((wchars + 1) * sizeof(WCHAR)); + unicode[wchars] = 0; + + err = MultiByteToWideChar(codepage, MB_PRECOMPOSED, src, (int)strlennull(src), unicode, wchars); + if (err != wchars) + { + SAFE_FREE((void**)&unicode); + return NULL; // Failure + } + + return (TCHAR*)unicode; + } + else + return strdupT((TCHAR*)src); +} + +char* tchar_to_ansi(const TCHAR* src) +{ + if (g_UnicodeCore) + { + char *ansi; + int chars; + int err; + + chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (WCHAR*)src, -1, NULL, 0, NULL, NULL); + + if (chars == 0) return NULL; // Failure + + ansi = (char*)malloc((chars + 1)*sizeof(char)); + if (ansi == NULL) return NULL; // Failure + + err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (WCHAR*)src, -1, ansi, chars, NULL, NULL); + if (err != chars) + { + SAFE_FREE((void**)&ansi); + return NULL; + } + return ansi; + } + else + return (char*)strdupT(src); +} + +TCHAR* utf8_to_tchar(const unsigned char* utf) +{ + if (g_UnicodeCore) + return (TCHAR*)make_unicode_string(utf); + else + { + char* szAnsi = NULL; + + if (utf8_decode(utf, &szAnsi)) + return (TCHAR*)szAnsi; + else + return NULL; // Failure + } +} \ No newline at end of file diff --git a/plugins/ContactsPlus/src/utils.h b/plugins/ContactsPlus/src/utils.h new file mode 100644 index 0000000000..3bc2d8e00d --- /dev/null +++ b/plugins/ContactsPlus/src/utils.h @@ -0,0 +1,86 @@ +// --------------------------------------------------------------------------- +// Contacts+ for Miranda Instant Messenger +// _______________________________________ +// +// Copyright © 2002 Dominus Procellarum +// Copyright © 2004-2008 Joe Kucera +// +// 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. +// +// --------------------------------------------------------------------------- + +#ifndef __UTILS_H +#define __UTILS_H + + +extern HINSTANCE hInst; + +// utils.cpp +void __fastcall SAFE_FREE(void** p); +size_t __fastcall strlennull(const char *string); +int __fastcall strcmpnull(const char *str1, const char *str2); +char* __fastcall null_strdup(const char *string); + +char *GetContactProto(HANDLE hContact); +char *GetContactUID(HANDLE hContact, int bTchar); +TCHAR *GetContactDisplayNameT(HANDLE hContact); +TCHAR* MirandaStatusToStringT(int mirandaStatus); + +HANDLE __fastcall SRCFindFirstContact(); +HANDLE __fastcall SRCFindNextContact(HANDLE hContact); +int DBGetContactSettingT(HANDLE hContact, const char *szModule, const char* szSetting, DBVARIANT *dbv); +TCHAR* DBGetContactSettingStringT(HANDLE hContact, const char *szModule,const char* szSetting, TCHAR* szDef); +int DBWriteContactSettingStringT(HANDLE hContact, const char *szModule, const char* szSetting, TCHAR* szValue); + +void DrawProtocolIcon(HWND hwndDlg, LPARAM lParam, HANDLE hContact); +void UpdateDialogTitle(HWND hwndDlg, HANDLE hContact, char* pszTitleStart); +void UpdateDialogAddButton(HWND hwndDlg, HANDLE hContact); + +HICON InitMButton(HWND hDlg, int idButton, LPCSTR szIcon, char* szTip); + +void DialogAddContactExecute(HWND hwndDlg, HANDLE hNewContact); + +HICON LoadContactProtoIcon(HANDLE hContact); + +void EnableDlgItem(HWND hwndDlg, UINT control, int state); + +/// Unicode 2 in 1 Framework +size_t __fastcall strlenT(const TCHAR *string); +TCHAR* __fastcall strdupT(const TCHAR *string); +int __fastcall strcmpT(const TCHAR *string1, const TCHAR *string2); +TCHAR* __fastcall strcpyT(TCHAR* dest, const TCHAR* src); +TCHAR* __fastcall strncpyT(TCHAR* dest, const TCHAR* src, size_t len); +TCHAR* __fastcall strcatT(TCHAR* dest, const TCHAR* src); +int _snprintfT(TCHAR *buffer, size_t count, const char* fmt, ...); + +LRESULT SendMessageT(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +TCHAR* GetWindowTextT(HWND hWnd); +BOOL SetWindowTextT(HWND hWnd, TCHAR* lpString); +TCHAR* GetDlgItemTextT(HWND hDlg, int nIDDlgItem); +BOOL SetDlgItemTextT(HWND hDlg, int nIDDlgItem, TCHAR* lpString); +HWND CreateDialogParamT(HINSTANCE hInstance, const char* szTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam); +int ListView_InsertColumnT(HWND hwnd, int iCol, const LPLVCOLUMN pcol); +void ListView_SetItemTextT(HWND hwnd, int i, int iSubItem, TCHAR* pszText); + +TCHAR* __fastcall SRCTranslateT(const char* src, const WCHAR* unibuf); + +void InitI18N(void); +TCHAR* ansi_to_tchar(const char* string, int codepage = CP_ACP); +char* tchar_to_ansi(const TCHAR* src); +TCHAR* utf8_to_tchar(const unsigned char* utf); +unsigned char *make_utf8_string(const wchar_t *unicode); + + +#endif /* __UTILS_H */ \ No newline at end of file diff --git a/plugins/ContactsPlus/utils.cpp b/plugins/ContactsPlus/utils.cpp deleted file mode 100644 index 1838b3bea8..0000000000 --- a/plugins/ContactsPlus/utils.cpp +++ /dev/null @@ -1,832 +0,0 @@ -// --------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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. -// -// --------------------------------------------------------------------------- - -#include "contacts.h" - -int utf8_decode(const unsigned char *from, char **to); - -/* a strlennull() that likes NULL */ -size_t __fastcall strlennull(const char *string) -{ - if (string) - return strlen(string); - - return 0; -} - - -int __fastcall strcmpnull(const char *str1, const char *str2) -{ - if (!str1 || !str2) return 1; - - return strcmp(str1, str2); -} - - -char* __fastcall null_strdup(const char *string) -{ - if (string) - return strdup(string); - - return NULL; -} - - -void __fastcall SAFE_FREE(void** p) -{ - if (*p) - { - free(*p); - *p = NULL; - } -} - - -char *GetContactProto(HANDLE hContact) -{ - return (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); -} - - -TCHAR *GetContactDisplayNameT(HANDLE hContact) -{ - return (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, g_UnicodeCore ? GCDNF_UNICODE : 0); -} - - -char *GetContactUID(HANDLE hContact, int bTchar) -{ - DBVARIANT vrUid; - char *szUid = NULL; - - char *szProto = GetContactProto(hContact); - char *uid = (char*)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); // v0.3+ only - - if (((int)uid != CALLSERVICE_NOTFOUND) && uid) - { // it worked, yeah :) - if (!DBGetContactSettingT(hContact, szProto, uid, &vrUid)) - { - if (vrUid.type == DBVT_DWORD) - { - szUid = (char*)_alloca(17); - szUid[0] = 0; // empty string - _itoa(vrUid.dVal, szUid, 10); - } - else if (vrUid.type == DBVT_ASCIIZ) - { - szUid = (char*)_alloca(strlennull(vrUid.pszVal) + 1); - strcpy(szUid, vrUid.pszVal); - } - else if (vrUid.type == DBVT_UTF8) - { // yeah, jabber gives this! - char *szAnsi = NULL; - - if (utf8_decode((unsigned char*)vrUid.pszVal, &szAnsi)) - { - szUid = (char*)_alloca(strlennull(szAnsi) + 1); - strcpy(szUid, szAnsi); - SAFE_FREE((void**)&szAnsi); - } - } - DBFreeVariant(&vrUid); - } - } - if (bTchar) - return ansi_to_tchar(szUid); - else - return null_strdup(szUid); -} - - -TCHAR* MirandaStatusToStringT(int mirandaStatus) -{ - return (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, mirandaStatus, g_UnicodeCore ? GSMDF_UNICODE : 0); -} - -HANDLE __fastcall SRCFindFirstContact() -{ - return (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); -} - -HANDLE __fastcall SRCFindNextContact(HANDLE hContact) -{ - return (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); -} - -int DBGetContactSettingT(HANDLE hContact, const char *szModule, const char* szSetting, DBVARIANT *dbv) -{ - if (ServiceExists(MS_DB_CONTACT_GETSETTING_STR)) - return DBGetContactSettingW(hContact, szModule, szSetting, dbv); - else - return DBGetContactSetting(hContact, szModule, szSetting, dbv); -} - - -TCHAR* DBGetContactSettingStringT(HANDLE hContact, const char *szModule, const char* szSetting, TCHAR* szDef) -{ - DBVARIANT dbv = {DBVT_DELETED}; - TCHAR* szRes; - - if (g_UnicodeCore) - { - if (DBGetContactSettingWString(hContact, szModule, szSetting, &dbv)) - return strdupT(szDef); - - szRes = strdupT(dbv.ptszVal); - DBFreeVariant(&dbv); - } - else - { - if (DBGetContactSettingT(hContact, szModule, szSetting, &dbv)) - return strdupT(szDef); - - if (dbv.type == DBVT_ASCIIZ) - szRes = ansi_to_tchar(dbv.pszVal); - else if (dbv.type == DBVT_UTF8) - szRes = utf8_to_tchar((unsigned char*)dbv.pszVal); - else - szRes = strdupT(szDef); - DBFreeVariant(&dbv); - } - return szRes; -} - -int DBWriteContactSettingStringT(HANDLE hContact, const char *szModule, const char* szSetting, TCHAR* szValue) -{ - if (g_UnicodeCore) - return DBWriteContactSettingWString(hContact, szModule, szSetting, (WCHAR*)szValue); - else - return DBWriteContactSettingString(hContact, szModule, szSetting, (char*)szValue); -} - - - -void DialogAddContactExecute(HWND hwndDlg, HANDLE hNewContact) -{ - ADDCONTACTSTRUCT acs={0}; - - acs.handle = hNewContact; - acs.handleType = HANDLE_CONTACT; - - CallService(MS_ADDCONTACT_SHOW, (WPARAM)hwndDlg, (LPARAM)&acs); -} - - -void DrawProtocolIcon(HWND hwndDlg, LPARAM lParam, HANDLE hContact) -{ - LPDRAWITEMSTRUCT dis=(LPDRAWITEMSTRUCT)lParam; - - if (dis->hwndItem==GetDlgItem(hwndDlg, IDC_PROTOCOL)) - { - HICON hIcon = LoadContactProtoIcon(hContact); - if (hIcon) - { - DrawIconEx(dis->hDC,dis->rcItem.left,dis->rcItem.top,hIcon,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL); - DestroyIcon(hIcon); - } - } -} - - -void UpdateDialogTitle(HWND hwndDlg, HANDLE hContact, char* pszTitleStart) -{ - TCHAR newtitle[512]; - WCHAR str[MAX_PATH]; - TCHAR *oldTitle; - TCHAR *szStatus; - char *szProto; - - if (hContact) - { - szProto = GetContactProto(hContact); - if (szProto) - { - TCHAR *uid = GetContactUID(hContact, TRUE); - TCHAR *contactName = GetContactDisplayNameT(hContact); - - oldTitle = GetDlgItemTextT(hwndDlg, IDC_NAME); - - if (strcmpT(uid?uid:contactName, oldTitle)) - SetDlgItemTextT(hwndDlg, IDC_NAME, uid?uid:contactName); - - szStatus = MirandaStatusToStringT(szProto==NULL ? ID_STATUS_OFFLINE:DBGetContactSettingWord(hContact,szProto,"Status",ID_STATUS_OFFLINE)); - _snprintfT(newtitle, 256, "%s %s (%s)", SRCTranslateT(pszTitleStart, str), contactName, szStatus); - - SAFE_FREE((void**)&uid); - SAFE_FREE((void**)&oldTitle); - } - else - strncpyT(newtitle, SRCTranslateT(pszTitleStart, str), 256); - } - else - strncpyT(newtitle, SRCTranslateT(pszTitleStart, str), 256); - - oldTitle = GetWindowTextT(hwndDlg); - - if (strcmpT(newtitle, oldTitle)) - SetWindowTextT(hwndDlg, newtitle); - - SAFE_FREE((void**)&oldTitle); -} - - -void UpdateDialogAddButton(HWND hwndDlg, HANDLE hContact) -{ - int bVisible = DBGetContactSettingByte(hContact,"CList","NotOnList",0); - - ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), bVisible?SW_SHOW:SW_HIDE); -} - - -HICON InitMButton(HWND hDlg, int idButton, LPCSTR szIcon, char* szTip) -{ - HWND hButton = GetDlgItem(hDlg, idButton); - HICON hIcon = (HICON)LoadImage(GetModuleHandle(NULL),szIcon,IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0); - - SendMessageT(hButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - SendMessageT(hButton, BUTTONSETASFLATBTN, TRUE, 0); - SendMessageT(hButton, BUTTONADDTOOLTIP, (WPARAM)Translate(szTip), 0); - - return hIcon; -} - - -HICON LoadContactProtoIcon(HANDLE hContact) -{ - char* szProto = GetContactProto(hContact); - if (szProto) - return (HICON)CallProtoService(szProto, PS_LOADICON, PLI_PROTOCOL|PLIF_SMALL, 0); - return NULL; -} - - -void EnableDlgItem(HWND hwndDlg, UINT control, int state) -{ - EnableWindow(GetDlgItem(hwndDlg, control), state); -} - - -LRESULT SendMessageT(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - if (g_UnicodeCore) - return SendMessageW(hWnd, Msg, wParam, lParam); - else - return SendMessageA(hWnd, Msg, wParam, lParam); -} - -TCHAR* GetWindowTextT(HWND hWnd) -{ - if (g_UnicodeCore) - { - int len = GetWindowTextLengthW(hWnd) + 1; - WCHAR* txt = (WCHAR*)malloc(len * sizeof(WCHAR)); - if (txt) { - txt[0] = 0; - GetWindowTextW(hWnd, txt, len); - } - return (TCHAR*)txt; - } - else - { - int len = GetWindowTextLengthA(hWnd) + 1; - char* txt = (char*)malloc(len * sizeof(char)); - if (txt) { - txt[0] = 0; - GetWindowTextA(hWnd, txt, len); - } - return (TCHAR*)txt; - } -} - -BOOL SetWindowTextT(HWND hWnd, TCHAR* lpString) -{ - if (g_UnicodeCore) - return SetWindowTextW(hWnd, (WCHAR*)lpString); - else - return SetWindowTextA(hWnd, lpString); -} - -TCHAR* GetDlgItemTextT(HWND hDlg, int nIDDlgItem) -{ - return GetWindowTextT(GetDlgItem(hDlg, nIDDlgItem)); -} - -BOOL SetDlgItemTextT(HWND hDlg, int nIDDlgItem, TCHAR* lpString) -{ - return SetWindowTextT(GetDlgItem(hDlg, nIDDlgItem), lpString); -} - -HWND CreateDialogParamT(HINSTANCE hInstance, const char* szTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) -{ - if (g_UnicodeCore) - return CreateDialogParamW(hInstance, (LPCWSTR)szTemplate, hWndParent, lpDialogFunc, dwInitParam); - else - return CreateDialogParamA(hInstance, szTemplate, hWndParent, lpDialogFunc, dwInitParam); -} - -int ListView_InsertColumnT(HWND hwnd, int iCol, const LPLVCOLUMN pcol) -{ - return SendMessageT(hwnd, g_UnicodeCore ? LVM_INSERTCOLUMNW : LVM_INSERTCOLUMNA, (WPARAM)iCol, (LPARAM)pcol); -} - -void ListView_SetItemTextT(HWND hwnd, int i, int iSubItem, TCHAR* pszText) -{ - LV_ITEM lvi = {0}; - - lvi.iSubItem = iSubItem; - lvi.pszText = pszText; - SendMessageT(hwnd, g_UnicodeCore ? LVM_SETITEMTEXTW : LVM_SETITEMTEXTA, (WPARAM)i, (LPARAM)&lvi); -} - - - -size_t __fastcall strlenT(const TCHAR *string) -{ - if (string) - { - if (g_UnicodeCore) - return wcslen((WCHAR*)string); - else - return strlen((char*)string); - } - return 0; -} - -TCHAR* __fastcall strdupT(const TCHAR *string) -{ - if (string) - { - if (g_UnicodeCore) - return (TCHAR*)wcsdup((WCHAR*)string); - else - return (TCHAR*)strdup((char*)string); - } - return NULL; -} - -int __fastcall strcmpT(const TCHAR *string1, const TCHAR *string2) -{ - if (!string1 || !string2) return 1; - - if (g_UnicodeCore) - return wcscmp((WCHAR*)string1, (WCHAR*)string2); - else - return strcmp((char*)string1, (char*)string2); -} - -TCHAR* __fastcall strcpyT(TCHAR* dest, const TCHAR* src) -{ - if (src) - { - if (g_UnicodeCore) - return (TCHAR*)wcscpy((WCHAR*)dest, (WCHAR*)src); - else - return (TCHAR*)strcpy((char*)dest, (char*)src); - } - return dest; -} - -TCHAR* __fastcall strncpyT(TCHAR* dest, const TCHAR* src, size_t len) -{ - if (src) - { - if (g_UnicodeCore) - return (TCHAR*)wcsncpy((WCHAR*)dest, (WCHAR*)src, len); - else - return (TCHAR*)strncpy((char*)dest, (char*)src, len); - } - return dest; -} - -TCHAR* __fastcall strcatT(TCHAR* dest, const TCHAR* src) -{ - if (src) - { - if (g_UnicodeCore) - return (TCHAR*)wcscat((WCHAR*)dest, (WCHAR*)src); - else - return (TCHAR*)strcat((char*)dest, (char*)src); - } - return dest; -} - -int _snprintfT(TCHAR *buffer, size_t count, const char* fmt, ...) -{ - va_list va; - int len; - - va_start(va, fmt); - if (g_UnicodeCore) - { - TCHAR* wfmt = ansi_to_tchar(fmt); - - len = _vsnwprintf((WCHAR*)buffer, count-1, (WCHAR*)wfmt, va); - ((WCHAR*)buffer)[count-1] = 0; - SAFE_FREE((void**)&wfmt); - } - else - { - len = _vsnprintf((char*)buffer, count-1, fmt, va); - ((char*)buffer)[count-1] = 0; - } - va_end(va); - return len; -} - -TCHAR* __fastcall SRCTranslateT(const char* src, const WCHAR* unibuf) -{ // this takes Ascii strings only!!! - char* szRes = NULL; - - if (!strlennull(src)) - { // for the case of empty strings - return ""; - } - - if (g_UnicodeCore) - { // we give WCHAR - WCHAR *unicode; - int wchars, err; - - wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, - (int)strlennull(src), NULL, 0); - - if (wchars == 0) return NULL; // Failure - - unicode = (WCHAR*)unibuf; - if (!unicode) - unicode = (WCHAR*)malloc((wchars + 1) * sizeof(WCHAR)); - - unicode[wchars] = 0; - - err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, - (int)strlennull(src), unicode, wchars); - if (err != wchars) return NULL; // Failure - - return (TCHAR*)TranslateW(unicode); - } - else - return (TCHAR*)Translate(src); -} - -static BOOL bHasCP_UTF8 = FALSE; - - -void InitI18N(void) -{ - CPINFO CPInfo; - - - bHasCP_UTF8 = GetCPInfo(CP_UTF8, &CPInfo); -} - - -// Scans a string encoded in UTF-8 to verify that it contains -// only valid sequences. It will return 1 if the string contains -// only legitimate encoding sequences; otherwise it will return 0; -// From 'Secure Programming Cookbook', John Viega & Matt Messier, 2003 -int UTF8_IsValid(const unsigned char* pszInput) -{ - int nb, i; - const unsigned char* c = pszInput; - - if (!pszInput) return 0; - - for (c = pszInput; *c; c += (nb + 1)) - { - if (!(*c & 0x80)) - nb = 0; - else if ((*c & 0xc0) == 0x80) return 0; - else if ((*c & 0xe0) == 0xc0) nb = 1; - else if ((*c & 0xf0) == 0xe0) nb = 2; - else if ((*c & 0xf8) == 0xf0) nb = 3; - else if ((*c & 0xfc) == 0xf8) nb = 4; - else if ((*c & 0xfe) == 0xfc) nb = 5; - - for (i = 1; i<=nb; i++) // we this forward, do not cross end of string - if ((*(c + i) & 0xc0) != 0x80) - return 0; - } - - return 1; -} - - -/* - * The following UTF8 routines are - * - * Copyright (C) 2001 Peter Harris - * Copyright (C) 2001 Edmund Grimley Evans - * - * under a GPL license - * - * -------------------------------------------------------------- - * Convert a string between UTF-8 and the locale's charset. - * Invalid bytes are replaced by '#', and characters that are - * not available in the target encoding are replaced by '?'. - * - * If the locale's charset is not set explicitly then it is - * obtained using nl_langinfo(CODESET), where available, the - * environment variable CHARSET, or assumed to be US-ASCII. - * - * Return value of conversion functions: - * - * -1 : memory allocation failed - * 0 : data was converted exactly - * 1 : valid data was converted approximately (using '?') - * 2 : input was invalid (but still converted, using '#') - * 3 : unknown encoding (but still converted, using '?') - */ - - - -/* - * Convert a string between UTF-8 and the locale's charset. - */ -unsigned char *make_utf8_string(const wchar_t *unicode) -{ - int size = 0; - int index = 0; - int out_index = 0; - unsigned char* out; - unsigned short c; - - if (!unicode) return NULL; - - /* first calculate the size of the target string */ - c = unicode[index++]; - while (c) - { - if (c < 0x0080) - size += 1; - else if (c < 0x0800) - size += 2; - else - size += 3; - c = unicode[index++]; - } - - out = (unsigned char*)malloc(size + 1); - if (out == NULL) - return NULL; - index = 0; - - c = unicode[index++]; - while (c) - { - if (c < 0x080) - { - out[out_index++] = (unsigned char)c; - } - else if (c < 0x800) - { - out[out_index++] = 0xc0 | (c >> 6); - out[out_index++] = 0x80 | (c & 0x3f); - } - else - { - out[out_index++] = 0xe0 | (c >> 12); - out[out_index++] = 0x80 | ((c >> 6) & 0x3f); - out[out_index++] = 0x80 | (c & 0x3f); - } - c = unicode[index++]; - } - out[out_index] = 0x00; - - return out; -} - - - -WCHAR *make_unicode_string(const unsigned char *utf8) -{ - int size = 0, index = 0, out_index = 0; - wchar_t *out; - unsigned char c; - - if (!utf8) return NULL; - - /* first calculate the size of the target string */ - c = utf8[index++]; - while (c) - { - if ((c & 0x80) == 0) - { - index += 0; - } - else if ((c & 0xe0) == 0xe0) - { - index += 2; - } - else - { - index += 1; - } - size += 1; - c = utf8[index++]; - } - - out = (wchar_t*)malloc((size + 1) * sizeof(wchar_t)); - if (out == NULL) - return NULL; - index = 0; - - c = utf8[index++]; - while (c) - { - if ((c & 0x80) == 0) - { - out[out_index++] = c; - } - else if ((c & 0xe0) == 0xe0) - { - out[out_index] = (c & 0x1F) << 12; - c = utf8[index++]; - out[out_index] |= (c & 0x3F) << 6; - c = utf8[index++]; - out[out_index++] |= (c & 0x3F); - } - else - { - out[out_index] = (c & 0x3F) << 6; - c = utf8[index++]; - out[out_index++] |= (c & 0x3F); - } - c = utf8[index++]; - } - out[out_index] = 0; - - return out; -} - - -// Returns 0 on error, 1 on success -static int utf8_decode(const unsigned char *from, char **to) -{ - int nResult = 0; - -// _ASSERTE(!(*to)); // You passed a non-zero pointer, make sure it doesnt point to unfreed memory - - // Validate the string - if (!UTF8_IsValid(from)) - return 0; - - // Use the native conversion routines when available - if (bHasCP_UTF8) - { - WCHAR *wszTemp = NULL; - int inlen = (int)strlennull((char*)from); - - wszTemp = (WCHAR *)_alloca(sizeof(WCHAR) * (inlen + 1)); - - // Convert the UTF-8 string to UCS - if (MultiByteToWideChar(CP_UTF8, 0, (char*)from, -1, wszTemp, inlen + 1)) - { - // Convert the UCS string to local ANSI codepage - *to = (char*)malloc(inlen+1); - if (WideCharToMultiByte(CP_ACP, 0, wszTemp, -1, *to, inlen+1, NULL, NULL)) - { - nResult = 1; - } - else - { - SAFE_FREE((void**)to); - } - } - } - else - { - wchar_t *unicode; - int chars; - int err; - - unicode = make_unicode_string(from); - if (unicode == NULL) - { -// fprintf(stderr, "Out of memory processing string from UTF8 to UNICODE16\n"); - return 0; - } - - chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); - - if(chars == 0) - { -// fprintf(stderr, "Unicode translation error %d\n", GetLastError()); - SAFE_FREE((void**)&unicode); - return 0; - } - - *to = (char*)malloc((chars + 1)*sizeof(unsigned char)); - if (*to == NULL) - { -// fprintf(stderr, "Out of memory processing string to local charset\n"); - SAFE_FREE((void**)&unicode); - return 0; - } - - err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); - if (err != chars) - { -// fprintf(stderr, "Unicode translation error %d\n", GetLastError()); - SAFE_FREE((void**)&unicode); - SAFE_FREE((void**)to); - return 0; - } - - SAFE_FREE((void**)&unicode); - - nResult = 1; - } - - return nResult; -} - - - -TCHAR* ansi_to_tchar(const char* src, int codepage) -{ - if (g_UnicodeCore) - { - WCHAR *unicode; - int wchars, err; - - wchars = MultiByteToWideChar(codepage, MB_PRECOMPOSED, src, (int)strlennull(src), NULL, 0); - - if (wchars == 0) return NULL; // Failure - - unicode = (WCHAR*)malloc((wchars + 1) * sizeof(WCHAR)); - unicode[wchars] = 0; - - err = MultiByteToWideChar(codepage, MB_PRECOMPOSED, src, (int)strlennull(src), unicode, wchars); - if (err != wchars) - { - SAFE_FREE((void**)&unicode); - return NULL; // Failure - } - - return (TCHAR*)unicode; - } - else - return strdupT((TCHAR*)src); -} - -char* tchar_to_ansi(const TCHAR* src) -{ - if (g_UnicodeCore) - { - char *ansi; - int chars; - int err; - - chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (WCHAR*)src, -1, NULL, 0, NULL, NULL); - - if (chars == 0) return NULL; // Failure - - ansi = (char*)malloc((chars + 1)*sizeof(char)); - if (ansi == NULL) return NULL; // Failure - - err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (WCHAR*)src, -1, ansi, chars, NULL, NULL); - if (err != chars) - { - SAFE_FREE((void**)&ansi); - return NULL; - } - return ansi; - } - else - return (char*)strdupT(src); -} - -TCHAR* utf8_to_tchar(const unsigned char* utf) -{ - if (g_UnicodeCore) - return (TCHAR*)make_unicode_string(utf); - else - { - char* szAnsi = NULL; - - if (utf8_decode(utf, &szAnsi)) - return (TCHAR*)szAnsi; - else - return NULL; // Failure - } -} \ No newline at end of file diff --git a/plugins/ContactsPlus/utils.h b/plugins/ContactsPlus/utils.h deleted file mode 100644 index 3bc2d8e00d..0000000000 --- a/plugins/ContactsPlus/utils.h +++ /dev/null @@ -1,86 +0,0 @@ -// --------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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. -// -// --------------------------------------------------------------------------- - -#ifndef __UTILS_H -#define __UTILS_H - - -extern HINSTANCE hInst; - -// utils.cpp -void __fastcall SAFE_FREE(void** p); -size_t __fastcall strlennull(const char *string); -int __fastcall strcmpnull(const char *str1, const char *str2); -char* __fastcall null_strdup(const char *string); - -char *GetContactProto(HANDLE hContact); -char *GetContactUID(HANDLE hContact, int bTchar); -TCHAR *GetContactDisplayNameT(HANDLE hContact); -TCHAR* MirandaStatusToStringT(int mirandaStatus); - -HANDLE __fastcall SRCFindFirstContact(); -HANDLE __fastcall SRCFindNextContact(HANDLE hContact); -int DBGetContactSettingT(HANDLE hContact, const char *szModule, const char* szSetting, DBVARIANT *dbv); -TCHAR* DBGetContactSettingStringT(HANDLE hContact, const char *szModule,const char* szSetting, TCHAR* szDef); -int DBWriteContactSettingStringT(HANDLE hContact, const char *szModule, const char* szSetting, TCHAR* szValue); - -void DrawProtocolIcon(HWND hwndDlg, LPARAM lParam, HANDLE hContact); -void UpdateDialogTitle(HWND hwndDlg, HANDLE hContact, char* pszTitleStart); -void UpdateDialogAddButton(HWND hwndDlg, HANDLE hContact); - -HICON InitMButton(HWND hDlg, int idButton, LPCSTR szIcon, char* szTip); - -void DialogAddContactExecute(HWND hwndDlg, HANDLE hNewContact); - -HICON LoadContactProtoIcon(HANDLE hContact); - -void EnableDlgItem(HWND hwndDlg, UINT control, int state); - -/// Unicode 2 in 1 Framework -size_t __fastcall strlenT(const TCHAR *string); -TCHAR* __fastcall strdupT(const TCHAR *string); -int __fastcall strcmpT(const TCHAR *string1, const TCHAR *string2); -TCHAR* __fastcall strcpyT(TCHAR* dest, const TCHAR* src); -TCHAR* __fastcall strncpyT(TCHAR* dest, const TCHAR* src, size_t len); -TCHAR* __fastcall strcatT(TCHAR* dest, const TCHAR* src); -int _snprintfT(TCHAR *buffer, size_t count, const char* fmt, ...); - -LRESULT SendMessageT(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); -TCHAR* GetWindowTextT(HWND hWnd); -BOOL SetWindowTextT(HWND hWnd, TCHAR* lpString); -TCHAR* GetDlgItemTextT(HWND hDlg, int nIDDlgItem); -BOOL SetDlgItemTextT(HWND hDlg, int nIDDlgItem, TCHAR* lpString); -HWND CreateDialogParamT(HINSTANCE hInstance, const char* szTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam); -int ListView_InsertColumnT(HWND hwnd, int iCol, const LPLVCOLUMN pcol); -void ListView_SetItemTextT(HWND hwnd, int i, int iSubItem, TCHAR* pszText); - -TCHAR* __fastcall SRCTranslateT(const char* src, const WCHAR* unibuf); - -void InitI18N(void); -TCHAR* ansi_to_tchar(const char* string, int codepage = CP_ACP); -char* tchar_to_ansi(const TCHAR* src); -TCHAR* utf8_to_tchar(const unsigned char* utf); -unsigned char *make_utf8_string(const wchar_t *unicode); - - -#endif /* __UTILS_H */ \ No newline at end of file -- cgit v1.2.3