From cbe3cb21f5bca61a03bbd4ae811ee906e09b3f4f Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 13 Jun 2015 16:55:17 +0000 Subject: - miranda32.exe now does nothing bug extends PATH to %miranda_root%\libs and loads mir_app.dll; - everything that was in miranda32.exe (including resources) moved to mir_app.dll; - exports from mir_app.dll now available for using directly, without perversions; - src/stdplug.h deleted; git-svn-id: http://svn.miranda-ng.org/main/trunk@14143 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- src/modules/addcontact/addcontact.cpp | 247 --- src/modules/button/button.cpp | 629 ------ src/modules/chat/chat.h | 110 - src/modules/chat/chat_opts.cpp | 351 --- src/modules/chat/chat_rtf.cpp | 204 -- src/modules/chat/chat_svc.cpp | 631 ------ src/modules/chat/clist.cpp | 250 --- src/modules/chat/colorchooser.cpp | 284 --- src/modules/chat/log.cpp | 542 ----- src/modules/chat/manager.cpp | 1331 ----------- src/modules/chat/tools.cpp | 768 ------- src/modules/clist/Docking.cpp | 363 --- src/modules/clist/clc.cpp | 1334 ----------- src/modules/clist/clc.h | 207 -- src/modules/clist/clcfiledrop.cpp | 277 --- src/modules/clist/clcidents.cpp | 210 -- src/modules/clist/clcitems.cpp | 705 ------ src/modules/clist/clcmsgs.cpp | 474 ---- src/modules/clist/clcutils.cpp | 877 -------- src/modules/clist/clistcore.cpp | 232 -- src/modules/clist/clistevents.cpp | 423 ---- src/modules/clist/clistmenus.cpp | 1351 ----------- src/modules/clist/clistmod.cpp | 540 ----- src/modules/clist/clistsettings.cpp | 285 --- src/modules/clist/clisttray.cpp | 877 -------- src/modules/clist/clui.cpp | 1074 --------- src/modules/clist/cluiservices.cpp | 213 -- src/modules/clist/contact.cpp | 176 -- src/modules/clist/contacts.cpp | 452 ---- src/modules/clist/genmenu.cpp | 1236 ----------- src/modules/clist/genmenu.h | 146 -- src/modules/clist/genmenuopt.cpp | 481 ---- src/modules/clist/groups.cpp | 587 ----- src/modules/clist/keyboard.cpp | 112 - src/modules/clist/movetogroup.cpp | 149 -- src/modules/clist/protocolorder.cpp | 231 -- src/modules/crypt/encrypt.cpp | 88 - src/modules/database/database.cpp | 538 ----- src/modules/database/database.h | 53 - src/modules/database/dbini.cpp | 520 ----- src/modules/database/dbintf.cpp | 167 -- src/modules/database/dbutils.cpp | 367 --- src/modules/database/mdatabasecache.cpp | 252 --- src/modules/database/profilemanager.cpp | 649 ------ src/modules/database/profilemanager.h | 45 - src/modules/extraicons/BaseExtraIcon.cpp | 80 - src/modules/extraicons/CallbackExtraIcon.cpp | 75 - src/modules/extraicons/DefaultExtraIcons.cpp | 326 --- src/modules/extraicons/ExtraIcon.cpp | 75 - src/modules/extraicons/ExtraIcon.h | 180 -- src/modules/extraicons/ExtraIconGroup.cpp | 217 -- src/modules/extraicons/IcolibExtraIcon.cpp | 119 - src/modules/extraicons/extraicons.cpp | 545 ----- src/modules/extraicons/extraicons.h | 72 - src/modules/extraicons/options_ei.cpp | 472 ---- src/modules/extraicons/usedIcons.cpp | 94 - src/modules/extraicons/usedIcons.h | 34 - src/modules/findadd/findadd.cpp | 1061 --------- src/modules/findadd/findadd.h | 65 - src/modules/findadd/searchresults.cpp | 374 ---- src/modules/fonts/FontOptions.cpp | 1390 ------------ src/modules/fonts/FontService.cpp | 115 - src/modules/fonts/FontService.h | 80 - src/modules/fonts/services.cpp | 501 ----- src/modules/icolib/IcoLib.h | 108 - src/modules/icolib/extracticon.cpp | 282 --- src/modules/icolib/skin2icons.cpp | 902 -------- src/modules/icolib/skin2opts.cpp | 1047 --------- src/modules/ignore/ignore.cpp | 441 ---- src/modules/langpack/langpack.cpp | 94 - src/modules/langpack/langpack.h | 58 - src/modules/langpack/lpopts.cpp | 212 -- src/modules/langpack/lpservices.cpp | 113 - src/modules/metacontacts/meta_addto.cpp | 224 -- src/modules/metacontacts/meta_api.cpp | 72 - src/modules/metacontacts/meta_edit.cpp | 452 ---- src/modules/metacontacts/meta_main.cpp | 85 - src/modules/metacontacts/meta_menu.cpp | 449 ---- src/modules/metacontacts/meta_options.cpp | 129 -- src/modules/metacontacts/meta_services.cpp | 912 -------- src/modules/metacontacts/meta_utils.cpp | 576 ----- src/modules/metacontacts/metacontacts.h | 129 -- src/modules/netlib/netlib.cpp | 527 ----- src/modules/netlib/netlib.h | 220 -- src/modules/netlib/netlibautoproxy.cpp | 453 ---- src/modules/netlib/netlibbind.cpp | 307 --- src/modules/netlib/netlibhttp.cpp | 1168 ---------- src/modules/netlib/netlibhttpproxy.cpp | 459 ---- src/modules/netlib/netliblog.cpp | 532 ----- src/modules/netlib/netlibopenconn.cpp | 890 -------- src/modules/netlib/netlibopts.cpp | 530 ----- src/modules/netlib/netlibpktrecver.cpp | 89 - src/modules/netlib/netlibsecurity.cpp | 427 ---- src/modules/netlib/netlibsock.cpp | 313 --- src/modules/netlib/netlibupnp.cpp | 826 ------- src/modules/options/descbutton.cpp | 326 --- src/modules/options/filter.cpp | 159 -- src/modules/options/filter.h | 95 - src/modules/options/headerbar.cpp | 349 --- src/modules/options/iconheader.cpp | 534 ----- src/modules/options/options.cpp | 1327 ----------- src/modules/plugins/dll_sniffer.cpp | 159 -- src/modules/plugins/newplugins.cpp | 898 -------- src/modules/plugins/pluginopts.cpp | 575 ----- src/modules/plugins/plugins.h | 84 - src/modules/protocols/protoaccs.cpp | 453 ---- src/modules/protocols/protochains.cpp | 253 --- src/modules/protocols/protocols.cpp | 511 ----- src/modules/protocols/protodir.cpp | 243 -- src/modules/protocols/protoint.cpp | 304 --- src/modules/protocols/protoopts.cpp | 1062 --------- src/modules/skin/hotkey_opts.cpp | 1048 --------- src/modules/skin/hotkeys.cpp | 412 ---- src/modules/skin/skin.h | 75 - src/modules/skin/skinicons.cpp | 505 ----- src/modules/skin/sounds.cpp | 470 ---- src/modules/srmm/statusicon.cpp | 221 -- src/modules/utils/colourpicker.cpp | 108 - src/modules/utils/enterstring.cpp | 274 --- src/modules/utils/hyperlink.cpp | 272 --- src/modules/utils/imgconv.cpp | 144 -- src/modules/utils/openurl.cpp | 82 - src/modules/utils/path.cpp | 458 ---- src/modules/utils/resizer.cpp | 158 -- src/modules/utils/timeutils.cpp | 103 - src/modules/utils/timezones.cpp | 557 ----- src/modules/utils/utils.cpp | 496 ----- src/modules/utils/windowlist.cpp | 111 - src/modules/visibility/visibility.cpp | 289 --- src/modules/xml/xmlApi.cpp | 467 ---- src/modules/xml/xmlParser.cpp | 3076 -------------------------- src/modules/xml/xmlParser.h | 715 ------ 132 files changed, 57312 deletions(-) delete mode 100644 src/modules/addcontact/addcontact.cpp delete mode 100644 src/modules/button/button.cpp delete mode 100644 src/modules/chat/chat.h delete mode 100644 src/modules/chat/chat_opts.cpp delete mode 100644 src/modules/chat/chat_rtf.cpp delete mode 100644 src/modules/chat/chat_svc.cpp delete mode 100644 src/modules/chat/clist.cpp delete mode 100644 src/modules/chat/colorchooser.cpp delete mode 100644 src/modules/chat/log.cpp delete mode 100644 src/modules/chat/manager.cpp delete mode 100644 src/modules/chat/tools.cpp delete mode 100644 src/modules/clist/Docking.cpp delete mode 100644 src/modules/clist/clc.cpp delete mode 100644 src/modules/clist/clc.h delete mode 100644 src/modules/clist/clcfiledrop.cpp delete mode 100644 src/modules/clist/clcidents.cpp delete mode 100644 src/modules/clist/clcitems.cpp delete mode 100644 src/modules/clist/clcmsgs.cpp delete mode 100644 src/modules/clist/clcutils.cpp delete mode 100644 src/modules/clist/clistcore.cpp delete mode 100644 src/modules/clist/clistevents.cpp delete mode 100644 src/modules/clist/clistmenus.cpp delete mode 100644 src/modules/clist/clistmod.cpp delete mode 100644 src/modules/clist/clistsettings.cpp delete mode 100644 src/modules/clist/clisttray.cpp delete mode 100644 src/modules/clist/clui.cpp delete mode 100644 src/modules/clist/cluiservices.cpp delete mode 100644 src/modules/clist/contact.cpp delete mode 100644 src/modules/clist/contacts.cpp delete mode 100644 src/modules/clist/genmenu.cpp delete mode 100644 src/modules/clist/genmenu.h delete mode 100644 src/modules/clist/genmenuopt.cpp delete mode 100644 src/modules/clist/groups.cpp delete mode 100644 src/modules/clist/keyboard.cpp delete mode 100644 src/modules/clist/movetogroup.cpp delete mode 100644 src/modules/clist/protocolorder.cpp delete mode 100644 src/modules/crypt/encrypt.cpp delete mode 100644 src/modules/database/database.cpp delete mode 100644 src/modules/database/database.h delete mode 100644 src/modules/database/dbini.cpp delete mode 100644 src/modules/database/dbintf.cpp delete mode 100644 src/modules/database/dbutils.cpp delete mode 100644 src/modules/database/mdatabasecache.cpp delete mode 100644 src/modules/database/profilemanager.cpp delete mode 100644 src/modules/database/profilemanager.h delete mode 100644 src/modules/extraicons/BaseExtraIcon.cpp delete mode 100644 src/modules/extraicons/CallbackExtraIcon.cpp delete mode 100644 src/modules/extraicons/DefaultExtraIcons.cpp delete mode 100644 src/modules/extraicons/ExtraIcon.cpp delete mode 100644 src/modules/extraicons/ExtraIcon.h delete mode 100644 src/modules/extraicons/ExtraIconGroup.cpp delete mode 100644 src/modules/extraicons/IcolibExtraIcon.cpp delete mode 100644 src/modules/extraicons/extraicons.cpp delete mode 100644 src/modules/extraicons/extraicons.h delete mode 100644 src/modules/extraicons/options_ei.cpp delete mode 100644 src/modules/extraicons/usedIcons.cpp delete mode 100644 src/modules/extraicons/usedIcons.h delete mode 100644 src/modules/findadd/findadd.cpp delete mode 100644 src/modules/findadd/findadd.h delete mode 100644 src/modules/findadd/searchresults.cpp delete mode 100644 src/modules/fonts/FontOptions.cpp delete mode 100644 src/modules/fonts/FontService.cpp delete mode 100644 src/modules/fonts/FontService.h delete mode 100644 src/modules/fonts/services.cpp delete mode 100644 src/modules/icolib/IcoLib.h delete mode 100644 src/modules/icolib/extracticon.cpp delete mode 100644 src/modules/icolib/skin2icons.cpp delete mode 100644 src/modules/icolib/skin2opts.cpp delete mode 100644 src/modules/ignore/ignore.cpp delete mode 100644 src/modules/langpack/langpack.cpp delete mode 100644 src/modules/langpack/langpack.h delete mode 100644 src/modules/langpack/lpopts.cpp delete mode 100644 src/modules/langpack/lpservices.cpp delete mode 100644 src/modules/metacontacts/meta_addto.cpp delete mode 100644 src/modules/metacontacts/meta_api.cpp delete mode 100644 src/modules/metacontacts/meta_edit.cpp delete mode 100644 src/modules/metacontacts/meta_main.cpp delete mode 100644 src/modules/metacontacts/meta_menu.cpp delete mode 100644 src/modules/metacontacts/meta_options.cpp delete mode 100644 src/modules/metacontacts/meta_services.cpp delete mode 100644 src/modules/metacontacts/meta_utils.cpp delete mode 100644 src/modules/metacontacts/metacontacts.h delete mode 100644 src/modules/netlib/netlib.cpp delete mode 100644 src/modules/netlib/netlib.h delete mode 100644 src/modules/netlib/netlibautoproxy.cpp delete mode 100644 src/modules/netlib/netlibbind.cpp delete mode 100644 src/modules/netlib/netlibhttp.cpp delete mode 100644 src/modules/netlib/netlibhttpproxy.cpp delete mode 100644 src/modules/netlib/netliblog.cpp delete mode 100644 src/modules/netlib/netlibopenconn.cpp delete mode 100644 src/modules/netlib/netlibopts.cpp delete mode 100644 src/modules/netlib/netlibpktrecver.cpp delete mode 100644 src/modules/netlib/netlibsecurity.cpp delete mode 100644 src/modules/netlib/netlibsock.cpp delete mode 100644 src/modules/netlib/netlibupnp.cpp delete mode 100644 src/modules/options/descbutton.cpp delete mode 100644 src/modules/options/filter.cpp delete mode 100644 src/modules/options/filter.h delete mode 100644 src/modules/options/headerbar.cpp delete mode 100644 src/modules/options/iconheader.cpp delete mode 100644 src/modules/options/options.cpp delete mode 100644 src/modules/plugins/dll_sniffer.cpp delete mode 100644 src/modules/plugins/newplugins.cpp delete mode 100644 src/modules/plugins/pluginopts.cpp delete mode 100644 src/modules/plugins/plugins.h delete mode 100644 src/modules/protocols/protoaccs.cpp delete mode 100644 src/modules/protocols/protochains.cpp delete mode 100644 src/modules/protocols/protocols.cpp delete mode 100644 src/modules/protocols/protodir.cpp delete mode 100644 src/modules/protocols/protoint.cpp delete mode 100644 src/modules/protocols/protoopts.cpp delete mode 100644 src/modules/skin/hotkey_opts.cpp delete mode 100644 src/modules/skin/hotkeys.cpp delete mode 100644 src/modules/skin/skin.h delete mode 100644 src/modules/skin/skinicons.cpp delete mode 100644 src/modules/skin/sounds.cpp delete mode 100644 src/modules/srmm/statusicon.cpp delete mode 100644 src/modules/utils/colourpicker.cpp delete mode 100644 src/modules/utils/enterstring.cpp delete mode 100644 src/modules/utils/hyperlink.cpp delete mode 100644 src/modules/utils/imgconv.cpp delete mode 100644 src/modules/utils/openurl.cpp delete mode 100644 src/modules/utils/path.cpp delete mode 100644 src/modules/utils/resizer.cpp delete mode 100644 src/modules/utils/timeutils.cpp delete mode 100644 src/modules/utils/timezones.cpp delete mode 100644 src/modules/utils/utils.cpp delete mode 100644 src/modules/utils/windowlist.cpp delete mode 100644 src/modules/visibility/visibility.cpp delete mode 100644 src/modules/xml/xmlApi.cpp delete mode 100644 src/modules/xml/xmlParser.cpp delete mode 100644 src/modules/xml/xmlParser.h (limited to 'src/modules') diff --git a/src/modules/addcontact/addcontact.cpp b/src/modules/addcontact/addcontact.cpp deleted file mode 100644 index 9379e3f283..0000000000 --- a/src/modules/addcontact/addcontact.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -class CAddContactDlg : public CDlgBase -{ - ADDCONTACTSTRUCT m_acs; - - CCtrlEdit m_authReq, m_myHandle; - CCtrlCheck m_chkAdded, m_chkAuth, m_chkOpen; - CCtrlButton m_btnOk; - CCtrlCombo m_group; - -public: - CAddContactDlg(ADDCONTACTSTRUCT *acs) : - CDlgBase(hInst, IDD_ADDCONTACT), - m_chkAdded(this, IDC_ADDED), - m_chkAuth(this, IDC_AUTH), - m_chkOpen(this, IDC_OPEN_WINDOW), - m_btnOk(this, IDOK), - m_group(this, IDC_GROUP), - m_authReq(this, IDC_AUTHREQ), - m_myHandle(this, IDC_MYHANDLE) - { - m_chkAuth.OnChange = Callback(this, &CAddContactDlg::OnAuthClicked); - m_chkOpen.OnChange = Callback(this, &CAddContactDlg::OnOpenClicked); - m_btnOk.OnClick = Callback(this, &CAddContactDlg::OnOk); - - m_acs = *acs; - if (m_acs.psr) { - PROTOSEARCHRESULT *psr = (PROTOSEARCHRESULT*)mir_alloc(m_acs.psr->cbSize); - memcpy(psr, m_acs.psr, m_acs.psr->cbSize); - psr->nick.t = (psr->flags & PSR_UNICODE) ? mir_u2t((wchar_t*)psr->nick.t) : mir_a2t((char*)psr->nick.t); - psr->firstName.t = (psr->flags & PSR_UNICODE) ? mir_u2t((wchar_t*)psr->firstName.t) : mir_a2t((char*)psr->firstName.t); - psr->lastName.t = (psr->flags & PSR_UNICODE) ? mir_u2t((wchar_t*)psr->lastName.t) : mir_a2t((char*)psr->lastName.t); - psr->email.t = (psr->flags & PSR_UNICODE) ? mir_u2t((wchar_t*)psr->email.t) : mir_a2t((char*)psr->email.t); - psr->id.t = (psr->flags & PSR_UNICODE) ? mir_u2t((wchar_t*)psr->id.t) : mir_a2t((char*)psr->id.t); - psr->flags = psr->flags & ~PSR_UNICODE | PSR_TCHAR; - m_acs.psr = psr; - } - } - - void OnInitDialog() - { - char szUin[10]; - Window_SetIcon_IcoLib(m_hwnd, SKINICON_OTHER_ADDCONTACT); - if (m_acs.handleType == HANDLE_EVENT) { - DWORD dwUin; - DBEVENTINFO dbei = { sizeof(dbei) }; - dbei.cbBlob = sizeof(DWORD); - dbei.pBlob = (PBYTE)&dwUin; - db_event_get(m_acs.hDbEvent, &dbei); - _ltoa(dwUin, szUin, 10); - m_acs.szProto = dbei.szModule; - } - - MCONTACT hContact; - TCHAR *szName = NULL, *tmpStr = NULL; - if (m_acs.handleType == HANDLE_CONTACT) - szName = cli.pfnGetContactDisplayName(hContact = m_acs.hContact, 0); - else { - int isSet = 0; - hContact = 0; - - if (m_acs.handleType == HANDLE_EVENT) { - DBEVENTINFO dbei = { sizeof(dbei) }; - dbei.cbBlob = db_event_getBlobSize(m_acs.hDbEvent); - dbei.pBlob = (PBYTE)mir_alloc(dbei.cbBlob); - db_event_get(m_acs.hDbEvent, &dbei); - hContact = *(MCONTACT*)(dbei.pBlob + sizeof(DWORD)); - mir_free(dbei.pBlob); - if (hContact != INVALID_CONTACT_ID) { - szName = cli.pfnGetContactDisplayName(hContact, 0); - isSet = 1; - } - } - if (!isSet) { - szName = (m_acs.handleType == HANDLE_EVENT) ? (tmpStr = mir_a2t(szUin)) : - (m_acs.psr->id.t ? m_acs.psr->id.t : m_acs.psr->nick.t); - } - } - - if (szName && szName[0]) - SetCaption(CMString(FORMAT, TranslateT("Add %s"), szName)); - else - SetCaption(TranslateT("Add contact")); - mir_free(tmpStr); - - if (m_acs.handleType == HANDLE_CONTACT && m_acs.hContact) - if (m_acs.szProto == NULL || (m_acs.szProto != NULL && *m_acs.szProto == 0)) - m_acs.szProto = GetContactProto(m_acs.hContact); - - int groupSel = 0; - ptrT tszGroup(db_get_tsa(hContact, "CList", "Group")); - TCHAR *grpName; - for (int groupId = 1; (grpName = cli.pfnGetGroupName(groupId, NULL)) != NULL; groupId++) { - int id = m_group.AddString(grpName, groupId); - if (!mir_tstrcmpi(tszGroup, grpName)) - groupSel = id; - } - - m_group.InsertString(TranslateT("None"), 0); - m_group.SetCurSel(groupSel); - - // By default check both checkboxes - m_chkAdded.SetState(true); - m_chkAuth.SetState(true); - - // Set last choice - if (db_get_b(NULL, "Miranda", "AuthOpenWindow", 1)) - m_chkOpen.SetState(true); - - DWORD flags = (m_acs.szProto) ? CallProtoServiceInt(NULL, m_acs.szProto, PS_GETCAPS, PFLAGNUM_4, 0) : 0; - if (flags & PF4_FORCEADDED) // force you were added requests for this protocol - m_chkAdded.Enable(false); - - if (flags & PF4_FORCEAUTH) // force auth requests for this protocol - m_chkAuth.Enable(false); - - if (flags & PF4_NOCUSTOMAUTH) - m_authReq.Enable(false); - else { - m_authReq.Enable(m_chkAuth.Enabled()); - m_authReq.SetText(TranslateT("Please authorize my request and add me to your contact list.")); - } - } - - void OnDestroy() - { - Window_FreeIcon_IcoLib(m_hwnd); - - if (m_acs.psr) { - mir_free(m_acs.psr->nick.t); - mir_free(m_acs.psr->firstName.t); - mir_free(m_acs.psr->lastName.t); - mir_free(m_acs.psr->email.t); - mir_free(m_acs.psr); - } - } - - void OnAuthClicked(CCtrlButton*) - { - DWORD flags = CallProtoServiceInt(NULL, m_acs.szProto, PS_GETCAPS, PFLAGNUM_4, 0); - if (flags & PF4_NOCUSTOMAUTH) - m_authReq.Enable(false); - else - m_authReq.Enable(m_chkAuth.Enabled()); - } - - void OnOpenClicked(CCtrlButton*) - { - // Remember this choice - db_set_b(NULL, "Miranda", "AuthOpenWindow", m_chkOpen.Enabled()); - } - - void OnOk(CCtrlButton*) - { - MCONTACT hContact = INVALID_CONTACT_ID; - switch (m_acs.handleType) { - case HANDLE_EVENT: - { - DBEVENTINFO dbei = { sizeof(dbei) }; - db_event_get(m_acs.hDbEvent, &dbei); - hContact = (MCONTACT)CallProtoServiceInt(NULL, dbei.szModule, PS_ADDTOLISTBYEVENT, 0, (LPARAM)m_acs.hDbEvent); - } - break; - - case HANDLE_SEARCHRESULT: - hContact = (MCONTACT)CallProtoServiceInt(NULL, m_acs.szProto, PS_ADDTOLIST, 0, (LPARAM)m_acs.psr); - break; - - case HANDLE_CONTACT: - hContact = m_acs.hContact; - break; - } - - if (hContact == NULL) - return; - - ptrT szHandle(m_myHandle.GetText()); - if (mir_tstrlen(szHandle)) - db_set_ts(hContact, "CList", "MyHandle", szHandle); - - int item = m_group.GetCurSel(); - if (item > 0) - CallService(MS_CLIST_CONTACTCHANGEGROUP, hContact, m_group.GetItemData(item)); - - db_unset(hContact, "CList", "NotOnList"); - - if (m_chkAdded.GetState()) - CallContactService(hContact, PSS_ADDED, 0, 0); - - if (m_chkAuth.GetState()) { - DWORD flags = CallProtoServiceInt(NULL, m_acs.szProto, PS_GETCAPS, PFLAGNUM_4, 0); - if (flags & PF4_NOCUSTOMAUTH) - CallContactService(hContact, PSS_AUTHREQUEST, 0, 0); - else - CallContactService(hContact, PSS_AUTHREQUEST, 0, ptrT(m_authReq.GetText())); - } - - if (m_chkOpen.GetState()) - CallService(MS_CLIST_CONTACTDOUBLECLICKED, hContact, 0); - } -}; - -INT_PTR AddContactDialog(WPARAM wParam, LPARAM lParam) -{ - if (lParam == 0) - return 1; - - ADDCONTACTSTRUCT *acs = (ADDCONTACTSTRUCT*)lParam; - if (wParam) { - CAddContactDlg dlg(acs); - dlg.SetParent((HWND)wParam); - dlg.DoModal(); - } - else (new CAddContactDlg(acs))->Show(); - return 0; -} - -int LoadAddContactModule(void) -{ - CreateServiceFunction(MS_ADDCONTACT_SHOW, AddContactDialog); - return 0; -} diff --git a/src/modules/button/button.cpp b/src/modules/button/button.cpp deleted file mode 100644 index 483c85b0b4..0000000000 --- a/src/modules/button/button.cpp +++ /dev/null @@ -1,629 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#include - -#include -#include - -struct TTooltips -{ - DWORD ThreadId; - HWND hwnd; -}; - -static LIST lToolTips(1, NumericKeySortT); -static mir_cs csTips; -static BOOL bModuleInitialized = FALSE; - -// Used for our own cheap TrackMouseEvent -#define BUTTON_POLLID 100 -#define BUTTON_POLLDELAY 50 - -static void DestroyTheme(MButtonCtrl *ctl) -{ - if (ctl->hThemeButton) { - CloseThemeData(ctl->hThemeButton); - ctl->hThemeButton = NULL; - } - if (ctl->hThemeToolbar) { - CloseThemeData(ctl->hThemeToolbar); - ctl->hThemeToolbar = NULL; - } - ctl->bIsThemed = false; -} - -static void LoadTheme(MButtonCtrl *ctl) -{ - DestroyTheme(ctl); - ctl->hThemeButton = OpenThemeData(ctl->hwnd, L"BUTTON"); - ctl->hThemeToolbar = OpenThemeData(ctl->hwnd, L"TOOLBAR"); - ctl->bIsThemed = true; -} - -static void SetHwndPropInt(MButtonCtrl* bct, DWORD idObject, DWORD idChild, MSAAPROPID idProp, int val) -{ - if (bct->pAccPropServices == NULL) return; - VARIANT var; - var.vt = VT_I4; - var.lVal = val; - bct->pAccPropServices->SetHwndProp(bct->hwnd, idObject, idChild, idProp, var); -} - -static int TBStateConvert2Flat(int state) -{ - switch(state) { - case PBS_NORMAL: return TS_NORMAL; - case PBS_HOT: return TS_HOT; - case PBS_PRESSED: return TS_PRESSED; - case PBS_DISABLED: return TS_DISABLED; - case PBS_DEFAULTED: return TS_NORMAL; - } - return TS_NORMAL; -} - -#ifndef DFCS_HOT -#define DFCS_HOT 0x1000 -#endif - -/////////////////////////////////////////////////////////////////////////////// -// Button painter - -static void PaintWorker(MButtonCtrl *ctl, HDC hdcPaint) -{ - if (!hdcPaint) - return; - - RECT rcClient; - GetClientRect(ctl->hwnd, &rcClient); - - HDC hdcMem = CreateCompatibleDC(hdcPaint); - HBITMAP hbmMem = CreateCompatibleBitmap(hdcPaint, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top); - HDC hOld = (HDC)SelectObject(hdcMem, hbmMem); - - // If its a push button, check to see if it should stay pressed - if (ctl->bIsPushBtn && ctl->bIsPushed) - ctl->stateId = PBS_PRESSED; - - // Draw the flat button - if (ctl->bIsFlat) { - if (ctl->hThemeToolbar && ctl->bIsThemed) { - int state = IsWindowEnabled(ctl->hwnd)?(ctl->stateId == PBS_NORMAL && ctl->bIsDefault ? PBS_DEFAULTED : ctl->stateId):PBS_DISABLED; - if (IsThemeBackgroundPartiallyTransparent(ctl->hThemeToolbar, TP_BUTTON, TBStateConvert2Flat(state))) - DrawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient); - DrawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), &rcClient, &rcClient); - } - else { - HBRUSH hbr; - - if (ctl->stateId == PBS_PRESSED || ctl->stateId == PBS_HOT) - hbr = GetSysColorBrush(COLOR_3DLIGHT); - else { - HWND hwndParent = GetParent(ctl->hwnd); - HDC dc = GetDC(hwndParent); - HBRUSH oldBrush = (HBRUSH)GetCurrentObject(dc, OBJ_BRUSH); - hbr = (HBRUSH)SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM)dc, (LPARAM)hwndParent); - SelectObject(dc, oldBrush); - ReleaseDC(hwndParent, dc); - } - if (hbr) - FillRect(hdcMem, &rcClient, hbr); - if (ctl->stateId == PBS_HOT || ctl->focus) { - if (ctl->bIsPushed) - DrawEdge(hdcMem, &rcClient, EDGE_ETCHED, BF_RECT|BF_SOFT); - else DrawEdge(hdcMem, &rcClient, BDR_RAISEDOUTER, BF_RECT|BF_SOFT|BF_FLAT); - } - else if (ctl->stateId == PBS_PRESSED) - DrawEdge(hdcMem, &rcClient, BDR_SUNKENOUTER, BF_RECT|BF_SOFT); - } - } - else { - // Draw background/border - if (ctl->hThemeButton && ctl->bIsThemed) { - int state = IsWindowEnabled(ctl->hwnd)?(ctl->stateId == PBS_NORMAL && ctl->bIsDefault ? PBS_DEFAULTED : ctl->stateId) : PBS_DISABLED; - - if (IsThemeBackgroundPartiallyTransparent(ctl->hThemeButton, BP_PUSHBUTTON, state)) - DrawThemeParentBackground(ctl->hwnd, hdcMem, &rcClient); - - DrawThemeBackground(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, state, &rcClient, &rcClient); - } - else { - UINT uState = DFCS_BUTTONPUSH | ((ctl->stateId == PBS_HOT) ? DFCS_HOT : 0) | ((ctl->stateId == PBS_PRESSED) ? DFCS_PUSHED : 0); - if (ctl->bIsDefault && ctl->stateId == PBS_NORMAL) - uState |= DLGC_DEFPUSHBUTTON; - DrawFrameControl(hdcMem, &rcClient, DFC_BUTTON, uState); - } - - // Draw focus rectangle if button has focus - if (ctl->focus) { - RECT focusRect = rcClient; - InflateRect(&focusRect, -3, -3); - DrawFocusRect(hdcMem, &focusRect); - } - } - - // If we have an icon or a bitmap, ignore text and only draw the image on the button - int textLen = GetWindowTextLength(ctl->hwnd); - - if (ctl->hIcon) { - LONG g_cxsmIcon = GetSystemMetrics(SM_CXSMICON); - LONG g_cysmIcon = GetSystemMetrics(SM_CYSMICON); - int ix = (rcClient.right-rcClient.left)/2 - (g_cxsmIcon/2); - int iy = (rcClient.bottom-rcClient.top)/2 - (g_cysmIcon/2); - if (ctl->stateId == PBS_PRESSED) { - ix++; - iy++; - } - - HIMAGELIST hImageList = ImageList_Create(g_cxsmIcon, g_cysmIcon, ILC_MASK | ILC_COLOR32, 1, 0); - ImageList_AddIcon(hImageList, ctl->hIcon); - HICON hIconNew = ImageList_GetIcon(hImageList, 0, ILD_NORMAL); - DrawState(hdcMem, NULL, NULL, (LPARAM) hIconNew, 0, ix, iy, g_cxsmIcon, g_cysmIcon, DST_ICON | (IsWindowEnabled(ctl->hwnd) ? DSS_NORMAL : DSS_DISABLED)); - ImageList_RemoveAll(hImageList); - ImageList_Destroy(hImageList); - DestroyIcon(hIconNew); - } - else if (ctl->hBitmap) { - BITMAP bminfo; - int ix, iy; - - GetObject(ctl->hBitmap, sizeof(bminfo), &bminfo); - ix = (rcClient.right-rcClient.left)/2 - (bminfo.bmWidth/2); - iy = (rcClient.bottom-rcClient.top)/2 - (bminfo.bmHeight/2); - if (ctl->stateId == PBS_PRESSED) { - ix++; - iy++; - } - DrawState(hdcMem, NULL, NULL, (LPARAM)ctl->hBitmap, 0, ix, iy, bminfo.bmWidth, bminfo.bmHeight, IsWindowEnabled(ctl->hwnd)?DST_BITMAP:DST_BITMAP|DSS_DISABLED); - } - else if (textLen > 0) { - // Draw the text and optinally the arrow - SetBkMode(hdcMem, TRANSPARENT); - HFONT hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); - - SIZE sz; - TCHAR szText[MAX_PATH]; - GetWindowText(ctl->hwnd, szText, SIZEOF(szText)); - GetTextExtentPoint32(hdcMem, szText, (int)mir_tstrlen(szText), &sz); - int xOffset = (rcClient.right - rcClient.left - sz.cx)/2; - int yOffset = (rcClient.bottom - rcClient.top - sz.cy)/2; - - // XP w/themes doesn't used the glossy disabled text. Is it always using COLOR_GRAYTEXT? Seems so. - SetTextColor(hdcMem, IsWindowEnabled(ctl->hwnd) || !ctl->hThemeButton?GetSysColor(COLOR_BTNTEXT):GetSysColor(COLOR_GRAYTEXT)); - //!! move it up, to text extent points? - if (ctl->cHot) { - SIZE szHot; - GetTextExtentPoint32 (hdcMem, _T("&"), 1, &szHot); - sz.cx -= szHot.cx; - } - if (ctl->arrow) - DrawState(hdcMem, NULL, NULL, (LPARAM)ctl->arrow, 0, rcClient.right-rcClient.left-5-GetSystemMetrics(SM_CXSMICON)+(!ctl->hThemeButton && ctl->stateId == PBS_PRESSED?1:0), (rcClient.bottom-rcClient.top)/2-GetSystemMetrics(SM_CYSMICON)/2+(!ctl->hThemeButton && ctl->stateId == PBS_PRESSED?1:0), GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), IsWindowEnabled(ctl->hwnd)?DST_ICON:DST_ICON|DSS_DISABLED); - - SelectObject(hdcMem, ctl->hFont); - DrawState(hdcMem, NULL, NULL, (LPARAM)szText, 0, - xOffset+(!ctl->hThemeButton && ctl->stateId == PBS_PRESSED?1:0), - ctl->hThemeButton ? yOffset : yOffset - (ctl->stateId == PBS_PRESSED?0:1), - sz.cx, sz.cy, - IsWindowEnabled(ctl->hwnd) || ctl->hThemeButton?DST_PREFIXTEXT|DSS_NORMAL:DST_PREFIXTEXT|DSS_DISABLED); - SelectObject(hdcMem, hOldFont); - } - BitBlt(hdcPaint, 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, hdcMem, 0, 0, SRCCOPY); - SelectObject(hdcMem, hOld); - DeleteObject(hbmMem); - DeleteDC(hdcMem); -} - -/////////////////////////////////////////////////////////////////////////////// -// Button's window procedure - -static LRESULT CALLBACK MButtonWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - MButtonCtrl *bct = (MButtonCtrl *)GetWindowLongPtr(hwnd, 0); - - switch(msg) { - case WM_NCCREATE: - SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) | BS_OWNERDRAW); - bct = (MButtonCtrl*)mir_calloc(sizeof(MButtonCtrl)); - if (bct == NULL) - return FALSE; - bct->hwnd = hwnd; - bct->stateId = PBS_NORMAL; - bct->fnPainter = PaintWorker; - bct->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); - LoadTheme(bct); - - // Annotating the Role of this object to be PushButton - if (SUCCEEDED(CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, IID_IAccPropServices, (void**)&bct->pAccPropServices))) - SetHwndPropInt(bct, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, ROLE_SYSTEM_PUSHBUTTON); - else - bct->pAccPropServices = NULL; - - SetWindowLongPtr(hwnd, 0, (LONG_PTR)bct); - if (((CREATESTRUCT *)lParam)->lpszName) - SetWindowText(hwnd, ((CREATESTRUCT*)lParam)->lpszName); - return TRUE; - - case WM_DESTROY: - if (bct) { - if (bct->pAccPropServices) { - bct->pAccPropServices->Release(); - bct->pAccPropServices = NULL; - } - if (bct->hwndToolTips) { - TOOLINFO ti = {0}; - ti.cbSize = sizeof(ti); - ti.uFlags = TTF_IDISHWND; - ti.hwnd = bct->hwnd; - ti.uId = (UINT_PTR)bct->hwnd; - if (SendMessage(bct->hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM)&ti)) - SendMessage(bct->hwndToolTips, TTM_DELTOOL, 0, (LPARAM)&ti); - - if (SendMessage(bct->hwndToolTips, TTM_GETTOOLCOUNT, 0, (LPARAM)&ti) == 0) { - TTooltips tt; - tt.ThreadId = GetCurrentThreadId(); - - mir_cslock lck(csTips); - int idx = lToolTips.getIndex(&tt); - if (idx != -1) { - mir_free(lToolTips[idx]); - lToolTips.remove(idx); - DestroyWindow(bct->hwndToolTips); - } - bct->hwndToolTips = NULL; - } - } - if (bct->arrow) IcoLib_ReleaseIcon(bct->arrow, 0); - DestroyTheme(bct); - } - break; - - case WM_NCDESTROY: - SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); - mir_free(bct); - break; - - case WM_SETTEXT: - bct->cHot = 0; - if (lParam != 0) { - TCHAR *tmp = (TCHAR*)lParam; - while (*tmp) { - if (*tmp == '&' && *(tmp+1)) { - bct->cHot = _tolower(*(tmp+1)); - break; - } - tmp++; - } - InvalidateRect(bct->hwnd, NULL, TRUE); - } - break; - - case WM_KEYUP: - if (bct->stateId != PBS_DISABLED && wParam == VK_SPACE && !(GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_SHIFT) & 0x8000)) { - if (bct->bIsPushBtn) { - if (bct->bIsPushed) { - bct->bIsPushed = 0; - bct->stateId = PBS_NORMAL; - } - else { - bct->bIsPushed = 1; - bct->stateId = PBS_PRESSED; - } - InvalidateRect(bct->hwnd, NULL, TRUE); - } - SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwnd), BN_CLICKED), (LPARAM)hwnd); - return 0; - } - break; - - case WM_SYSKEYUP: - if (bct->stateId != PBS_DISABLED && !bct->bSendOnDown && bct->cHot && bct->cHot == tolower((int)wParam)) { - if (bct->bIsPushBtn) { - if (bct->bIsPushed) { - bct->bIsPushed = false; - bct->stateId = PBS_NORMAL; - } - else { - bct->bIsPushed = true; - bct->stateId = PBS_PRESSED; - } - InvalidateRect(bct->hwnd, NULL, TRUE); - } - SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwnd), BN_CLICKED), (LPARAM)hwnd); - return 0; - } - break; - - case WM_THEMECHANGED: - // themed changed, reload theme object - if (bct->bIsThemed) - LoadTheme(bct); - InvalidateRect(bct->hwnd, NULL, TRUE); // repaint it - break; - - case WM_SETFONT: // remember the font so we can use it later - bct->hFont = (HFONT)wParam; // maybe we should redraw? - break; - - case WM_NCPAINT: - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC hdcPaint = BeginPaint(hwnd, &ps); - if (hdcPaint) { - bct->fnPainter(bct, hdcPaint); - EndPaint(hwnd, &ps); - } - } - break; - - case BM_SETIMAGE: - { - HGDIOBJ hnd = NULL; - if (bct->hIcon) hnd = bct->hIcon; - else if (bct->hBitmap) hnd = bct->hBitmap; - - if (wParam == IMAGE_ICON) { - bct->hIcon = (HICON)lParam; - bct->hBitmap = NULL; - InvalidateRect(bct->hwnd, NULL, TRUE); - } - else if (wParam == IMAGE_BITMAP) { - bct->hBitmap = (HBITMAP)lParam; - bct->hIcon = NULL; - InvalidateRect(bct->hwnd, NULL, TRUE); - } - return (LRESULT)hnd; - } - - case BM_GETIMAGE: - if (bct->hIcon) return (LRESULT)bct->hIcon; - else if (bct->hBitmap) return (LRESULT)bct->hBitmap; - else return 0; - - case BM_SETCHECK: - if (!bct->bIsPushBtn) break; - if (wParam == BST_CHECKED) { - bct->bIsPushed = 1; - bct->stateId = PBS_PRESSED; - } - else if (wParam == BST_UNCHECKED) { - bct->bIsPushed = 0; - bct->stateId = PBS_NORMAL; - } - InvalidateRect(bct->hwnd, NULL, TRUE); - break; - - case BM_GETCHECK: - if (bct->bIsPushBtn) - return bct->bIsPushed ? BST_CHECKED : BST_UNCHECKED; - return 0; - - case BUTTONSETARROW: // turn arrow on/off - if (wParam) { - if (!bct->arrow) { - bct->arrow = LoadSkinIcon(SKINICON_OTHER_DOWNARROW); - SetHwndPropInt(bct, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, ROLE_SYSTEM_BUTTONDROPDOWN); - } - } - else { - if (bct->arrow) { - IcoLib_ReleaseIcon(bct->arrow, 0); - bct->arrow = NULL; - SetHwndPropInt(bct, OBJID_CLIENT, CHILDID_SELF, PROPID_ACC_ROLE, ROLE_SYSTEM_PUSHBUTTON); - } - } - InvalidateRect(bct->hwnd, NULL, TRUE); - break; - - case BUTTONSETDEFAULT: - bct->bIsDefault = (wParam != 0); - InvalidateRect(bct->hwnd, NULL, TRUE); - break; - - case BUTTONSETASPUSHBTN: - bct->bIsPushBtn = (wParam != 0); - InvalidateRect(bct->hwnd, NULL, TRUE); - break; - - case BUTTONSETASFLATBTN: - bct->bIsFlat = (wParam != 0); - InvalidateRect(bct->hwnd, NULL, TRUE); - break; - - case BUTTONSETASTHEMEDBTN: - if ((bct->bIsThemed = (wParam != 0)) != 0) - bct->bIsSkinned = false; - InvalidateRect(bct->hwnd, NULL, TRUE); - break; - - case BUTTONADDTOOLTIP: - if (wParam) { - if (!bct->hwndToolTips) { - TTooltips tt; - tt.ThreadId = GetCurrentThreadId(); - - mir_cslock lck(csTips); - int idx = lToolTips.getIndex(&tt); - if (idx != -1) - bct->hwndToolTips = lToolTips[idx]->hwnd; - else { - TTooltips *ptt = (TTooltips*)mir_alloc(sizeof(TTooltips)); - ptt->ThreadId = tt.ThreadId; - ptt->hwnd = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), TTS_ALWAYSTIP, 0, 0, 0, 0, NULL, NULL, hInst, NULL); - lToolTips.insert(ptt); - bct->hwndToolTips = ptt->hwnd; - } - } - TOOLINFO ti = {0}; - ti.cbSize = sizeof(ti); - ti.uFlags = TTF_IDISHWND; - ti.hwnd = bct->hwnd; - ti.uId = (UINT_PTR)bct->hwnd; - if (SendMessage(bct->hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM)&ti)) - SendMessage(bct->hwndToolTips, TTM_DELTOOL, 0, (LPARAM)&ti); - ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS; - ti.uId = (UINT_PTR)bct->hwnd; - if (lParam & BATF_UNICODE) - ti.lpszText = mir_wstrdup(TranslateW((WCHAR*)wParam)); - else - ti.lpszText = Langpack_PcharToTchar((char*)wParam); - if (bct->pAccPropServices) { - wchar_t *tmpstr = mir_t2u(ti.lpszText); - bct->pAccPropServices->SetHwndPropStr(bct->hwnd, OBJID_CLIENT, - CHILDID_SELF, PROPID_ACC_DESCRIPTION, tmpstr); - mir_free(tmpstr); - } - SendMessage(bct->hwndToolTips, TTM_ADDTOOL, 0, (LPARAM)&ti); - mir_free(ti.lpszText); - } - break; - - case BUTTONSETCUSTOMPAINT: - if (wParam > sizeof(MButtonCtrl)) { - bct = (MButtonCtrl*)mir_realloc(bct, wParam); - memset(bct+1, 0, wParam - sizeof(MButtonCtrl)); - SetWindowLongPtr(hwnd, 0, (LONG_PTR)bct); - } - if (lParam) - bct->fnPainter = pfnPainterFunc(lParam); - break; - - case BUTTONSETSENDONDOWN: - bct->bSendOnDown = (wParam != 0); - break; - - case WM_SETFOCUS: // set keybord focus and redraw - bct->focus = 1; - InvalidateRect(bct->hwnd, NULL, TRUE); - break; - - case WM_KILLFOCUS: // kill focus and redraw - bct->focus = 0; - InvalidateRect(bct->hwnd, NULL, TRUE); - break; - - case WM_WINDOWPOSCHANGED: - InvalidateRect(bct->hwnd, NULL, TRUE); - break; - - case WM_ENABLE: // windows tells us to enable/disable - bct->stateId = wParam ? PBS_NORMAL : PBS_DISABLED; - InvalidateRect(bct->hwnd, NULL, TRUE); - break; - - case WM_MOUSELEAVE: // faked by the WM_TIMER - if (bct->stateId != PBS_DISABLED) { // don't change states if disabled - bct->stateId = PBS_NORMAL; - InvalidateRect(bct->hwnd, NULL, TRUE); - } - break; - - case WM_LBUTTONDOWN: - if (bct->stateId != PBS_DISABLED) { // don't change states if disabled - bct->stateId = PBS_PRESSED; - InvalidateRect(bct->hwnd, NULL, TRUE); - if (bct->bSendOnDown) { - SendMessage( GetParent(hwnd), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwnd), BN_CLICKED), (LPARAM)hwnd); - bct->stateId = PBS_NORMAL; - InvalidateRect(bct->hwnd, NULL, TRUE); - } - } - break; - - case WM_LBUTTONUP: - { - int showClick = 0; - if (bct->bIsPushBtn) - bct->bIsPushed = !bct->bIsPushed; - - if (bct->stateId != PBS_DISABLED) { // don't change states if disabled - if (bct->stateId == PBS_PRESSED) - showClick = 1; - bct->stateId = PBS_HOT; - InvalidateRect(bct->hwnd, NULL, TRUE); - } - if (showClick && !bct->bSendOnDown) // Tell your daddy you got clicked. - SendMessage( GetParent(hwnd), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwnd), BN_CLICKED), (LPARAM)hwnd); - } - break; - - case WM_MOUSEMOVE: - if (bct->stateId == PBS_NORMAL) { - bct->stateId = PBS_HOT; - InvalidateRect(bct->hwnd, NULL, TRUE); - } - // Call timer, used to start cheesy TrackMouseEvent faker - SetTimer(hwnd, BUTTON_POLLID, BUTTON_POLLDELAY, NULL); - break; - - case WM_TIMER: // use a timer to check if they have did a mouseout - if (wParam == BUTTON_POLLID) { - RECT rc; - GetWindowRect(hwnd, &rc); - - POINT pt; - GetCursorPos(&pt); - if (!PtInRect(&rc, pt)) { // mouse must be gone, trigger mouse leave - PostMessage(hwnd, WM_MOUSELEAVE, 0, 0L); - KillTimer(hwnd, BUTTON_POLLID); - } } - break; - - case WM_ERASEBKGND: - return 1; - } - - return DefWindowProc(hwnd, msg, wParam, lParam); -} - -/////////////////////////////////////////////////////////////////////////////// -// Module load - -static INT_PTR GetButtonProc(WPARAM, LPARAM) -{ - return (INT_PTR)MButtonWndProc; -} - -int LoadButtonModule(void) -{ - if (bModuleInitialized) - return 0; - - bModuleInitialized = true; - - WNDCLASSEX wc = { 0 }; - wc.cbSize = sizeof(wc); - wc.lpszClassName = MIRANDABUTTONCLASS; - wc.lpfnWndProc = MButtonWndProc; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.cbWndExtra = sizeof(MButtonCtrl*); - wc.hbrBackground = 0; - wc.style = CS_GLOBALCLASS; - RegisterClassEx(&wc); - - CreateServiceFunction("Button/GetWindowProc", GetButtonProc); - return 0; -} diff --git a/src/modules/chat/chat.h b/src/modules/chat/chat.h deleted file mode 100644 index a84ed5cf54..0000000000 --- a/src/modules/chat/chat.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - -Chat module plugin for Miranda IM - -Copyright (C) 2003 Jrgen Persson - -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 -#include -#include - -struct MODULEINFO : public GCModuleInfoBase {}; -struct SESSION_INFO : public GCSessionInfoBase {}; -struct LOGSTREAMDATA : public GCLogStreamDataBase {}; - -// special service for tweaking performance -#define MS_GC_GETEVENTPTR "GChat/GetNewEventPtr" -typedef INT_PTR(*GETEVENTFUNC)(WPARAM wParam, LPARAM lParam); -struct GCPTRS -{ - GETEVENTFUNC pfnAddEvent; -}; - -extern HGENMENU hJoinMenuItem, hLeaveMenuItem; -extern GlobalLogSettingsBase *g_Settings; -extern int g_cbSession, g_cbModuleInfo, g_iFontMode, g_iChatLang; -extern TCHAR *g_szFontGroup; -extern mir_cs cs; - -extern char* pLogIconBmpBits[14]; -extern size_t logIconBmpSize[14]; - -// log.c -void LoadMsgLogBitmaps(void); -void FreeMsgLogBitmaps(void); -void ValidateFilename (TCHAR *filename); -TCHAR* MakeTimeStamp(TCHAR *pszStamp, time_t time); -TCHAR* GetChatLogsFilename(SESSION_INFO *si, time_t tTime); -char* Log_CreateRtfHeader(MODULEINFO *mi); -char* Log_CreateRTF(LOGSTREAMDATA *streamData); -char* Log_SetStyle(int style); - -// clist.c -BOOL AddEvent(MCONTACT hContact, HICON hIcon, MEVENT hEvent, int type, TCHAR* fmt, ...); -MCONTACT AddRoom(const char *pszModule, const TCHAR *pszRoom, const TCHAR *pszDisplayName, int iType); -MCONTACT FindRoom(const char *pszModule, const TCHAR *pszRoom); -BOOL SetAllOffline(BOOL bHide, const char *pszModule); -BOOL SetOffline(MCONTACT hContact, BOOL bHide); - -int RoomDoubleclicked(WPARAM wParam,LPARAM lParam); -INT_PTR EventDoubleclicked(WPARAM wParam,LPARAM lParam); -INT_PTR JoinChat(WPARAM wParam, LPARAM lParam); -INT_PTR LeaveChat(WPARAM wParam, LPARAM lParam); -int PrebuildContactMenu(WPARAM wParam, LPARAM lParam); -INT_PTR PrebuildContactMenuSvc(WPARAM wParam, LPARAM lParam); - -// colorchooser.c -void ColorChooser(SESSION_INFO *si, BOOL bFG, HWND hwndDlg, HWND hwndTarget, HWND hwndChooser); - -// options.c -int OptionsInit(void); -int OptionsUnInit(void); -void LoadMsgDlgFont(int i, LOGFONT * lf, COLORREF * colour); -void LoadGlobalSettings(void); -HICON LoadIconEx(char* pszIcoLibName, BOOL big); -void LoadLogFonts(void); -void SetIndentSize(void); -void RegisterFonts(void); - -// services.c -void LoadChatIcons(void); -int LoadChatModule(void); -void UnloadChatModule(void); - -// tools.c -int DoRtfToTags(CMString &pszText, int iNumColors, COLORREF *pColors); -int GetTextPixelSize(TCHAR* pszText, HFONT hFont, BOOL bWidth); -TCHAR *RemoveFormatting(const TCHAR* pszText); -BOOL DoSoundsFlashPopupTrayStuff(SESSION_INFO *si, GCEVENT *gce, BOOL bHighlight, int bManyFix); -int GetColorIndex(const char *pszModule, COLORREF cr); -void CheckColorsInModule(const char *pszModule); -int GetRichTextLength(HWND hwnd); -BOOL IsHighlighted(SESSION_INFO *si, GCEVENT *pszText); -UINT CreateGCMenu(HWND hwndDlg, HMENU *hMenu, int iIndex, POINT pt, SESSION_INFO *si, TCHAR* pszUID, TCHAR* pszWordText); -void DestroyGCMenu(HMENU *hMenu, int iIndex); -BOOL DoEventHookAsync(HWND hwnd, const TCHAR *pszID, const char *pszModule, int iType, const TCHAR* pszUID, const TCHAR* pszText, INT_PTR dwItem); -BOOL DoEventHook(const TCHAR *pszID, const char *pszModule, int iType, const TCHAR *pszUID, const TCHAR* pszText, INT_PTR dwItem); -BOOL IsEventSupported(int eventType); -BOOL LogToFile(SESSION_INFO *si, GCEVENT *gce); -BOOL DoTrayIcon(SESSION_INFO *si, GCEVENT *gce); -BOOL DoPopup(SESSION_INFO *si, GCEVENT *gce); -int ShowPopup(MCONTACT hContact, SESSION_INFO *si, HICON hIcon, char* pszProtoName, TCHAR* pszRoomName, COLORREF crBkg, const TCHAR* fmt, ...); - -const TCHAR* my_strstri(const TCHAR* s1, const TCHAR* s2); - -#pragma comment(lib,"comctl32.lib") diff --git a/src/modules/chat/chat_opts.cpp b/src/modules/chat/chat_opts.cpp deleted file mode 100644 index dd889280c2..0000000000 --- a/src/modules/chat/chat_opts.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* -Chat module plugin for Miranda IM - -Copyright (C) 2003 Jrgen Persson - -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 "..\..\core\commonheaders.h" - -#include "chat.h" - -#include - -extern SESSION_INFO g_TabSession; - -GlobalLogSettingsBase *g_Settings; -int g_cbSession, g_cbModuleInfo, g_iFontMode, g_iChatLang; -TCHAR *g_szFontGroup; - -#define FONTF_BOLD 1 -#define FONTF_ITALIC 2 -struct FontOptionsList -{ - LPCTSTR szDescr; - COLORREF defColour; - LPCTSTR szDefFace; - BYTE defCharset, defStyle; - char defSize; -}; - -//remeber to put these in the Translate( ) template file too - -static LOGFONT lfDefault; - -static FontOptionsList fontOptionsList[] = -{ - { LPGENT("Timestamp"), RGB(50, 50, 240), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("Others nicknames"), RGB(0, 0, 192), lfDefault.lfFaceName, DEFAULT_CHARSET, FONTF_BOLD, -12 }, - { LPGENT("Your nickname"), RGB(0, 0, 192), lfDefault.lfFaceName, DEFAULT_CHARSET, FONTF_BOLD, -12 }, - { LPGENT("User has joined"), RGB(90, 160, 90), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("User has left"), RGB(160, 160, 90), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("User has disconnected"), RGB(160, 90, 90), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("User kicked ..."), RGB(100, 100, 100), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("User is now known as ..."), RGB(90, 90, 160), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("Notice from user"), RGB(160, 130, 60), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("Incoming message"), RGB(90, 90, 90), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("Outgoing message"), RGB(90, 90, 90), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("The topic is ..."), RGB(70, 70, 160), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("Information messages"), RGB(130, 130, 195), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("User enables status for ..."), RGB(70, 150, 70), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("User disables status for ..."), RGB(150, 70, 70), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("Action message"), RGB(160, 90, 160), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("Highlighted message"), RGB(180, 150, 80), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { _T(""), 0, lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("Nick list members (online)"), RGB(0, 0, 0), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 }, - { LPGENT("Nick list members (away)"), RGB(170, 170, 170), lfDefault.lfFaceName, DEFAULT_CHARSET, 0, -12 } -}; - -static void LoadColors() -{ - g_Settings->crUserListBGColor = db_get_dw(NULL, CHAT_MODULE, "ColorNicklistBG", GetSysColor(COLOR_WINDOW)); - g_Settings->crUserListSelectedBGColor = db_get_dw(NULL, CHAT_MODULE, "ColorNicklistSelectedBG", GetSysColor(COLOR_HIGHLIGHT)); -} - -void LoadLogFonts(void) -{ - for (int i=0; i < OPTIONS_FONTCOUNT; i++) - LoadMsgDlgFont(i, &ci.aFonts[i].lf, &ci.aFonts[i].color); - LoadColors(); - - if (ci.hListBkgBrush != NULL) - DeleteObject(ci.hListBkgBrush); - ci.hListBkgBrush = CreateSolidBrush(g_Settings->crUserListBGColor); - - if (ci.hListSelectedBkgBrush != NULL) - DeleteObject(ci.hListSelectedBkgBrush); - ci.hListSelectedBkgBrush = CreateSolidBrush(g_Settings->crUserListSelectedBGColor); -} - -void LoadMsgDlgFont(int i, LOGFONT *lf, COLORREF *colour) -{ - char str[32]; - int style; - FontOptionsList &FO = fontOptionsList[i]; - - if (colour) { - mir_snprintf(str, "Font%dCol", i); - *colour = db_get_dw(NULL, CHATFONT_MODULE, str, FO.defColour); - } - if (lf) { - mir_snprintf(str, "Font%dSize", i); - lf->lfHeight = (char)db_get_b(NULL, CHATFONT_MODULE, str, FO.defSize); - lf->lfWidth = 0; - lf->lfEscapement = 0; - lf->lfOrientation = 0; - mir_snprintf(str, "Font%dSty", i); - style = db_get_b(NULL, CHATFONT_MODULE, str, FO.defStyle); - lf->lfWeight = style & FONTF_BOLD ? FW_BOLD : FW_NORMAL; - lf->lfItalic = style & FONTF_ITALIC ? 1 : 0; - lf->lfUnderline = 0; - lf->lfStrikeOut = 0; - mir_snprintf(str, "Font%dSet", i); - lf->lfCharSet = db_get_b(NULL, CHATFONT_MODULE, str, FO.defCharset); - lf->lfOutPrecision = OUT_DEFAULT_PRECIS; - lf->lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf->lfQuality = DEFAULT_QUALITY; - lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; - mir_snprintf(str, "Font%d", i); - - ptrT tszFace(db_get_tsa(NULL, CHATFONT_MODULE, str)); - if (tszFace == NULL) - mir_tstrcpy(lf->lfFaceName, FO.szDefFace); - else - _tcsncpy_s(lf->lfFaceName, tszFace, _TRUNCATE); - } -} - -void RegisterFonts(void) -{ - int index = 0; - - SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfDefault), &lfDefault, FALSE); - - FontIDT fontid = { sizeof(fontid) }; - fontid.flags = FIDF_ALLOWREREGISTER | FIDF_DEFAULTVALID | FIDF_NEEDRESTART; - _tcsncpy_s(fontid.backgroundGroup, g_szFontGroup, _TRUNCATE); - _tcsncpy_s(fontid.group, g_szFontGroup, _TRUNCATE); - - for (int i = 0; i < SIZEOF(fontOptionsList); i++, index++) { - FontOptionsList &FO = fontOptionsList[i]; - strncpy_s(fontid.dbSettingsGroup, CHATFONT_MODULE, _TRUNCATE); - _tcsncpy_s(fontid.name, FO.szDescr, _TRUNCATE); - - mir_snprintf(fontid.prefix, SIZEOF(fontid.prefix), "Font%d", index); - fontid.order = index; - - switch (i) { - case 18: - case 19: - _tcsncpy_s(fontid.backgroundName, LPGENT("Nick list background"), _TRUNCATE); - break; - case 17: - if (g_iFontMode == FONTMODE_SKIP) - continue; - if (g_iFontMode == FONTMODE_USE) { - _tcsncpy_s(fontid.name, LPGENT("Message typing area"), _TRUNCATE); - _tcsncpy_s(fontid.backgroundName, LPGENT("Message background"), _TRUNCATE); - FO.defColour = RGB(0, 0, 40); - break; - } - - _tcsncpy_s(fontid.name, LPGENT("Chat log symbols (Webdings)"), _TRUNCATE); - FO.szDefFace = _T("Webdings"); - FO.defColour = RGB(170, 170, 170); - FO.defCharset = SYMBOL_CHARSET; - // fall through - default: - _tcsncpy_s(fontid.backgroundName, LPGENT("Group chat log background"), _TRUNCATE); - break; - } - _tcsncpy_s(fontid.deffontsettings.szFace, FO.szDefFace, _TRUNCATE); - fontid.deffontsettings.charset = FO.defCharset; - fontid.deffontsettings.colour = FO.defColour; - fontid.deffontsettings.size = FO.defSize; - fontid.deffontsettings.style = FO.defStyle; - CallService("Font/RegisterW", (WPARAM)&fontid, g_iChatLang); - } -} - -// load icons from the skinning module if available - -HICON LoadIconEx(char* pszIcoLibName, BOOL big) -{ - char szTemp[256]; - mir_snprintf(szTemp, "chat_%s", pszIcoLibName); - return Skin_GetIcon(szTemp, big); -} - -static void InitSetting(TCHAR** ppPointer, char* pszSetting, TCHAR* pszDefault) -{ - DBVARIANT dbv; - if (!db_get_ts(NULL, CHAT_MODULE, pszSetting, &dbv)) { - replaceStrT(*ppPointer, dbv.ptszVal); - db_free(&dbv); - } - else replaceStrT(*ppPointer, pszDefault); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void LoadGlobalSettings(void) -{ - g_Settings->LogIconSize = 10; - g_Settings->bLogLimitNames = db_get_b(NULL, CHAT_MODULE, "LogLimitNames", 1) != 0; - g_Settings->bShowTime = db_get_b(NULL, CHAT_MODULE, "ShowTimeStamp", 1) != 0; - g_Settings->bSoundsFocus = db_get_b(NULL, CHAT_MODULE, "SoundsFocus", 0) != 0; - g_Settings->bShowTimeIfChanged = (BOOL)db_get_b(NULL, CHAT_MODULE, "ShowTimeStampIfChanged", 0) != 0; - g_Settings->bTimeStampEventColour = (BOOL)db_get_b(NULL, CHAT_MODULE, "TimeStampEventColour", 0) != 0; - g_Settings->iEventLimit = db_get_w(NULL, CHAT_MODULE, "LogLimit", 100); - g_Settings->dwIconFlags = db_get_dw(NULL, CHAT_MODULE, "IconFlags", 0x0000); - g_Settings->dwTrayIconFlags = db_get_dw(NULL, CHAT_MODULE, "TrayIconFlags", 0x1000); - g_Settings->dwPopupFlags = db_get_dw(NULL, CHAT_MODULE, "PopupFlags", 0x0000); - g_Settings->LoggingLimit = db_get_w(NULL, CHAT_MODULE, "LoggingLimit", 100); - g_Settings->bLoggingEnabled = (BOOL)db_get_b(NULL, CHAT_MODULE, "LoggingEnabled", 0) != 0; - g_Settings->bFlashWindow = (BOOL)db_get_b(NULL, CHAT_MODULE, "FlashWindow", 0) != 0; - g_Settings->bFlashWindowHighlight = (BOOL)db_get_b(NULL, CHAT_MODULE, "FlashWindowHighlight", false) != 0; - g_Settings->bHighlightEnabled = (BOOL)db_get_b(NULL, CHAT_MODULE, "HighlightEnabled", 1) != 0; - g_Settings->crLogBackground = db_get_dw(NULL, CHAT_MODULE, "ColorLogBG", GetSysColor(COLOR_WINDOW)); - g_Settings->crUserListColor = db_get_dw(NULL, CHATFONT_MODULE, "Font18Col", RGB(0, 0, 0)); - g_Settings->crUserListHeadingsColor = db_get_dw(NULL, CHATFONT_MODULE, "Font19Col", RGB(170, 170, 170)); - g_Settings->bStripFormat = (BOOL)db_get_b(NULL, CHAT_MODULE, "StripFormatting", 0) != 0; - g_Settings->bTrayIconInactiveOnly = (BOOL)db_get_b(NULL, CHAT_MODULE, "TrayIconInactiveOnly", 1) != 0; - g_Settings->bPopupInactiveOnly = (BOOL)db_get_b(NULL, CHAT_MODULE, "PopupInactiveOnly", 1) != 0; - g_Settings->bAddColonToAutoComplete = (BOOL)db_get_b(NULL, CHAT_MODULE, "AddColonToAutoComplete", 1) != 0; - g_Settings->iPopupStyle = db_get_b(NULL, CHAT_MODULE, "PopupStyle", 1); - g_Settings->iPopupTimeout = db_get_w(NULL, CHAT_MODULE, "PopupTimeout", 3); - g_Settings->crPUBkgColour = db_get_dw(NULL, CHAT_MODULE, "PopupColorBG", GetSysColor(COLOR_WINDOW)); - g_Settings->crPUTextColour = db_get_dw(NULL, CHAT_MODULE, "PopupColorText", 0); - g_Settings->bShowContactStatus = db_get_b(NULL, CHAT_MODULE, "ShowContactStatus", 0) != 0; - g_Settings->bContactStatusFirst = db_get_b(NULL, CHAT_MODULE, "ContactStatusFirst", 0) != 0; - - LoadColors(); - - if (ci.OnLoadSettings) - ci.OnLoadSettings(); - - InitSetting(&g_Settings->pszTimeStamp, "HeaderTime", _T("[%H:%M]")); - InitSetting(&g_Settings->pszTimeStampLog, "LogTimestamp", _T("[%d %b %y %H:%M]")); - InitSetting(&g_Settings->pszIncomingNick, "HeaderIncoming", _T("%n:")); - InitSetting(&g_Settings->pszOutgoingNick, "HeaderOutgoing", _T("%n:")); - InitSetting(&g_Settings->pszHighlightWords, "HighlightWords", _T("%m")); - - InitSetting(&g_Settings->pszLogDir, "LogDirectory", _T("%miranda_logpath%\\%proto%\\%userid%.log")); - g_Settings->bLogIndentEnabled = db_get_b(NULL, CHAT_MODULE, "LogIndentEnabled", 1) != 0; - - LOGFONT lf; - if (g_Settings->UserListFont) - DeleteObject(g_Settings->UserListFont); - LoadMsgDlgFont(18, &lf, NULL); - g_Settings->UserListFont = CreateFontIndirect(&lf); - - if (g_Settings->UserListHeadingsFont) - DeleteObject(g_Settings->UserListHeadingsFont); - LoadMsgDlgFont(19, &lf, NULL); - g_Settings->UserListHeadingsFont = CreateFontIndirect(&lf); - - SetIndentSize(); -} - -static void FreeGlobalSettings(void) -{ - if (g_Settings == NULL) - return; - - mir_free(g_Settings->pszTimeStamp); - mir_free(g_Settings->pszTimeStampLog); - mir_free(g_Settings->pszIncomingNick); - mir_free(g_Settings->pszOutgoingNick); - mir_free(g_Settings->pszHighlightWords); - mir_free(g_Settings->pszLogDir); - if (g_Settings->UserListFont) - DeleteObject(g_Settings->UserListFont); - if (g_Settings->UserListHeadingsFont) - DeleteObject(g_Settings->UserListHeadingsFont); - if (g_Settings->NameFont) - DeleteObject(g_Settings->NameFont); -} - -void SetIndentSize() -{ - if (g_Settings->bShowTime) { - LOGFONT lf; - LoadMsgDlgFont(0, &lf, NULL); - HFONT hFont = CreateFontIndirect(&lf); - int iText = GetTextPixelSize(MakeTimeStamp(g_Settings->pszTimeStamp, time(NULL)), hFont, TRUE); - DeleteObject(hFont); - g_Settings->LogTextIndent = iText * 12 / 10; - } - else g_Settings->LogTextIndent = 0; -} - -int GetTextPixelSize(TCHAR* pszText, HFONT hFont, BOOL bWidth) -{ - if (!pszText || !hFont) - return 0; - - HDC hdc = GetDC(NULL); - HFONT hOldFont = (HFONT)SelectObject(hdc, hFont); - - RECT rc = { 0 }; - int i = DrawText(hdc, pszText, -1, &rc, DT_CALCRECT); - SelectObject(hdc, hOldFont); - ReleaseDC(NULL, hdc); - return bWidth ? rc.right - rc.left : rc.bottom - rc.top; -} - -int OptionsInit(void) -{ - LoadLogFonts(); - - LOGFONT lf; - LoadMsgDlgFont(18, &lf, NULL); - mir_tstrcpy(lf.lfFaceName, _T("MS Shell Dlg")); - lf.lfUnderline = lf.lfItalic = lf.lfStrikeOut = 0; - lf.lfHeight = -17; - lf.lfWeight = FW_BOLD; - g_Settings->NameFont = CreateFontIndirect(&lf); - g_Settings->UserListFont = NULL; - g_Settings->UserListHeadingsFont = NULL; - g_Settings->iWidth = db_get_dw(NULL, CHAT_MODULE, "roomwidth", -1); - g_Settings->iHeight = db_get_dw(NULL, CHAT_MODULE, "roomheight", -1); - - g_Settings->iSplitterX = db_get_w(NULL, CHAT_MODULE, "SplitterX", 105); - if (g_Settings->iSplitterX <= 50) - g_Settings->iSplitterX = 105; - g_Settings->iSplitterY = db_get_w(NULL, CHAT_MODULE, "SplitterY", 90); - if (g_Settings->iSplitterY <= 65) - g_Settings->iSplitterY = 90; - - SkinAddNewSoundEx("ChatMessage", LPGEN("Group chats"), LPGEN("Incoming message")); - SkinAddNewSoundEx("ChatHighlight", LPGEN("Group chats"), LPGEN("Message is highlighted")); - SkinAddNewSoundEx("ChatAction", LPGEN("Group chats"), LPGEN("User has performed an action")); - SkinAddNewSoundEx("ChatJoin", LPGEN("Group chats"), LPGEN("User has joined")); - SkinAddNewSoundEx("ChatPart", LPGEN("Group chats"), LPGEN("User has left")); - SkinAddNewSoundEx("ChatKick", LPGEN("Group chats"), LPGEN("User has kicked some other user")); - SkinAddNewSoundEx("ChatMode", LPGEN("Group chats"), LPGEN("User's status was changed")); - SkinAddNewSoundEx("ChatNick", LPGEN("Group chats"), LPGEN("User has changed name")); - SkinAddNewSoundEx("ChatNotice", LPGEN("Group chats"), LPGEN("User has sent a notice")); - SkinAddNewSoundEx("ChatQuit", LPGEN("Group chats"), LPGEN("User has disconnected")); - SkinAddNewSoundEx("ChatTopic", LPGEN("Group chats"), LPGEN("The topic has been changed")); - return 0; -} - -int OptionsUnInit(void) -{ - FreeGlobalSettings(); - return 0; -} diff --git a/src/modules/chat/chat_rtf.cpp b/src/modules/chat/chat_rtf.cpp deleted file mode 100644 index 255a051ef9..0000000000 --- a/src/modules/chat/chat_rtf.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* -Chat module plugin for Miranda IM - -Copyright 2000-12 Miranda IM, 2012-15 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#include "chat.h" - -///////////////////////////////////////////////////////////////////////////////////////// -// convert rich edit code to bbcode (if wanted). Otherwise, strip all RTF formatting -// tags and return plain text - -static TCHAR tszRtfBreaks[] = _T(" \\\n\r"); - -static void CreateColorMap(CMString &Text, int iCount, COLORREF *pSrc, int *pDst) -{ - const TCHAR *pszText = Text; - int iIndex = 1, i = 0; - - static const TCHAR *lpszFmt = _T("\\red%[^ \x5b\\]\\green%[^ \x5b\\]\\blue%[^ \x5b;];"); - TCHAR szRed[10], szGreen[10], szBlue[10]; - - const TCHAR *p1 = _tcsstr(pszText, _T("\\colortbl")); - if (!p1) - return; - - const TCHAR *pEnd = _tcschr(p1, '}'); - - const TCHAR *p2 = _tcsstr(p1, _T("\\red")); - - for (i = 0; i < iCount; i++) - pDst[i] = -1; - - while (p2 && p2 < pEnd) { - if (_stscanf(p2, lpszFmt, &szRed, &szGreen, &szBlue) > 0) { - for (int i = 0; i < iCount; i++) { - if (pSrc[i] == RGB(_ttoi(szRed), _ttoi(szGreen), _ttoi(szBlue))) - pDst[i] = iIndex; - } - } - iIndex++; - p1 = p2; - p1++; - - p2 = _tcsstr(p1, _T("\\red")); - } -} - -static int GetRtfIndex(int iCol, int iCount, int *pIndex) -{ - for (int i = 0; i < iCount; i++) - if (pIndex[i] == iCol) - return i; - - return -1; -} - -int DoRtfToTags(CMString &pszText, int iNumColors, COLORREF *pColors) -{ - if (pszText.IsEmpty()) - return FALSE; - - // create an index of colors in the module and map them to - // corresponding colors in the RTF color table - int *pIndex = (int*)_alloca(iNumColors * sizeof(int)); - CreateColorMap(pszText, iNumColors, pColors, pIndex); - - // scan the file for rtf commands and remove or parse them - int idx = pszText.Find(_T("\\pard")); - if (idx == -1) { - if ((idx = pszText.Find(_T("\\ltrpar"))) == -1) - return FALSE; - idx += 7; - } - else idx += 5; - - bool bInsideColor = false, bInsideUl = false; - CMString res; - - // iterate through all characters, if rtf control character found then take action - for (const TCHAR *p = pszText.GetString() + idx; *p;) { - switch (*p) { - case '\\': - if (p[1] == '\\' || p[1] == '{' || p[1] == '}') { // escaped characters - res.AppendChar(p[1]); - p += 2; break; - } - if (p[1] == '~') { // non-breaking space - res.AppendChar(0xA0); - p += 2; break; - } - - if (!_tcsncmp(p, _T("\\cf"), 3)) { // foreground color - int iCol = _ttoi(p + 3); - int iInd = GetRtfIndex(iCol, iNumColors, pIndex); - bInsideColor = iInd > 0; - } - else if (!_tcsncmp(p, _T("\\highlight"), 10)) { //background color - TCHAR szTemp[20]; - int iCol = _ttoi(p + 10); - mir_sntprintf(szTemp, _T("%d"), iCol); - } - else if (!_tcsncmp(p, _T("\\line"), 5)) { // soft line break; - res.AppendChar('\n'); - } - else if (!_tcsncmp(p, _T("\\endash"), 7)) { - res.AppendChar(0x2013); - } - else if (!_tcsncmp(p, _T("\\emdash"), 7)) { - res.AppendChar(0x2014); - } - else if (!_tcsncmp(p, _T("\\bullet"), 7)) { - res.AppendChar(0x2022); - } - else if (!_tcsncmp(p, _T("\\ldblquote"), 10)) { - res.AppendChar(0x201C); - } - else if (!_tcsncmp(p, _T("\\rdblquote"), 10)) { - res.AppendChar(0x201D); - } - else if (!_tcsncmp(p, _T("\\lquote"), 7)) { - res.AppendChar(0x2018); - } - else if (!_tcsncmp(p, _T("\\rquote"), 7)) { - res.AppendChar(0x2019); - } - else if (!_tcsncmp(p, _T("\\b"), 2)) { //bold - res.Append((p[2] != '0') ? _T("[b]") : _T("[/b]")); - } - else if (!_tcsncmp(p, _T("\\i"), 2)) { // italics - res.Append((p[2] != '0') ? _T("[i]") : _T("[/i]")); - } - else if (!_tcsncmp(p, _T("\\strike"), 7)) { // strike-out - res.Append((p[7] != '0') ? _T("[s]") : _T("[/s]")); - } - else if (!_tcsncmp(p, _T("\\ul"), 3)) { // underlined - if (p[3] == 0 || _tcschr(tszRtfBreaks, p[3])) { - res.Append(_T("[u]")); - bInsideUl = true; - } - else if (!_tcsnccmp(p + 3, _T("none"), 4)) { - if (bInsideUl) - res.Append(_T("[/u]")); - bInsideUl = false; - } - } - else if (!_tcsncmp(p, _T("\\tab"), 4)) { // tab - res.AppendChar('\t'); - } - else if (p[1] == '\'') { // special character - if (p[2] != ' ' && p[2] != '\\') { - TCHAR tmp[10], *t = tmp; - *t++ = p[2]; - if (p[3] != ' ' && p[3] != '\\') - *t++ = p[3]; - *t = 0; - - // convert string containing char in hex format to int. - TCHAR *stoppedHere; - res.AppendChar(_tcstol(tmp, &stoppedHere, 16)); - } - } - - p++; // skip initial slash - p += _tcscspn(p, tszRtfBreaks); - if (*p == ' ') - p++; - break; - - case '{': // other RTF control characters - case '}': - p++; - break; - - default: // other text that should not be touched - res.AppendChar(*p++); - break; - } - } - - if (bInsideUl) - res.Append(_T("[/u]")); - - pszText = res; - return TRUE; -} diff --git a/src/modules/chat/chat_svc.cpp b/src/modules/chat/chat_svc.cpp deleted file mode 100644 index 31b0fc9080..0000000000 --- a/src/modules/chat/chat_svc.cpp +++ /dev/null @@ -1,631 +0,0 @@ -/* -Chat module plugin for Miranda IM - -Copyright 2000-12 Miranda IM, 2012-15 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -INT_PTR SvcGetChatManager(WPARAM, LPARAM); - -#include "chat.h" - -HGENMENU hJoinMenuItem, hLeaveMenuItem; -mir_cs cs; - -static HANDLE - hServiceRegister = NULL, - hServiceNewChat = NULL, - hServiceAddEvent = NULL, - hServiceGetAddEventPtr = NULL, - hServiceGetInfo = NULL, - hServiceGetCount = NULL, - hEventPrebuildMenu = NULL, - hEventDoubleclicked = NULL, - hEventJoinChat = NULL, - hEventLeaveChat = NULL, - hHookEvent = NULL; - -///////////////////////////////////////////////////////////////////////////////////////// -// Post-load event hooks - -void LoadChatIcons(void) -{ - ci.hIcons[ICON_ACTION] = LoadIconEx("log_action", FALSE); - ci.hIcons[ICON_ADDSTATUS] = LoadIconEx("log_addstatus", FALSE); - ci.hIcons[ICON_HIGHLIGHT] = LoadIconEx("log_highlight", FALSE); - ci.hIcons[ICON_INFO] = LoadIconEx("log_info", FALSE); - ci.hIcons[ICON_JOIN] = LoadIconEx("log_join", FALSE); - ci.hIcons[ICON_KICK] = LoadIconEx("log_kick", FALSE); - ci.hIcons[ICON_MESSAGE] = LoadIconEx("log_message_in", FALSE); - ci.hIcons[ICON_MESSAGEOUT] = LoadIconEx("log_message_out", FALSE); - ci.hIcons[ICON_NICK] = LoadIconEx("log_nick", FALSE); - ci.hIcons[ICON_NOTICE] = LoadIconEx("log_notice", FALSE); - ci.hIcons[ICON_PART] = LoadIconEx("log_part", FALSE); - ci.hIcons[ICON_QUIT] = LoadIconEx("log_quit", FALSE); - ci.hIcons[ICON_REMSTATUS] = LoadIconEx("log_removestatus", FALSE); - ci.hIcons[ICON_TOPIC] = LoadIconEx("log_topic", FALSE); - ci.hIcons[ICON_STATUS0] = LoadIconEx("status0", FALSE); - ci.hIcons[ICON_STATUS1] = LoadIconEx("status1", FALSE); - ci.hIcons[ICON_STATUS2] = LoadIconEx("status2", FALSE); - ci.hIcons[ICON_STATUS3] = LoadIconEx("status3", FALSE); - ci.hIcons[ICON_STATUS4] = LoadIconEx("status4", FALSE); - ci.hIcons[ICON_STATUS5] = LoadIconEx("status5", FALSE); - - FreeMsgLogBitmaps(); - LoadMsgLogBitmaps(); -} - -static int FontsChanged(WPARAM, LPARAM) -{ - LoadGlobalSettings(); - LoadLogFonts(); - - FreeMsgLogBitmaps(); - LoadMsgLogBitmaps(); - - SetIndentSize(); - g_Settings->bLogIndentEnabled = (db_get_b(NULL, CHAT_MODULE, "LogIndentEnabled", 1) != 0) ? TRUE : FALSE; - - ci.MM_FontsChanged(); - ci.MM_FixColors(); - ci.SM_BroadcastMessage(NULL, GC_SETWNDPROPS, 0, 0, TRUE); - return 0; -} - -static int IconsChanged(WPARAM, LPARAM) -{ - FreeMsgLogBitmaps(); - LoadMsgLogBitmaps(); - - ci.MM_IconsChanged(); - ci.SM_BroadcastMessage(NULL, GC_SETWNDPROPS, 0, 0, FALSE); - return 0; -} - -static int PreShutdown(WPARAM, LPARAM) -{ - if (g_Settings != NULL) { - ci.SM_BroadcastMessage(NULL, GC_CLOSEWINDOW, 0, 1, FALSE); - - ci.SM_RemoveAll(); - ci.MM_RemoveAll(); - - DeleteObject(ci.hListBkgBrush); - DeleteObject(ci.hListSelectedBkgBrush); - } - return 0; -} - -static int SmileyOptionsChanged(WPARAM, LPARAM) -{ - ci.SM_BroadcastMessage(NULL, GC_REDRAWLOG, 0, 1, FALSE); - return 0; -} - -static INT_PTR Service_GetCount(WPARAM, LPARAM lParam) -{ - if (!lParam) - return -1; - - mir_cslock lck(cs); - return ci.SM_GetCount((char *)lParam); -} - -static INT_PTR Service_GetInfo(WPARAM, LPARAM lParam) -{ - GC_INFO *gci = (GC_INFO *)lParam; - if (!gci || !gci->pszModule) - return 1; - - mir_cslock lck(cs); - - SESSION_INFO *si; - if (gci->Flags & GCF_BYINDEX) - si = ci.SM_FindSessionByIndex(gci->pszModule, gci->iItem); - else - si = ci.SM_FindSession(gci->pszID, gci->pszModule); - if (si == NULL) - return 1; - - if (gci->Flags & GCF_DATA) gci->dwItemData = si->dwItemData; - if (gci->Flags & GCF_HCONTACT) gci->hContact = si->hContact; - if (gci->Flags & GCF_TYPE) gci->iType = si->iType; - if (gci->Flags & GCF_COUNT) gci->iCount = si->nUsersInNicklist; - if (gci->Flags & GCF_USERS) gci->pszUsers = ci.SM_GetUsers(si); - if (gci->Flags & GCF_ID) gci->pszID = si->ptszID; - if (gci->Flags & GCF_NAME) gci->pszName = si->ptszName; - return 0; -} - -static INT_PTR Service_Register(WPARAM, LPARAM lParam) -{ - GCREGISTER *gcr = (GCREGISTER *)lParam; - if (gcr == NULL) - return GC_REGISTER_ERROR; - - if (gcr->cbSize != sizeof(GCREGISTER)) - return GC_REGISTER_WRONGVER; - - mir_cslock lck(cs); - MODULEINFO *mi = ci.MM_AddModule(gcr->pszModule); - if (mi == NULL) - return GC_REGISTER_ERROR; - - mi->ptszModDispName = mir_tstrdup(gcr->ptszDispName); - mi->bBold = (gcr->dwFlags & GC_BOLD) != 0; - mi->bUnderline = (gcr->dwFlags & GC_UNDERLINE) != 0; - mi->bItalics = (gcr->dwFlags & GC_ITALICS) != 0; - mi->bColor = (gcr->dwFlags & GC_COLOR) != 0; - mi->bBkgColor = (gcr->dwFlags & GC_BKGCOLOR) != 0; - mi->bAckMsg = (gcr->dwFlags & GC_ACKMSG) != 0; - mi->bChanMgr = (gcr->dwFlags & GC_CHANMGR) != 0; - mi->bSingleFormat = (gcr->dwFlags & GC_SINGLEFORMAT) != 0; - mi->bFontSize = (gcr->dwFlags & GC_FONTSIZE) != 0; - mi->iMaxText = gcr->iMaxText; - mi->nColorCount = gcr->nColors; - if (gcr->nColors > 0) { - mi->crColors = (COLORREF *)mir_alloc(sizeof(COLORREF)* gcr->nColors); - memcpy(mi->crColors, gcr->pColors, sizeof(COLORREF)* gcr->nColors); - } - - mi->pszHeader = ci.Log_CreateRtfHeader(mi); - - CheckColorsInModule((char*)gcr->pszModule); - ci.SetAllOffline(TRUE, gcr->pszModule); - return 0; -} - -static INT_PTR Service_NewChat(WPARAM, LPARAM lParam) -{ - GCSESSION *gcw = (GCSESSION *)lParam; - if (gcw == NULL) - return GC_NEWSESSION_ERROR; - - if (gcw->cbSize != sizeof(GCSESSION)) - return GC_NEWSESSION_WRONGVER; - - mir_cslock lck(cs); - MODULEINFO *mi = ci.MM_FindModule(gcw->pszModule); - if (mi == NULL) - return GC_NEWSESSION_ERROR; - - // create a new session and set the defaults - SESSION_INFO *si = ci.SM_AddSession(gcw->ptszID, gcw->pszModule); - if (si != NULL) { - si->dwItemData = gcw->dwItemData; - if (gcw->iType != GCW_SERVER) - si->wStatus = ID_STATUS_ONLINE; - si->iType = gcw->iType; - si->dwFlags = gcw->dwFlags; - si->ptszName = mir_tstrdup(gcw->ptszName); - si->ptszStatusbarText = mir_tstrdup(gcw->ptszStatusbarText); - si->iSplitterX = g_Settings->iSplitterX; - si->iSplitterY = g_Settings->iSplitterY; - si->iLogFilterFlags = db_get_dw(NULL, CHAT_MODULE, "FilterFlags", 0x03E0); - si->bFilterEnabled = db_get_b(NULL, CHAT_MODULE, "FilterEnabled", 0); - si->bNicklistEnabled = db_get_b(NULL, CHAT_MODULE, "ShowNicklist", 1); - - if (mi->bColor) { - si->iFG = 4; - si->bFGSet = TRUE; - } - if (mi->bBkgColor) { - si->iBG = 2; - si->bBGSet = TRUE; - } - - TCHAR szTemp[256]; - if (si->iType == GCW_SERVER) - mir_sntprintf(szTemp, _T("Server: %s"), si->ptszName); - else - _tcsncpy_s(szTemp, si->ptszName, _TRUNCATE); - si->hContact = ci.AddRoom(gcw->pszModule, gcw->ptszID, szTemp, si->iType); - db_set_s(si->hContact, si->pszModule, "Topic", ""); - db_unset(si->hContact, "CList", "StatusMsg"); - if (si->ptszStatusbarText) - db_set_ts(si->hContact, si->pszModule, "StatusBar", si->ptszStatusbarText); - else - db_set_s(si->hContact, si->pszModule, "StatusBar", ""); - - if (ci.OnCreateSession) - ci.OnCreateSession(si, mi); - } - else if (si = ci.SM_FindSession(gcw->ptszID, gcw->pszModule)) { - ci.UM_RemoveAll(&si->pUsers); - ci.TM_RemoveAll(&si->pStatuses); - - si->iStatusCount = 0; - si->nUsersInNicklist = 0; - - if (ci.OnReplaceSession) - ci.OnReplaceSession(si); - } - - return 0; -} - -static void SetInitDone(SESSION_INFO *si) -{ - if (si->bInitDone) - return; - - si->bInitDone = true; - for (STATUSINFO *p = si->pStatuses; p; p = p->next) - if ((UINT_PTR)p->hIcon < STATUSICONCOUNT) - p->hIcon = HICON(si->iStatusCount - (int)p->hIcon - 1); -} - -static int DoControl(GCEVENT *gce, WPARAM wp) -{ - SESSION_INFO *si; - - if (gce->pDest->iType == GC_EVENT_CONTROL) { - switch (wp) { - case WINDOW_HIDDEN: - if (si = ci.SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule)) { - SetInitDone(si); - ci.SetActiveSession(si->ptszID, si->pszModule); - if (si->hWnd) - ci.ShowRoom(si, wp, FALSE); - } - return 0; - - case WINDOW_MINIMIZE: - case WINDOW_MAXIMIZE: - case WINDOW_VISIBLE: - case SESSION_INITDONE: - if (si = ci.SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule)) { - SetInitDone(si); - if (wp != SESSION_INITDONE || db_get_b(NULL, CHAT_MODULE, "PopupOnJoin", 0) == 0) - ci.ShowRoom(si, wp, TRUE); - return 0; - } - break; - - case SESSION_OFFLINE: - ci.SM_SetOffline(gce->pDest->ptszID, gce->pDest->pszModule); - // fall through - - case SESSION_ONLINE: - ci.SM_SetStatus(gce->pDest->ptszID, gce->pDest->pszModule, wp == SESSION_ONLINE ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE); - break; - - case WINDOW_CLEARLOG: - if (si = ci.SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule)) { - ci.LM_RemoveAll(&si->pLog, &si->pLogEnd); - if (ci.OnClearLog) - ci.OnClearLog(si); - si->iEventCount = 0; - si->LastTime = 0; - } - break; - - case SESSION_TERMINATE: - return ci.SM_RemoveSession(gce->pDest->ptszID, gce->pDest->pszModule, (gce->dwFlags & GCEF_REMOVECONTACT) != 0); - } - ci.SM_SendMessage(gce->pDest->ptszID, gce->pDest->pszModule, GC_EVENT_CONTROL + WM_USER + 500, wp, 0); - } - - else if (gce->pDest->iType == GC_EVENT_CHUID && gce->ptszText) { - ci.SM_ChangeUID(gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszNick, gce->ptszText); - } - - else if (gce->pDest->iType == GC_EVENT_CHANGESESSIONAME && gce->ptszText) { - if (si = ci.SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule)) { - replaceStrT(si->ptszName, gce->ptszText); - if (si->hWnd) - SendMessage(si->hWnd, GC_UPDATETITLE, 0, 0); - if (ci.OnRenameSession) - ci.OnRenameSession(si); - } - } - - else if (gce->pDest->iType == GC_EVENT_SETITEMDATA) { - if (si = ci.SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule)) - si->dwItemData = gce->dwItemData; - } - - else if (gce->pDest->iType == GC_EVENT_GETITEMDATA) { - if (si = ci.SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule)) { - gce->dwItemData = si->dwItemData; - return si->dwItemData; - } - return 0; - } - else if (gce->pDest->iType == GC_EVENT_SETSBTEXT) { - if (si = ci.SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule)) { - replaceStrT(si->ptszStatusbarText, gce->ptszText); - if (si->ptszStatusbarText) - db_set_ts(si->hContact, si->pszModule, "StatusBar", si->ptszStatusbarText); - else - db_set_s(si->hContact, si->pszModule, "StatusBar", ""); - - if (ci.OnSetStatusBar) - ci.OnSetStatusBar(si); - } - } - else if (gce->pDest->iType == GC_EVENT_ACK) { - ci.SM_SendMessage(gce->pDest->ptszID, gce->pDest->pszModule, GC_ACKMESSAGE, 0, 0); - } - else if (gce->pDest->iType == GC_EVENT_SENDMESSAGE && gce->ptszText) { - ci.SM_SendUserMessage(gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszText); - } - else if (gce->pDest->iType == GC_EVENT_SETSTATUSEX) { - ci.SM_SetStatusEx(gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszText, gce->dwItemData); - } - else return 1; - - return 0; -} - -static void AddUser(GCEVENT *gce) -{ - SESSION_INFO *si = ci.SM_FindSession(gce->pDest->ptszID, gce->pDest->pszModule); - if (si == NULL) return; - - WORD status = ci.TM_StringToWord(si->pStatuses, gce->ptszStatus); - USERINFO *ui = ci.SM_AddUser(gce->pDest->ptszID, gce->pDest->pszModule, gce->ptszUID, gce->ptszNick, status); - if (ui == NULL) return; - - ui->pszNick = mir_tstrdup(gce->ptszNick); - if (gce->bIsMe) - si->pMe = ui; - ui->Status = status; - ui->Status |= si->pStatuses->Status; - - if (ci.OnNewUser) - ci.OnNewUser(si, ui); -} - -static INT_PTR Service_AddEvent(WPARAM wParam, LPARAM lParam) -{ - GCEVENT *gce = (GCEVENT*)lParam; - BOOL bIsHighlighted = FALSE; - BOOL bRemoveFlag = FALSE; - - if (gce == NULL) - return GC_EVENT_ERROR; - - GCDEST *gcd = gce->pDest; - if (gcd == NULL) - return GC_EVENT_ERROR; - - if (gce->cbSize != sizeof(GCEVENT)) - return GC_EVENT_WRONGVER; - - if (!IsEventSupported(gcd->iType)) - return GC_EVENT_ERROR; - - NotifyEventHooks(hHookEvent, wParam, lParam); - - SESSION_INFO *si; - mir_cslock lck(cs); - - // Do different things according to type of event - switch (gcd->iType) { - case GC_EVENT_ADDGROUP: - { - STATUSINFO *si = ci.SM_AddStatus(gcd->ptszID, gcd->pszModule, gce->ptszStatus); - if (si && gce->dwItemData) - si->hIcon = CopyIcon((HICON)gce->dwItemData); - } - return 0; - - case GC_EVENT_CHUID: - case GC_EVENT_CHANGESESSIONAME: - case GC_EVENT_SETITEMDATA: - case GC_EVENT_GETITEMDATA: - case GC_EVENT_CONTROL: - case GC_EVENT_SETSBTEXT: - case GC_EVENT_ACK: - case GC_EVENT_SENDMESSAGE: - case GC_EVENT_SETSTATUSEX: - return DoControl(gce, wParam); - - case GC_EVENT_SETCONTACTSTATUS: - return ci.SM_SetContactStatus(gcd->ptszID, gcd->pszModule, gce->ptszUID, (WORD)gce->dwItemData); - - case GC_EVENT_TOPIC: - if (si = ci.SM_FindSession(gcd->ptszID, gcd->pszModule)) { - if (gce->ptszText) { - replaceStrT(si->ptszTopic, RemoveFormatting(gce->ptszText)); - db_set_ts(si->hContact, si->pszModule, "Topic", si->ptszTopic); - if (ci.OnSetTopic) - ci.OnSetTopic(si); - if (db_get_b(NULL, CHAT_MODULE, "TopicOnClist", 0)) - db_set_ts(si->hContact, "CList", "StatusMsg", si->ptszTopic); - } - } - break; - - case GC_EVENT_ADDSTATUS: - ci.SM_GiveStatus(gcd->ptszID, gcd->pszModule, gce->ptszUID, gce->ptszStatus); - bIsHighlighted = ci.IsHighlighted(NULL, gce); - break; - - case GC_EVENT_REMOVESTATUS: - ci.SM_TakeStatus(gcd->ptszID, gcd->pszModule, gce->ptszUID, gce->ptszStatus); - bIsHighlighted = ci.IsHighlighted(NULL, gce); - break; - - case GC_EVENT_MESSAGE: - case GC_EVENT_ACTION: - if (!gce->bIsMe && gcd->ptszID && gce->ptszText) { - si = ci.SM_FindSession(gcd->ptszID, gcd->pszModule); - bIsHighlighted = ci.IsHighlighted(si, gce); - } - break; - - case GC_EVENT_NICK: - ci.SM_ChangeNick(gcd->ptszID, gcd->pszModule, gce); - bIsHighlighted = ci.IsHighlighted(NULL, gce); - break; - - case GC_EVENT_JOIN: - AddUser(gce); - bIsHighlighted = ci.IsHighlighted(NULL, gce); - break; - - case GC_EVENT_PART: - case GC_EVENT_QUIT: - case GC_EVENT_KICK: - bRemoveFlag = TRUE; - bIsHighlighted = ci.IsHighlighted(NULL, gce); - break; - } - - // Decide which window (log) should have the event - LPCTSTR pWnd = NULL; - LPCSTR pMod = NULL; - if (gcd->ptszID) { - pWnd = gcd->ptszID; - pMod = gcd->pszModule; - } - else if (gcd->iType == GC_EVENT_NOTICE || gcd->iType == GC_EVENT_INFORMATION) { - si = ci.GetActiveSession(); - if (si && !mir_strcmp(si->pszModule, gcd->pszModule)) { - pWnd = si->ptszID; - pMod = si->pszModule; - } - else return 0; - } - else { - // Send the event to all windows with a user pszUID. Used for broadcasting QUIT etc - ci.SM_AddEventToAllMatchingUID(gce); - if (!bRemoveFlag) - return 0; - } - - // add to log - if (pWnd) { - si = ci.SM_FindSession(pWnd, pMod); - - // fix for IRC's old stuyle mode notifications. Should not affect any other protocol - if ((gcd->iType == GC_EVENT_ADDSTATUS || gcd->iType == GC_EVENT_REMOVESTATUS) && !(gce->dwFlags & GCEF_ADDTOLOG)) - return 0; - - if (gcd->iType == GC_EVENT_JOIN && gce->time == 0) - return 0; - - if (si && (si->bInitDone || gcd->iType == GC_EVENT_TOPIC || (gcd->iType == GC_EVENT_JOIN && gce->bIsMe))) { - int isOk = ci.SM_AddEvent(pWnd, pMod, gce, bIsHighlighted); - if (ci.OnAddLog) - ci.OnAddLog(si, isOk); - if (!(gce->dwFlags & GCEF_NOTNOTIFY)) - ci.DoSoundsFlashPopupTrayStuff(si, gce, bIsHighlighted, 0); - if ((gce->dwFlags & GCEF_ADDTOLOG) && g_Settings->bLoggingEnabled) - ci.LogToFile(si, gce); - } - - if (!bRemoveFlag) - return 0; - } - - if (bRemoveFlag) - return ci.SM_RemoveUser(gcd->ptszID, gcd->pszModule, gce->ptszUID) == 0; - - return GC_EVENT_ERROR; -} - -static INT_PTR Service_GetAddEventPtr(WPARAM, LPARAM lParam) -{ - GCPTRS *gp = (GCPTRS *)lParam; - - mir_cslock lck(cs); - gp->pfnAddEvent = Service_AddEvent; - return 0; -} - -static int ModulesLoaded(WPARAM, LPARAM) -{ - LoadChatIcons(); - - HookEvent(ME_SMILEYADD_OPTIONSCHANGED, SmileyOptionsChanged); - HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu); - - CLISTMENUITEM mi = { sizeof(mi) }; - mi.position = -2000090001; - mi.flags = CMIF_DEFAULT; - mi.icolibItem = LoadSkinnedIconHandle(SKINICON_CHAT_JOIN); - mi.pszName = LPGEN("&Join chat"); - mi.pszService = "GChat/JoinChat"; - hJoinMenuItem = Menu_AddContactMenuItem(&mi); - - mi.position = -2000090000; - mi.icolibItem = LoadSkinnedIconHandle(SKINICON_CHAT_LEAVE); - mi.flags = CMIF_NOTOFFLINE; - mi.pszName = LPGEN("&Leave chat"); - mi.pszService = "GChat/LeaveChat"; - hLeaveMenuItem = Menu_AddContactMenuItem(&mi); - - ci.SetAllOffline(TRUE, NULL); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Service creation - -static bool bInited = false; - -int LoadChatModule(void) -{ - HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); - HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); - HookEvent(ME_SKIN_ICONSCHANGED, IconsChanged); - - CreateServiceFunction(MS_GC_REGISTER, Service_Register); - CreateServiceFunction(MS_GC_NEWSESSION, Service_NewChat); - CreateServiceFunction(MS_GC_EVENT, Service_AddEvent); - CreateServiceFunction(MS_GC_GETEVENTPTR, Service_GetAddEventPtr); - CreateServiceFunction(MS_GC_GETINFO, Service_GetInfo); - CreateServiceFunction(MS_GC_GETSESSIONCOUNT, Service_GetCount); - - CreateServiceFunction("GChat/DblClickEvent", EventDoubleclicked); - CreateServiceFunction("GChat/PrebuildMenuEvent", PrebuildContactMenuSvc); - CreateServiceFunction("GChat/JoinChat", JoinChat); - CreateServiceFunction("GChat/LeaveChat", LeaveChat); - CreateServiceFunction("GChat/GetInterface", SvcGetChatManager); - - ci.hSendEvent = CreateHookableEvent(ME_GC_EVENT); - ci.hBuildMenuEvent = CreateHookableEvent(ME_GC_BUILDMENU); - hHookEvent = CreateHookableEvent(ME_GC_HOOK_EVENT); - - HookEvent(ME_FONT_RELOAD, FontsChanged); - HookEvent(ME_SKIN2_ICONSCHANGED, IconsChanged); - - bInited = true; - return 0; -} - -void UnloadChatModule(void) -{ - if (!bInited) - return; - - mir_free(ci.szActiveWndID); - mir_free(ci.szActiveWndModule); - - FreeMsgLogBitmaps(); - OptionsUnInit(); - - DestroyHookableEvent(ci.hSendEvent); - DestroyHookableEvent(ci.hBuildMenuEvent); - DestroyHookableEvent(hHookEvent); -} diff --git a/src/modules/chat/clist.cpp b/src/modules/chat/clist.cpp deleted file mode 100644 index 4306806568..0000000000 --- a/src/modules/chat/clist.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/* -Chat module plugin for Miranda IM - -Copyright (C) 2003 Jrgen Persson - -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 "..\..\core\commonheaders.h" - -#include "chat.h" - -MCONTACT AddRoom(const char *pszModule, const TCHAR *pszRoom, const TCHAR *pszDisplayName, int iType) -{ - TCHAR pszGroup[50]; *pszGroup = '\0'; - ptrT groupName(db_get_tsa(NULL, CHAT_MODULE, "AddToGroup")); - if (groupName) - _tcsncpy_s(pszGroup, groupName, _TRUNCATE); - else - mir_tstrcpy(pszGroup, _T("Chat rooms")); - - if (pszGroup[0]) { - HANDLE hGroup = Clist_GroupExists(pszGroup); - if (hGroup == 0) { - hGroup = Clist_CreateGroup(0, pszGroup); - if (hGroup) { - CallService(MS_CLUI_GROUPADDED, (WPARAM)hGroup, 0); - CallService(MS_CLIST_GROUPSETEXPANDED, (WPARAM)hGroup, 1); - } - } - } - - MCONTACT hContact = ci.FindRoom(pszModule, pszRoom); - if (hContact) { //contact exist, make sure it is in the right group - if (pszGroup[0]) { - ptrT grpName(db_get_tsa(hContact, "CList", "Group")); - if (!mir_tstrcmp(pszGroup, grpName)) - db_set_ts(hContact, "CList", "Group", pszGroup); - } - - db_set_w(hContact, pszModule, "Status", ID_STATUS_OFFLINE); - db_set_ts(hContact, pszModule, "Nick", pszDisplayName); - return hContact; - } - - // here we create a new one since no one is to be found - if ((hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0)) == NULL) - return NULL; - - CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)pszModule); - if (pszGroup[0]) - db_set_ts(hContact, "CList", "Group", pszGroup); - else - db_unset(hContact, "CList", "Group"); - db_set_ts(hContact, pszModule, "Nick", pszDisplayName); - db_set_ts(hContact, pszModule, "ChatRoomID", pszRoom); - db_set_b(hContact, pszModule, "ChatRoom", (BYTE)iType); - db_set_w(hContact, pszModule, "Status", ID_STATUS_OFFLINE); - return hContact; -} - -BOOL SetOffline(MCONTACT hContact, BOOL bHide) -{ - if (hContact) { - char *szProto = GetContactProto(hContact); - db_set_w(hContact, szProto, "ApparentMode", 0); - db_set_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); - return TRUE; - } - - return FALSE; -} - -BOOL SetAllOffline(BOOL bHide, const char *pszModule) -{ - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - char *szProto = GetContactProto(hContact); - if (!ci.MM_FindModule(szProto)) - continue; - if (pszModule && mir_strcmp(pszModule, szProto)) - continue; - int i = db_get_b(hContact, szProto, "ChatRoom", 0); - if (i != 0) { - db_set_w(hContact, szProto, "ApparentMode", 0); - db_set_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); - } - } - - return TRUE; -} - -int RoomDoubleclicked(WPARAM hContact, LPARAM lParam) -{ - if (!hContact) - return 0; - - char *szProto = GetContactProto(hContact); - if (ci.MM_FindModule(szProto) == NULL) - return 0; - if (db_get_b(hContact, szProto, "ChatRoom", 0) == 0) - return 0; - - ptrT roomid(db_get_tsa(hContact, szProto, "ChatRoomID")); - if (roomid == NULL) - return 0; - - SESSION_INFO *si = ci.SM_FindSession(roomid, szProto); - if (si) { - // is the "toggle visibility option set, so we need to close the window? - if (si->hWnd != NULL && - db_get_b(NULL, CHAT_MODULE, "ToggleVisibility", 0) == 1 && - !CallService(MS_CLIST_GETEVENT, hContact, 0) && - IsWindowVisible(si->hWnd) && !IsIconic(si->hWnd)) - { - if (ci.OnDblClickSession) - ci.OnDblClickSession(si); - return 1; - } - ci.ShowRoom(si, WINDOW_VISIBLE, TRUE); - } - return 1; -} - -INT_PTR EventDoubleclicked(WPARAM wParam,LPARAM lParam) -{ - return RoomDoubleclicked((WPARAM)((CLISTEVENT*)lParam)->hContact, 0); -} - -INT_PTR JoinChat(WPARAM hContact, LPARAM lParam) -{ - if (hContact) { - char *szProto = GetContactProto(hContact); - if (szProto) { - if (db_get_w(hContact, szProto, "Status", 0) == ID_STATUS_OFFLINE) - CallProtoService(szProto, PS_JOINCHAT, hContact, lParam); - else - RoomDoubleclicked(hContact, 0); - } - } - - return 0; -} - -INT_PTR LeaveChat(WPARAM hContact, LPARAM lParam) -{ - if (hContact) { - char *szProto = GetContactProto(hContact); - if (szProto) - CallProtoService(szProto, PS_LEAVECHAT, hContact, lParam); - } - return 0; -} - -int PrebuildContactMenu(WPARAM hContact, LPARAM) -{ - if (hContact == 0) - return 0; - - bool bEnabledJoin = false, bEnabledLeave = false; - char *szProto = GetContactProto(hContact); - if (szProto) { - // display this menu item only for chats - if (db_get_b(hContact, szProto, "ChatRoom", 0)) { - // still hide it for offline protos - if (CallProtoService(szProto, PS_GETSTATUS, 0, 0) != ID_STATUS_OFFLINE) { - CLISTMENUITEM mi = { sizeof(mi) }; - mi.flags = CMIM_NAME; - if (db_get_w(hContact, szProto, "Status", 0) == ID_STATUS_OFFLINE) { - if (ProtoServiceExists(szProto, PS_JOINCHAT)) { - bEnabledJoin = true; - mi.pszName = LPGEN("&Join chat"); - } - } - else { - bEnabledJoin = true; - mi.pszName = LPGEN("&Open chat window"); - } - Menu_ModifyItem(hJoinMenuItem, &mi); - } - bEnabledLeave = ProtoServiceExists(szProto, PS_LEAVECHAT) != 0; - } - } - - Menu_ShowItem(hJoinMenuItem, bEnabledJoin); - Menu_ShowItem(hLeaveMenuItem, bEnabledLeave); - return 0; -} - -INT_PTR PrebuildContactMenuSvc(WPARAM wParam, LPARAM lParam) -{ - return PrebuildContactMenu(wParam, lParam); -} - -BOOL AddEvent(MCONTACT hContact, HICON hIcon, MEVENT hEvent, int type, TCHAR* fmt, ...) -{ - TCHAR szBuf[4096]; - - if (!fmt || !fmt[0] || mir_tstrlen(fmt) > 2000) - return FALSE; - - va_list marker; - va_start(marker, fmt); - mir_vsntprintf(szBuf, SIZEOF(szBuf), fmt, marker); - va_end(marker); - - CLISTEVENT cle = { 0 }; - cle.cbSize = sizeof(cle); - cle.hContact = hContact; - cle.hDbEvent = hEvent; - cle.flags = type | CLEF_TCHAR; - cle.hIcon = hIcon; - cle.pszService = "GChat/DblClickEvent" ; - cle.ptszTooltip = TranslateTS(szBuf); - if (type) { - if (!CallService(MS_CLIST_GETEVENT, hContact, 0)) - CallService(MS_CLIST_ADDEVENT, hContact, (LPARAM)&cle); - } - else { - if (CallService(MS_CLIST_GETEVENT, hContact, 0)) - CallService(MS_CLIST_REMOVEEVENT, hContact, (LPARAM)GC_FAKE_EVENT); - CallService(MS_CLIST_ADDEVENT, hContact, (LPARAM)&cle); - } - return TRUE; -} - -MCONTACT FindRoom(const char *pszModule, const TCHAR *pszRoom) -{ - for (MCONTACT hContact = db_find_first(pszModule); hContact; hContact = db_find_next(hContact, pszModule)) { - if (!db_get_b(hContact, pszModule, "ChatRoom", 0)) - continue; - - ptrT roomid(db_get_tsa(hContact, pszModule, "ChatRoomID")); - if (roomid != NULL && !mir_tstrcmpi(roomid, pszRoom)) - return hContact; - } - - return 0; -} diff --git a/src/modules/chat/colorchooser.cpp b/src/modules/chat/colorchooser.cpp deleted file mode 100644 index f81012b527..0000000000 --- a/src/modules/chat/colorchooser.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/* -Chat module plugin for Miranda IM - -Copyright 2000-12 Miranda IM, 2012-15 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#include "chat.h" - -struct COLORCHOOSER -{ - MODULEINFO *pModule; - int xPosition, yPosition; - HWND hWndTarget, hWndChooser; - BOOL bForeground; - GCSessionInfoBase *si; -}; - -static int CalculateCoordinatesToButton(COLORCHOOSER * pCC, POINT pt) -{ - int iSquareRoot = (int)sqrt(static_cast(pCC->pModule->nColorCount)); - int nCols = iSquareRoot * iSquareRoot < pCC->pModule->nColorCount ? iSquareRoot + 1 : iSquareRoot; - - int col = pt.x / 25; - int row = (pt.y - 20) / 20; - int pos = nCols * row + col; - - if (pt.y < 20 && pos >= pCC->pModule->nColorCount) - pos = -1; - - return pos; -} - -static RECT CalculateButtonToCoordinates(COLORCHOOSER * pCC, int buttonPosition) -{ - int iSquareRoot = (int)sqrt(static_cast(pCC->pModule->nColorCount)); - int nCols = iSquareRoot * iSquareRoot < pCC->pModule->nColorCount ? iSquareRoot + 1 : iSquareRoot; - - int row = buttonPosition / nCols; - int col = buttonPosition % nCols; - - RECT pt; - pt.left = col * 25 + 1; - pt.top = row * 20 + 20; - pt.right = pt.left + 25 - 1; - pt.bottom = pt.top + 20; - - return pt; -} - -static INT_PTR CALLBACK DlgProcColorToolWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static COLORCHOOSER* pCC = NULL; - static int iCurrentHotTrack; - static BOOL bChoosing; - static int iRows; - static int iColumns; - static HWND hPreviousActiveWindow; - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - { - pCC = (COLORCHOOSER*) lParam; - - iCurrentHotTrack = -2; - bChoosing = FALSE; - - int iSquareRoot = (int)sqrt(static_cast(pCC->pModule->nColorCount)); - - iColumns = iSquareRoot * iSquareRoot == pCC->pModule->nColorCount ? iSquareRoot : iSquareRoot + 1; - iRows = iSquareRoot; - - RECT rc; - rc.top = rc.left = 100; - rc.right = 100 + iColumns * 25 + 1; - rc.bottom = iRows * 20 + 100 + 20; - - AdjustWindowRectEx(&rc, GetWindowLongPtr(hwndDlg, GWL_STYLE), FALSE, GetWindowLongPtr(hwndDlg, GWL_EXSTYLE)); - - int width = rc.right - rc.left; - int height = rc.bottom - rc.top; - - pCC->yPosition -= height; - - SetDlgItemText(hwndDlg, IDC_COLORTEXT, pCC->bForeground ? TranslateT("Text color") : TranslateT("Background color")); - SetWindowPos(GetDlgItem(hwndDlg, IDC_COLORTEXT), NULL, 0, 0, width, 20, 0); - SetWindowPos(hwndDlg, NULL, pCC->xPosition, pCC->yPosition, width, height, SWP_SHOWWINDOW); - } - break; - - case WM_CTLCOLOREDIT: - case WM_CTLCOLORSTATIC: - if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_COLORTEXT)) { - SetTextColor((HDC)wParam, RGB(60, 60, 150)); - SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); - return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - if (iCurrentHotTrack >= 0) - PostMessage(hwndDlg, WM_LBUTTONUP, 0, 0); - break; - case IDCANCEL: - DestroyWindow(hwndDlg); - break; - } - break; - - case WM_LBUTTONUP: - if (iCurrentHotTrack >= 0 && iCurrentHotTrack < pCC->pModule->nColorCount && pCC->hWndTarget != NULL) { - CHARFORMAT2 cf; - cf.cbSize = sizeof(CHARFORMAT2); - cf.dwMask = 0; - cf.dwEffects = 0; - - HWND hWindow = GetParent(pCC->hWndTarget); - int ctrlId = GetDlgCtrlID(pCC->hWndChooser); - - if (pCC->bForeground) { - pCC->si->bFGSet = TRUE; - pCC->si->iFG = iCurrentHotTrack; - if (IsDlgButtonChecked(hWindow, ctrlId)) { - cf.dwMask = CFM_COLOR; - cf.crTextColor = pCC->pModule->crColors[iCurrentHotTrack]; - SendMessage(pCC->hWndTarget, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); - } - } - else { - pCC->si->bBGSet = TRUE; - pCC->si->iBG = iCurrentHotTrack; - if (IsDlgButtonChecked(hWindow, ctrlId)) { - cf.dwMask = CFM_BACKCOLOR; - cf.crBackColor = pCC->pModule->crColors[iCurrentHotTrack]; - SendMessage(pCC->hWndTarget, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); - } - } - } - PostMessage(hwndDlg, WM_CLOSE, 0, 0); - break; - - case WM_ACTIVATE: - if (wParam == WA_INACTIVE) - PostMessage(hwndDlg, WM_CLOSE, 0, 0); - else if ((wParam == WA_ACTIVE) || (wParam == WA_CLICKACTIVE)) - hPreviousActiveWindow = (HWND)lParam; - break; - - case WM_MOUSEMOVE: - { - HDC hdc = GetDC(hwndDlg); - POINT pt; - RECT rect; - int but; - - pt.x = LOWORD(lParam); - pt.y = HIWORD(lParam); - - if (iCurrentHotTrack == -2) - return 0; // prevent focussing when not drawn yet! - - but = CalculateCoordinatesToButton(pCC, pt); - - // weird stuff - if (but != iCurrentHotTrack) { - if (iCurrentHotTrack >= 0) { - rect = CalculateButtonToCoordinates(pCC, iCurrentHotTrack); - DrawFocusRect(hdc, &rect); - iCurrentHotTrack = -1; - } - iCurrentHotTrack = but; - - if (iCurrentHotTrack >= 0) { - rect = CalculateButtonToCoordinates(pCC, iCurrentHotTrack); - DrawFocusRect(hdc, &rect); - } - } - ReleaseDC(hwndDlg, hdc); - } - break; - - case WM_PAINT: - { - PAINTSTRUCT ps; - int iThisRow = 1; - int iThisColumn = 0; - - RECT rc; - GetClientRect(hwndDlg, &rc); - rc.top += 20; - - HDC hdc = BeginPaint(hwndDlg, &ps); - - // fill background - FillRect(hdc, &rc, GetSysColorBrush(COLOR_WINDOW)); - - for (int i=0; i < pCC->pModule->nColorCount; i++) { - // decide place to draw the color block in the window - iThisColumn ++; - if (iThisColumn > iColumns) { - iThisColumn = 1; - iThisRow++; - } - - if (pCC->bForeground && pCC->si->bFGSet && pCC->si->iFG == i || !pCC->bForeground && pCC->si->bBGSet && pCC->si->iBG == i) { - rc.top = (iThisRow - 1) * 20 + 1 + 20 ; - rc.left = (iThisColumn - 1) * 25 + 1 + 1 ; - rc.bottom = iThisRow * 20 - 1 + 20 ; - rc.right = iThisColumn * 25 - 1 ; - - DrawEdge(hdc, &rc, EDGE_RAISED, BF_TOP | BF_LEFT | BF_RIGHT | BF_BOTTOM); - } - - rc.top = (iThisRow - 1) * 20 + 3 + 20 ; - rc.left = (iThisColumn - 1) * 25 + 3 + 1 ; - rc.bottom = iThisRow * 20 - 3 + 20 ; - rc.right = iThisColumn * 25 - 3 ; - - FillRect(hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); - - HBRUSH hbr = CreateSolidBrush(pCC->pModule->crColors[i]); - - rc.top = (iThisRow - 1) * 20 + 4 + 20; - rc.left = (iThisColumn - 1) * 25 + 4 + 1; - rc.bottom = iThisRow * 20 - 4 + 20; - rc.right = iThisColumn * 25 - 4; - - FillRect(hdc, &rc, hbr); - DeleteObject(hbr); - } - - EndPaint(hwndDlg, &ps); - iCurrentHotTrack = -1; - } - break; - - case WM_CLOSE: - SetFocus(pCC->hWndTarget); - DestroyWindow(hwndDlg); - break; - - case WM_DESTROY: - mir_free(pCC); - return TRUE; - } - - return FALSE; -} - -void ColorChooser(SESSION_INFO *si, BOOL bFG, HWND hwndDlg, HWND hwndTarget, HWND hwndChooser) -{ - RECT rc; - GetWindowRect(hwndChooser, &rc); - - COLORCHOOSER *pCC = (COLORCHOOSER *)mir_alloc(sizeof(COLORCHOOSER)); - pCC->hWndTarget = hwndTarget; - pCC->pModule = ci.MM_FindModule(si->pszModule); - pCC->xPosition = rc.left + 3; - pCC->yPosition = IsWindowVisible(hwndChooser) ? rc.top - 1 : rc.top + 20; - pCC->bForeground = bFG; - pCC->hWndChooser = hwndChooser; - pCC->si = si; - CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_COLORCHOOSER), hwndDlg, DlgProcColorToolWindow, (LPARAM)pCC); -} diff --git a/src/modules/chat/log.cpp b/src/modules/chat/log.cpp deleted file mode 100644 index 4ad98b44eb..0000000000 --- a/src/modules/chat/log.cpp +++ /dev/null @@ -1,542 +0,0 @@ -/* -Chat module plugin for Miranda IM - -Copyright (C) 2003 Jrgen Persson - -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 "..\..\core\commonheaders.h" - -#include "chat.h" - -// The code for streaming the text is to a large extent copied from -// the srmm module and then modified to fit the chat module. - -char* pLogIconBmpBits[14]; -size_t logIconBmpSize[ SIZEOF(pLogIconBmpBits) ]; - -#define RTFCACHELINESIZE 128 -static char CHAT_rtfFontsGlobal[OPTIONS_FONTCOUNT][RTFCACHELINESIZE]; - -static int EventToIndex(LOGINFO *lin) -{ - switch (lin->iType) { - case GC_EVENT_MESSAGE: - if (lin->bIsMe) - return 10; - else - return 9; - - case GC_EVENT_JOIN: return 3; - case GC_EVENT_PART: return 4; - case GC_EVENT_QUIT: return 5; - case GC_EVENT_NICK: return 7; - case GC_EVENT_KICK: return 6; - case GC_EVENT_NOTICE: return 8; - case GC_EVENT_TOPIC: return 11; - case GC_EVENT_INFORMATION:return 12; - case GC_EVENT_ADDSTATUS: return 13; - case GC_EVENT_REMOVESTATUS: return 14; - case GC_EVENT_ACTION: return 15; - } - return 0; -} - -static int EventToIcon(LOGINFO *lin) -{ - switch (lin->iType) { - case GC_EVENT_MESSAGE: - if (lin->bIsMe) - return ICON_MESSAGEOUT; - else - return ICON_MESSAGE; - - case GC_EVENT_JOIN: return ICON_JOIN; - case GC_EVENT_PART: return ICON_PART; - case GC_EVENT_QUIT: return ICON_QUIT; - case GC_EVENT_NICK: return ICON_NICK; - case GC_EVENT_KICK: return ICON_KICK; - case GC_EVENT_NOTICE: return ICON_NOTICE; - case GC_EVENT_TOPIC: return ICON_TOPIC; - case GC_EVENT_INFORMATION:return ICON_INFO; - case GC_EVENT_ADDSTATUS: return ICON_ADDSTATUS; - case GC_EVENT_REMOVESTATUS: return ICON_REMSTATUS; - case GC_EVENT_ACTION: return ICON_ACTION; - } - return 0; -} - -char* Log_SetStyle(int style) -{ - if (style < OPTIONS_FONTCOUNT) - return CHAT_rtfFontsGlobal[style]; - - return ""; -} - -static void Log_Append(char *&buffer, size_t &cbBufferEnd, size_t &cbBufferAlloced, const char *fmt, ...) -{ - va_list va; - int charsDone = 0; - - va_start(va, fmt); - for (;;) { - charsDone = mir_vsnprintf(buffer + cbBufferEnd, cbBufferAlloced - cbBufferEnd, fmt, va); - if (charsDone >= 0) - break; - cbBufferAlloced += 4096; - buffer = (char*)mir_realloc(buffer, cbBufferAlloced); - } - va_end(va); - cbBufferEnd += charsDone; -} - -static int Log_AppendRTF(LOGSTREAMDATA *streamData, BOOL simpleMode, char *&buffer, size_t &cbBufferEnd, size_t &cbBufferAlloced, const TCHAR *fmt, ...) -{ - va_list va; - int lineLen, textCharsCount = 0; - TCHAR* line = (TCHAR*)alloca(8001 * sizeof(TCHAR)); - - va_start(va, fmt); - lineLen = mir_vsntprintf(line, 8000, fmt, va); - if (lineLen < 0) lineLen = 8000; - line[lineLen] = 0; - va_end(va); - - lineLen = lineLen * 20 + 8; - if (cbBufferEnd + lineLen > cbBufferAlloced) { - cbBufferAlloced += (lineLen + 1024 - lineLen % 1024); - buffer = (char *)mir_realloc(buffer, cbBufferAlloced); - } - - char *d = buffer + cbBufferEnd; - - for (; *line; line++, textCharsCount++) { - if (*line == '\r' && line[1] == '\n') { - memcpy(d, "\\par ", 5); - line++; - d += 5; - } - else if (*line == '\n') { - memcpy(d, "\\line ", 6); - d += 6; - } - else if (*line == '%' && !simpleMode) { - char szTemp[200]; - - szTemp[0] = '\0'; - switch (*++line) { - case '\0': - case '%': - *d++ = '%'; - break; - - case 'c': - case 'f': - if (g_Settings->bStripFormat || streamData->bStripFormat) - line += 2; - - else if (line[1] != '\0' && line[2] != '\0') { - TCHAR szTemp3[3], c = *line; - int col; - szTemp3[0] = line[1]; - szTemp3[1] = line[2]; - szTemp3[2] = '\0'; - line += 2; - - col = _ttoi(szTemp3); - col += (OPTIONS_FONTCOUNT + 1); - mir_snprintf(szTemp, (c == 'c') ? "\\cf%u " : "\\highlight%u ", col); - } - break; - case 'C': - case 'F': - if (!g_Settings->bStripFormat && !streamData->bStripFormat) { - int j = streamData->lin->bIsHighlighted ? 16 : EventToIndex(streamData->lin); - if (*line == 'C') - mir_snprintf(szTemp, "\\cf%u ", j + 1); - else - mir_snprintf(szTemp, "\\highlight0 "); - } - break; - case 'b': - case 'u': - case 'i': - if (!streamData->bStripFormat) - mir_snprintf(szTemp, (*line == 'u') ? "\\%cl " : "\\%c ", *line); - break; - - case 'B': - case 'U': - case 'I': - if (!streamData->bStripFormat) { - mir_snprintf(szTemp, (*line == 'U') ? "\\%cl0 " : "\\%c0 ", *line); - CharLowerA(szTemp); - } - break; - - case 'r': - if (!streamData->bStripFormat) { - int index = EventToIndex(streamData->lin); - mir_snprintf(szTemp, "%s ", Log_SetStyle(index)); - } - break; - } - - if (szTemp[0]) { - size_t iLen = mir_strlen(szTemp); - memcpy(d, szTemp, iLen); - d += iLen; - } - } - else if (*line == '\t' && !streamData->bStripFormat) { - memcpy(d, "\\tab ", 5); - d += 5; - } - else if ((*line == '\\' || *line == '{' || *line == '}') && !streamData->bStripFormat) { - *d++ = '\\'; - *d++ = (char)*line; - } - else if (*line > 0 && *line < 128) { - *d++ = (char)*line; - } - else d += sprintf(d, "\\u%u ?", (WORD)*line); //!!!!!!!!!!! - } - - cbBufferEnd = (int)(d - buffer); - return textCharsCount; -} - -static void AddEventToBuffer(char *&buffer, size_t &bufferEnd, size_t &bufferAlloced, LOGSTREAMDATA *streamData) -{ - TCHAR szTemp[512], szTemp2[512]; - TCHAR* pszNick = NULL; - if (streamData->lin->ptszNick) { - if (g_Settings->bLogLimitNames && mir_tstrlen(streamData->lin->ptszNick) > 20) { - mir_tstrncpy(szTemp2, streamData->lin->ptszNick, 20); - mir_tstrncpy(szTemp2 + 20, _T("..."), 4); - } - else mir_tstrncpy(szTemp2, streamData->lin->ptszNick, 511); - - if (streamData->lin->ptszUserInfo) - mir_sntprintf(szTemp, _T("%s (%s)"), szTemp2, streamData->lin->ptszUserInfo); - else - _tcsncpy_s(szTemp, szTemp2, _TRUNCATE); - pszNick = szTemp; - } - - switch (streamData->lin->iType) { - case GC_EVENT_MESSAGE: - if (streamData->lin->ptszText) - Log_AppendRTF(streamData, FALSE, buffer, bufferEnd, bufferAlloced, _T("%s"), streamData->lin->ptszText); - break; - case GC_EVENT_ACTION: - if (streamData->lin->ptszNick && streamData->lin->ptszText) { - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, _T("%s "), streamData->lin->ptszNick); - Log_AppendRTF(streamData, FALSE, buffer, bufferEnd, bufferAlloced, _T("%s"), streamData->lin->ptszText); - } - break; - case GC_EVENT_JOIN: - if (pszNick) { - if (!streamData->lin->bIsMe) - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s has joined"), pszNick); - else - Log_AppendRTF(streamData, FALSE, buffer, bufferEnd, bufferAlloced, TranslateT("You have joined %s"), streamData->si->ptszName); - } - break; - case GC_EVENT_PART: - if (pszNick) - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s has left"), pszNick); - if (streamData->lin->ptszText) - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, _T(": %s"), streamData->lin->ptszText); - break; - case GC_EVENT_QUIT: - if (pszNick) - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s has disconnected"), pszNick); - if (streamData->lin->ptszText) - Log_AppendRTF(streamData, FALSE, buffer, bufferEnd, bufferAlloced, _T(": %s"), streamData->lin->ptszText); - break; - case GC_EVENT_NICK: - if (pszNick && streamData->lin->ptszText) { - if (!streamData->lin->bIsMe) - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s is now known as %s"), pszNick, streamData->lin->ptszText); - else - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("You are now known as %s"), streamData->lin->ptszText); - } - break; - case GC_EVENT_KICK: - if (streamData->lin->ptszNick && streamData->lin->ptszStatus) - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s kicked %s"), streamData->lin->ptszStatus, streamData->lin->ptszNick); - if (streamData->lin->ptszText) - Log_AppendRTF(streamData, FALSE, buffer, bufferEnd, bufferAlloced, _T(": %s"), streamData->lin->ptszText); - break; - case GC_EVENT_NOTICE: - if (pszNick && streamData->lin->ptszText) { - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("Notice from %s: "), pszNick); - Log_AppendRTF(streamData, FALSE, buffer, bufferEnd, bufferAlloced, _T("%s"), streamData->lin->ptszText); - } - break; - case GC_EVENT_TOPIC: - if (streamData->lin->ptszText) - Log_AppendRTF(streamData, FALSE, buffer, bufferEnd, bufferAlloced, TranslateT("The topic is '%s%s'"), streamData->lin->ptszText, _T("%r")); - if (streamData->lin->ptszNick) - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, - streamData->lin->ptszUserInfo ? TranslateT(" (set by %s on %s)") : TranslateT(" (set by %s)"), - streamData->lin->ptszNick, streamData->lin->ptszUserInfo); - break; - case GC_EVENT_INFORMATION: - if (streamData->lin->ptszText) - Log_AppendRTF(streamData, FALSE, buffer, bufferEnd, bufferAlloced, (streamData->lin->bIsMe) ? _T("--> %s") : _T("%s"), streamData->lin->ptszText); - break; - case GC_EVENT_ADDSTATUS: - if (streamData->lin->ptszNick && streamData->lin->ptszText && streamData->lin->ptszStatus) - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s enables '%s' status for %s"), streamData->lin->ptszText, streamData->lin->ptszStatus, streamData->lin->ptszNick); - break; - case GC_EVENT_REMOVESTATUS: - if (streamData->lin->ptszNick && streamData->lin->ptszText && streamData->lin->ptszStatus) - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, TranslateT("%s disables '%s' status for %s"), streamData->lin->ptszText, streamData->lin->ptszStatus, streamData->lin->ptszNick); - break; - } -} - -TCHAR* MakeTimeStamp(TCHAR *pszStamp, time_t time) -{ - static TCHAR szTime[30]; - if (!_tcsftime(szTime, SIZEOF(szTime)-1, pszStamp, localtime(&time))) - _tcsncpy_s(szTime, TranslateT(""), _TRUNCATE); - return szTime; -} - -char* Log_CreateRTF(LOGSTREAMDATA *streamData) -{ - MODULEINFO *mi = ci.MM_FindModule(streamData->si->pszModule); - - // guesstimate amount of memory for the RTF - size_t bufferEnd = 0, bufferAlloced = streamData->bRedraw ? 1024 * (streamData->si->iEventCount + 2) : 2048; - char *buffer = (char *)mir_alloc(bufferAlloced); - buffer[0] = '\0'; - - // ### RTF HEADER - char *header = mi->pszHeader; - if (header) - Log_Append(buffer, bufferEnd, bufferAlloced, header); - - // ### RTF BODY (one iteration per event that should be streamed in) - for (LOGINFO *lin = streamData->lin; lin; lin = lin->prev) { - // filter - if (streamData->si->iType == GCW_CHATROOM || streamData->si->iType == GCW_PRIVMESS) - if (streamData->si->bFilterEnabled && (streamData->si->iLogFilterFlags & lin->iType) == 0) - continue; - - // create new line, and set font and color - if (lin->next != NULL) - Log_Append(buffer, bufferEnd, bufferAlloced, "\\par "); - Log_Append(buffer, bufferEnd, bufferAlloced, "%s ", Log_SetStyle(0)); - - // Insert icon - if ((lin->iType & g_Settings->dwIconFlags) || lin->bIsHighlighted && (g_Settings->dwIconFlags & GC_EVENT_HIGHLIGHT)) { - int iIndex = (lin->bIsHighlighted && g_Settings->dwIconFlags & GC_EVENT_HIGHLIGHT) ? ICON_HIGHLIGHT : EventToIcon(lin); - Log_Append(buffer, bufferEnd, bufferAlloced, "\\f0\\fs14"); - while (bufferAlloced - bufferEnd < logIconBmpSize[0]) - bufferAlloced += 4096; - buffer = (char *)mir_realloc(buffer, bufferAlloced); - memcpy(buffer + bufferEnd, pLogIconBmpBits[iIndex], logIconBmpSize[iIndex]); - bufferEnd += logIconBmpSize[iIndex]; - } - - if (g_Settings->bTimeStampEventColour) { - LOGFONT &lf = ci.aFonts[0].lf; - - // colored timestamps - static char szStyle[256]; - if (lin->ptszNick && lin->iType == GC_EVENT_MESSAGE) { - int iii = lin->bIsHighlighted ? 16 : (lin->bIsMe ? 2 : 1); - mir_snprintf(szStyle, SIZEOF(szStyle), "\\f0\\cf%u\\ul0\\highlight0\\b%d\\i%d\\fs%u", iii + 1, lf.lfWeight >= FW_BOLD ? 1 : 0, lf.lfItalic, 2 * abs(lf.lfHeight) * 74 / ci.logPixelSY); - Log_Append(buffer, bufferEnd, bufferAlloced, "%s ", szStyle); - } - else { - int iii = lin->bIsHighlighted ? 16 : EventToIndex(lin); - mir_snprintf(szStyle, SIZEOF(szStyle), "\\f0\\cf%u\\ul0\\highlight0\\b%d\\i%d\\fs%u", iii + 1, lf.lfWeight >= FW_BOLD ? 1 : 0, lf.lfItalic, 2 * abs(lf.lfHeight) * 74 / ci.logPixelSY); - Log_Append(buffer, bufferEnd, bufferAlloced, "%s ", szStyle); - } - } - else Log_Append(buffer, bufferEnd, bufferAlloced, "%s ", Log_SetStyle(0)); - - if (g_Settings->dwIconFlags) - Log_Append(buffer, bufferEnd, bufferAlloced, "\\tab "); - - //insert timestamp - if (g_Settings->bShowTime) { - TCHAR szTimeStamp[30], szOldTimeStamp[30]; - - mir_tstrncpy(szTimeStamp, MakeTimeStamp(g_Settings->pszTimeStamp, lin->time), 30); - mir_tstrncpy(szOldTimeStamp, MakeTimeStamp(g_Settings->pszTimeStamp, streamData->si->LastTime), 30); - if (!g_Settings->bShowTimeIfChanged || streamData->si->LastTime == 0 || mir_tstrcmp(szTimeStamp, szOldTimeStamp)) { - streamData->si->LastTime = lin->time; - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, _T("%s"), szTimeStamp); - } - Log_Append(buffer, bufferEnd, bufferAlloced, "\\tab "); - } - - // Insert the nick - if (lin->ptszNick && lin->iType == GC_EVENT_MESSAGE) { - TCHAR pszTemp[300], *p1; - - Log_Append(buffer, bufferEnd, bufferAlloced, "%s ", Log_SetStyle(lin->bIsMe ? 2 : 1)); - mir_tstrncpy(pszTemp, lin->bIsMe ? g_Settings->pszOutgoingNick : g_Settings->pszIncomingNick, 299); - p1 = _tcsstr(pszTemp, _T("%n")); - if (p1) - p1[1] = 's'; - - Log_AppendRTF(streamData, TRUE, buffer, bufferEnd, bufferAlloced, pszTemp, lin->ptszNick); - Log_Append(buffer, bufferEnd, bufferAlloced, " "); - } - - // Insert the message - Log_Append(buffer, bufferEnd, bufferAlloced, "%s ", Log_SetStyle(lin->bIsHighlighted ? 16 : EventToIndex(lin))); - streamData->lin = lin; - AddEventToBuffer(buffer, bufferEnd, bufferAlloced, streamData); - } - - // ### RTF END - if (streamData->bRedraw) - Log_Append(buffer, bufferEnd, bufferAlloced, "\\par}"); - else - Log_Append(buffer, bufferEnd, bufferAlloced, "}"); - return buffer; -} - -char* Log_CreateRtfHeader(MODULEINFO *mi) -{ - int i; - - // guesstimate amount of memory for the RTF header - size_t bufferEnd = 0, bufferAlloced = 4096; - char *buffer = (char *)mir_realloc(mi->pszHeader, bufferAlloced); - buffer[0] = '\0'; - - // get the number of pixels per logical inch - HDC hdc = GetDC(NULL); - ci.logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY); - ci.logPixelSX = GetDeviceCaps(hdc, LOGPIXELSX); - ReleaseDC(NULL, hdc); - - // ### RTF HEADER - - // font table - Log_Append(buffer, bufferEnd, bufferAlloced, "{\\rtf1\\ansi\\deff0{\\fonttbl"); - for (i = 0; i < OPTIONS_FONTCOUNT; i++) - Log_Append(buffer, bufferEnd, bufferAlloced, "{\\f%u\\fnil\\fcharset%u%S;}", i, ci.aFonts[i].lf.lfCharSet, ci.aFonts[i].lf.lfFaceName); - - // colour table - Log_Append(buffer, bufferEnd, bufferAlloced, "}{\\colortbl ;"); - - for (i = 0; i < OPTIONS_FONTCOUNT; i++) - Log_Append(buffer, bufferEnd, bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(ci.aFonts[i].color), GetGValue(ci.aFonts[i].color), GetBValue(ci.aFonts[i].color)); - - for (i = 0; i < mi->nColorCount; i++) - Log_Append(buffer, bufferEnd, bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(mi->crColors[i]), GetGValue(mi->crColors[i]), GetBValue(mi->crColors[i])); - - // new paragraph - Log_Append(buffer, bufferEnd, bufferAlloced, "}\\pard"); - - // set tabs and indents - int iIndent = 0; - - if (g_Settings->dwIconFlags) { - iIndent += (14 * 1440) / ci.logPixelSX; - Log_Append(buffer, bufferEnd, bufferAlloced, "\\tx%u", iIndent); - } - if (g_Settings->bShowTime) { - int iSize = (g_Settings->LogTextIndent * 1440) / ci.logPixelSX; - Log_Append(buffer, bufferEnd, bufferAlloced, "\\tx%u", iIndent + iSize); - if (g_Settings->bLogIndentEnabled) - iIndent += iSize; - } - - Log_Append(buffer, bufferEnd, bufferAlloced, "\\fi-%u\\li%u", iIndent, iIndent); - return buffer; -} - -#define RTFPICTHEADERMAXSIZE 78 - -void LoadMsgLogBitmaps(void) -{ - HBRUSH hBkgBrush = CreateSolidBrush(g_Settings->crLogBackground); - - BITMAPINFOHEADER bih = { 0 }; - bih.biSize = sizeof(bih); - bih.biBitCount = 24; - bih.biCompression = BI_RGB; - bih.biHeight = bih.biWidth = g_Settings->LogIconSize; - bih.biPlanes = 1; - int widthBytes = ((bih.biWidth * bih.biBitCount + 31) >> 5) * 4; - - RECT rc; - rc.top = rc.left = 0; - rc.right = bih.biWidth; - rc.bottom = bih.biHeight; - - HDC hdc = GetDC(NULL); - HBITMAP hBmp = CreateCompatibleBitmap(hdc, bih.biWidth, bih.biHeight); - HDC hdcMem = CreateCompatibleDC(hdc); - PBYTE pBmpBits = (PBYTE)mir_alloc(widthBytes * bih.biHeight); - for (int i = 0; i < SIZEOF(pLogIconBmpBits); i++) { - size_t size = RTFPICTHEADERMAXSIZE + (bih.biSize + widthBytes * bih.biHeight) * 2; - pLogIconBmpBits[i] = (char*)mir_alloc(size); - size_t rtfHeaderSize = mir_snprintf((char *)pLogIconBmpBits[i], size, "{\\pict\\dibitmap0\\wbmbitspixel%u\\wbmplanes1\\wbmwidthbytes%u\\picw%u\\pich%u ", bih.biBitCount, widthBytes, bih.biWidth, bih.biHeight); - - HICON hIcon = ci.hIcons[i]; - HBITMAP hoBmp = (HBITMAP)SelectObject(hdcMem, hBmp); - FillRect(hdcMem, &rc, hBkgBrush); - DrawIconEx(hdcMem, 0, 0, hIcon, bih.biWidth, bih.biHeight, 0, NULL, DI_NORMAL); - SelectObject(hdcMem, hoBmp); - GetDIBits(hdc, hBmp, 0, bih.biHeight, pBmpBits, (BITMAPINFO *)& bih, DIB_RGB_COLORS); - - char *szDest = pLogIconBmpBits[i] + rtfHeaderSize; - bin2hex(&bih, sizeof(bih), szDest); szDest += sizeof(bih) * 2; - bin2hex(pBmpBits, widthBytes * bih.biHeight, szDest); szDest += widthBytes * bih.biHeight * 2; - mir_strcpy(szDest, "}"); - - logIconBmpSize[i] = size_t(szDest - pLogIconBmpBits[i]) + 1; - } - mir_free(pBmpBits); - DeleteDC(hdcMem); - DeleteObject(hBmp); - ReleaseDC(NULL, hdc); - DeleteObject(hBkgBrush); - - if (ci.logPixelSY == 0) { - HDC hdc; - hdc = GetDC(NULL); - ci.logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY); - ci.logPixelSX = GetDeviceCaps(hdc, LOGPIXELSX); - ReleaseDC(NULL, hdc); - } - - for (int i = 0; i < OPTIONS_FONTCOUNT; i++) { - LOGFONT &F = ci.aFonts[i].lf; - mir_snprintf(CHAT_rtfFontsGlobal[i], RTFCACHELINESIZE, - "\\f%u\\cf%u\\ul0\\highlight0\\b%d\\i%d\\ul%d\\fs%u", i, i + 1, - F.lfWeight >= FW_BOLD ? 1 : 0, F.lfItalic, F.lfUnderline, 2 * abs(F.lfHeight) * 74 / ci.logPixelSY); - } -} - -void FreeMsgLogBitmaps(void) -{ - for (int i = 0; i < SIZEOF(pLogIconBmpBits); i++) - mir_free(pLogIconBmpBits[i]); -} diff --git a/src/modules/chat/manager.cpp b/src/modules/chat/manager.cpp deleted file mode 100644 index bbc846c89f..0000000000 --- a/src/modules/chat/manager.cpp +++ /dev/null @@ -1,1331 +0,0 @@ -/* -Chat module plugin for Miranda IM - -Copyright 2000-12 Miranda IM, 2012-15 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#include "chat.h" - -#define WINDOWS_COMMANDS_MAX 30 - -CHAT_MANAGER ci; - -MODULEINFO *m_ModList = 0; - -static void SetActiveSessionEx(SESSION_INFO *si) -{ - if (si) { - replaceStrT(ci.szActiveWndID, si->ptszID); - replaceStr(ci.szActiveWndModule, si->pszModule); - } -} - -static void SetActiveSession(const TCHAR *pszID, const char *pszModule) -{ - SESSION_INFO *si = ci.SM_FindSession(pszID, pszModule); - if (si) - SetActiveSessionEx(si); -} - -static SESSION_INFO* GetActiveSession(void) -{ - SESSION_INFO *si = ci.SM_FindSession(ci.szActiveWndID, ci.szActiveWndModule); - if (si) - return si; - - return ci.wndList; -} - -//--------------------------------------------------- -// Session Manager functions -// -// Keeps track of all sessions and its windows -//--------------------------------------------------- - -static SESSION_INFO* SM_AddSession(const TCHAR *pszID, const char *pszModule) -{ - if (!pszID || !pszModule) - return NULL; - - if (ci.SM_FindSession(pszID, pszModule)) - return NULL; - - SESSION_INFO *node = (SESSION_INFO*)mir_calloc(g_cbSession); - node->ptszID = mir_tstrdup(pszID); - node->pszModule = mir_strdup(pszModule); - - if (ci.wndList == NULL) { // list is empty - ci.wndList = node; - node->next = NULL; - } - else { - node->next = ci.wndList; - ci.wndList = node; - } - return node; -} - -static void SM_FreeSession(SESSION_INFO *si) -{ - // contact may have been deleted here already, since function may be called after deleting - // contact so the handle may be invalid, therefore db_get_b shall return 0 - if (si->hContact && db_get_b(si->hContact, si->pszModule, "ChatRoom", 0) != 0) { - ci.SetOffline(si->hContact, (si->iType == GCW_CHATROOM || si->iType == GCW_PRIVMESS) ? TRUE : FALSE); - db_set_s(si->hContact, si->pszModule, "Topic", ""); - db_set_s(si->hContact, si->pszModule, "StatusBar", ""); - db_unset(si->hContact, "CList", "StatusMsg"); - } - - ci.UM_RemoveAll(&si->pUsers); - ci.TM_RemoveAll(&si->pStatuses); - ci.LM_RemoveAll(&si->pLog, &si->pLogEnd); - - si->iStatusCount = 0; - si->nUsersInNicklist = 0; - - mir_free(si->pszModule); - mir_free(si->ptszID); - mir_free(si->ptszName); - mir_free(si->ptszStatusbarText); - mir_free(si->ptszTopic); - - while (si->lpCommands != NULL) { - COMMANDINFO *pNext = si->lpCommands->next; - mir_free(si->lpCommands->lpCommand); - mir_free(si->lpCommands); - si->lpCommands = pNext; - } - - mir_free(si); -} - -static int SM_RemoveSession(const TCHAR *pszID, const char *pszModule, BOOL removeContact) -{ - if (!pszModule) - return FALSE; - - SESSION_INFO *pTemp = ci.wndList, *pLast = NULL; - while (pTemp != NULL) { - // match - if ((!pszID && pTemp->iType != GCW_SERVER || !mir_tstrcmpi(pTemp->ptszID, pszID)) && !mir_strcmpi(pTemp->pszModule, pszModule)) { - DWORD dw = pTemp->dwItemData; - - if (ci.OnRemoveSession) - ci.OnRemoveSession(pTemp); - DoEventHook(pTemp->ptszID, pTemp->pszModule, GC_SESSION_TERMINATE, NULL, NULL, (DWORD)pTemp->dwItemData); - - if (pLast == NULL) - ci.wndList = pTemp->next; - else - pLast->next = pTemp->next; - - // contact may have been deleted here already, since function may be called after deleting - // contact so the handle may be invalid, therefore db_get_b shall return 0 - if (pTemp->hContact && removeContact) - CallService(MS_DB_CONTACT_DELETE, (WPARAM)pTemp->hContact, 0); - - SM_FreeSession(pTemp); - - if (pszID) - return (int)dw; - if (pLast) - pTemp = pLast->next; - else - pTemp = ci.wndList; - } - else { - pLast = pTemp; - pTemp = pTemp->next; - } - } - return FALSE; -} - -static SESSION_INFO* SM_FindSession(const TCHAR *pszID, const char *pszModule) -{ - if (!pszID || !pszModule) - return NULL; - - for (SESSION_INFO *si = ci.wndList; si != NULL; si = si->next) - if (!mir_tstrcmpi(si->ptszID, pszID) && !mir_strcmpi(si->pszModule, pszModule)) - return si; - - return NULL; -} - -static BOOL SM_SetOffline(const TCHAR *pszID, const char *pszModule) -{ - if (!pszModule) - return FALSE; - - for (SESSION_INFO *si = ci.wndList; si != NULL; si = si->next) { - if ((pszID && mir_tstrcmpi(si->ptszID, pszID)) || mir_strcmpi(si->pszModule, pszModule)) - continue; - - ci.UM_RemoveAll(&si->pUsers); - si->nUsersInNicklist = 0; - if (si->iType != GCW_SERVER) - si->bInitDone = FALSE; - if (ci.OnOfflineSession) - ci.OnOfflineSession(si); - if (pszID) - return TRUE; - } - return TRUE; -} - -static BOOL SM_SetStatusEx(const TCHAR *pszID, const char *pszModule, const TCHAR* pszText, int flags) -{ - if (!pszModule) - return FALSE; - - for (SESSION_INFO *si = ci.wndList; si != NULL; si = si->next) { - if ((pszID && mir_tstrcmpi(si->ptszID, pszID)) || mir_strcmpi(si->pszModule, pszModule)) - continue; - - ci.UM_SetStatusEx(si->pUsers, pszText, flags); - if (si->hWnd) - RedrawWindow(GetDlgItem(si->hWnd, IDC_LIST), NULL, NULL, RDW_INVALIDATE); - if (pszID) - return TRUE; - } - return TRUE; -} - -static HICON SM_GetStatusIcon(SESSION_INFO *si, USERINFO * ui) -{ - if (!ui || !si) - return NULL; - - STATUSINFO *ti = ci.TM_FindStatus(si->pStatuses, ci.TM_WordToString(si->pStatuses, ui->Status)); - if (ti != NULL) { - if ((UINT_PTR)ti->hIcon >= STATUSICONCOUNT) - return ti->hIcon; - - return ci.hIcons[ICON_STATUS0 + (int)ti->hIcon]; - } - return ci.hIcons[ICON_STATUS0]; -} - -static BOOL SM_AddEventToAllMatchingUID(GCEVENT *gce) -{ - int bManyFix = 0; - - for (SESSION_INFO *p = ci.wndList; p != NULL; p = p->next) { - if (!p->bInitDone || mir_strcmpi(p->pszModule, gce->pDest->pszModule)) - continue; - - if (!ci.UM_FindUser(p->pUsers, gce->ptszUID)) - continue; - - if (ci.OnEventBroadcast) - ci.OnEventBroadcast(p, gce); - - if (!(gce->dwFlags & GCEF_NOTNOTIFY)) - ci.DoSoundsFlashPopupTrayStuff(p, gce, FALSE, bManyFix); - - bManyFix++; - if ((gce->dwFlags & GCEF_ADDTOLOG) && g_Settings->bLoggingEnabled) - ci.LogToFile(p, gce); - } - - return 0; -} - -static BOOL SM_AddEvent(const TCHAR *pszID, const char *pszModule, GCEVENT *gce, BOOL bIsHighlighted) -{ - SESSION_INFO *p = SM_FindSession(pszID, pszModule); - if (p == NULL) - return TRUE; - - LOGINFO *li = ci.LM_AddEvent(&p->pLog, &p->pLogEnd); - p->iEventCount += 1; - - li->iType = gce->pDest->iType; - li->ptszNick = mir_tstrdup(gce->ptszNick); - li->ptszText = mir_tstrdup(gce->ptszText); - li->ptszStatus = mir_tstrdup(gce->ptszStatus); - li->ptszUserInfo = mir_tstrdup(gce->ptszUserInfo); - - li->bIsMe = gce->bIsMe; - li->time = gce->time; - li->bIsHighlighted = bIsHighlighted; - - if (g_Settings->iEventLimit > 0 && p->iEventCount > g_Settings->iEventLimit + 20) { - ci.LM_TrimLog(&p->pLog, &p->pLogEnd, p->iEventCount - g_Settings->iEventLimit); - p->bTrimmed = true; - p->iEventCount = g_Settings->iEventLimit; - return FALSE; - } - return TRUE; -} - -static USERINFO* SM_AddUser(const TCHAR *pszID, const char *pszModule, const TCHAR *pszUID, const TCHAR *pszNick, WORD wStatus) -{ - SESSION_INFO *si = SM_FindSession(pszID, pszModule); - if (si == NULL) - return NULL; - - USERINFO *p = ci.UM_AddUser(si->pStatuses, &si->pUsers, pszUID, pszNick, wStatus); - si->nUsersInNicklist++; - if (ci.OnAddUser) - ci.OnAddUser(si, p); - return p; -} - -static BOOL SM_MoveUser(const TCHAR *pszID, const char *pszModule, const TCHAR *pszUID) -{ - if (!pszUID) - return FALSE; - - SESSION_INFO *si = SM_FindSession(pszID, pszModule); - if (si == NULL) - return FALSE; - - ci.UM_SortUser(&si->pUsers, pszUID); - return TRUE; -} - -static BOOL SM_RemoveUser(const TCHAR *pszID, const char *pszModule, const TCHAR *pszUID) -{ - if (!pszModule || !pszUID) - return FALSE; - - for (SESSION_INFO *si = ci.wndList; si != NULL; si = si->next) { - if ((pszID && mir_tstrcmpi(si->ptszID, pszID)) || mir_strcmpi(si->pszModule, pszModule)) - continue; - - USERINFO *ui = ci.UM_FindUser(si->pUsers, pszUID); - if (ui) { - si->nUsersInNicklist--; - if (ci.OnRemoveUser) - ci.OnRemoveUser(si, ui); - - ci.UM_RemoveUser(&si->pUsers, pszUID); - - if (si->hWnd) - SendMessage(si->hWnd, GC_UPDATENICKLIST, 0, 0); - - if (pszID) - return TRUE; - } - } - - return 0; -} - -static USERINFO* SM_GetUserFromIndex(const TCHAR *pszID, const char *pszModule, int index) -{ - SESSION_INFO *si = SM_FindSession(pszID, pszModule); - return (si == NULL) ? NULL : ci.UM_FindUserFromIndex(si->pUsers, index); -} - -STATUSINFO* SM_AddStatus(const TCHAR *pszID, const char *pszModule, const TCHAR *pszStatus) -{ - SESSION_INFO *si = SM_FindSession(pszID, pszModule); - if (si == NULL) - return NULL; - - STATUSINFO *ti = ci.TM_AddStatus(&si->pStatuses, pszStatus, &si->iStatusCount); - if (ti) - si->iStatusCount++; - if (ci.OnAddStatus) - ci.OnAddStatus(si, ti); - return ti; -} - -static BOOL SM_GiveStatus(const TCHAR *pszID, const char *pszModule, const TCHAR *pszUID, const TCHAR *pszStatus) -{ - SESSION_INFO *si = SM_FindSession(pszID, pszModule); - if (si == NULL) - return FALSE; - - USERINFO *ui = ci.UM_GiveStatus(si->pUsers, pszUID, ci.TM_StringToWord(si->pStatuses, pszStatus)); - if (ui) { - SM_MoveUser(si->ptszID, si->pszModule, ui->pszUID); - if (si->hWnd) - SendMessage(si->hWnd, GC_UPDATENICKLIST, 0, 0); - } - return TRUE; -} - -static BOOL SM_SetContactStatus(const TCHAR *pszID, const char *pszModule, const TCHAR *pszUID, WORD wStatus) -{ - SESSION_INFO *si = SM_FindSession(pszID, pszModule); - if (si == NULL) - return FALSE; - - USERINFO *ui = ci.UM_SetContactStatus(si->pUsers, pszUID, wStatus); - if (ui) { - SM_MoveUser(si->ptszID, si->pszModule, ui->pszUID); - if (si->hWnd) - SendMessage(si->hWnd, GC_UPDATENICKLIST, 0, 0); - } - return TRUE; -} - -static BOOL SM_TakeStatus(const TCHAR *pszID, const char *pszModule, const TCHAR *pszUID, const TCHAR *pszStatus) -{ - SESSION_INFO *si = SM_FindSession(pszID, pszModule); - if (si == NULL) - return FALSE; - - USERINFO *ui = ci.UM_TakeStatus(si->pUsers, pszUID, ci.TM_StringToWord(si->pStatuses, pszStatus)); - if (ui) { - SM_MoveUser(si->ptszID, si->pszModule, ui->pszUID); - if (si->hWnd) - SendMessage(si->hWnd, GC_UPDATENICKLIST, 0, 0); - } - return TRUE; -} - -static LRESULT SM_SendMessage(const TCHAR *pszID, const char *pszModule, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (pszModule == NULL) - return 0; - - for (SESSION_INFO *si = ci.wndList; si != NULL; si = si->next) { - if ((pszID && mir_tstrcmpi(si->ptszID, pszID)) || mir_strcmpi(si->pszModule, pszModule)) - continue; - - if (si->hWnd) { - LRESULT i = SendMessage(si->hWnd, msg, wParam, lParam); - if (pszID) - return i; - } - if (pszID) - return 0; - } - return 0; -} - -static BOOL SM_PostMessage(const TCHAR *pszID, const char *pszModule, UINT msg, WPARAM wParam, LPARAM lParam) -{ - SESSION_INFO *si = SM_FindSession(pszID, pszModule); - if (si == NULL) - return FALSE; - - if (si->hWnd) - return PostMessage(si->hWnd, msg, wParam, lParam); - return FALSE; -} - -static BOOL SM_BroadcastMessage(const char *pszModule, UINT msg, WPARAM wParam, LPARAM lParam, BOOL bAsync) -{ - for (SESSION_INFO *si = ci.wndList; si != NULL; si = si->next) { - if (pszModule && _strcmpi(si->pszModule, pszModule)) - continue; - - if (si->hWnd) { - if (bAsync) - PostMessage(si->hWnd, msg, wParam, lParam); - else - SendMessage(si->hWnd, msg, wParam, lParam); - } - } - return TRUE; -} - -static BOOL SM_SetStatus(const TCHAR *pszID, const char *pszModule, int wStatus) -{ - if (!pszModule) - return FALSE; - - for (SESSION_INFO *si = ci.wndList; si != NULL; si = si->next) { - if ((pszID && mir_tstrcmpi(si->ptszID, pszID)) || mir_strcmpi(si->pszModule, pszModule)) - continue; - - si->wStatus = wStatus; - if (si->hContact) { - if (si->iType != GCW_SERVER && wStatus != ID_STATUS_OFFLINE) - db_unset(si->hContact, "CList", "Hidden"); - - db_set_w(si->hContact, si->pszModule, "Status", (WORD)wStatus); - } - - if (ci.OnSetStatus) - ci.OnSetStatus(si, wStatus); - - if (pszID) - return TRUE; - } - return TRUE; -} - -static BOOL SM_SendUserMessage(const TCHAR *pszID, const char *pszModule, const TCHAR* pszText) -{ - if (!pszModule || !pszText) - return FALSE; - - for (SESSION_INFO *si = ci.wndList; si != NULL; si = si->next) { - if ((pszID && mir_tstrcmpi(si->ptszID, pszID)) || mir_strcmpi(si->pszModule, pszModule)) - continue; - - if (si->iType == GCW_CHATROOM || si->iType == GCW_PRIVMESS) - DoEventHook(si->ptszID, si->pszModule, GC_USER_MESSAGE, NULL, pszText, 0); - if (pszID) - return TRUE; - } - return TRUE; -} - -static BOOL SM_ChangeUID(const TCHAR *pszID, const char *pszModule, const TCHAR *pszUID, const TCHAR* pszNewUID) -{ - if (!pszModule) - return FALSE; - - for (SESSION_INFO *si = ci.wndList; si != NULL; si = si->next) { - if ((pszID && mir_tstrcmpi(si->ptszID, pszID)) || mir_strcmpi(si->pszModule, pszModule)) - continue; - - USERINFO* ui = ci.UM_FindUser(si->pUsers, pszUID); - if (ui) - replaceStrT(ui->pszUID, pszNewUID); - if (pszID) - return TRUE; - } - return TRUE; -} - -static BOOL SM_ChangeNick(const TCHAR *pszID, const char *pszModule, GCEVENT *gce) -{ - if (!pszModule) - return FALSE; - - for (SESSION_INFO *si = ci.wndList; si != NULL; si = si->next) { - if ((!pszID || !mir_tstrcmpi(si->ptszID, pszID)) && !mir_strcmpi(si->pszModule, pszModule)) { - USERINFO *ui = ci.UM_FindUser(si->pUsers, gce->ptszUID); - if (ui) { - replaceStrT(ui->pszNick, gce->ptszText); - SM_MoveUser(si->ptszID, si->pszModule, ui->pszUID); - if (si->hWnd) - SendMessage(si->hWnd, GC_UPDATENICKLIST, 0, 0); - if (ci.OnChangeNick) - ci.OnChangeNick(si); - } - - if (pszID) - return TRUE; - } - } - return TRUE; -} - -static BOOL SM_SetTabbedWindowHwnd(SESSION_INFO *si, HWND hwnd) -{ - for (SESSION_INFO *p = ci.wndList; p != NULL; p = p->next) { - if (si && si == p) - p->hWnd = hwnd; - else - p->hWnd = NULL; - } - return TRUE; -} - -static BOOL SM_RemoveAll(void) -{ - while (ci.wndList) { - SESSION_INFO *pLast = ci.wndList->next; - - if (ci.wndList->hWnd) - SendMessage(ci.wndList->hWnd, GC_EVENT_CONTROL + WM_USER + 500, SESSION_TERMINATE, 0); - DoEventHook(ci.wndList->ptszID, ci.wndList->pszModule, GC_SESSION_TERMINATE, NULL, NULL, (DWORD)ci.wndList->dwItemData); - - SM_FreeSession(ci.wndList); - ci.wndList = pLast; - } - ci.wndList = NULL; - return TRUE; -} - -static void SM_AddCommand(const TCHAR *pszID, const char *pszModule, const char* lpNewCommand) -{ - SESSION_INFO *si = SM_FindSession(pszID, pszModule); - if (si == NULL) - return; - - COMMANDINFO *node = (COMMANDINFO *)mir_alloc(sizeof(COMMANDINFO)); - node->lpCommand = mir_strdup(lpNewCommand); - node->last = NULL; // always added at beginning! - - // new commands are added at start - if (si->lpCommands == NULL) { - node->next = NULL; - si->lpCommands = node; - } - else { - node->next = si->lpCommands; - si->lpCommands->last = node; // hmm, weird - si->lpCommands = node; - } - si->lpCurrentCommand = NULL; // current command - si->wCommandsNum++; - - if (si->wCommandsNum > WINDOWS_COMMANDS_MAX) { - COMMANDINFO *pCurComm = si->lpCommands; - while (pCurComm->next != NULL) { pCurComm = pCurComm->next; } - COMMANDINFO *pLast = pCurComm->last; - mir_free(pCurComm->lpCommand); - mir_free(pCurComm); - pLast->next = NULL; - // done - si->wCommandsNum--; - } -} - -static char* SM_GetPrevCommand(const TCHAR *pszID, const char *pszModule) // get previous command. returns NULL if previous command does not exist. current command remains as it was. -{ - SESSION_INFO *si = SM_FindSession(pszID, pszModule); - if (si == NULL) - return NULL; - - COMMANDINFO *pPrevCmd = NULL; - if (si->lpCurrentCommand != NULL) { - if (si->lpCurrentCommand->next != NULL) // not NULL - pPrevCmd = si->lpCurrentCommand->next; // next command (newest at beginning) - else - pPrevCmd = si->lpCurrentCommand; - } - else pPrevCmd = si->lpCommands; - - si->lpCurrentCommand = pPrevCmd; // make it the new command - return (pPrevCmd) ? pPrevCmd->lpCommand : NULL; -} - -static char* SM_GetNextCommand(const TCHAR *pszID, const char *pszModule) // get next command. returns NULL if next command does not exist. current command becomes NULL (a prev command after this one will get you the last command) -{ - SESSION_INFO *si = SM_FindSession(pszID, pszModule); - if (si == NULL) - return NULL; - - COMMANDINFO *pNextCmd = NULL; - if (si->lpCurrentCommand != NULL) - pNextCmd = si->lpCurrentCommand->last; // last command (newest at beginning) - - si->lpCurrentCommand = pNextCmd; // make it the new command - return (pNextCmd) ? pNextCmd->lpCommand : NULL; -} - -static int SM_GetCount(const char *pszModule) -{ - int count = 0; - - for (SESSION_INFO *si = ci.wndList; si != NULL; si = si->next) - if (!mir_strcmpi(pszModule, si->pszModule)) - count++; - - return count; -} - -static SESSION_INFO* SM_FindSessionByIndex(const char *pszModule, int iItem) -{ - int count = 0; - for (SESSION_INFO *si = ci.wndList; si != NULL; si = si->next) { - if (!mir_strcmpi(pszModule, si->pszModule)) { - if (iItem == count) - return si; - - count++; - } - } - return NULL; - -} - -static char* SM_GetUsers(SESSION_INFO *si) -{ - if (si == NULL) - return NULL; - - USERINFO *utemp = NULL; - for (SESSION_INFO *p = ci.wndList; p != NULL; p = p->next) { - if (si == p) { - if ((utemp = p->pUsers) == NULL) - return NULL; - - break; - } - } - if (utemp == NULL) - return NULL; - - char* p = NULL; - size_t alloced = 0; - do { - size_t pLen = mir_strlen(p), nameLen = mir_tstrlen(utemp->pszUID); - if (pLen + nameLen + 2 > alloced) - p = (char*)mir_realloc(p, alloced += 4096); - - WideCharToMultiByte(CP_ACP, 0, utemp->pszUID, -1, p + pLen, (int)nameLen + 1, 0, 0); - mir_strcpy(p + pLen + nameLen, " "); - utemp = utemp->next; - } - while (utemp != NULL); - return p; -} - -static void SM_InvalidateLogDirectories() -{ - for (SESSION_INFO *si = ci.wndList; si; si = si->next) - si->pszLogFileName[0] = si->pszLogFileName[1] = 0; -} - -//--------------------------------------------------- -// Module Manager functions -// -// Necessary to keep track of all modules -// that has registered with the plugin -//--------------------------------------------------- - -static MODULEINFO* MM_AddModule(const char *pszModule) -{ - if (pszModule == NULL) - return NULL; - - if (ci.MM_FindModule(pszModule)) - return NULL; - - MODULEINFO *node = (MODULEINFO*)mir_calloc(g_cbModuleInfo); - replaceStr(node->pszModule, pszModule); - if (ci.OnCreateModule) - ci.OnCreateModule(node); - - if (m_ModList == NULL) { // list is empty - m_ModList = node; - node->next = NULL; - } - else { - node->next = m_ModList; - m_ModList = node; - } - return node; -} - -static void MM_IconsChanged() -{ - LoadChatIcons(); - - for (MODULEINFO *mi = m_ModList; mi != NULL; mi = mi->next) { - Safe_DestroyIcon(mi->hOnlineIcon); - Safe_DestroyIcon(mi->hOfflineIcon); - Safe_DestroyIcon(mi->hOnlineTalkIcon); - Safe_DestroyIcon(mi->hOfflineTalkIcon); - - if (ci.OnCreateModule) // recreate icons - ci.OnCreateModule(mi); - } -} - -static void MM_FontsChanged() -{ - for (MODULEINFO *mi = m_ModList; mi != NULL; mi = mi->next) - mi->pszHeader = ci.Log_CreateRtfHeader(mi); -} - -static MODULEINFO* MM_FindModule(const char *pszModule) -{ - if (!pszModule) - return NULL; - - for (MODULEINFO *mi = m_ModList; mi != NULL; mi = mi->next) - if (mir_strcmpi(mi->pszModule, pszModule) == 0) - return mi; - - return NULL; -} - -// stupid thing.. -static void MM_FixColors() -{ - for (MODULEINFO *mi = m_ModList; mi != NULL; mi = mi->next) - CheckColorsInModule(mi->pszModule); -} - -static BOOL MM_RemoveAll(void) -{ - while (m_ModList != NULL) { - MODULEINFO *pLast = m_ModList->next; - mir_free(m_ModList->pszModule); - mir_free(m_ModList->ptszModDispName); - mir_free(m_ModList->pszHeader); - mir_free(m_ModList->crColors); - - Safe_DestroyIcon(m_ModList->hOnlineIcon); - Safe_DestroyIcon(m_ModList->hOfflineIcon); - Safe_DestroyIcon(m_ModList->hOnlineTalkIcon); - Safe_DestroyIcon(m_ModList->hOfflineTalkIcon); - - mir_free(m_ModList); - m_ModList = pLast; - } - m_ModList = NULL; - return TRUE; -} - -//--------------------------------------------------- -// Status manager functions -// -// Necessary to keep track of what user statuses -// per window nicklist that is available -//--------------------------------------------------- - -static STATUSINFO* TM_AddStatus(STATUSINFO **ppStatusList, const TCHAR *pszStatus, int *iCount) -{ - if (!ppStatusList || !pszStatus) - return NULL; - - if (!ci.TM_FindStatus(*ppStatusList, pszStatus)) { - STATUSINFO *node = (STATUSINFO*)mir_alloc(sizeof(STATUSINFO)); - memset(node, 0, sizeof(STATUSINFO)); - replaceStrT(node->pszGroup, pszStatus); - node->hIcon = (HICON)(*iCount); - while ((int)node->hIcon > STATUSICONCOUNT - 1) - node->hIcon--; - - if (*ppStatusList == NULL) { // list is empty - node->Status = 1; - *ppStatusList = node; - node->next = NULL; - } - else { - node->Status = ppStatusList[0]->Status * 2; - node->next = *ppStatusList; - *ppStatusList = node; - } - return node; - - } - return FALSE; -} - -static STATUSINFO* TM_FindStatus(STATUSINFO *pStatusList, const TCHAR *pszStatus) -{ - if (!pStatusList || !pszStatus) - return NULL; - - for (STATUSINFO *pTemp = pStatusList; pTemp != NULL; pTemp = pTemp->next) - if (mir_tstrcmpi(pTemp->pszGroup, pszStatus) == 0) - return pTemp; - - return 0; -} - -static WORD TM_StringToWord(STATUSINFO *pStatusList, const TCHAR *pszStatus) -{ - if (!pStatusList || !pszStatus) - return 0; - - for (STATUSINFO *pTemp = pStatusList; pTemp != NULL; pTemp = pTemp->next) { - if (mir_tstrcmpi(pTemp->pszGroup, pszStatus) == 0) - return pTemp->Status; - - if (pTemp->next == NULL) - return pStatusList->Status; - } - return 0; -} - -static TCHAR* TM_WordToString(STATUSINFO *pStatusList, WORD Status) -{ - if (!pStatusList) - return NULL; - - for (STATUSINFO *pTemp = pStatusList; pTemp != NULL; pTemp = pTemp->next) { - if (pTemp->Status & Status) { - Status -= pTemp->Status; - if (Status == 0) - return pTemp->pszGroup; - } - } - return 0; -} - -static BOOL TM_RemoveAll(STATUSINFO **ppStatusList) -{ - if (!ppStatusList) - return FALSE; - - while (*ppStatusList != NULL) { - STATUSINFO *pLast = ppStatusList[0]->next; - mir_free(ppStatusList[0]->pszGroup); - if ((int)ppStatusList[0]->hIcon > 10) - DestroyIcon(ppStatusList[0]->hIcon); - mir_free(*ppStatusList); - *ppStatusList = pLast; - } - *ppStatusList = NULL; - return TRUE; -} - -//--------------------------------------------------- -// User manager functions -// -// Necessary to keep track of the users -// in a window nicklist -//--------------------------------------------------- - -static int UM_CompareItem(USERINFO *u1, const TCHAR *pszNick, WORD wStatus) -{ - WORD dw1 = u1->Status; - WORD dw2 = wStatus; - - for (int i = 0; i < 8; i++) { - if ((dw1 & 1) && !(dw2 & 1)) - return -1; - if ((dw2 & 1) && !(dw1 & 1)) - return 1; - if ((dw1 & 1) && (dw2 & 1)) - return mir_tstrcmpi(u1->pszNick, pszNick); - - dw1 = dw1 >> 1; - dw2 = dw2 >> 1; - } - return mir_tstrcmpi(u1->pszNick, pszNick); -} - -static USERINFO* UM_SortUser(USERINFO **ppUserList, const TCHAR *pszUID) -{ - USERINFO *ui = *ppUserList, *pLast = NULL; - if (!ui || !pszUID) - return NULL; - - while (ui && mir_tstrcmpi(ui->pszUID, pszUID)) { - pLast = ui; - ui = ui->next; - } - - if (ui == NULL) - return NULL; - - USERINFO *node = ui; - if (pLast) - pLast->next = ui->next; - else - *ppUserList = ui->next; - ui = *ppUserList; - - pLast = NULL; - - while (ui && ci.UM_CompareItem(ui, node->pszNick, node->Status) <= 0) { - pLast = ui; - ui = ui->next; - } - - if (*ppUserList == NULL) { // list is empty - *ppUserList = node; - node->next = NULL; - } - else { - if (pLast) { - node->next = ui; - pLast->next = node; - } - else { - node->next = *ppUserList; - *ppUserList = node; - } - } - - return node; -} - -USERINFO* UM_AddUser(STATUSINFO *pStatusList, USERINFO **ppUserList, const TCHAR *pszUID, const TCHAR *pszNick, WORD wStatus) -{ - if (pStatusList == NULL || ppUserList == NULL || pszNick == NULL) - return NULL; - - USERINFO *ui = *ppUserList, *pLast = NULL; - while (ui && ci.UM_CompareItem(ui, pszNick, wStatus) <= 0) { - pLast = ui; - ui = ui->next; - } - - // if (!UM_FindUser(*ppUserList, pszUI, wStatus) - USERINFO *node = (USERINFO*)mir_calloc(sizeof(USERINFO)); - replaceStrT(node->pszUID, pszUID); - - if (*ppUserList == NULL) { // list is empty - *ppUserList = node; - node->next = NULL; - } - else { - if (pLast) { - node->next = ui; - pLast->next = node; - } - else { - node->next = *ppUserList; - *ppUserList = node; - } - } - - return node; -} - -static USERINFO* UM_FindUser(USERINFO *pUserList, const TCHAR *pszUID) -{ - if (!pUserList || !pszUID) - return NULL; - - for (USERINFO *ui = pUserList; ui != NULL; ui = ui->next) - if (!mir_tstrcmpi(ui->pszUID, pszUID)) - return ui; - - return NULL; -} - -static USERINFO* UM_FindUserFromIndex(USERINFO *pUserList, int index) -{ - if (!pUserList) - return NULL; - - int i = 0; - for (USERINFO *ui = pUserList; ui != NULL; ui = ui->next) { - if (i == index) - return ui; - i++; - } - return NULL; -} - -static USERINFO* UM_GiveStatus(USERINFO *pUserList, const TCHAR *pszUID, WORD status) -{ - USERINFO *ui = UM_FindUser(pUserList, pszUID); - if (ui == NULL) - return NULL; - - ui->Status |= status; - return ui; -} - -static USERINFO* UM_SetContactStatus(USERINFO *pUserList, const TCHAR *pszUID, WORD status) -{ - USERINFO *ui = UM_FindUser(pUserList, pszUID); - if (ui == NULL) - return NULL; - - ui->ContactStatus = status; - return ui; -} - -static BOOL UM_SetStatusEx(USERINFO *pUserList, const TCHAR* pszText, int flags) -{ - int bOnlyMe = (flags & GC_SSE_ONLYLISTED) != 0, bSetStatus = (flags & GC_SSE_ONLINE) != 0; - char cDelimiter = (flags & GC_SSE_TABDELIMITED) ? '\t' : ' '; - - for (USERINFO *ui = pUserList; ui != NULL; ui = ui->next) { - if (!bOnlyMe) - ui->iStatusEx = 0; - - if (pszText != NULL) { - TCHAR *s = (TCHAR *)_tcsstr(pszText, ui->pszUID); - if (s) { - ui->iStatusEx = 0; - if (s == pszText || s[-1] == cDelimiter) { - size_t len = mir_tstrlen(ui->pszUID); - if (s[len] == cDelimiter || s[len] == '\0') - ui->iStatusEx = (!bOnlyMe || bSetStatus) ? 1 : 0; - } - } - } - } - return TRUE; -} - -static USERINFO* UM_TakeStatus(USERINFO *pUserList, const TCHAR *pszUID, WORD status) -{ - USERINFO *ui = UM_FindUser(pUserList, pszUID); - if (ui == NULL) - return NULL; - - ui->Status &= ~status; - return ui; -} - -static TCHAR* UM_FindUserAutoComplete(USERINFO *pUserList, const TCHAR* pszOriginal, const TCHAR* pszCurrent) -{ - if (!pUserList || !pszOriginal || !pszCurrent) - return NULL; - - TCHAR *pszName = NULL; - for (USERINFO *ui = pUserList; ui != NULL; ui = ui->next) - if (ui->pszNick && my_strstri(ui->pszNick, pszOriginal) == ui->pszNick) - if (mir_tstrcmpi(ui->pszNick, pszCurrent) > 0 && (!pszName || mir_tstrcmpi(ui->pszNick, pszName) < 0)) - pszName = ui->pszNick; - - return pszName; -} - -static BOOL UM_RemoveUser(USERINFO **ppUserList, const TCHAR *pszUID) -{ - if (!ppUserList || !pszUID) - return FALSE; - - USERINFO *ui = *ppUserList, *pLast = NULL; - while (ui != NULL) { - if (!mir_tstrcmpi(ui->pszUID, pszUID)) { - if (pLast == NULL) - *ppUserList = ui->next; - else - pLast->next = ui->next; - mir_free(ui->pszNick); - mir_free(ui->pszUID); - mir_free(ui); - return TRUE; - } - pLast = ui; - ui = ui->next; - } - return FALSE; -} - -static BOOL UM_RemoveAll(USERINFO **ppUserList) -{ - if (!ppUserList) - return FALSE; - - while (*ppUserList != NULL) { - USERINFO *pLast = ppUserList[0]->next; - mir_free(ppUserList[0]->pszUID); - mir_free(ppUserList[0]->pszNick); - mir_free(*ppUserList); - *ppUserList = pLast; - } - *ppUserList = NULL; - return TRUE; -} - -//--------------------------------------------------- -// Log manager functions -// -// Necessary to keep track of events -// in a window log -//--------------------------------------------------- - -static LOGINFO* LM_AddEvent(LOGINFO **ppLogListStart, LOGINFO** ppLogListEnd) -{ - if (!ppLogListStart || !ppLogListEnd) - return NULL; - - LOGINFO *node = (LOGINFO*)mir_calloc(sizeof(LOGINFO)); - if (*ppLogListStart == NULL) { // list is empty - *ppLogListStart = node; - *ppLogListEnd = node; - node->next = NULL; - node->prev = NULL; - } - else { - ppLogListStart[0]->prev = node; - node->next = *ppLogListStart; - *ppLogListStart = node; - ppLogListStart[0]->prev = NULL; - } - - return node; -} - -static BOOL LM_TrimLog(LOGINFO **ppLogListStart, LOGINFO **ppLogListEnd, int iCount) -{ - LOGINFO *pTemp = *ppLogListEnd; - while (pTemp != NULL && iCount > 0) { - *ppLogListEnd = pTemp->prev; - if (*ppLogListEnd == NULL) - *ppLogListStart = NULL; - - mir_free(pTemp->ptszNick); - mir_free(pTemp->ptszUserInfo); - mir_free(pTemp->ptszText); - mir_free(pTemp->ptszStatus); - mir_free(pTemp); - pTemp = *ppLogListEnd; - iCount--; - } - ppLogListEnd[0]->next = NULL; - - return TRUE; -} - -static BOOL LM_RemoveAll(LOGINFO **ppLogListStart, LOGINFO **ppLogListEnd) -{ - while (*ppLogListStart != NULL) { - LOGINFO *pLast = ppLogListStart[0]->next; - mir_free(ppLogListStart[0]->ptszText); - mir_free(ppLogListStart[0]->ptszNick); - mir_free(ppLogListStart[0]->ptszStatus); - mir_free(ppLogListStart[0]->ptszUserInfo); - mir_free(*ppLogListStart); - *ppLogListStart = pLast; - } - *ppLogListStart = NULL; - *ppLogListEnd = NULL; - return TRUE; -} - -INT_PTR SvcGetChatManager(WPARAM wParam, LPARAM lParam) -{ - if (lParam == NULL) - return (INT_PTR)&ci; - - // wipe out old junk - memset(PBYTE(&ci) + offsetof(CHAT_MANAGER, OnCreateModule), 0, sizeof(CHAT_MANAGER)-offsetof(CHAT_MANAGER, OnCreateModule)); - - CHAT_MANAGER_INITDATA *pInit = (CHAT_MANAGER_INITDATA*)lParam; - if (g_cbSession) { // reallocate old sessions - mir_cslock lck(cs); - SESSION_INFO *pPrev = NULL; - for (SESSION_INFO *p = ci.wndList; p; p = p->next) { - SESSION_INFO *p1 = (SESSION_INFO*)mir_realloc(p, pInit->cbSession); - memset(PBYTE(p1) + sizeof(GCSessionInfoBase), 0, pInit->cbSession - sizeof(GCSessionInfoBase)); - if (p1 != p) { // realloc could change a pointer, reinsert a structure - if (ci.wndList == p) - ci.wndList = p1; - if (pPrev != NULL) - pPrev->next = p1; - p = p1; - } - pPrev = p; - } - } - if (g_cbModuleInfo) { // reallocate old modules - mir_cslock lck(cs); - MODULEINFO *pPrev = NULL; - for (MODULEINFO *p = m_ModList; p; p = p->next) { - MODULEINFO *p1 = (MODULEINFO*)mir_realloc(p, pInit->cbModuleInfo); - memset(PBYTE(p1) + sizeof(GCModuleInfoBase), 0, pInit->cbModuleInfo - sizeof(GCModuleInfoBase)); - if (p1 != p) { // realloc could change a pointer, reinsert a structure - if (m_ModList == p) - m_ModList = p1; - if (pPrev != NULL) - pPrev->next = p1; - p = p1; - } - pPrev = p; - } - } - g_Settings = pInit->pSettings; - g_szFontGroup = pInit->szFontGroup; - g_cbSession = pInit->cbSession; - g_cbModuleInfo = pInit->cbModuleInfo; - g_iFontMode = pInit->iFontMode; - g_iChatLang = (int)wParam; - - ci.SetActiveSession = SetActiveSession; - ci.SetActiveSessionEx = SetActiveSessionEx; - ci.GetActiveSession = GetActiveSession; - ci.SM_AddSession = SM_AddSession; - ci.SM_RemoveSession = SM_RemoveSession; - ci.SM_FindSession = SM_FindSession; - ci.SM_AddUser = SM_AddUser; - ci.SM_ChangeUID = SM_ChangeUID; - ci.SM_ChangeNick = SM_ChangeNick; - ci.SM_RemoveUser = SM_RemoveUser; - ci.SM_SetOffline = SM_SetOffline; - ci.SM_SetTabbedWindowHwnd = SM_SetTabbedWindowHwnd; - ci.SM_GetStatusIcon = SM_GetStatusIcon; - ci.SM_SetStatus = SM_SetStatus; - ci.SM_SetStatusEx = SM_SetStatusEx; - ci.SM_SendUserMessage = SM_SendUserMessage; - ci.SM_AddStatus = SM_AddStatus; - ci.SM_AddEventToAllMatchingUID = SM_AddEventToAllMatchingUID; - ci.SM_AddEvent = SM_AddEvent; - ci.SM_SendMessage = SM_SendMessage; - ci.SM_PostMessage = SM_PostMessage; - ci.SM_BroadcastMessage = SM_BroadcastMessage; - ci.SM_RemoveAll = SM_RemoveAll; - ci.SM_GiveStatus = SM_GiveStatus; - ci.SM_SetContactStatus = SM_SetContactStatus; - ci.SM_TakeStatus = SM_TakeStatus; - ci.SM_MoveUser = SM_MoveUser; - ci.SM_AddCommand = SM_AddCommand; - ci.SM_GetPrevCommand = SM_GetPrevCommand; - ci.SM_GetNextCommand = SM_GetNextCommand; - ci.SM_GetCount = SM_GetCount; - ci.SM_FindSessionByIndex = SM_FindSessionByIndex; - ci.SM_GetUsers = SM_GetUsers; - ci.SM_GetUserFromIndex = SM_GetUserFromIndex; - ci.SM_InvalidateLogDirectories = SM_InvalidateLogDirectories; - - ci.MM_AddModule = MM_AddModule; - ci.MM_FindModule = MM_FindModule; - ci.MM_FixColors = MM_FixColors; - ci.MM_FontsChanged = MM_FontsChanged; - ci.MM_IconsChanged = MM_IconsChanged; - ci.MM_RemoveAll = MM_RemoveAll; - - ci.TM_AddStatus = TM_AddStatus; - ci.TM_FindStatus = TM_FindStatus; - ci.TM_StringToWord = TM_StringToWord; - ci.TM_WordToString = TM_WordToString; - ci.TM_RemoveAll = TM_RemoveAll; - - ci.UM_SetStatusEx = UM_SetStatusEx; - ci.UM_AddUser = UM_AddUser; - ci.UM_SortUser = UM_SortUser; - ci.UM_FindUser = UM_FindUser; - ci.UM_FindUserFromIndex = UM_FindUserFromIndex; - ci.UM_GiveStatus = UM_GiveStatus; - ci.UM_SetContactStatus = UM_SetContactStatus; - ci.UM_TakeStatus = UM_TakeStatus; - ci.UM_FindUserAutoComplete = UM_FindUserAutoComplete; - ci.UM_RemoveUser = UM_RemoveUser; - ci.UM_RemoveAll = UM_RemoveAll; - ci.UM_CompareItem = UM_CompareItem; - - ci.LM_AddEvent = LM_AddEvent; - ci.LM_TrimLog = LM_TrimLog; - ci.LM_RemoveAll = LM_RemoveAll; - - ci.AddRoom = AddRoom; - ci.SetOffline = SetOffline; - ci.SetAllOffline = SetAllOffline; - ci.AddEvent = AddEvent; - ci.FindRoom = FindRoom; - ci.DoRtfToTags = DoRtfToTags; - - ci.Log_CreateRTF = Log_CreateRTF; - ci.Log_CreateRtfHeader = Log_CreateRtfHeader; - ci.LoadMsgDlgFont = LoadMsgDlgFont; - ci.MakeTimeStamp = MakeTimeStamp; - - ci.DoEventHook = DoEventHook; - ci.DoEventHookAsync = DoEventHookAsync; - - ci.DoSoundsFlashPopupTrayStuff = DoSoundsFlashPopupTrayStuff; - ci.DoTrayIcon = DoTrayIcon; - ci.DoPopup = DoPopup; - ci.ShowPopup = ShowPopup; - ci.LogToFile = LogToFile; - ci.GetChatLogsFilename = GetChatLogsFilename; - ci.GetColorIndex = GetColorIndex; - ci.Log_SetStyle = Log_SetStyle; - - ci.IsHighlighted = IsHighlighted; - ci.RemoveFormatting = RemoveFormatting; - ci.ReloadSettings = LoadGlobalSettings; - ci.ColorChooser = ColorChooser; - - ci.pLogIconBmpBits = pLogIconBmpBits; - ci.logIconBmpSize = logIconBmpSize; - - RegisterFonts(); - OptionsInit(); - return (INT_PTR)&ci; -} diff --git a/src/modules/chat/tools.cpp b/src/modules/chat/tools.cpp deleted file mode 100644 index b91686d538..0000000000 --- a/src/modules/chat/tools.cpp +++ /dev/null @@ -1,768 +0,0 @@ -/* -Chat module plugin for Miranda IM - -Copyright 2000-12 Miranda IM, 2012-15 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#include "chat.h" - -int GetRichTextLength(HWND hwnd) -{ - GETTEXTLENGTHEX gtl; - gtl.flags = GTL_PRECISE; - gtl.codepage = CP_ACP; - return (int)SendMessage(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static TCHAR szTemp[10000]; - -TCHAR* RemoveFormatting(const TCHAR *pszWord) -{ - if (pszWord == NULL) - return NULL; - - TCHAR *d = szTemp; - size_t cbLen = mir_tstrlen(pszWord); - if (cbLen > SIZEOF(szTemp)) - cbLen = SIZEOF(szTemp)-1; - - for (size_t i = 0; i < cbLen;) { - if (pszWord[i] == '%') { - switch (pszWord[i+1]) { - case '%': - *d++ = '%'; - - case 'b': - case 'u': - case 'i': - case 'B': - case 'U': - case 'I': - case 'r': - case 'C': - case 'F': - i += 2; - continue; - - case 'c': - case 'f': - i += 4; - continue; - } - } - - *d++ = pszWord[i++]; - } - *d = 0; - - return szTemp; -} - -BOOL DoTrayIcon(SESSION_INFO *si, GCEVENT *gce) -{ - switch (gce->pDest->iType) { - case GC_EVENT_MESSAGE | GC_EVENT_HIGHLIGHT: - case GC_EVENT_ACTION | GC_EVENT_HIGHLIGHT: - ci.AddEvent(si->hContact, LoadSkinnedIcon(SKINICON_EVENT_MESSAGE), GC_FAKE_EVENT, 0, TranslateT("%s wants your attention in %s"), gce->ptszNick, si->ptszName); - break; - case GC_EVENT_MESSAGE: - ci.AddEvent(si->hContact, ci.hIcons[ICON_MESSAGE], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s speaks in %s"), gce->ptszNick, si->ptszName); - break; - case GC_EVENT_ACTION: - ci.AddEvent(si->hContact, ci.hIcons[ICON_ACTION], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s speaks in %s"), gce->ptszNick, si->ptszName); - break; - case GC_EVENT_JOIN: - ci.AddEvent(si->hContact, ci.hIcons[ICON_JOIN], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s has joined %s"), gce->ptszNick, si->ptszName); - break; - case GC_EVENT_PART: - ci.AddEvent(si->hContact, ci.hIcons[ICON_PART], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s has left %s"), gce->ptszNick, si->ptszName); - break; - case GC_EVENT_QUIT: - ci.AddEvent(si->hContact, ci.hIcons[ICON_QUIT], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s has disconnected"), gce->ptszNick); - break; - case GC_EVENT_NICK: - ci.AddEvent(si->hContact, ci.hIcons[ICON_NICK], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s is now known as %s"), gce->ptszNick, gce->ptszText); - break; - case GC_EVENT_KICK: - ci.AddEvent(si->hContact, ci.hIcons[ICON_KICK], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s kicked %s from %s"), gce->ptszStatus, gce->ptszNick, si->ptszName); - break; - case GC_EVENT_NOTICE: - ci.AddEvent(si->hContact, ci.hIcons[ICON_NOTICE], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("Notice from %s"), gce->ptszNick); - break; - case GC_EVENT_TOPIC: - ci.AddEvent(si->hContact, ci.hIcons[ICON_TOPIC], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("Topic change in %s"), si->ptszName); - break; - case GC_EVENT_INFORMATION: - ci.AddEvent(si->hContact, ci.hIcons[ICON_INFO], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("Information in %s"), si->ptszName); - break; - case GC_EVENT_ADDSTATUS: - ci.AddEvent(si->hContact, ci.hIcons[ICON_ADDSTATUS], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s enables '%s' status for %s in %s"), gce->ptszText, gce->ptszStatus, gce->ptszNick, si->ptszName); - break; - case GC_EVENT_REMOVESTATUS: - ci.AddEvent(si->hContact, ci.hIcons[ICON_REMSTATUS], GC_FAKE_EVENT, CLEF_ONLYAFEW, TranslateT("%s disables '%s' status for %s in %s"), gce->ptszText, gce->ptszStatus, gce->ptszNick, si->ptszName); - break; - } - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static void __stdcall ShowRoomFromPopup(void *pi) -{ - SESSION_INFO *si = (SESSION_INFO*)pi; - ci.ShowRoom(si, WINDOW_VISIBLE, TRUE); -} - -static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - case WM_COMMAND: - if (HIWORD(wParam) == STN_CLICKED) { - SESSION_INFO *si = (SESSION_INFO*)PUGetPluginData(hWnd); - CallFunctionAsync(ShowRoomFromPopup, si); - - PUDeletePopup(hWnd); - return TRUE; - } - break; - case WM_CONTEXTMENU: - SESSION_INFO *si = (SESSION_INFO*)PUGetPluginData(hWnd); - if (si->hContact) - if (CallService(MS_CLIST_GETEVENT, (WPARAM)si->hContact, 0)) - CallService(MS_CLIST_REMOVEEVENT, (WPARAM)si->hContact, (LPARAM)GC_FAKE_EVENT); - - if (si->hWnd && KillTimer(si->hWnd, TIMERID_FLASHWND)) - FlashWindow(si->hWnd, FALSE); - - PUDeletePopup(hWnd); - break; - } - return DefWindowProc(hWnd, message, wParam, lParam); -} - -int ShowPopup(MCONTACT hContact, SESSION_INFO *si, HICON hIcon, char* pszProtoName, TCHAR* pszRoomName, COLORREF crBkg, const TCHAR* fmt, ...) -{ - static TCHAR szBuf[4 * 1024]; - - if (!fmt || fmt[0] == 0 || mir_tstrlen(fmt) > 2000) - return 0; - - va_list marker; - va_start(marker, fmt); - mir_vsntprintf(szBuf, 4096, fmt, marker); - va_end(marker); - - POPUPDATAT pd = { 0 }; - pd.lchContact = hContact; - - if (hIcon) - pd.lchIcon = hIcon; - else - pd.lchIcon = LoadIconEx("window", FALSE); - - PROTOACCOUNT *pa = ProtoGetAccount(pszProtoName); - mir_sntprintf(pd.lptzContactName, SIZEOF(pd.lptzContactName), _T("%s - %s"), - (pa == NULL) ? _A2T(pszProtoName) : pa->tszAccountName, - cli.pfnGetContactDisplayName(hContact, 0)); - - mir_tstrncpy(pd.lptzText, TranslateTS(szBuf), SIZEOF(pd.lptzText)); - pd.iSeconds = g_Settings->iPopupTimeout; - - if (g_Settings->iPopupStyle == 2) { - pd.colorBack = 0; - pd.colorText = 0; - } - else if (g_Settings->iPopupStyle == 3) { - pd.colorBack = g_Settings->crPUBkgColour; - pd.colorText = g_Settings->crPUTextColour; - } - else { - pd.colorBack = g_Settings->crLogBackground; - pd.colorText = crBkg; - } - - pd.PluginWindowProc = PopupDlgProc; - pd.PluginData = si; - return PUAddPopupT(&pd); -} - -BOOL DoPopup(SESSION_INFO *si, GCEVENT *gce) -{ - switch (gce->pDest->iType) { - case GC_EVENT_MESSAGE | GC_EVENT_HIGHLIGHT: - ci.ShowPopup(si->hContact, si, LoadSkinnedIcon(SKINICON_EVENT_MESSAGE), si->pszModule, si->ptszName, ci.aFonts[16].color, TranslateT("%s says: %s"), gce->ptszNick, RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_ACTION | GC_EVENT_HIGHLIGHT: - ci.ShowPopup(si->hContact, si, LoadSkinnedIcon(SKINICON_EVENT_MESSAGE), si->pszModule, si->ptszName, ci.aFonts[16].color, _T("%s %s"), gce->ptszNick, RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_MESSAGE: - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_MESSAGE], si->pszModule, si->ptszName, ci.aFonts[9].color, TranslateT("%s says: %s"), gce->ptszNick, RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_ACTION: - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_ACTION], si->pszModule, si->ptszName, ci.aFonts[15].color, _T("%s %s"), gce->ptszNick, RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_JOIN: - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_JOIN], si->pszModule, si->ptszName, ci.aFonts[3].color, TranslateT("%s has joined"), gce->ptszNick); - break; - case GC_EVENT_PART: - if (!gce->ptszText) - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_PART], si->pszModule, si->ptszName, ci.aFonts[4].color, TranslateT("%s has left"), gce->ptszNick); - else - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_PART], si->pszModule, si->ptszName, ci.aFonts[4].color, TranslateT("%s has left (%s)"), gce->ptszNick, RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_QUIT: - if (!gce->ptszText) - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_QUIT], si->pszModule, si->ptszName, ci.aFonts[5].color, TranslateT("%s has disconnected"), gce->ptszNick); - else - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_QUIT], si->pszModule, si->ptszName, ci.aFonts[5].color, TranslateT("%s has disconnected (%s)"), gce->ptszNick, RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_NICK: - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_NICK], si->pszModule, si->ptszName, ci.aFonts[7].color, TranslateT("%s is now known as %s"), gce->ptszNick, gce->ptszText); - break; - case GC_EVENT_KICK: - if (!gce->ptszText) - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_KICK], si->pszModule, si->ptszName, ci.aFonts[6].color, TranslateT("%s kicked %s"), (char *)gce->ptszStatus, gce->ptszNick); - else - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_KICK], si->pszModule, si->ptszName, ci.aFonts[6].color, TranslateT("%s kicked %s (%s)"), (char *)gce->ptszStatus, gce->ptszNick, RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_NOTICE: - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_NOTICE], si->pszModule, si->ptszName, ci.aFonts[8].color, TranslateT("Notice from %s: %s"), gce->ptszNick, RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_TOPIC: - if (!gce->ptszNick) - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_TOPIC], si->pszModule, si->ptszName, ci.aFonts[11].color, TranslateT("The topic is '%s'"), RemoveFormatting(gce->ptszText)); - else - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_TOPIC], si->pszModule, si->ptszName, ci.aFonts[11].color, TranslateT("The topic is '%s' (set by %s)"), RemoveFormatting(gce->ptszText), gce->ptszNick); - break; - case GC_EVENT_INFORMATION: - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_INFO], si->pszModule, si->ptszName, ci.aFonts[12].color, _T("%s"), RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_ADDSTATUS: - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_ADDSTATUS], si->pszModule, si->ptszName, ci.aFonts[13].color, TranslateT("%s enables '%s' status for %s"), gce->ptszText, (char *)gce->ptszStatus, gce->ptszNick); - break; - case GC_EVENT_REMOVESTATUS: - ci.ShowPopup(si->hContact, si, ci.hIcons[ICON_REMSTATUS], si->pszModule, si->ptszName, ci.aFonts[14].color, TranslateT("%s disables '%s' status for %s"), gce->ptszText, (char *)gce->ptszStatus, gce->ptszNick); - break; - } - - return TRUE; -} - -BOOL DoSoundsFlashPopupTrayStuff(SESSION_INFO *si, GCEVENT *gce, BOOL bHighlight, int bManyFix) -{ - if (!gce || !si || gce->bIsMe || si->iType == GCW_SERVER) - return FALSE; - - BOOL bInactive = si->hWnd == NULL || GetForegroundWindow() != si->hWnd; - - int iEvent = gce->pDest->iType; - - if (bHighlight) { - gce->pDest->iType |= GC_EVENT_HIGHLIGHT; - if (bInactive || !g_Settings->bSoundsFocus) - SkinPlaySound("ChatHighlight"); - if (db_get_b(si->hContact, "CList", "Hidden", 0) != 0) - db_unset(si->hContact, "CList", "Hidden"); - if (bInactive) - ci.DoTrayIcon(si, gce); - if (bInactive || !g_Settings->bPopupInactiveOnly) - ci.DoPopup(si, gce); - if (ci.OnFlashHighlight) - ci.OnFlashHighlight(si, bInactive); - return TRUE; - } - - // do blinking icons in tray - if (bInactive || !g_Settings->bTrayIconInactiveOnly) - ci.DoTrayIcon(si, gce); - - // stupid thing to not create multiple popups for a QUIT event for instance - if (bManyFix == 0) { - // do popups - if (bInactive || !g_Settings->bPopupInactiveOnly) - ci.DoPopup(si, gce); - - // do sounds and flashing - switch (iEvent) { - case GC_EVENT_JOIN: - if (bInactive || !g_Settings->bSoundsFocus) - SkinPlaySound("ChatJoin"); - break; - case GC_EVENT_PART: - if (bInactive || !g_Settings->bSoundsFocus) - SkinPlaySound("ChatPart"); - break; - case GC_EVENT_QUIT: - if (bInactive || !g_Settings->bSoundsFocus) - SkinPlaySound("ChatQuit"); - break; - case GC_EVENT_ADDSTATUS: - case GC_EVENT_REMOVESTATUS: - if (bInactive || !g_Settings->bSoundsFocus) - SkinPlaySound("ChatMode"); - break; - case GC_EVENT_KICK: - if (bInactive || !g_Settings->bSoundsFocus) - SkinPlaySound("ChatKick"); - break; - case GC_EVENT_MESSAGE: - if (bInactive || !g_Settings->bSoundsFocus) - SkinPlaySound("ChatMessage"); - - if (bInactive && !(si->wState & STATE_TALK)) { - si->wState |= STATE_TALK; - db_set_w(si->hContact, si->pszModule, "ApparentMode", ID_STATUS_OFFLINE); - } - if (ci.OnFlashWindow) - ci.OnFlashWindow(si, bInactive); - break; - case GC_EVENT_ACTION: - if (bInactive || !g_Settings->bSoundsFocus) - SkinPlaySound("ChatAction"); - break; - case GC_EVENT_NICK: - if (bInactive || !g_Settings->bSoundsFocus) - SkinPlaySound("ChatNick"); - break; - case GC_EVENT_NOTICE: - if (bInactive || !g_Settings->bSoundsFocus) - SkinPlaySound("ChatNotice"); - break; - case GC_EVENT_TOPIC: - if (bInactive || !g_Settings->bSoundsFocus) - SkinPlaySound("ChatTopic"); - break; - } - } - - return TRUE; -} - -int GetColorIndex(const char *pszModule, COLORREF cr) -{ - MODULEINFO *pMod = ci.MM_FindModule(pszModule); - int i = 0; - - if (!pMod || pMod->nColorCount == 0) - return -1; - - for (i = 0; i < pMod->nColorCount; i++) - if (pMod->crColors[i] == cr) - return i; - - return -1; -} - -// obscure function that is used to make sure that any of the colors -// passed by the protocol is used as fore- or background color -// in the messagebox. THis is to vvercome limitations in the richedit -// that I do not know currently how to fix - -void CheckColorsInModule(const char *pszModule) -{ - MODULEINFO *pMod = ci.MM_FindModule(pszModule); - int i = 0; - COLORREF crFG; - COLORREF crBG = (COLORREF)db_get_dw(NULL, CHAT_MODULE, "ColorMessageBG", GetSysColor(COLOR_WINDOW)); - - LoadMsgDlgFont(17, NULL, &crFG); - - if (!pMod) - return; - - for (i = 0; i < pMod->nColorCount; i++) { - if (pMod->crColors[i] == crFG || pMod->crColors[i] == crBG) { - if (pMod->crColors[i] == RGB(255, 255, 255)) - pMod->crColors[i]--; - else - pMod->crColors[i]++; - } - } -} - -const TCHAR* my_strstri(const TCHAR* s1, const TCHAR* s2) -{ - int i, j, k; - for (i = 0; s1[i]; i++) - for (j = i, k = 0; _totlower(s1[j]) == _totlower(s2[k]); j++, k++) - if (!s2[k + 1]) - return s1 + i; - - return NULL; -} - -static TCHAR szTrimString[] = _T(":,.!?;\'>)"); - -BOOL IsHighlighted(SESSION_INFO *si, GCEVENT *gce) -{ - if (!g_Settings->bHighlightEnabled || !g_Settings->pszHighlightWords || !gce || !si || !si->pMe) - return FALSE; - - if (gce->ptszText == NULL) - return FALSE; - - TCHAR *buf = RemoveFormatting(NEWTSTR_ALLOCA(gce->ptszText)); - - int iStart = 0; - CMString tszHighlightWords(g_Settings->pszHighlightWords); - - while (true) { - CMString tszToken = tszHighlightWords.Tokenize(_T("\t "), iStart); - if (iStart == -1) - break; - - // replace %m with the users nickname - if (tszToken == _T("%m")) - tszToken = si->pMe->pszNick; - - if (tszToken.Find('*') == -1) - tszToken = '*' + tszToken + '*'; - - // time to get the next/first word in the incoming text string - for (const TCHAR *p = buf; *p != '\0'; p += _tcscspn(p, _T(" "))) { - p += _tcsspn(p, _T(" ")); - - // compare the words, using wildcards - if (wildcmpit(RemoveFormatting(p), tszToken)) - return TRUE; - } - } - - return FALSE; -} - -BOOL LogToFile(SESSION_INFO *si, GCEVENT *gce) -{ - TCHAR szBuffer[4096]; - TCHAR szLine[4096]; - TCHAR p = '\0'; - szBuffer[0] = '\0'; - - GetChatLogsFilename(si, gce->time); - BOOL bFileJustCreated = !PathFileExists(si->pszLogFileName); - - TCHAR tszFolder[MAX_PATH]; - _tcsncpy_s(tszFolder, si->pszLogFileName, _TRUNCATE); - PathRemoveFileSpec(tszFolder); - if (!PathIsDirectory(tszFolder)) - CreateDirectoryTreeT(tszFolder); - - TCHAR szTime[100]; - mir_tstrncpy(szTime, ci.MakeTimeStamp(g_Settings->pszTimeStampLog, gce->time), 99); - - FILE *hFile = _tfopen(si->pszLogFileName, _T("ab+")); - if (hFile == NULL) - return FALSE; - - TCHAR szTemp[512], szTemp2[512]; - TCHAR* pszNick = NULL; - if (bFileJustCreated) - fputws((const wchar_t*)"\377\376", hFile); //UTF-16 LE BOM == FF FE - if (gce->ptszNick) { - if (g_Settings->bLogLimitNames && mir_tstrlen(gce->ptszNick) > 20) { - mir_tstrncpy(szTemp2, gce->ptszNick, 20); - mir_tstrncpy(szTemp2 + 20, _T("..."), 4); - } - else mir_tstrncpy(szTemp2, gce->ptszNick, 511); - - if (gce->ptszUserInfo) - mir_sntprintf(szTemp, _T("%s (%s)"), szTemp2, gce->ptszUserInfo); - else - _tcsncpy_s(szTemp, szTemp2, _TRUNCATE); - pszNick = szTemp; - } - - switch (gce->pDest->iType) { - case GC_EVENT_MESSAGE: - case GC_EVENT_MESSAGE | GC_EVENT_HIGHLIGHT: - p = '*'; - mir_sntprintf(szBuffer, _T("%s: %s"), gce->ptszNick, ci.RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_ACTION: - case GC_EVENT_ACTION | GC_EVENT_HIGHLIGHT: - p = '*'; - mir_sntprintf(szBuffer, _T("%s %s"), gce->ptszNick, ci.RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_JOIN: - p = '>'; - mir_sntprintf(szBuffer, TranslateT("%s has joined"), pszNick); - break; - case GC_EVENT_PART: - p = '<'; - if (!gce->ptszText) - mir_sntprintf(szBuffer, TranslateT("%s has left"), pszNick); - else - mir_sntprintf(szBuffer, TranslateT("%s has left (%s)"), pszNick, ci.RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_QUIT: - p = '<'; - if (!gce->ptszText) - mir_sntprintf(szBuffer, TranslateT("%s has disconnected"), pszNick); - else - mir_sntprintf(szBuffer, TranslateT("%s has disconnected (%s)"), pszNick, ci.RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_NICK: - p = '^'; - mir_sntprintf(szBuffer, TranslateT("%s is now known as %s"), gce->ptszNick, gce->ptszText); - break; - case GC_EVENT_KICK: - p = '~'; - if (!gce->ptszText) - mir_sntprintf(szBuffer, TranslateT("%s kicked %s"), gce->ptszStatus, gce->ptszNick); - else - mir_sntprintf(szBuffer, TranslateT("%s kicked %s (%s)"), gce->ptszStatus, gce->ptszNick, ci.RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_NOTICE: - p = 'o'; - mir_sntprintf(szBuffer, TranslateT("Notice from %s: %s"), gce->ptszNick, ci.RemoveFormatting(gce->ptszText)); - break; - case GC_EVENT_TOPIC: - p = '#'; - if (!gce->ptszNick) - mir_sntprintf(szBuffer, TranslateT("The topic is '%s'"), ci.RemoveFormatting(gce->ptszText)); - else - mir_sntprintf(szBuffer, TranslateT("The topic is '%s' (set by %s)"), ci.RemoveFormatting(gce->ptszText), gce->ptszNick); - break; - case GC_EVENT_INFORMATION: - p = '!'; - _tcsncpy_s(szBuffer, ci.RemoveFormatting(gce->ptszText), _TRUNCATE); - break; - case GC_EVENT_ADDSTATUS: - p = '+'; - mir_sntprintf(szBuffer, TranslateT("%s enables '%s' status for %s"), gce->ptszText, gce->ptszStatus, gce->ptszNick); - break; - case GC_EVENT_REMOVESTATUS: - p = '-'; - mir_sntprintf(szBuffer, TranslateT("%s disables '%s' status for %s"), gce->ptszText, gce->ptszStatus, gce->ptszNick); - break; - } - - // formatting strings don't need to be translatable - changing them via language pack would - // only screw up the log format. - if (p) - mir_sntprintf(szLine, SIZEOF(szLine), _T("%s %c %s\r\n"), szTime, p, szBuffer); - else - mir_sntprintf(szLine, SIZEOF(szLine), _T("%s %s\r\n"), szTime, szBuffer); - - if (szLine[0]) { - _fputts(szLine, hFile); - - if (g_Settings->LoggingLimit > 0) { - fseek(hFile, 0, SEEK_END); - long dwSize = ftell(hFile); - rewind(hFile); - - long trimlimit = g_Settings->LoggingLimit * 1024; - if (dwSize > trimlimit) { - time_t now = time(0); - - TCHAR tszTimestamp[20]; - _tcsftime(tszTimestamp, 20, _T("%Y%m%d-%H%M%S"), _localtime32((__time32_t *)&now)); - tszTimestamp[19] = 0; - - // max size reached, rotate the log - // move old logs to /archived sub folder just inside the log root folder. - // add a time stamp to the file name. - TCHAR tszDrive[_MAX_DRIVE], tszDir[_MAX_DIR], tszName[_MAX_FNAME], tszExt[_MAX_EXT]; - _tsplitpath(si->pszLogFileName, tszDrive, tszDir, tszName, tszExt); - - TCHAR tszNewPath[_MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 20]; - mir_sntprintf(tszNewPath, SIZEOF(tszNewPath), _T("%s%sarchived\\"), tszDrive, tszDir); - CreateDirectoryTreeT(tszNewPath); - - TCHAR tszNewName[_MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 20]; - mir_sntprintf(tszNewName, SIZEOF(tszNewName), _T("%s%s-%s%s"), tszNewPath, tszName, tszTimestamp, tszExt); - fclose(hFile); - hFile = 0; - if (!PathFileExists(tszNewName)) - CopyFile(si->pszLogFileName, tszNewName, TRUE); - DeleteFile(si->pszLogFileName); - } - } - } - - if (hFile) - fclose(hFile); - return TRUE; -} - -BOOL DoEventHookAsync(HWND hwnd, const TCHAR *pszID, const char *pszModule, int iType, const TCHAR* pszUID, const TCHAR* pszText, INT_PTR dwItem) -{ - SESSION_INFO *si = ci.SM_FindSession(pszID, pszModule); - if (si == NULL) - return FALSE; - - GCDEST *gcd = (GCDEST*)mir_calloc(sizeof(GCDEST)); - gcd->pszModule = mir_strdup(pszModule); - gcd->ptszID = mir_tstrdup(pszID); - gcd->iType = iType; - - GCHOOK *gch = (GCHOOK*)mir_calloc(sizeof(GCHOOK)); - gch->ptszUID = mir_tstrdup(pszUID); - gch->ptszText = mir_tstrdup(pszText); - gch->dwData = dwItem; - gch->pDest = gcd; - PostMessage(hwnd, GC_FIREHOOK, 0, (LPARAM)gch); - return TRUE; -} - -BOOL DoEventHook(const TCHAR *pszID, const char *pszModule, int iType, const TCHAR *pszUID, const TCHAR* pszText, INT_PTR dwItem) -{ - SESSION_INFO *si = ci.SM_FindSession(pszID, pszModule); - if (si == NULL) - return FALSE; - - GCDEST gcd = { (char*)pszModule, pszID, iType }; - GCHOOK gch = { 0 }; - gch.ptszUID = (LPTSTR)pszUID; - gch.ptszText = (LPTSTR)pszText; - gch.dwData = dwItem; - gch.pDest = &gcd; - NotifyEventHooks(ci.hSendEvent, 0, (WPARAM)&gch); - return TRUE; -} - -BOOL IsEventSupported(int eventType) -{ - // Supported events - switch (eventType) { - case GC_EVENT_JOIN: - case GC_EVENT_PART: - case GC_EVENT_QUIT: - case GC_EVENT_KICK: - case GC_EVENT_NICK: - case GC_EVENT_NOTICE: - case GC_EVENT_MESSAGE: - case GC_EVENT_TOPIC: - case GC_EVENT_INFORMATION: - case GC_EVENT_ACTION: - case GC_EVENT_ADDSTATUS: - case GC_EVENT_REMOVESTATUS: - case GC_EVENT_CHUID: - case GC_EVENT_CHANGESESSIONAME: - case GC_EVENT_ADDGROUP: - case GC_EVENT_SETITEMDATA: - case GC_EVENT_GETITEMDATA: - case GC_EVENT_SETSBTEXT: - case GC_EVENT_ACK: - case GC_EVENT_SENDMESSAGE: - case GC_EVENT_SETSTATUSEX: - case GC_EVENT_CONTROL: - case GC_EVENT_SETCONTACTSTATUS: - return TRUE; - } - - // Other events - return FALSE; -} - -void ValidateFilename(TCHAR *filename) -{ - TCHAR *p1 = filename; - TCHAR szForbidden[] = _T("\\/:*?\"<>|"); - while (*p1 != '\0') { - if (_tcschr(szForbidden, *p1)) - *p1 = '_'; - p1 += 1; - } -} - -static TCHAR tszOldTimeStamp[30]; - -TCHAR* GetChatLogsFilename(SESSION_INFO *si, time_t tTime) -{ - if (!tTime) - time(&tTime); - - // check whether relevant parts of the timestamp have changed and - // we have to reparse the filename - TCHAR *tszNow = ci.MakeTimeStamp(_T("%a%d%m%Y"), tTime); // once a day - if (mir_tstrcmp(tszOldTimeStamp, tszNow)) { - _tcsncpy_s(tszOldTimeStamp, tszNow, _TRUNCATE); - *si->pszLogFileName = 0; - } - - if (si->pszLogFileName[0] == 0) { - REPLACEVARSARRAY rva[11]; - rva[0].lptzKey = _T("d"); - rva[0].lptzValue = mir_tstrdup(ci.MakeTimeStamp(_T("%#d"), tTime)); - // day 01-31 - rva[1].lptzKey = _T("dd"); - rva[1].lptzValue = mir_tstrdup(ci.MakeTimeStamp(_T("%d"), tTime)); - // month 1-12 - rva[2].lptzKey = _T("m"); - rva[2].lptzValue = mir_tstrdup(ci.MakeTimeStamp(_T("%#m"), tTime)); - // month 01-12 - rva[3].lptzKey = _T("mm"); - rva[3].lptzValue = mir_tstrdup(ci.MakeTimeStamp(_T("%m"), tTime)); - // month text short - rva[4].lptzKey = _T("mon"); - rva[4].lptzValue = mir_tstrdup(ci.MakeTimeStamp(_T("%b"), tTime)); - // month text - rva[5].lptzKey = _T("month"); - rva[5].lptzValue = mir_tstrdup(ci.MakeTimeStamp(_T("%B"), tTime)); - // year 01-99 - rva[6].lptzKey = _T("yy"); - rva[6].lptzValue = mir_tstrdup(ci.MakeTimeStamp(_T("%y"), tTime)); - // year 1901-9999 - rva[7].lptzKey = _T("yyyy"); - rva[7].lptzValue = mir_tstrdup(ci.MakeTimeStamp(_T("%Y"), tTime)); - // weekday short - rva[8].lptzKey = _T("wday"); - rva[8].lptzValue = mir_tstrdup(ci.MakeTimeStamp(_T("%a"), tTime)); - // weekday - rva[9].lptzKey = _T("weekday"); - rva[9].lptzValue = mir_tstrdup(ci.MakeTimeStamp(_T("%A"), tTime)); - // end of array - rva[10].lptzKey = NULL; - rva[10].lptzValue = NULL; - - TCHAR tszTemp[MAX_PATH], *ptszVarPath; - if (g_Settings->pszLogDir[mir_tstrlen(g_Settings->pszLogDir) - 1] == '\\') { - mir_sntprintf(tszTemp, SIZEOF(tszTemp), _T("%s%s"), g_Settings->pszLogDir, _T("%userid%.log")); - ptszVarPath = tszTemp; - } - else ptszVarPath = g_Settings->pszLogDir; - - REPLACEVARSDATA dat = { sizeof(dat) }; - dat.dwFlags = RVF_TCHAR; - dat.hContact = si->hContact; - dat.variables = rva; - TCHAR *tszParsedName = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)ptszVarPath, (LPARAM)&dat); - if (ci.OnGetLogName) - ci.OnGetLogName(si, tszParsedName); - else - PathToAbsoluteT(tszParsedName, si->pszLogFileName); - mir_free(tszParsedName); - - for (int i = 0; i < SIZEOF(rva); i++) - mir_free(rva[i].lptzValue); - - for (TCHAR *p = si->pszLogFileName + 2; *p; ++p) - if (*p == ':' || *p == '*' || *p == '?' || *p == '"' || *p == '<' || *p == '>' || *p == '|') - *p = _T('_'); - } - - return si->pszLogFileName; -} diff --git a/src/modules/clist/Docking.cpp b/src/modules/clist/Docking.cpp deleted file mode 100644 index 7d9fbd62c6..0000000000 --- a/src/modules/clist/Docking.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -#define WM_DOCKCALLBACK (WM_USER+121) -#define EDGESENSITIVITY 3 - -#define DOCKED_NONE 0 -#define DOCKED_LEFT 1 -#define DOCKED_RIGHT 2 - -static char docked; -static POINT dockPos; - -static void Docking_GetMonitorRectFromPoint(LPPOINT pt, LPRECT rc) -{ - MONITORINFO monitorInfo; - HMONITOR hMonitor = MonitorFromPoint(*pt, MONITOR_DEFAULTTONEAREST); // always returns a valid value - monitorInfo.cbSize = sizeof(monitorInfo); - - if (GetMonitorInfo(hMonitor, &monitorInfo)) { - *rc = monitorInfo.rcMonitor; - return; - } - - // "generic" win95/NT support, also serves as failsafe - rc->left = 0; - rc->top = 0; - rc->bottom = GetSystemMetrics(SM_CYSCREEN); - rc->right = GetSystemMetrics(SM_CXSCREEN); -} - -static void Docking_RectToDock(LPRECT rc) -{ - rc->right += dockPos.x - rc->left; - rc->left = dockPos.x; - rc->bottom += dockPos.y - rc->top; - rc->top = dockPos.y; -} - -static void Docking_PosCommand(HWND hwnd, LPRECT rc, bool query) -{ - APPBARDATA abd = { 0 }; - - abd.cbSize = sizeof(abd); - abd.hWnd = hwnd; - abd.uEdge = docked == DOCKED_LEFT ? ABE_LEFT : ABE_RIGHT; - abd.rc = *rc; - SHAppBarMessage(query ? ABM_QUERYPOS : ABM_SETPOS, &abd); - *rc = abd.rc; -} - -static UINT_PTR Docking_Command(HWND hwnd, int cmd) -{ - APPBARDATA abd = { 0 }; - - abd.cbSize = sizeof(abd); - abd.hWnd = hwnd; - abd.uCallbackMessage = WM_DOCKCALLBACK; - return SHAppBarMessage(cmd, &abd); -} - -static void Docking_AdjustPosition(HWND hwnd, LPRECT rcDisplay, LPRECT rc, bool query, bool move) -{ - int cx = rc->right - rc->left; - - rc->top = rcDisplay->top; - rc->bottom = rcDisplay->bottom; - if (docked == DOCKED_LEFT) { - rc->right = rcDisplay->left + (rc->right - rc->left); - rc->left = rcDisplay->left; - } - else { - rc->left = rcDisplay->right - (rc->right - rc->left); - rc->right = rcDisplay->right; - } - Docking_PosCommand(hwnd, rc, true); - - if (docked == DOCKED_LEFT) - rc->right = rc->left + cx; - else - rc->left = rc->right - cx; - - if (!query) { - Docking_PosCommand(hwnd, rc, false); - dockPos = *(LPPOINT)rc; - } - - if (move) - MoveWindow(hwnd, rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top, TRUE); -} - -static void Docking_SetSize(HWND hwnd, LPRECT rc, bool query, bool move) -{ - RECT rcMonitor; - Docking_GetMonitorRectFromPoint( - docked == DOCKED_LEFT && !query ? (LPPOINT)&rc->right : (LPPOINT)rc, &rcMonitor); - Docking_AdjustPosition(hwnd, &rcMonitor, rc, query, move); -} - -static bool Docking_IsWindowVisible(HWND hwnd) -{ - LONG style = GetWindowLongPtr(hwnd, GWL_STYLE); - return style & WS_VISIBLE && !(style & WS_MINIMIZE); -} - -INT_PTR Docking_IsDocked(WPARAM, LPARAM) -{ - return docked; -} - -int fnDocking_ProcessWindowMessage(WPARAM wParam, LPARAM lParam) -{ - static int draggingTitle; - MSG *msg = (MSG *)wParam; - - if (msg->message == WM_DESTROY) { - if (docked) { - db_set_b(NULL, "CList", "Docked", (BYTE)docked); - db_set_dw(NULL, "CList", "DockX", (DWORD)dockPos.x); - db_set_dw(NULL, "CList", "DockY", (DWORD)dockPos.y); - } - else { - db_unset(NULL, "CList", "Docked"); - db_unset(NULL, "CList", "DockX"); - db_unset(NULL, "CList", "DockY"); - } - } - - if (!docked && msg->message != WM_CREATE && msg->message != WM_MOVING) - return 0; - - switch (msg->message) { - case WM_CREATE: - draggingTitle = 0; - docked = db_get_b(NULL, "CLUI", "DockToSides", 1) ? - (char)db_get_b(NULL, "CList", "Docked", 0) : 0; - dockPos.x = (int)db_get_dw(NULL, "CList", "DockX", 0); - dockPos.y = (int)db_get_dw(NULL, "CList", "DockY", 0); - break; - - case WM_ACTIVATE: - Docking_Command(msg->hwnd, ABM_ACTIVATE); - break; - - case WM_WINDOWPOSCHANGING: - { - LPWINDOWPOS wp = (LPWINDOWPOS)msg->lParam; - - bool vis = Docking_IsWindowVisible(msg->hwnd); - if (wp->flags & SWP_SHOWWINDOW) - vis = !IsIconic(msg->hwnd); - if (wp->flags & SWP_HIDEWINDOW) - vis = false; - - if (vis) { - if (!(wp->flags & (SWP_NOMOVE | SWP_NOSIZE))) { - bool addbar = Docking_Command(msg->hwnd, ABM_NEW) != 0; - - RECT rc = { 0 }; - GetWindowRect(msg->hwnd, &rc); - - int cx = rc.right - rc.left; - if (!(wp->flags & SWP_NOMOVE)) { rc.left = wp->x; rc.top = wp->y; } - - if (addbar) - Docking_RectToDock(&rc); - - if (!(wp->flags & SWP_NOSIZE)) { - rc.right = rc.left + wp->cx; - rc.bottom = rc.top + wp->cy; - addbar |= (cx != wp->cx); - } - - Docking_SetSize(msg->hwnd, &rc, !addbar, false); - - if (!(wp->flags & SWP_NOMOVE)) { wp->x = rc.left; wp->y = rc.top; } - if (!(wp->flags & SWP_NOSIZE)) wp->cy = rc.bottom - rc.top; - - *((LRESULT *)lParam) = TRUE; - return TRUE; - } - else { - if ((wp->flags & SWP_SHOWWINDOW) && Docking_Command(msg->hwnd, ABM_NEW)) { - RECT rc = { 0 }; - GetWindowRect(msg->hwnd, &rc); - Docking_RectToDock(&rc); - - Docking_SetSize(msg->hwnd, &rc, false, false); - - wp->x = rc.left; - wp->y = rc.top; - wp->cy = rc.bottom - rc.top; - wp->cx = rc.right - rc.left; - wp->flags &= ~(SWP_NOSIZE | SWP_NOMOVE); - } - } - } - } - break; - - case WM_WINDOWPOSCHANGED: - { - LPWINDOWPOS wp = (LPWINDOWPOS)msg->lParam; - bool vis = Docking_IsWindowVisible(msg->hwnd); - if (wp->flags & SWP_SHOWWINDOW) - vis = !IsIconic(msg->hwnd); - if (wp->flags & SWP_HIDEWINDOW) - vis = false; - - if (!vis) - Docking_Command(msg->hwnd, ABM_REMOVE); - else - Docking_Command(msg->hwnd, ABM_WINDOWPOSCHANGED); - } - break; - - case WM_DISPLAYCHANGE: - if (Docking_IsWindowVisible(msg->hwnd)) { - RECT rc = { 0 }; - GetWindowRect(msg->hwnd, &rc); - Docking_RectToDock(&rc); - Docking_SetSize(msg->hwnd, &rc, false, true); - } - break; - - case WM_MOVING: - if (!docked) { - RECT rcMonitor; - POINT ptCursor; - - // stop early - if (GetAsyncKeyState(VK_CONTROL) & 0x8000) - return 0; - - // GetMessagePos() is no good, position is always unsigned - // GetCursorPos(&ptCursor); - DWORD pos = GetMessagePos(); - ptCursor.x = GET_X_LPARAM(pos); - ptCursor.y = GET_Y_LPARAM(pos); - Docking_GetMonitorRectFromPoint(&ptCursor, &rcMonitor); - - if (((ptCursor.x < rcMonitor.left + EDGESENSITIVITY) || - (ptCursor.x >= rcMonitor.right - EDGESENSITIVITY)) && - db_get_b(NULL, "CLUI", "DockToSides", 1)) { - docked = (ptCursor.x < rcMonitor.left + EDGESENSITIVITY) ? DOCKED_LEFT : DOCKED_RIGHT; - PostMessage(msg->hwnd, WM_LBUTTONUP, 0, MAKELPARAM(ptCursor.x, ptCursor.y)); - - Docking_Command(msg->hwnd, ABM_NEW); - Docking_AdjustPosition(msg->hwnd, &rcMonitor, (LPRECT)msg->lParam, false, true); - - *((LRESULT *)lParam) = TRUE; - return TRUE; - } - } - break; - - case WM_NCHITTEST: - switch (DefWindowProc(msg->hwnd, WM_NCHITTEST, msg->wParam, msg->lParam)) { - case HTSIZE: case HTTOP: case HTTOPLEFT: case HTTOPRIGHT: - case HTBOTTOM: case HTBOTTOMRIGHT: case HTBOTTOMLEFT: - *((LRESULT *)lParam) = HTCLIENT; - return TRUE; - - case HTLEFT: - if (docked == DOCKED_LEFT) { - *((LRESULT *)lParam) = HTCLIENT; - return TRUE; - } - break; - - case HTRIGHT: - if (docked == DOCKED_RIGHT) { - *((LRESULT *)lParam) = HTCLIENT; - return TRUE; - } - break; - } - break; - - case WM_SYSCOMMAND: - if ((msg->wParam & 0xFFF0) != SC_MOVE) - return 0; - - SetActiveWindow(msg->hwnd); - SetCapture(msg->hwnd); - draggingTitle = 1; - *((LRESULT *)lParam) = 0; - return 1; - - case WM_MOUSEMOVE: - if (draggingTitle) { - RECT rc; - POINT pt; - GetClientRect(msg->hwnd, &rc); - if ((docked == DOCKED_LEFT && (short)LOWORD(msg->lParam) > rc.right) || - (docked == DOCKED_RIGHT && (short)LOWORD(msg->lParam) < 0)) { - ReleaseCapture(); - draggingTitle = 0; - docked = 0; - GetCursorPos(&pt); - PostMessage(msg->hwnd, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(pt.x, pt.y)); - SetWindowPos(msg->hwnd, 0, pt.x - rc.right / 2, - pt.y - GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYSMCAPTION) / 2, - db_get_dw(NULL, "CList", "Width", 0), - db_get_dw(NULL, "CList", "Height", 0), - SWP_NOZORDER); - Docking_Command(msg->hwnd, ABM_REMOVE); - } - return 1; - } - break; - - case WM_LBUTTONUP: - if (draggingTitle) { - ReleaseCapture(); - draggingTitle = 0; - } - break; - - case WM_DOCKCALLBACK: - switch (msg->wParam) { - case ABN_WINDOWARRANGE: - ShowWindow(msg->hwnd, msg->lParam ? SW_HIDE : SW_SHOW); - break; - - case ABN_POSCHANGED: - RECT rc = { 0 }; - GetWindowRect(msg->hwnd, &rc); - Docking_SetSize(msg->hwnd, &rc, false, true); - break; - } - return 1; - - case WM_DESTROY: - Docking_Command(msg->hwnd, ABM_REMOVE); - break; - } - return 0; -} diff --git a/src/modules/clist/clc.cpp b/src/modules/clist/clc.cpp deleted file mode 100644 index 6ab8f89aa0..0000000000 --- a/src/modules/clist/clc.cpp +++ /dev/null @@ -1,1334 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -int InitGenMenu(void); -int UnitGenMenu(void); - -void InitCustomMenus(void); -void UninitCustomMenus(void); - -void MTG_OnmodulesLoad(void); - -static bool bModuleInitialized = false; -static HANDLE hClcWindowList; -static HANDLE hShowInfoTipEvent; -HANDLE hHideInfoTipEvent; -static LIST arEvents(10); - -int g_IconWidth, g_IconHeight; - -void FreeDisplayNameCache(void); - -void fnInitAutoRebuild(HWND hWnd) -{ - if (!cli.bAutoRebuild && hWnd) { - cli.bAutoRebuild = true; - SendMessage(hWnd, CLM_AUTOREBUILD, 0, 0); - } -} - -void fnClcBroadcast(int msg, WPARAM wParam, LPARAM lParam) -{ - WindowList_Broadcast(hClcWindowList, msg, wParam, lParam); -} - -void fnClcOptionsChanged(void) -{ - cli.pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0); -} - -HMENU fnBuildGroupPopupMenu(ClcGroup* group) -{ - HMENU hMenu = LoadMenu(cli.hInst, MAKEINTRESOURCE(IDR_CONTEXT)); - HMENU hGroupMenu = GetSubMenu(hMenu, 2); - RemoveMenu(hMenu, 2, MF_BYPOSITION); - DestroyMenu(hMenu); - TranslateMenu(hGroupMenu); - - CheckMenuItem(hGroupMenu, POPUP_GROUPHIDEOFFLINE, group->hideOffline ? MF_CHECKED : MF_UNCHECKED); - return hGroupMenu; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// standard CLC services - -static int ClcSettingChanged(WPARAM hContact, LPARAM lParam) -{ - DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam; - if (hContact == NULL) { - if (!mir_strcmp(cws->szModule, "CListGroups")) - cli.pfnClcBroadcast(INTM_GROUPSCHANGED, hContact, lParam); - return 0; - } - - if (!mir_strcmp(cws->szModule, "CList")) { - if (!mir_strcmp(cws->szSetting, "MyHandle")) { - cli.pfnInvalidateDisplayNameCacheEntry(hContact); - cli.pfnClcBroadcast(INTM_NAMECHANGED, hContact, lParam); - } - else if (!mir_strcmp(cws->szSetting, "Group")) - cli.pfnClcBroadcast(INTM_GROUPCHANGED, hContact, lParam); - else if (!mir_strcmp(cws->szSetting, "Hidden")) - cli.pfnClcBroadcast(INTM_HIDDENCHANGED, hContact, lParam); - else if (!mir_strcmp(cws->szSetting, "NotOnList")) - cli.pfnClcBroadcast(INTM_NOTONLISTCHANGED, hContact, lParam); - else if (!mir_strcmp(cws->szSetting, "Status")) - cli.pfnClcBroadcast(INTM_INVALIDATE, 0, 0); - else if (!mir_strcmp(cws->szSetting, "NameOrder")) - cli.pfnClcBroadcast(INTM_NAMEORDERCHANGED, 0, 0); - } - else { - char *szProto = GetContactProto(hContact); - if (szProto != NULL) { - if (!mir_strcmp(cws->szModule, "Protocol") && !mir_strcmp(cws->szSetting, "p")) - cli.pfnClcBroadcast(INTM_PROTOCHANGED, hContact, lParam); - - // something is being written to a protocol module - if (!mir_strcmp(szProto, cws->szModule)) { - // was a unique setting key written? - char *id = (char *) CallProtoServiceInt(NULL,szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); - if ((INT_PTR)id != CALLSERVICE_NOTFOUND && id != NULL && !mir_strcmp(id, cws->szSetting)) - cli.pfnClcBroadcast(INTM_PROTOCHANGED, hContact, lParam); - } - } - if (szProto == NULL || mir_strcmp(szProto, cws->szModule)) - return 0; - if (!mir_strcmp(cws->szSetting, "Nick") || !mir_strcmp(cws->szSetting, "FirstName") || !mir_strcmp(cws->szSetting, "e-mail") - || !mir_strcmp(cws->szSetting, "LastName") || !mir_strcmp(cws->szSetting, "UIN")) - cli.pfnClcBroadcast(INTM_NAMECHANGED, hContact, lParam); - else if (!mir_strcmp(cws->szSetting, "ApparentMode")) - cli.pfnClcBroadcast(INTM_APPARENTMODECHANGED, hContact, lParam); - else if (!mir_strcmp(cws->szSetting, "IdleTS")) - cli.pfnClcBroadcast(INTM_IDLECHANGED, hContact, lParam); - } - return 0; -} - -static int ClcAccountsChanged(WPARAM, LPARAM) -{ - int i, cnt; - for (i=0, cnt=0; i < accounts.getCount(); i++) - if (Proto_IsAccountEnabled(accounts[i])) - cnt++; - - cli.hClcProtoCount = cnt; - cli.clcProto = (ClcProtoStatus *) mir_realloc(cli.clcProto, sizeof(ClcProtoStatus) * cli.hClcProtoCount); - - for (i=0, cnt=0; i < accounts.getCount(); i++) { - if (Proto_IsAccountEnabled(accounts[i])) { - cli.clcProto[cnt].szProto = accounts[i]->szModuleName; - cli.clcProto[cnt].dwStatus = CallProtoServiceInt(NULL,accounts[i]->szModuleName, PS_GETSTATUS, 0, 0); - ++cnt; - } - } - return 0; -} - -static int ClcModulesLoaded(WPARAM, LPARAM) -{ - ClcAccountsChanged(0, 0); - MTG_OnmodulesLoad(); - return 0; -} - -static int ClcProtoAck(WPARAM, LPARAM lParam) -{ - ACKDATA *ack = (ACKDATA *) lParam; - if (ack->type == ACKTYPE_STATUS) { - WindowList_BroadcastAsync(hClcWindowList, INTM_INVALIDATE, 0, 0); - if (ack->result == ACKRESULT_SUCCESS) { - for (int i=0; i < cli.hClcProtoCount; i++) { - if (!mir_strcmp(cli.clcProto[i].szProto, ack->szModule)) { - cli.clcProto[i].dwStatus = (WORD) ack->lParam; - break; - } - } - } - } - return 0; -} - -static int ClcContactAdded(WPARAM wParam, LPARAM lParam) -{ - WindowList_BroadcastAsync(hClcWindowList, INTM_CONTACTADDED, wParam, lParam); - return 0; -} - -static int ClcContactDeleted(WPARAM wParam, LPARAM lParam) -{ - WindowList_BroadcastAsync(hClcWindowList, INTM_CONTACTDELETED, wParam, lParam); - return 0; -} - -static int ClcContactIconChanged(WPARAM wParam, LPARAM lParam) -{ - WindowList_BroadcastAsync(hClcWindowList, INTM_ICONCHANGED, wParam, lParam); - return 0; -} - -static int ClcIconsChanged(WPARAM, LPARAM) -{ - WindowList_BroadcastAsync(hClcWindowList, INTM_INVALIDATE, 0, 0); - return 0; -} - -static INT_PTR SetInfoTipHoverTime(WPARAM wParam, LPARAM) -{ - db_set_w(NULL, "CLC", "InfoTipHoverTime", (WORD) wParam); - cli.pfnClcBroadcast(INTM_SETINFOTIPHOVERTIME, wParam, 0); - return 0; -} - -static INT_PTR GetInfoTipHoverTime(WPARAM, LPARAM) -{ - return db_get_w(NULL, "CLC", "InfoTipHoverTime", 750); -} - -static void SortClcByTimer(HWND hwnd) -{ - KillTimer(hwnd, TIMERID_DELAYEDRESORTCLC); - SetTimer(hwnd, TIMERID_DELAYEDRESORTCLC, 200, NULL); -} - -int LoadCLCModule(void) -{ - bModuleInitialized = true; - - g_IconWidth = GetSystemMetrics(SM_CXSMICON); - g_IconHeight = GetSystemMetrics(SM_CYSMICON); - - hClcWindowList = WindowList_Create(); - hShowInfoTipEvent = CreateHookableEvent(ME_CLC_SHOWINFOTIP); - hHideInfoTipEvent = CreateHookableEvent(ME_CLC_HIDEINFOTIP); - CreateServiceFunction(MS_CLC_SETINFOTIPHOVERTIME, SetInfoTipHoverTime); - CreateServiceFunction(MS_CLC_GETINFOTIPHOVERTIME, GetInfoTipHoverTime); - - InitFileDropping(); - - arEvents.insert(HookEvent(ME_SYSTEM_MODULESLOADED, ClcModulesLoaded)); - arEvents.insert(HookEvent(ME_PROTO_ACCLISTCHANGED, ClcAccountsChanged)); - arEvents.insert(HookEvent(ME_DB_CONTACT_SETTINGCHANGED, ClcSettingChanged)); - arEvents.insert(HookEvent(ME_DB_CONTACT_ADDED, ClcContactAdded)); - arEvents.insert(HookEvent(ME_DB_CONTACT_DELETED, ClcContactDeleted)); - arEvents.insert(HookEvent(ME_CLIST_CONTACTICONCHANGED, ClcContactIconChanged)); - arEvents.insert(HookEvent(ME_SKIN_ICONSCHANGED, ClcIconsChanged)); - arEvents.insert(HookEvent(ME_PROTO_ACK, ClcProtoAck)); - - InitCustomMenus(); - return 0; -} - -void UnloadClcModule() -{ - if (!bModuleInitialized) - return; - - for (int i = 0; i < arEvents.getCount(); i++) - UnhookEvent(arEvents[i]); - - mir_free(cli.clcProto); - WindowList_Destroy(hClcWindowList); hClcWindowList = NULL; - - FreeDisplayNameCache(); - - UninitCustomMenus(); - UnitGenMenu(); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// default contact list control window procedure - -LRESULT CALLBACK fnContactListControlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - ClcGroup *group; - ClcContact *contact; - DWORD hitFlags; - int hit; - - ClcData *dat = (struct ClcData *) GetWindowLongPtr(hwnd, 0); - if (msg >= CLM_FIRST && msg < CLM_LAST) - return cli.pfnProcessExternalMessages(hwnd, dat, msg, wParam, lParam); - - switch (msg) { - case WM_CREATE: - WindowList_Add(hClcWindowList, hwnd, NULL); - cli.pfnRegisterFileDropping(hwnd); - if (dat == NULL) { - dat = (struct ClcData *) mir_calloc(sizeof(struct ClcData)); - SetWindowLongPtr(hwnd, 0, (LONG_PTR) dat); - } - { - for (int i=0; i <= FONTID_MAX; i++) - dat->fontInfo[i].changed = 1; - } - dat->selection = -1; - dat->iconXSpace = 20; - dat->checkboxSize = 13; - dat->dragAutoScrollHeight = 30; - dat->iDragItem = -1; - dat->iInsertionMark = -1; - dat->insertionMarkHitHeight = 5; - dat->iHotTrack = -1; - dat->infoTipTimeout = db_get_w(NULL, "CLC", "InfoTipHoverTime", 750); - dat->extraColumnSpacing = 20; - dat->list.cl.increment = 30; - dat->needsResort = 1; - cli.pfnLoadClcOptions(hwnd, dat, TRUE); - if (!IsWindowVisible(hwnd)) - SetTimer(hwnd, TIMERID_REBUILDAFTER, 10, NULL); - else { - cli.pfnRebuildEntireList(hwnd, dat); - NMCLISTCONTROL nm; - nm.hdr.code = CLN_LISTREBUILT; - nm.hdr.hwndFrom = hwnd; - nm.hdr.idFrom = GetDlgCtrlID(hwnd); - SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm); - } - break; - - case INTM_SCROLLBARCHANGED: - if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_CONTACTLIST) { - if (dat->noVScrollbar) - ShowScrollBar(hwnd, SB_VERT, FALSE); - else - cli.pfnRecalcScrollBar(hwnd, dat); - } - break; - - case INTM_RELOADOPTIONS: - cli.pfnLoadClcOptions(hwnd, dat, FALSE); - cli.pfnSaveStateAndRebuildList(hwnd, dat); - break; - - case WM_THEMECHANGED: - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - break; - - case WM_SIZE: - cli.pfnEndRename(hwnd, dat, 1); - KillTimer(hwnd, TIMERID_INFOTIP); - KillTimer(hwnd, TIMERID_RENAME); - cli.pfnRecalcScrollBar(hwnd, dat); - { - // creating imagelist containing blue line for highlight - RECT rc; - GetClientRect(hwnd, &rc); - if (rc.right == 0) - break; - - rc.bottom = dat->rowHeight; - HDC hdc = GetDC(hwnd); - int depth = GetDeviceCaps(hdc, BITSPIXEL); - if (depth < 16) - depth = 16; - HBITMAP hBmp = CreateBitmap(rc.right, rc.bottom, 1, depth, NULL); - HBITMAP hBmpMask = CreateBitmap(rc.right, rc.bottom, 1, 1, NULL); - HDC hdcMem = CreateCompatibleDC(hdc); - HBITMAP hoBmp = (HBITMAP) SelectObject(hdcMem, hBmp); - HBRUSH hBrush = CreateSolidBrush(dat->useWindowsColours ? GetSysColor(COLOR_HIGHLIGHT) : dat->selBkColour); - FillRect(hdcMem, &rc, hBrush); - DeleteObject(hBrush); - - HBITMAP hoMaskBmp = (HBITMAP)SelectObject(hdcMem, hBmpMask); - FillRect(hdcMem, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); - SelectObject(hdcMem, hoMaskBmp); - SelectObject(hdcMem, hoBmp); - DeleteDC(hdcMem); - ReleaseDC(hwnd, hdc); - if (dat->himlHighlight) - ImageList_Destroy(dat->himlHighlight); - dat->himlHighlight = ImageList_Create(rc.right, rc.bottom, ILC_COLOR32 | ILC_MASK, 1, 1); - ImageList_Add(dat->himlHighlight, hBmp, hBmpMask); - DeleteObject(hBmpMask); - DeleteObject(hBmp); - } - break; - - case WM_SYSCOLORCHANGE: - SendMessage(hwnd, WM_SIZE, 0, 0); - break; - - case WM_GETDLGCODE: - if (lParam) { - MSG *msg = (MSG *) lParam; - if (msg->message == WM_KEYDOWN) { - if (msg->wParam == VK_TAB) - return 0; - if (msg->wParam == VK_ESCAPE && dat->hwndRenameEdit == NULL && dat->szQuickSearch[0] == 0) - return 0; - } - if (msg->message == WM_CHAR) { - if (msg->wParam == '\t') - return 0; - if (msg->wParam == 27 && dat->hwndRenameEdit == NULL && dat->szQuickSearch[0] == 0) - return 0; - } - } - return DLGC_WANTMESSAGE; - - case WM_KILLFOCUS: - KillTimer(hwnd, TIMERID_INFOTIP); - KillTimer(hwnd, TIMERID_RENAME); - case WM_SETFOCUS: - case WM_ENABLE: - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - break; - - case WM_GETFONT: - return (LRESULT)dat->fontInfo[FONTID_CONTACTS].hFont; - - case INTM_GROUPSCHANGED: - { - DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING *) lParam; - if (dbcws->value.type == DBVT_ASCIIZ || dbcws->value.type == DBVT_UTF8) { - int groupId = atoi(dbcws->szSetting) + 1; - TCHAR szFullName[512]; - int i, eq; - //check name of group and ignore message if just being expanded/collapsed - if (cli.pfnFindItem(hwnd, dat, groupId | HCONTACT_ISGROUP, &contact, &group, NULL)) { - mir_tstrcpy(szFullName, contact->szText); - while (group->parent) { - for (i=0; i < group->parent->cl.count; i++) - if (group->parent->cl.items[i]->group == group) - break; - if (i == group->parent->cl.count) { - szFullName[0] = '\0'; - break; - } - group = group->parent; - size_t nameLen = mir_tstrlen(group->cl.items[i]->szText); - if (mir_tstrlen(szFullName) + 1 + nameLen > SIZEOF(szFullName)) { - szFullName[0] = '\0'; - break; - } - memmove(szFullName + 1 + nameLen, szFullName, sizeof(TCHAR)*(mir_tstrlen(szFullName) + 1)); - memcpy(szFullName, group->cl.items[i]->szText, sizeof(TCHAR)*nameLen); - szFullName[nameLen] = '\\'; - } - - if (dbcws->value.type == DBVT_ASCIIZ) { - WCHAR* wszGrpName = mir_a2u(dbcws->value.pszVal+1); - eq = !mir_tstrcmp(szFullName, wszGrpName); - mir_free(wszGrpName); - } - else { - char* szGrpName = NEWSTR_ALLOCA(dbcws->value.pszVal+1); - WCHAR* wszGrpName; - Utf8Decode(szGrpName, &wszGrpName); - eq = !mir_tstrcmp(szFullName, wszGrpName); - mir_free(wszGrpName); - } - if (eq && (contact->group->hideOffline != 0) == ((dbcws->value.pszVal[0] & GROUPF_HIDEOFFLINE) != 0)) - break; //only expanded has changed: no action reqd - } - } - cli.pfnSaveStateAndRebuildList(hwnd, dat); - } - break; - - case INTM_NAMEORDERCHANGED: - cli.pfnInitAutoRebuild(hwnd); - break; - - case INTM_CONTACTADDED: - cli.pfnAddContactToTree(hwnd, dat, wParam, 1, 1); - cli.pfnNotifyNewContact(hwnd, wParam); - SortClcByTimer(hwnd); - break; - - case INTM_CONTACTDELETED: - cli.pfnDeleteItemFromTree(hwnd, wParam); - SortClcByTimer(hwnd); - break; - - case INTM_HIDDENCHANGED: - { - DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING *) lParam; - if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_SHOWHIDDEN) - break; - if (dbcws->value.type == DBVT_DELETED || dbcws->value.bVal == 0) { - if (cli.pfnFindItem(hwnd, dat, wParam, NULL, NULL, NULL)) - break; - cli.pfnAddContactToTree(hwnd, dat, wParam, 1, 1); - cli.pfnNotifyNewContact(hwnd, wParam); - } - else cli.pfnDeleteItemFromTree(hwnd, wParam); - - dat->needsResort = 1; - SortClcByTimer(hwnd); - } - break; - - case INTM_GROUPCHANGED: - { - WORD iExtraImage[EXTRA_ICON_COUNT]; - BYTE flags = 0; - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - memset(iExtraImage, 0xFF, sizeof(iExtraImage)); - else { - memcpy(iExtraImage, contact->iExtraImage, sizeof(iExtraImage)); - flags = contact->flags; - } - cli.pfnDeleteItemFromTree(hwnd, wParam); - if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_SHOWHIDDEN || !db_get_b(wParam, "CList", "Hidden", 0)) { - NMCLISTCONTROL nm; - cli.pfnAddContactToTree(hwnd, dat, wParam, 1, 1); - if (cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) { - memcpy(contact->iExtraImage, iExtraImage, sizeof(iExtraImage)); - if (flags & CONTACTF_CHECKED) - contact->flags |= CONTACTF_CHECKED; - } - nm.hdr.code = CLN_CONTACTMOVED; - nm.hdr.hwndFrom = hwnd; - nm.hdr.idFrom = GetDlgCtrlID(hwnd); - nm.flags = 0; - nm.hItem = (HANDLE)wParam; - SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm); - dat->needsResort = 1; - } - } - SetTimer(hwnd, TIMERID_REBUILDAFTER, 1, NULL); - break; - - case INTM_ICONCHANGED: - { - int recalcScrollBar = 0, shouldShow; - WORD status; - MCONTACT hSelItem = NULL; - ClcContact *selcontact = NULL; - - char *szProto = GetContactProto(wParam); - if (szProto == NULL) - status = ID_STATUS_OFFLINE; - else - status = db_get_w(wParam, szProto, "Status", ID_STATUS_OFFLINE); - - // this means an offline msg is flashing, so the contact should be shown - DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE); - shouldShow = (style & CLS_SHOWHIDDEN || !db_get_b(wParam, "CList", "Hidden", 0)) - && (!cli.pfnIsHiddenMode(dat, status) || CallService(MS_CLIST_GETCONTACTICON, wParam, 0) != lParam); - - contact = NULL; - group = NULL; - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, &group, NULL)) { - if (shouldShow && CallService(MS_DB_CONTACT_IS, wParam, 0)) { - if (dat->selection >= 0 && cli.pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) != -1) - hSelItem = (MCONTACT)cli.pfnContactToHItem(selcontact); - cli.pfnAddContactToTree(hwnd, dat, wParam, (style & CLS_CONTACTLIST) == 0, 0); - recalcScrollBar = 1; - cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL); - if (contact) { - contact->iImage = (WORD) lParam; - cli.pfnNotifyNewContact(hwnd, wParam); - dat->needsResort = 1; - } - } - } - else { // item in list already - if (contact->iImage == (WORD) lParam) - break; - if (!shouldShow && !(style & CLS_NOHIDEOFFLINE) && (style & CLS_HIDEOFFLINE || group->hideOffline)) { - if (dat->selection >= 0 && cli.pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) != -1) - hSelItem = (MCONTACT)cli.pfnContactToHItem(selcontact); - cli.pfnRemoveItemFromGroup(hwnd, group, contact, (style & CLS_CONTACTLIST) == 0); - recalcScrollBar = 1; - } - else { - contact->iImage = (WORD) lParam; - if (!cli.pfnIsHiddenMode(dat, status)) - contact->flags |= CONTACTF_ONLINE; - else - contact->flags &= ~CONTACTF_ONLINE; - } - dat->needsResort = 1; - } - if (hSelItem) { - ClcGroup *selgroup; - if (cli.pfnFindItem(hwnd, dat, hSelItem, &selcontact, &selgroup, NULL)) - dat->selection = cli.pfnGetRowsPriorTo(&dat->list, selgroup, List_IndexOf((SortedList*)&selgroup->cl, selcontact)); - else - dat->selection = -1; - } - SortClcByTimer(hwnd); - } - break; - - case INTM_NAMECHANGED: - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - break; - - mir_tstrncpy(contact->szText, cli.pfnGetContactDisplayName(wParam, 0), SIZEOF(contact->szText)); - dat->needsResort = 1; - SortClcByTimer(hwnd); - break; - - case INTM_PROTOCHANGED: - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - break; - - contact->proto = GetContactProto(wParam); - cli.pfnInvalidateDisplayNameCacheEntry(wParam); - mir_tstrncpy(contact->szText, cli.pfnGetContactDisplayName(wParam, 0), SIZEOF(contact->szText)); - SortClcByTimer(hwnd); - break; - - case INTM_NOTONLISTCHANGED: - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - break; - - if (contact->type == CLCIT_CONTACT) { - DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING *) lParam; - if (dbcws->value.type == DBVT_DELETED || dbcws->value.bVal == 0) - contact->flags &= ~CONTACTF_NOTONLIST; - else - contact->flags |= CONTACTF_NOTONLIST; - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - } - break; - - case INTM_INVALIDATE: - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - break; - - case INTM_APPARENTMODECHANGED: - if (cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) { - char *szProto = GetContactProto(wParam); - if (szProto == NULL) - break; - - WORD apparentMode = db_get_w(wParam, szProto, "ApparentMode", 0); - contact->flags &= ~(CONTACTF_INVISTO | CONTACTF_VISTO); - if (apparentMode == ID_STATUS_OFFLINE) - contact->flags |= CONTACTF_INVISTO; - else if (apparentMode == ID_STATUS_ONLINE) - contact->flags |= CONTACTF_VISTO; - else if (apparentMode) - contact->flags |= CONTACTF_VISTO | CONTACTF_INVISTO; - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - } - break; - - case INTM_SETINFOTIPHOVERTIME: - dat->infoTipTimeout = wParam; - break; - - case INTM_IDLECHANGED: - if (cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) { - char *szProto = GetContactProto(wParam); - if (szProto == NULL) - break; - contact->flags &= ~CONTACTF_IDLE; - if (db_get_dw(wParam, szProto, "IdleTS", 0)) - contact->flags |= CONTACTF_IDLE; - - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - } - break; - - case WM_PRINTCLIENT: - cli.pfnPaintClc(hwnd, dat, (HDC) wParam, NULL); - break; - - case WM_NCPAINT: - if (wParam != 1) { - POINT ptTopLeft = { 0, 0 }; - HRGN hClientRgn; - ClientToScreen(hwnd, &ptTopLeft); - hClientRgn = CreateRectRgn(0, 0, 1, 1); - CombineRgn(hClientRgn, (HRGN) wParam, NULL, RGN_COPY); - OffsetRgn(hClientRgn, -ptTopLeft.x, -ptTopLeft.y); - InvalidateRgn(hwnd, hClientRgn, FALSE); - DeleteObject(hClientRgn); - UpdateWindow(hwnd); - } - break; - - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC hdc = BeginPaint(hwnd, &ps); - /* we get so many cli.pfnInvalidateRect()'s that there is no point painting, - Windows in theory shouldn't queue up WM_PAINTs in this case but it does so - we'll just ignore them */ - if (IsWindowVisible(hwnd)) - cli.pfnPaintClc(hwnd, dat, hdc, &ps.rcPaint); - EndPaint(hwnd, &ps); - } - break; - - case WM_VSCROLL: - cli.pfnEndRename(hwnd, dat, 1); - cli.pfnHideInfoTip(hwnd, dat); - KillTimer(hwnd, TIMERID_INFOTIP); - KillTimer(hwnd, TIMERID_RENAME); - { - int desty = dat->yScroll, noSmooth = 0; - - RECT clRect; - GetClientRect(hwnd, &clRect); - switch (LOWORD(wParam)) { - case SB_LINEUP: desty -= dat->rowHeight; break; - case SB_LINEDOWN: desty += dat->rowHeight; break; - case SB_PAGEUP: desty -= clRect.bottom - dat->rowHeight; break; - case SB_PAGEDOWN: desty += clRect.bottom - dat->rowHeight; break; - case SB_BOTTOM: desty = 0x7FFFFFFF; break; - case SB_TOP: desty = 0; break; - case SB_THUMBTRACK: desty = HIWORD(wParam); noSmooth = 1; break; //noone has more than 4000 contacts, right? - default: return 0; - } - cli.pfnScrollTo(hwnd, dat, desty, noSmooth); - } - break; - - case WM_MOUSEWHEEL: - cli.pfnEndRename(hwnd, dat, 1); - cli.pfnHideInfoTip(hwnd, dat); - KillTimer(hwnd, TIMERID_INFOTIP); - KillTimer(hwnd, TIMERID_RENAME); - { - UINT scrollLines; - if (!SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, FALSE)) - scrollLines = 3; - cli.pfnScrollTo(hwnd, dat, dat->yScroll - (short) HIWORD(wParam) * dat->rowHeight * (signed) scrollLines / WHEEL_DELTA, 0); - } - return 0; - - case WM_KEYDOWN: - { - int selMoved = 0; - int changeGroupExpand = 0; - int pageSize; - cli.pfnHideInfoTip(hwnd, dat); - KillTimer(hwnd, TIMERID_INFOTIP); - KillTimer(hwnd, TIMERID_RENAME); - if (CallService(MS_CLIST_MENUPROCESSHOTKEY, wParam, MPCF_CONTACTMENU)) - break; - { - RECT clRect; - GetClientRect(hwnd, &clRect); - pageSize = clRect.bottom / dat->rowHeight; - } - switch (wParam) { - case VK_DOWN: dat->selection++; selMoved = 1; break; - case VK_UP: dat->selection--; selMoved = 1; break; - case VK_PRIOR: dat->selection -= pageSize; selMoved = 1; break; - case VK_NEXT: dat->selection += pageSize; selMoved = 1; break; - case VK_HOME: dat->selection = 0; selMoved = 1; break; - case VK_END: dat->selection = cli.pfnGetGroupContentsCount(&dat->list, 1) - 1; selMoved = 1; break; - case VK_LEFT: changeGroupExpand = 1; break; - case VK_RIGHT: changeGroupExpand = 2; break; - case VK_RETURN: - cli.pfnDoSelectionDefaultAction(hwnd, dat); - dat->szQuickSearch[0] = 0; - if (dat->filterSearch) - cli.pfnSaveStateAndRebuildList(hwnd, dat); - return 0; - case VK_F2: cli.pfnBeginRenameSelection(hwnd, dat); return 0; - case VK_DELETE: cli.pfnDeleteFromContactList(hwnd, dat); return 0; - default: - { - NMKEY nmkey; - nmkey.hdr.hwndFrom = hwnd; - nmkey.hdr.idFrom = GetDlgCtrlID(hwnd); - nmkey.hdr.code = NM_KEYDOWN; - nmkey.nVKey = wParam; - nmkey.uFlags = HIWORD(lParam); - if (SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nmkey)) - return 0; - } - } - if (changeGroupExpand) { - if (!dat->filterSearch) - dat->szQuickSearch[0] = 0; - hit = cli.pfnGetRowByIndex(dat, dat->selection, &contact, &group); - if (hit != -1) { - if (changeGroupExpand == 1 && contact->type == CLCIT_CONTACT) { - if (group == &dat->list) - return 0; - dat->selection = cli.pfnGetRowsPriorTo(&dat->list, group, -1); - selMoved = 1; - } - else { - if (contact->type == CLCIT_GROUP) - cli.pfnSetGroupExpand(hwnd, dat, contact->group, changeGroupExpand == 2); - return 0; - } - } - else - return 0; - } - if (selMoved) { - if (!dat->filterSearch) - dat->szQuickSearch[0] = 0; - if (dat->selection >= cli.pfnGetGroupContentsCount(&dat->list, 1)) - dat->selection = cli.pfnGetGroupContentsCount(&dat->list, 1) - 1; - if (dat->selection < 0) - dat->selection = 0; - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - cli.pfnEnsureVisible(hwnd, dat, dat->selection, 0); - UpdateWindow(hwnd); - return 0; - } - } - break; - - case WM_CHAR: - cli.pfnHideInfoTip(hwnd, dat); - KillTimer(hwnd, TIMERID_INFOTIP); - KillTimer(hwnd, TIMERID_RENAME); - if (wParam == 27) //escape - dat->szQuickSearch[0] = 0; - else if (wParam == '\b' && dat->szQuickSearch[0]) - dat->szQuickSearch[mir_tstrlen(dat->szQuickSearch) - 1] = '\0'; - else if (wParam < ' ') - break; - else if (wParam == ' ' && dat->szQuickSearch[0] == '\0' && GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_CHECKBOXES) { - NMCLISTCONTROL nm; - if (cli.pfnGetRowByIndex(dat, dat->selection, &contact, NULL) == -1) - break; - if (contact->type != CLCIT_CONTACT) - break; - contact->flags ^= CONTACTF_CHECKED; - if (contact->type == CLCIT_GROUP) - cli.pfnSetGroupChildCheckboxes(contact->group, contact->flags & CONTACTF_CHECKED); - cli.pfnRecalculateGroupCheckboxes(hwnd, dat); - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - nm.hdr.code = CLN_CHECKCHANGED; - nm.hdr.hwndFrom = hwnd; - nm.hdr.idFrom = GetDlgCtrlID(hwnd); - nm.flags = 0; - nm.hItem = cli.pfnContactToItemHandle(contact, &nm.flags); - SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm); - } - else { - TCHAR szNew[2]; - szNew[0] = (TCHAR) wParam; - szNew[1] = '\0'; - if (mir_tstrlen(dat->szQuickSearch) >= SIZEOF(dat->szQuickSearch) - 1) { - MessageBeep(MB_OK); - break; - } - mir_tstrcat(dat->szQuickSearch, szNew); - } - - if (dat->filterSearch) - cli.pfnSaveStateAndRebuildList(hwnd, dat); - - if (dat->szQuickSearch[0]) { - int index; - index = cli.pfnFindRowByText(hwnd, dat, dat->szQuickSearch, 1); - if (index != -1) - dat->selection = index; - else { - MessageBeep(MB_OK); - dat->szQuickSearch[ mir_tstrlen(dat->szQuickSearch) - 1] = '\0'; - cli.pfnSaveStateAndRebuildList(hwnd, dat); - } - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - cli.pfnEnsureVisible(hwnd, dat, dat->selection, 0); - } - else - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - break; - - case WM_SYSKEYDOWN: - cli.pfnEndRename(hwnd, dat, 1); - cli.pfnHideInfoTip(hwnd, dat); - KillTimer(hwnd, TIMERID_INFOTIP); - KillTimer(hwnd, TIMERID_RENAME); - dat->iHotTrack = -1; - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - ReleaseCapture(); - if (wParam == VK_F10 && GetKeyState(VK_SHIFT) & 0x8000) - break; - SendMessage(GetParent(hwnd), msg, wParam, lParam); - return 0; - - case WM_TIMER: - switch(wParam) { - case TIMERID_RENAME: - cli.pfnBeginRenameSelection(hwnd, dat); - break; - case TIMERID_DRAGAUTOSCROLL: - cli.pfnScrollTo(hwnd, dat, dat->yScroll + dat->dragAutoScrolling * dat->rowHeight * 2, 0); - break; - case TIMERID_INFOTIP: - { - CLCINFOTIP it; - RECT clRect; - POINT ptClientOffset = { 0 }; - - KillTimer(hwnd, wParam); - GetCursorPos(&it.ptCursor); - ScreenToClient(hwnd, &it.ptCursor); - if (it.ptCursor.x != dat->ptInfoTip.x || it.ptCursor.y != dat->ptInfoTip.y) - break; - GetClientRect(hwnd, &clRect); - it.rcItem.left = 0; - it.rcItem.right = clRect.right; - hit = cli.pfnHitTest(hwnd, dat, it.ptCursor.x, it.ptCursor.y, &contact, NULL, NULL); - if (hit == -1) - break; - if (contact->type != CLCIT_GROUP && contact->type != CLCIT_CONTACT) - break; - ClientToScreen(hwnd, &it.ptCursor); - ClientToScreen(hwnd, &ptClientOffset); - it.isTreeFocused = GetFocus() == hwnd; - it.rcItem.top = cli.pfnGetRowTopY(dat, hit) - dat->yScroll; - it.rcItem.bottom = it.rcItem.top + cli.pfnGetRowHeight(dat, hit); - OffsetRect(&it.rcItem, ptClientOffset.x, ptClientOffset.y); - it.isGroup = contact->type == CLCIT_GROUP; - it.hItem = (contact->type == CLCIT_GROUP) ? (HANDLE)contact->groupId : (HANDLE)contact->hContact; - it.cbSize = sizeof(it); - dat->hInfoTipItem = cli.pfnContactToHItem(contact); - NotifyEventHooks(hShowInfoTipEvent, 0, (LPARAM) & it); - break; - } - case TIMERID_REBUILDAFTER: - KillTimer(hwnd, TIMERID_REBUILDAFTER); - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - cli.pfnSaveStateAndRebuildList(hwnd, dat); - break; - - case TIMERID_DELAYEDRESORTCLC: - KillTimer(hwnd, TIMERID_DELAYEDRESORTCLC); - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - cli.pfnSortCLC(hwnd, dat, 1); - cli.pfnRecalcScrollBar(hwnd, dat); - break; - } - break; - - case WM_MBUTTONDOWN: - case WM_LBUTTONDOWN: - if (GetFocus() != hwnd) - SetFocus(hwnd); - - cli.pfnHideInfoTip(hwnd, dat); - KillTimer(hwnd, TIMERID_INFOTIP); - KillTimer(hwnd, TIMERID_RENAME); - cli.pfnEndRename(hwnd, dat, 1); - dat->ptDragStart.x = (short) LOWORD(lParam); - dat->ptDragStart.y = (short) HIWORD(lParam); - if (!dat->filterSearch) - dat->szQuickSearch[0] = 0; - - hit = cli.pfnHitTest(hwnd, dat, (short) LOWORD(lParam), (short) HIWORD(lParam), &contact, &group, &hitFlags); - if (hit != -1) { - if (hit == dat->selection && hitFlags & CLCHT_ONITEMLABEL && dat->exStyle & CLS_EX_EDITLABELS) { - SetCapture(hwnd); - dat->iDragItem = dat->selection; - dat->dragStage = DRAGSTAGE_NOTMOVED | DRAGSTAGEF_MAYBERENAME; - dat->dragAutoScrolling = 0; - break; - } - } - - if (hit != -1 && contact->type == CLCIT_GROUP) { - if (hitFlags & CLCHT_ONITEMICON) { - ClcGroup *selgroup; - ClcContact *selcontact; - dat->selection = cli.pfnGetRowByIndex(dat, dat->selection, &selcontact, &selgroup); - cli.pfnSetGroupExpand(hwnd, dat, contact->group, -1); - if (dat->selection != -1) { - dat->selection = - cli.pfnGetRowsPriorTo(&dat->list, selgroup, List_IndexOf((SortedList*)&selgroup->cl, selcontact)); - if (dat->selection == -1) - dat->selection = cli.pfnGetRowsPriorTo(&dat->list, contact->group, -1); - } - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - UpdateWindow(hwnd); - break; - } - } - if (hit != -1 && hitFlags & CLCHT_ONITEMCHECK) { - NMCLISTCONTROL nm; - contact->flags ^= CONTACTF_CHECKED; - if (contact->type == CLCIT_GROUP) - cli.pfnSetGroupChildCheckboxes(contact->group, contact->flags & CONTACTF_CHECKED); - cli.pfnRecalculateGroupCheckboxes(hwnd, dat); - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - nm.hdr.code = CLN_CHECKCHANGED; - nm.hdr.hwndFrom = hwnd; - nm.hdr.idFrom = GetDlgCtrlID(hwnd); - nm.flags = 0; - nm.hItem = cli.pfnContactToItemHandle(contact, &nm.flags); - SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm); - } - if (!(hitFlags & (CLCHT_ONITEMICON | CLCHT_ONITEMLABEL | CLCHT_ONITEMCHECK))) { - NMCLISTCONTROL nm; - nm.hdr.code = NM_CLICK; - nm.hdr.hwndFrom = hwnd; - nm.hdr.idFrom = GetDlgCtrlID(hwnd); - nm.flags = 0; - if (hit == -1) - nm.hItem = NULL; - else - nm.hItem = cli.pfnContactToItemHandle(contact, &nm.flags); - nm.iColumn = hitFlags & CLCHT_ONITEMEXTRA ? HIBYTE(HIWORD(hitFlags)) : -1; - nm.pt = dat->ptDragStart; - SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm); - } - if (hitFlags & (CLCHT_ONITEMCHECK | CLCHT_ONITEMEXTRA)) - break; - dat->selection = hit; - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - if (dat->selection != -1) - cli.pfnEnsureVisible(hwnd, dat, hit, 0); - UpdateWindow(hwnd); - if (dat->selection != -1 && (contact->type == CLCIT_CONTACT || contact->type == CLCIT_GROUP) - && !(hitFlags & (CLCHT_ONITEMEXTRA | CLCHT_ONITEMCHECK))) { - SetCapture(hwnd); - dat->iDragItem = dat->selection; - dat->dragStage = DRAGSTAGE_NOTMOVED; - dat->dragAutoScrolling = 0; - } - break; - - case WM_MOUSEMOVE: - if (dat->iDragItem == -1) { - int iOldHotTrack = dat->iHotTrack; - if (dat->hwndRenameEdit != NULL) - break; - if (GetKeyState(VK_MENU) & 0x8000 || GetKeyState(VK_F10) & 0x8000) - break; - dat->iHotTrack = cli.pfnHitTest(hwnd, dat, (short) LOWORD(lParam), (short) HIWORD(lParam), NULL, NULL, NULL); - if (iOldHotTrack != dat->iHotTrack) { - if (iOldHotTrack == -1) - SetCapture(hwnd); - else if (dat->iHotTrack == -1) - ReleaseCapture(); - if (dat->exStyle & CLS_EX_TRACKSELECT) { - cli.pfnInvalidateItem(hwnd, dat, iOldHotTrack); - cli.pfnInvalidateItem(hwnd, dat, dat->iHotTrack); - } - cli.pfnHideInfoTip(hwnd, dat); - } - KillTimer(hwnd, TIMERID_INFOTIP); - if (wParam == 0 && dat->hInfoTipItem == NULL) { - dat->ptInfoTip.x = (short) LOWORD(lParam); - dat->ptInfoTip.y = (short) HIWORD(lParam); - SetTimer(hwnd, TIMERID_INFOTIP, dat->infoTipTimeout, NULL); - } - break; - } - if ((dat->dragStage & DRAGSTAGEM_STAGE) == DRAGSTAGE_NOTMOVED && !(dat->exStyle & CLS_EX_DISABLEDRAGDROP)) { - if (abs((short) LOWORD(lParam) - dat->ptDragStart.x) >= GetSystemMetrics(SM_CXDRAG) - || abs((short) HIWORD(lParam) - dat->ptDragStart.y) >= GetSystemMetrics(SM_CYDRAG)) - dat->dragStage = (dat->dragStage & ~DRAGSTAGEM_STAGE) | DRAGSTAGE_ACTIVE; - } - if ((dat->dragStage & DRAGSTAGEM_STAGE) == DRAGSTAGE_ACTIVE) { - HCURSOR hNewCursor; - RECT clRect; - POINT pt; - int target; - - GetClientRect(hwnd, &clRect); - pt.x = (short) LOWORD(lParam); - pt.y = (short) HIWORD(lParam); - hNewCursor = LoadCursor(NULL, IDC_NO); - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - if (dat->dragAutoScrolling) { - KillTimer(hwnd, TIMERID_DRAGAUTOSCROLL); - dat->dragAutoScrolling = 0; - } - target = cli.pfnGetDropTargetInformation(hwnd, dat, pt); - if (dat->dragStage & DRAGSTAGEF_OUTSIDE && target != DROPTARGET_OUTSIDE) { - - cli.pfnGetRowByIndex(dat, dat->iDragItem, &contact, NULL); - NMCLISTCONTROL nm; - nm.hdr.code = CLN_DRAGSTOP; - nm.hdr.hwndFrom = hwnd; - nm.hdr.idFrom = GetDlgCtrlID(hwnd); - nm.flags = 0; - nm.hItem = cli.pfnContactToItemHandle(contact, &nm.flags); - SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm); - dat->dragStage &= ~DRAGSTAGEF_OUTSIDE; - } - switch (target) { - case DROPTARGET_ONSELF: - case DROPTARGET_ONCONTACT: - break; - case DROPTARGET_ONGROUP: - hNewCursor = LoadCursor(cli.hInst, MAKEINTRESOURCE(IDC_DROPUSER)); - break; - case DROPTARGET_INSERTION: - hNewCursor = LoadCursor(cli.hInst, MAKEINTRESOURCE(IDC_DROPUSER)); - break; - case DROPTARGET_OUTSIDE: - { - NMCLISTCONTROL nm; - - if (pt.x >= 0 && pt.x < clRect.right - && ((pt.y < 0 && pt.y > -dat->dragAutoScrollHeight) - || (pt.y >= clRect.bottom && pt.y < clRect.bottom + dat->dragAutoScrollHeight))) { - if (!dat->dragAutoScrolling) { - if (pt.y < 0) - dat->dragAutoScrolling = -1; - else - dat->dragAutoScrolling = 1; - SetTimer(hwnd, TIMERID_DRAGAUTOSCROLL, dat->scrollTime, NULL); - } - SendMessage(hwnd, WM_TIMER, TIMERID_DRAGAUTOSCROLL, 0); - } - - dat->dragStage |= DRAGSTAGEF_OUTSIDE; - cli.pfnGetRowByIndex(dat, dat->iDragItem, &contact, NULL); - nm.hdr.code = CLN_DRAGGING; - nm.hdr.hwndFrom = hwnd; - nm.hdr.idFrom = GetDlgCtrlID(hwnd); - nm.flags = 0; - nm.hItem = cli.pfnContactToItemHandle(contact, &nm.flags); - nm.pt = pt; - if (SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm)) - return 0; - } - break; - - default: - cli.pfnGetRowByIndex(dat, dat->iDragItem, NULL, &group); - if (group->parent) - hNewCursor = LoadCursor(cli.hInst, MAKEINTRESOURCE(IDC_DROPUSER)); - break; - } - SetCursor(hNewCursor); - } - break; - - case WM_LBUTTONUP: - if (dat->iDragItem == -1) - break; - - SetCursor((HCURSOR) GetClassLongPtr(hwnd, GCLP_HCURSOR)); - if (dat->exStyle & CLS_EX_TRACKSELECT) { - dat->iHotTrack = cli.pfnHitTest(hwnd, dat, (short) LOWORD(lParam), (short) HIWORD(lParam), NULL, NULL, NULL); - if (dat->iHotTrack == -1) - ReleaseCapture(); - } - else ReleaseCapture(); - KillTimer(hwnd, TIMERID_DRAGAUTOSCROLL); - if (dat->dragStage == (DRAGSTAGE_NOTMOVED | DRAGSTAGEF_MAYBERENAME)) - SetTimer(hwnd, TIMERID_RENAME, GetDoubleClickTime(), NULL); - else if ((dat->dragStage & DRAGSTAGEM_STAGE) == DRAGSTAGE_ACTIVE) { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - int target = cli.pfnGetDropTargetInformation(hwnd, dat, pt); - switch (target) { - case DROPTARGET_ONSELF: - case DROPTARGET_ONCONTACT: - break; - - case DROPTARGET_ONGROUP: - { - ClcContact *contactn, *contacto; - cli.pfnGetRowByIndex(dat, dat->selection, &contactn, NULL); - cli.pfnGetRowByIndex(dat, dat->iDragItem, &contacto, NULL); - if (contacto->type == CLCIT_CONTACT) //dropee is a contact - CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)contacto->hContact, contactn->groupId); - else if (contacto->type == CLCIT_GROUP) { //dropee is a group - TCHAR szNewName[120]; - mir_sntprintf(szNewName, SIZEOF(szNewName), _T("%s\\%s"), cli.pfnGetGroupName(contactn->groupId, NULL), contacto->szText); - cli.pfnRenameGroup(contacto->groupId, szNewName); - } - } - break; - - case DROPTARGET_INSERTION: - cli.pfnGetRowByIndex(dat, dat->iDragItem, &contact, NULL); - { - ClcContact *destcontact; - ClcGroup *destgroup; - if (cli.pfnGetRowByIndex(dat, dat->iInsertionMark, &destcontact, &destgroup) == -1 || destgroup != contact->group->parent) - CallService(MS_CLIST_GROUPMOVEBEFORE, contact->groupId, 0); - else { - if (destcontact->type == CLCIT_GROUP) - destgroup = destcontact->group; - CallService(MS_CLIST_GROUPMOVEBEFORE, contact->groupId, destgroup->groupId); - } - } - break; - case DROPTARGET_OUTSIDE: - cli.pfnGetRowByIndex(dat, dat->iDragItem, &contact, NULL); - { - NMCLISTCONTROL nm; - nm.hdr.code = CLN_DROPPED; - nm.hdr.hwndFrom = hwnd; - nm.hdr.idFrom = GetDlgCtrlID(hwnd); - nm.flags = 0; - nm.hItem = cli.pfnContactToItemHandle(contact, &nm.flags); - nm.pt = pt; - SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm); - } - break; - default: - cli.pfnGetRowByIndex(dat, dat->iDragItem, &contact, &group); - if (!group->parent) - break; - if (contact->type == CLCIT_GROUP) { //dropee is a group - TCHAR szNewName[120]; - mir_tstrncpy(szNewName, contact->szText, SIZEOF(szNewName)); - cli.pfnRenameGroup(contact->groupId, szNewName); - } - else if (contact->type == CLCIT_CONTACT) //dropee is a contact - CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)contact->hContact, 0); - } - } - - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - dat->iDragItem = -1; - dat->iInsertionMark = -1; - break; - - case WM_LBUTTONDBLCLK: - ReleaseCapture(); - dat->iHotTrack = -1; - cli.pfnHideInfoTip(hwnd, dat); - KillTimer(hwnd, TIMERID_RENAME); - KillTimer(hwnd, TIMERID_INFOTIP); - - dat->selection = cli.pfnHitTest(hwnd, dat, (short)LOWORD(lParam), (short)HIWORD(lParam), &contact, NULL, &hitFlags); - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - if (dat->selection != -1) - cli.pfnEnsureVisible(hwnd, dat, dat->selection, 0); - if (!(hitFlags & (CLCHT_ONITEMICON | CLCHT_ONITEMLABEL))) - break; - - UpdateWindow(hwnd); - cli.pfnDoSelectionDefaultAction(hwnd, dat); - dat->szQuickSearch[0] = 0; - if (dat->filterSearch) - cli.pfnSaveStateAndRebuildList(hwnd, dat); - break; - - case WM_CONTEXTMENU: - cli.pfnEndRename(hwnd, dat, 1); - cli.pfnHideInfoTip(hwnd, dat); - KillTimer(hwnd, TIMERID_RENAME); - KillTimer(hwnd, TIMERID_INFOTIP); - if (GetFocus() != hwnd) - SetFocus(hwnd); - dat->iHotTrack = -1; - if (!dat->filterSearch) - dat->szQuickSearch[0] = 0; - { - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - if (pt.x == -1 && pt.y == -1) { - dat->selection = cli.pfnGetRowByIndex(dat, dat->selection, &contact, NULL); - if (dat->selection != -1) - cli.pfnEnsureVisible(hwnd, dat, dat->selection, 0); - pt.x = dat->iconXSpace + 15; - pt.y = cli.pfnGetRowTopY(dat, dat->selection) - dat->yScroll + (int)(cli.pfnGetRowHeight(dat, dat->selection) * .7); - hitFlags = (dat->selection == -1) ? CLCHT_NOWHERE : CLCHT_ONITEMLABEL; - } - else { - ScreenToClient(hwnd, &pt); - dat->selection = cli.pfnHitTest(hwnd, dat, pt.x, pt.y, &contact, NULL, &hitFlags); - } - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - if (dat->selection != -1) - cli.pfnEnsureVisible(hwnd, dat, dat->selection, 0); - UpdateWindow(hwnd); - - HMENU hMenu = NULL; - if (dat->selection != -1 && hitFlags & (CLCHT_ONITEMICON | CLCHT_ONITEMCHECK | CLCHT_ONITEMLABEL)) { - if (contact->type == CLCIT_GROUP) { - hMenu = cli.pfnBuildGroupPopupMenu(contact->group); - ClientToScreen(hwnd, &pt); - TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL); - DestroyMenu(hMenu); - return 0; - } - if (contact->type == CLCIT_CONTACT) - hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)contact->hContact, 0); - } - else { - //call parent for new group/hide offline menu - SendMessage(GetParent(hwnd), WM_CONTEXTMENU, wParam, lParam); - } - if (hMenu != NULL) { - ClientToScreen(hwnd, &pt); - TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL); - DestroyMenu(hMenu); - } - } - return 0; - - case WM_MEASUREITEM: - return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); - - case WM_DRAWITEM: - return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); - - case WM_COMMAND: - hit = cli.pfnGetRowByIndex(dat, dat->selection, &contact, NULL); - if (hit == -1) - break; - if (contact->type == CLCIT_CONTACT) - if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)contact->hContact)) - break; - switch (LOWORD(wParam)) { - case POPUP_NEWSUBGROUP: - if (contact->type != CLCIT_GROUP) - break; - SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~CLS_HIDEEMPTYGROUPS); - CallService(MS_CLIST_GROUPCREATE, contact->groupId, 0); - break; - case POPUP_RENAMEGROUP: - cli.pfnBeginRenameSelection(hwnd, dat); - break; - case POPUP_DELETEGROUP: - if (contact->type != CLCIT_GROUP) - break; - CallService(MS_CLIST_GROUPDELETE, contact->groupId, 0); - break; - case POPUP_GROUPHIDEOFFLINE: - if (contact->type != CLCIT_GROUP) - break; - CallService(MS_CLIST_GROUPSETFLAGS, contact->groupId, MAKELPARAM(contact->group->hideOffline ? 0 : GROUPF_HIDEOFFLINE, GROUPF_HIDEOFFLINE)); - break; - } - break; - - case WM_DESTROY: - cli.pfnHideInfoTip(hwnd, dat); - - for (int i = 0; i <= FONTID_MAX; i++) - if (!dat->fontInfo[i].changed) - DeleteObject(dat->fontInfo[i].hFont); - - if (dat->himlHighlight) - ImageList_Destroy(dat->himlHighlight); - if (dat->hwndRenameEdit) - DestroyWindow(dat->hwndRenameEdit); - if (dat->hBmpBackground) - DeleteObject(dat->hBmpBackground); - cli.pfnFreeGroup(&dat->list); - mir_free(dat); - cli.pfnUnregisterFileDropping(hwnd); - WindowList_Remove(hClcWindowList, hwnd); - } - return DefWindowProc(hwnd, msg, wParam, lParam); -} diff --git a/src/modules/clist/clc.h b/src/modules/clist/clc.h deleted file mode 100644 index 3a79db0804..0000000000 --- a/src/modules/clist/clc.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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. -*/ - -struct ClcContact : public ClcContactBase -{ -}; - -struct ClcData : public ClcDataBase -{ -}; - -struct ClcCacheEntry : public ClcCacheEntryBase -{ -}; - -/* clc.c */ -extern int g_IconWidth, g_IconHeight; - -void fnClcOptionsChanged(void); -void fnClcBroadcast(int msg, WPARAM wParam, LPARAM lParam); -HMENU fnBuildGroupPopupMenu(ClcGroup* group); -void fnInitAutoRebuild(HWND hWnd); - -LRESULT CALLBACK fnContactListControlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - -/* clcidents.c */ -int fnGetRowsPriorTo(ClcGroup *group, ClcGroup *subgroup, int contactIndex); -int fnFindItem(HWND hwnd, struct ClcData *dat, DWORD dwItem, ClcContact **contact, ClcGroup **subgroup, int *isVisible); -int fnGetRowByIndex(struct ClcData *dat, int testindex, ClcContact **contact, ClcGroup **subgroup); -HANDLE fnContactToHItem(ClcContact *contact); -HANDLE fnContactToItemHandle(ClcContact *contact, DWORD *nmFlags); - -/* clcitems.c */ -ClcGroup* fnAddGroup(HWND hwnd, struct ClcData *dat, const TCHAR *szName, DWORD flags, int groupId, int calcTotalMembers); -ClcGroup* fnRemoveItemFromGroup(HWND hwnd, ClcGroup *group, ClcContact *contact, int updateTotalCount); - -void fnFreeContact(ClcContact *p); -void fnFreeGroup(ClcGroup *group); -int fnAddInfoItemToGroup(ClcGroup *group, int flags, const TCHAR *pszText); -int fnAddItemToGroup(ClcGroup *group, int iAboveItem); -void fnAddContactToTree(HWND hwnd, struct ClcData *dat, MCONTACT hContact, int updateTotalCount, int checkHideOffline); -int fnAddContactToGroup(struct ClcData *dat, ClcGroup *group, MCONTACT hContact); -void fnDeleteItemFromTree(HWND hwnd, MCONTACT hItem); -void fnRebuildEntireList(HWND hwnd, struct ClcData *dat); -int fnGetGroupContentsCount(ClcGroup *group, int visibleOnly); -void fnSortCLC(HWND hwnd, struct ClcData *dat, int useInsertionSort); -void fnSaveStateAndRebuildList(HWND hwnd, struct ClcData *dat); - -/* clcmsgs.c */ -LRESULT fnProcessExternalMessages(HWND hwnd, struct ClcData *dat, UINT msg, WPARAM wParam, LPARAM lParam); - -/* clcutils.c */ -TCHAR* fnGetGroupCountsText(struct ClcData *dat, ClcContact *contact); -int fnHitTest(HWND hwnd, struct ClcData *dat, int testx, int testy, ClcContact **contact, ClcGroup **group, DWORD * flags); -void fnScrollTo(HWND hwnd, struct ClcData *dat, int desty, int noSmooth); -void fnEnsureVisible(HWND hwnd, struct ClcData *dat, int iItem, int partialOk); -void fnRecalcScrollBar(HWND hwnd, struct ClcData *dat); -void fnSetGroupExpand(HWND hwnd, struct ClcData *dat, ClcGroup *group, int newState); -void fnDoSelectionDefaultAction(HWND hwnd, struct ClcData *dat); -int fnFindRowByText(HWND hwnd, struct ClcData *dat, const TCHAR *text, int prefixOk); -void fnEndRename(HWND hwnd, struct ClcData *dat, int save); -void fnDeleteFromContactList(HWND hwnd, struct ClcData *dat); -void fnBeginRenameSelection(HWND hwnd, struct ClcData *dat); -void fnCalcEipPosition(struct ClcData *dat, ClcContact *contact, ClcGroup *group, POINT *result); -int fnGetDropTargetInformation(HWND hwnd, struct ClcData *dat, POINT pt); -int fnClcStatusToPf2(int status); -int fnIsHiddenMode(struct ClcData *dat, int status); -void fnHideInfoTip(HWND hwnd, struct ClcData *dat); -void fnNotifyNewContact(HWND hwnd, MCONTACT hContact); -DWORD fnGetDefaultExStyle(void); -void fnGetSetting(int i, LOGFONT* lf, COLORREF* colour); -void fnGetDefaultFontSetting(int i, LOGFONT* lf, COLORREF* colour); -void fnGetFontSetting(int i, LOGFONT* lf, COLORREF* colour); -void fnLoadClcOptions(HWND hwnd, struct ClcData *dat, BOOL bFirst); -void fnRecalculateGroupCheckboxes(HWND hwnd, struct ClcData *dat); -void fnSetGroupChildCheckboxes(ClcGroup *group, int checked); -void fnSetContactCheckboxes(ClcContact *cc, int checked); -void fnInvalidateItem(HWND hwnd, struct ClcData *dat, int iItem); - -int fnGetRowBottomY(struct ClcData *dat, int item); -int fnGetRowHeight(struct ClcData *dat, int item); -int fnGetRowTopY(struct ClcData *dat, int item); -int fnGetRowTotalHeight(struct ClcData *dat); -int fnRowHitTest(struct ClcData *dat, int y); - -/* clcopts.c */ -int ClcOptInit(WPARAM wParam, LPARAM lParam); -void GetFontSetting(int i, LOGFONTA *lf, COLORREF *colour); - -/* clistmenus.c */ -HGENMENU fnGetProtocolMenu(const char*); -int fnGetProtocolVisibility(const char* accName); -int fnConvertMenu(CLISTMENUITEM*, TMO_MenuItem*); -int fnGetAverageMode(int *pNetProtoCount); - -int fnGetAccountIndexByPos(int Pos); -int fnGetProtoIndexByPos(PROTOCOLDESCRIPTOR **proto, int protoCnt, int Pos); -void RebuildMenuOrder(void); - -INT_PTR MenuProcessCommand(WPARAM wParam, LPARAM lParam); - -/* clistsettings.c */ -TCHAR* fnGetContactDisplayName(MCONTACT hContact, int mode); -void fnGetDefaultFontSetting(int i, LOGFONT* lf, COLORREF * colour); -void fnInvalidateDisplayNameCacheEntry(MCONTACT hContact); - -ClcCacheEntry* fnGetCacheEntry(MCONTACT hContact); -ClcCacheEntry* fnCreateCacheItem (MCONTACT hContact); -void fnCheckCacheItem(ClcCacheEntry *p); -void fnFreeCacheItem(ClcCacheEntry *p); - -/* clcfiledrop.c */ -void InitFileDropping(void); - -void fnRegisterFileDropping (HWND hwnd); -void fnUnregisterFileDropping (HWND hwnd); - -/* clistevents.c */ -struct CListEvent* fnAddEvent(CLISTEVENT *cle); -CLISTEVENT* fnGetEvent(MCONTACT hContact, int idx); - -struct CListEvent* fnCreateEvent(void); -void fnFreeEvent(struct CListEvent* p); - -int fnEventsProcessContactDoubleClick(MCONTACT hContact); -int fnEventsProcessTrayDoubleClick(int); -int fnGetImlIconIndex(HICON hIcon); -int fnRemoveEvent(MCONTACT hContact, MEVENT dbEvent); - -/* clistmod.c */ -int fnGetContactIcon(MCONTACT hContact); -int fnIconFromStatusMode(const char *szProto, int status, MCONTACT hContact); -int fnShowHide(WPARAM wParam, LPARAM lParam); -HICON fnGetIconFromStatusMode(MCONTACT hContact, const char *szProto, int status); -TCHAR* fnGetStatusModeDescription(int wParam, int lParam); -int fnGetWindowVisibleState(HWND hWnd, int iStepX, int iStepY); - -/* clisttray.c */ -extern mir_cs trayLockCS; - -void fnInitTray(void); -void fnUninitTray(void); -int fnCListTrayNotify(MIRANDASYSTRAYNOTIFY *msn); -int fnTrayIconAdd(HWND hwnd, const char *szProto, const char *szIconProto, int status); -int fnTrayIconDestroy(HWND hwnd); -void fnTrayIconIconsChanged (void); -int fnTrayIconInit(HWND hwnd); -TCHAR* fnTrayIconMakeTooltip(const TCHAR *szPrefix, const char *szProto); -int fnTrayIconPauseAutoHide (WPARAM wParam, LPARAM lParam); -INT_PTR fnTrayIconProcessMessage (WPARAM wParam, LPARAM lParam); -void fnTrayIconRemove(HWND hwnd, const char *szProto); -int fnTrayIconSetBaseInfo(HICON hIcon, const char *szPreferredProto); -void fnTrayIconSetToBase (char *szPreferredProto); -void fnTrayIconTaskbarCreated(HWND hwnd); -int fnTrayIconUpdate(HICON hNewIcon, const TCHAR *szNewTip, const char *szPreferredProto, int isBase); -void fnTrayIconUpdateBase (const char *szChangedProto); -int fnTrayCalcChanged(const char *szChangedProto, int averageMode, int netProtoCount); -void fnTrayIconUpdateWithImageList (int iImage, const TCHAR *szNewTip, char *szPreferredProto); - -VOID CALLBACK fnTrayCycleTimerProc(HWND hwnd, UINT message, UINT_PTR idEvent, DWORD dwTime); - -/* clui.c */ -LRESULT CALLBACK fnContactListWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -void fnLoadCluiGlobalOpts(void); -void fnCluiProtocolStatusChanged(int, const char*); -void fnDrawMenuItem(DRAWITEMSTRUCT *dis, HICON hIcon, HICON eventIcon); - -/* contact.c */ -void fnChangeContactIcon (MCONTACT hContact, int iIcon, int add); -void fnLoadContactTree (void); -int fnCompareContacts (const ClcContact *contact1, const ClcContact *contact2); -void fnSortContacts (void); -int fnSetHideOffline (WPARAM wParam, LPARAM lParam); - -/* docking.c */ -int fnDocking_ProcessWindowMessage (WPARAM wParam, LPARAM lParam); - -/* group.c */ -TCHAR* fnGetGroupName (int idx, DWORD* pdwFlags); -int fnRenameGroup (int groupID, TCHAR* newName); - -/* keyboard.c */ -int fnHotKeysRegister (HWND hwnd); -void fnHotKeysUnregister (HWND hwnd); -int fnHotKeysProcess (HWND hwnd, WPARAM wParam, LPARAM lParam); -int fnHotkeysProcessMessage (WPARAM wParam, LPARAM lParam); diff --git a/src/modules/clist/clcfiledrop.cpp b/src/modules/clist/clcfiledrop.cpp deleted file mode 100644 index 4a8f5e33fc..0000000000 --- a/src/modules/clist/clcfiledrop.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" -#include - -struct CDropTarget : IDropTarget -{ - LONG refCount; - IDropTargetHelper *pDropTargetHelper; - - ULONG STDMETHODCALLTYPE AddRef(void); - ULONG STDMETHODCALLTYPE Release(void); - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject); - - HRESULT STDMETHODCALLTYPE DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); - HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); - HRESULT STDMETHODCALLTYPE DragLeave(void); - HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); -} -static dropTarget; - -static HWND hwndCurrentDrag = NULL; -static int originalSelection; - -HRESULT CDropTarget::QueryInterface(REFIID riid, LPVOID * ppvObj) -{ - if (riid == IID_IDropTarget) { - *ppvObj = this; - AddRef(); - return S_OK; - } - *ppvObj = NULL; - return E_NOINTERFACE; -} - -ULONG CDropTarget::AddRef(void) -{ - return InterlockedIncrement(&refCount); -} - -ULONG CDropTarget::Release(void) -{ - if (refCount == 1) { - if (pDropTargetHelper) - pDropTargetHelper->Release(); - } - return InterlockedDecrement(&refCount); -} - -static MCONTACT HContactFromPoint(HWND hwnd, struct ClcData *dat, int x, int y, int *hitLine) -{ - DWORD hitFlags; - ClcContact *contact; - int hit = cli.pfnHitTest(hwnd, dat, x, y, &contact, NULL, &hitFlags); - if (hit == -1 || !(hitFlags & (CLCHT_ONITEMLABEL | CLCHT_ONITEMICON)) || contact->type != CLCIT_CONTACT) - return NULL; - - char *szProto = GetContactProto(contact->hContact); - if (szProto == NULL) - return NULL; - - DWORD protoCaps = CallProtoServiceInt(NULL,szProto, PS_GETCAPS, PFLAGNUM_1, 0); - if (!(protoCaps & PF1_FILESEND)) - return NULL; - if (ID_STATUS_OFFLINE == db_get_w(contact->hContact, szProto, "Status", ID_STATUS_OFFLINE)) - return NULL; - if (hitLine) - *hitLine = hit; - return contact->hContact; -} - -HRESULT CDropTarget::DragOver(DWORD /*grfKeyState*/, POINTL pt, DWORD * pdwEffect) -{ - POINT shortPt; - struct ClcData *dat; - RECT clRect; - int hit; - MCONTACT hContact; - - if (pDropTargetHelper && hwndCurrentDrag) - pDropTargetHelper->DragOver((POINT*)&pt, *pdwEffect); - - *pdwEffect = 0; - if (hwndCurrentDrag == NULL) { - *pdwEffect = DROPEFFECT_NONE; - return S_OK; - } - cli.pfnTrayIconPauseAutoHide(0, 0); - dat = (struct ClcData *) GetWindowLongPtr(hwndCurrentDrag, 0); - shortPt.x = pt.x; - shortPt.y = pt.y; - ScreenToClient(hwndCurrentDrag, &shortPt); - GetClientRect(hwndCurrentDrag, &clRect); - - if (shortPt.y < dat->dragAutoScrollHeight || shortPt.y >= clRect.bottom - dat->dragAutoScrollHeight) { - *pdwEffect |= DROPEFFECT_SCROLL; - cli.pfnScrollTo(hwndCurrentDrag, dat, dat->yScroll + (shortPt.y < dat->dragAutoScrollHeight ? -1 : 1) * dat->rowHeight * 2, 0); - } - hContact = HContactFromPoint(hwndCurrentDrag, dat, shortPt.x, shortPt.y, &hit); - if (hContact == NULL) { - hit = -1; - *pdwEffect |= DROPEFFECT_NONE; - } - else - *pdwEffect |= DROPEFFECT_COPY; - - if (dat->selection != hit) { - dat->selection = hit; - cli.pfnInvalidateRect(hwndCurrentDrag, NULL, FALSE); - if (pDropTargetHelper) pDropTargetHelper->Show(FALSE); - UpdateWindow(hwndCurrentDrag); - if (pDropTargetHelper) pDropTargetHelper->Show(TRUE); - } - - return S_OK; -} - -HRESULT CDropTarget::DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) -{ - HWND hwnd; - TCHAR szWindowClass[64]; - POINT shortPt; - - shortPt.x = pt.x; - shortPt.y = pt.y; - hwnd = WindowFromPoint(shortPt); - GetClassName(hwnd, szWindowClass, SIZEOF(szWindowClass)); - if (!mir_tstrcmp(szWindowClass, _T(CLISTCONTROL_CLASS))) { - struct ClcData *dat; - hwndCurrentDrag = hwnd; - dat = (struct ClcData *) GetWindowLongPtr(hwndCurrentDrag, 0); - originalSelection = dat->selection; - dat->showSelAlways = 1; - } - if (pDropTargetHelper && hwndCurrentDrag) - pDropTargetHelper->DragEnter(hwndCurrentDrag, pDataObj, (POINT*)&pt, *pdwEffect); - return DragOver(grfKeyState, pt, pdwEffect); -} - -HRESULT CDropTarget::DragLeave(void) -{ - if (hwndCurrentDrag) { - struct ClcData *dat; - if (pDropTargetHelper) - pDropTargetHelper->DragLeave(); - dat = (struct ClcData *) GetWindowLongPtr(hwndCurrentDrag, 0); - dat->showSelAlways = 0; - dat->selection = originalSelection; - cli.pfnInvalidateRect(hwndCurrentDrag, NULL, FALSE); - } - hwndCurrentDrag = NULL; - return S_OK; -} - -static void AddToFileList(TCHAR ***pppFiles, int *totalCount, const TCHAR *szFilename) -{ - *pppFiles = (TCHAR **) mir_realloc(*pppFiles, (++*totalCount + 1) * sizeof(TCHAR *)); - (*pppFiles)[*totalCount] = NULL; - (*pppFiles)[*totalCount - 1] = mir_tstrdup(szFilename); - if (GetFileAttributes(szFilename) & FILE_ATTRIBUTE_DIRECTORY) { - WIN32_FIND_DATA fd; - HANDLE hFind; - TCHAR szPath[MAX_PATH]; - mir_tstrcpy(szPath, szFilename); - mir_tstrcat(szPath, _T("\\*")); - if (hFind = FindFirstFile(szPath, &fd)) { - do { - if (!mir_tstrcmp(fd.cFileName, _T(".")) || !mir_tstrcmp(fd.cFileName, _T(".."))) - continue; - mir_tstrcpy(szPath, szFilename); - mir_tstrcat(szPath, _T("\\")); - mir_tstrcat(szPath, fd.cFileName); - AddToFileList(pppFiles, totalCount, szPath); - } while (FindNextFile(hFind, &fd)); - FindClose(hFind); - } - } -} - -HRESULT CDropTarget::Drop(IDataObject * pDataObj, DWORD /*fKeyState*/, POINTL pt, DWORD * pdwEffect) -{ - FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - STGMEDIUM stg; - HDROP hDrop; - POINT shortPt; - struct ClcData *dat; - - if (pDropTargetHelper && hwndCurrentDrag) - pDropTargetHelper->Drop(pDataObj, (POINT*)&pt, *pdwEffect); - - *pdwEffect = DROPEFFECT_NONE; - if (hwndCurrentDrag == NULL || S_OK != pDataObj->GetData(&fe, &stg)) - return S_OK; - hDrop = (HDROP) stg.hGlobal; - dat = (struct ClcData *) GetWindowLongPtr(hwndCurrentDrag, 0); - - shortPt.x = pt.x; - shortPt.y = pt.y; - ScreenToClient(hwndCurrentDrag, &shortPt); - MCONTACT hContact = HContactFromPoint(hwndCurrentDrag, dat, shortPt.x, shortPt.y, NULL); - if (hContact != NULL) { - TCHAR **ppFiles = NULL; - TCHAR szFilename[MAX_PATH]; - int fileCount, totalCount = 0, i; - - fileCount = DragQueryFile(hDrop, -1, NULL, 0); - ppFiles = NULL; - for (i=0; i < fileCount; i++) { - DragQueryFile(hDrop, i, szFilename, SIZEOF(szFilename)); - AddToFileList(&ppFiles, &totalCount, szFilename); - } - - if (!CallService(MS_FILE_SENDSPECIFICFILEST, hContact, (LPARAM)ppFiles)) - *pdwEffect = DROPEFFECT_COPY; - - for (i=0; ppFiles[i]; i++) - mir_free(ppFiles[i]); - mir_free(ppFiles); - } - - if (stg.pUnkForRelease) - stg.pUnkForRelease->Release(); - else - GlobalFree(stg.hGlobal); - - DragLeave(); - return S_OK; -} - -static VOID CALLBACK CreateDropTargetHelperTimerProc(HWND hwnd, UINT, UINT_PTR idEvent, DWORD) -{ - KillTimer(hwnd, idEvent); - //This is a ludicrously slow function (~200ms) so we delay load it a bit. - if (S_OK != CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER, - IID_IDropTargetHelper, (LPVOID*)&dropTarget.pDropTargetHelper)) - dropTarget.pDropTargetHelper = NULL; -} - -void InitFileDropping(void) -{ - // Disabled as this function loads tons of dlls for no apparenet reason - // we will se what the reaction will be -// SetTimer(NULL, 1, 1000, CreateDropTargetHelperTimerProc); -} - -void fnRegisterFileDropping(HWND hwnd) -{ - RegisterDragDrop(hwnd, (IDropTarget *) & dropTarget); -} - -void fnUnregisterFileDropping(HWND hwnd) -{ - RevokeDragDrop(hwnd); -} diff --git a/src/modules/clist/clcidents.cpp b/src/modules/clist/clcidents.cpp deleted file mode 100644 index 606b2ecf4c..0000000000 --- a/src/modules/clist/clcidents.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -/* the CLC uses 3 different ways to identify elements in its list, this file -contains routines to convert between them. - -1) ClcContact/ClcGroup pair. Only ever used within the duration - of a single operation, but used at some point in nearly everything -2) index integer. The 0-based number of the item from the top. Only visible - items are counted (ie not closed groups). Used for saving selection and drag - highlight -3) hItem handle. Either the hContact or (hGroup|HCONTACT_ISGROUP). Used - exclusively externally - -1->2: GetRowsPriorTo() -1->3: ContactToHItem() -3->1: FindItem() -2->1: GetRowByIndex() -*/ - -int fnGetRowsPriorTo(ClcGroup *group, ClcGroup *subgroup, int contactIndex) -{ - int count = 0; - - group->scanIndex = 0; - for (;;) { - if (group->scanIndex == group->cl.count) { - group = group->parent; - if (group == NULL) - break; - group->scanIndex++; - continue; - } - if (group == subgroup && contactIndex == group->scanIndex) - return count; - count++; - - ClcContact *cc = group->cl.items[group->scanIndex]; - if (cc->type == CLCIT_GROUP) { - if (cc->group == subgroup && contactIndex == -1) - return count - 1; - if (cc->group->expanded) { - group = cc->group; - group->scanIndex = 0; - continue; - } - } - group->scanIndex++; - } - return -1; -} - -int fnFindItem(HWND hwnd, struct ClcData *dat, DWORD dwItem, ClcContact **contact, ClcGroup **subgroup, int *isVisible) -{ - int index = 0; - int nowVisible = 1; - ClcGroup *group = &dat->list; - - group->scanIndex = 0; - for (;;) { - if (group->scanIndex == group->cl.count) { - ClcGroup *tgroup; - group = group->parent; - if (group == NULL) - break; - nowVisible = 1; - for (tgroup = group; tgroup; tgroup = tgroup->parent) - if (!group->expanded) { - nowVisible = 0; - break; - } - group->scanIndex++; - continue; - } - if (nowVisible) - index++; - - ClcContact *cc = group->cl.items[group->scanIndex]; - if ((IsHContactGroup(dwItem) && cc->type == CLCIT_GROUP && (dwItem & ~HCONTACT_ISGROUP) == cc->groupId) || - (IsHContactContact(dwItem) && cc->type == CLCIT_CONTACT && cc->hContact == dwItem) || - (IsHContactInfo(dwItem) && cc->type == CLCIT_INFO && cc->hContact == (dwItem & ~HCONTACT_ISINFO))) - { - if (isVisible) { - if (!nowVisible) - *isVisible = 0; - else { - int posY = cli.pfnGetRowTopY(dat, index+1); - if (posY < dat->yScroll) - *isVisible = 0; - else { - RECT clRect; - GetClientRect(hwnd, &clRect); - if (posY >= dat->yScroll + clRect.bottom) - *isVisible = 0; - else - *isVisible = 1; - } - } - } - if (contact) - *contact = cc; - if (subgroup) - *subgroup = group; - return 1; - } - if (cc->type == CLCIT_GROUP) { - group = cc->group; - group->scanIndex = 0; - nowVisible &= group->expanded; - continue; - } - group->scanIndex++; - } - - if (isVisible) *isVisible = FALSE; - if (contact) *contact = NULL; - if (subgroup) *subgroup = NULL; - return 0; -} - -int fnGetRowByIndex(struct ClcData *dat, int testindex, ClcContact **contact, ClcGroup **subgroup) -{ - int index = 0; - ClcGroup *group = &dat->list; - - if (testindex<0) - return (-1); - - group->scanIndex = 0; - for (;;) { - if (group->scanIndex == group->cl.count) { - group = group->parent; - if (group == NULL) - break; - group->scanIndex++; - continue; - } - - ClcContact *cc = group->cl.items[group->scanIndex]; - if (testindex == index) { - if (contact) - *contact = cc; - if (subgroup) - *subgroup = group; - return index; - } - index++; - if (cc->type == CLCIT_GROUP && cc->group->expanded) { - group = cc->group; - group->scanIndex = 0; - continue; - } - group->scanIndex++; - } - return -1; -} - -HANDLE fnContactToHItem(ClcContact *contact) -{ - switch (contact->type) { - case CLCIT_CONTACT: - return (HANDLE)contact->hContact; - case CLCIT_GROUP: - return (HANDLE)(contact->groupId | HCONTACT_ISGROUP); - case CLCIT_INFO: - return (HANDLE)((UINT_PTR)contact->hContact | HCONTACT_ISINFO); - } - return NULL; -} - -HANDLE fnContactToItemHandle(ClcContact *contact, DWORD *nmFlags) -{ - switch (contact->type) { - case CLCIT_CONTACT: - return (HANDLE)contact->hContact; - case CLCIT_GROUP: - if (nmFlags) - *nmFlags |= CLNF_ISGROUP; - return (HANDLE)contact->groupId; - case CLCIT_INFO: - if (nmFlags) - *nmFlags |= CLNF_ISINFO; - return (HANDLE)((UINT_PTR)contact->hContact | HCONTACT_ISINFO); - } - return NULL; -} diff --git a/src/modules/clist/clcitems.cpp b/src/modules/clist/clcitems.cpp deleted file mode 100644 index c298d6b3d8..0000000000 --- a/src/modules/clist/clcitems.cpp +++ /dev/null @@ -1,705 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -//routines for managing adding/removal of items in the list, including sorting - -int fnAddItemToGroup(ClcGroup *group, int iAboveItem) -{ - ClcContact* newItem = cli.pfnCreateClcContact(); - newItem->type = CLCIT_DIVIDER; - newItem->flags = 0; - newItem->szText[0] = '\0'; - memset(newItem->iExtraImage, 0xFF, sizeof(newItem->iExtraImage)); - - List_Insert((SortedList*)&group->cl, newItem, iAboveItem); - return iAboveItem; -} - -ClcGroup* fnAddGroup(HWND hwnd, struct ClcData *dat, const TCHAR *szName, DWORD flags, int groupId, int calcTotalMembers) -{ - TCHAR *pBackslash, *pNextField, szThisField[ SIZEOF(dat->list.cl.items[0]->szText) ]; - ClcGroup *group = &dat->list; - int i, compareResult; - - dat->needsResort = 1; - if (!(GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_USEGROUPS)) - return &dat->list; - - pNextField = (TCHAR*)szName; - do { - pBackslash = _tcschr(pNextField, '\\'); - if (pBackslash == NULL) { - mir_tstrncpy(szThisField, pNextField, SIZEOF(szThisField)); - pNextField = NULL; - } - else { - mir_tstrncpy(szThisField, pNextField, min(SIZEOF(szThisField), pBackslash - pNextField + 1)); - pNextField = pBackslash + 1; - } - compareResult = 1; - for (i=0; i < group->cl.count; i++) { - if (group->cl.items[i]->type == CLCIT_CONTACT) - break; - if (group->cl.items[i]->type != CLCIT_GROUP) - continue; - compareResult = mir_tstrcmp(szThisField, group->cl.items[i]->szText); - if (compareResult == 0) { - if (pNextField == NULL && flags != (DWORD) - 1) { - group->cl.items[i]->groupId = (WORD) groupId; - group = group->cl.items[i]->group; - group->expanded = (flags & GROUPF_EXPANDED) != 0; - group->hideOffline = (flags & GROUPF_HIDEOFFLINE) != 0; - group->groupId = groupId; - } - else - group = group->cl.items[i]->group; - break; - } - if (pNextField == NULL && group->cl.items[i]->groupId == 0) - break; - if (!(dat->exStyle & CLS_EX_SORTGROUPSALPHA) && groupId && group->cl.items[i]->groupId > groupId) - break; - } - if (compareResult) { - if (groupId == 0) - return NULL; - i = cli.pfnAddItemToGroup(group, i); - group->cl.items[i]->type = CLCIT_GROUP; - mir_tstrncpy(group->cl.items[i]->szText, szThisField, SIZEOF(group->cl.items[i]->szText)); - group->cl.items[i]->groupId = (WORD) (pNextField ? 0 : groupId); - group->cl.items[i]->group = (ClcGroup *) mir_alloc(sizeof(ClcGroup)); - group->cl.items[i]->group->parent = group; - group = group->cl.items[i]->group; - memset(&group->cl, 0, sizeof(group->cl)); - group->cl.increment = 10; - if (flags == (DWORD) - 1 || pNextField != NULL) { - group->expanded = 0; - group->hideOffline = 0; - } - else { - group->expanded = (flags & GROUPF_EXPANDED) != 0; - group->hideOffline = (flags & GROUPF_HIDEOFFLINE) != 0; - } - group->groupId = pNextField ? 0 : groupId; - group->totalMembers = 0; - if (flags != (DWORD) - 1 && pNextField == NULL && calcTotalMembers) { - DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE); - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - ClcCacheEntry *cache = cli.pfnGetCacheEntry(hContact); - if (!mir_tstrcmp(cache->tszGroup, szName) && (style & CLS_SHOWHIDDEN || !cache->bIsHidden)) - group->totalMembers++; - } - } - } - } - while (pNextField); - return group; -} - -void fnFreeContact(ClcContact* p) -{ - if (p->type == CLCIT_GROUP) { - cli.pfnFreeGroup(p->group); - mir_free(p->group); - p->group = NULL; - } -} - -void fnFreeGroup(ClcGroup *group) -{ - if (!group) - return; - if (group->cl.items) { - for (int i=0; i < group->cl.count; i++) { - cli.pfnFreeContact(group->cl.items[i]); - mir_free(group->cl.items[i]); - } - mir_free(group->cl.items); - group->cl.items = NULL; - } - group->cl.limit = group->cl.count = 0; -} - -static int iInfoItemUniqueHandle = 0; -int fnAddInfoItemToGroup(ClcGroup *group, int flags, const TCHAR *pszText) -{ - int i=0; - - if (flags & CLCIIF_BELOWCONTACTS) - i = group->cl.count; - else if (flags & CLCIIF_BELOWGROUPS) { - for (; i < group->cl.count; i++) - if (group->cl.items[i]->type == CLCIT_CONTACT) - break; - } - else - for (; i < group->cl.count; i++) - if (group->cl.items[i]->type != CLCIT_INFO) - break; - i = cli.pfnAddItemToGroup(group, i); - iInfoItemUniqueHandle = LOWORD(iInfoItemUniqueHandle+1); - if (iInfoItemUniqueHandle == 0) - ++iInfoItemUniqueHandle; - group->cl.items[i]->type = CLCIT_INFO; - group->cl.items[i]->flags = (BYTE) flags; - group->cl.items[i]->hContact = (MCONTACT)++iInfoItemUniqueHandle; - mir_tstrncpy(group->cl.items[i]->szText, pszText, SIZEOF(group->cl.items[i]->szText)); - return i; -} - -int fnAddContactToGroup(struct ClcData *dat, ClcGroup *group, MCONTACT hContact) -{ - int i, index = -1; - - dat->needsResort = 1; - for (i = group->cl.count - 1; i >= 0; i--) { - if (group->cl.items[i]->hContact == hContact) - return i; - - if (index == -1) - if (group->cl.items[i]->type != CLCIT_INFO || !(group->cl.items[i]->flags & CLCIIF_BELOWCONTACTS)) - index = i; - } - - i = cli.pfnAddItemToGroup(group, index + 1); - char *szProto = GetContactProto(hContact); - group->cl.items[i]->type = CLCIT_CONTACT; - group->cl.items[i]->iImage = CallService(MS_CLIST_GETCONTACTICON, hContact, 0); - group->cl.items[i]->hContact = hContact; - group->cl.items[i]->proto = szProto; - if (szProto != NULL && !cli.pfnIsHiddenMode(dat, db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE))) - group->cl.items[i]->flags |= CONTACTF_ONLINE; - WORD apparentMode = szProto != NULL ? db_get_w(hContact, szProto, "ApparentMode", 0) : 0; - if (apparentMode == ID_STATUS_OFFLINE) - group->cl.items[i]->flags |= CONTACTF_INVISTO; - else if (apparentMode == ID_STATUS_ONLINE) - group->cl.items[i]->flags |= CONTACTF_VISTO; - else if (apparentMode) - group->cl.items[i]->flags |= CONTACTF_VISTO | CONTACTF_INVISTO; - if (db_get_b(hContact, "CList", "NotOnList", 0)) - group->cl.items[i]->flags |= CONTACTF_NOTONLIST; - DWORD idleMode = szProto != NULL ? db_get_dw(hContact, szProto, "IdleTS", 0) : 0; - if (idleMode) - group->cl.items[i]->flags |= CONTACTF_IDLE; - mir_tstrncpy(group->cl.items[i]->szText, cli.pfnGetContactDisplayName(hContact, 0), SIZEOF(group->cl.items[i]->szText)); - - ClcCacheEntry *p = cli.pfnGetCacheEntry(hContact); - if (p != NULL) - replaceStrT(p->tszGroup, NULL); - - return i; -} - -void fnAddContactToTree(HWND hwnd, struct ClcData *dat, MCONTACT hContact, int updateTotalCount, int checkHideOffline) -{ - ClcGroup *group; - DBVARIANT dbv; - DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE); - WORD status = ID_STATUS_OFFLINE; - char *szProto = GetContactProto(hContact); - - dat->needsResort = 1; - if (style & CLS_NOHIDEOFFLINE) - checkHideOffline = 0; - if (checkHideOffline) - if (szProto != NULL) - status = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); - - if (db_get_ts(hContact, "CList", "Group", &dbv)) - group = &dat->list; - else { - group = cli.pfnAddGroup(hwnd, dat, dbv.ptszVal, (DWORD) - 1, 0, 0); - if (group == NULL) { - int i; - DWORD groupFlags; - TCHAR *szGroupName; - if (!(style & CLS_HIDEEMPTYGROUPS)) { - mir_free(dbv.ptszVal); - return; - } - if (checkHideOffline && cli.pfnIsHiddenMode(dat, status)) { - for (i = 1;; i++) { - szGroupName = cli.pfnGetGroupName(i, &groupFlags); - if (szGroupName == NULL) { - mir_free(dbv.ptszVal); - return; - } - if (!mir_tstrcmp(szGroupName, dbv.ptszVal)) - break; - } - if (groupFlags & GROUPF_HIDEOFFLINE) { - mir_free(dbv.ptszVal); - return; - } - } - for (i = 1;; i++) { - szGroupName = cli.pfnGetGroupName(i, &groupFlags); - if (szGroupName == NULL) { - mir_free(dbv.ptszVal); - return; - } - if (!mir_tstrcmp(szGroupName, dbv.ptszVal)) - break; - size_t len = mir_tstrlen(szGroupName); - if (!_tcsncmp(szGroupName, dbv.ptszVal, len) && dbv.ptszVal[len] == '\\') - cli.pfnAddGroup(hwnd, dat, szGroupName, groupFlags, i, 1); - } - group = cli.pfnAddGroup(hwnd, dat, dbv.ptszVal, groupFlags, i, 1); - } - mir_free(dbv.ptszVal); - } - if (checkHideOffline) { - if (cli.pfnIsHiddenMode(dat, status) && (style & CLS_HIDEOFFLINE || group->hideOffline)) { - if (updateTotalCount) - group->totalMembers++; - return; - } - } - cli.pfnAddContactToGroup(dat, group, hContact); - if (updateTotalCount) - group->totalMembers++; -} - -ClcGroup* fnRemoveItemFromGroup(HWND hwnd, ClcGroup *group, ClcContact *contact, int updateTotalCount) -{ - int iContact; - if ((iContact = List_IndexOf((SortedList*)&group->cl, contact)) == -1) - return group; - - if (contact->type == CLCIT_CONTACT) { - if (updateTotalCount) - group->totalMembers--; - - ClcCacheEntry *p = cli.pfnGetCacheEntry(contact->hContact); - if (p != NULL) - replaceStrT(p->tszGroup, NULL); - } - - cli.pfnFreeContact(group->cl.items[iContact]); - mir_free(group->cl.items[iContact]); - List_Remove((SortedList*)&group->cl, iContact); - - if ((GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_HIDEEMPTYGROUPS) && group->cl.count == 0 && group->parent != NULL) - for (int i=0; i < group->parent->cl.count; i++) - if (group->parent->cl.items[i]->type == CLCIT_GROUP && group->parent->cl.items[i]->groupId == group->groupId) - return cli.pfnRemoveItemFromGroup(hwnd, group->parent, group->parent->cl.items[i], 0); - - return group; -} - -void fnDeleteItemFromTree(HWND hwnd, MCONTACT hItem) -{ - ClcContact *contact; - ClcGroup *group; - struct ClcData *dat = (struct ClcData *) GetWindowLongPtr(hwnd, 0); - - dat->needsResort = 1; - if (!cli.pfnFindItem(hwnd, dat, hItem, &contact, &group, NULL)) { - DBVARIANT dbv; - int i, nameOffset; - if (!IsHContactContact(hItem)) - return; - if (db_get_ts(hItem, "CList", "Group", &dbv)) - return; - - //decrease member counts of all parent groups too - group = &dat->list; - nameOffset = 0; - for (i=0;; i++) { - if (group->scanIndex == group->cl.count) - break; - if (group->cl.items[i]->type == CLCIT_GROUP) { - size_t len = mir_tstrlen(group->cl.items[i]->szText); - if (!_tcsncmp(group->cl.items[i]->szText, dbv.ptszVal + nameOffset, len) && - (dbv.ptszVal[nameOffset + len] == '\\' || dbv.ptszVal[nameOffset + len] == '\0')) { - group->totalMembers--; - if (dbv.ptszVal[nameOffset + len] == '\0') - break; - } - } - } - mir_free(dbv.ptszVal); - } - else cli.pfnRemoveItemFromGroup(hwnd, group, contact, 1); -} - -void fnRebuildEntireList(HWND hwnd, struct ClcData *dat) -{ - DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE); - ClcGroup *group; - - dat->list.expanded = 1; - dat->list.hideOffline = db_get_b(NULL, "CLC", "HideOfflineRoot", 0) && style&CLS_USEGROUPS; - dat->list.cl.count = dat->list.cl.limit = 0; - dat->selection = -1; - - for (int i = 1;; i++) { - DWORD groupFlags; - TCHAR *szGroupName = cli.pfnGetGroupName(i, &groupFlags); - if (szGroupName == NULL) - break; - cli.pfnAddGroup(hwnd, dat, szGroupName, groupFlags, i, 0); - } - - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - if (style & CLS_SHOWHIDDEN || !db_get_b(hContact, "CList", "Hidden", 0)) { - DBVARIANT dbv; - if (db_get_ts(hContact, "CList", "Group", &dbv)) - group = &dat->list; - else { - group = cli.pfnAddGroup(hwnd, dat, dbv.ptszVal, (DWORD) - 1, 0, 0); - if (group == NULL && style & CLS_SHOWHIDDEN) group = &dat->list; - mir_free(dbv.ptszVal); - } - - if (group != NULL) { - group->totalMembers++; - - if (dat->filterSearch && dat->szQuickSearch[0] != '\0') { - TCHAR *name = cli.pfnGetContactDisplayName(hContact, 0); - TCHAR *lowered_name = CharLowerW(NEWTSTR_ALLOCA(name)); - TCHAR *lowered_search = CharLowerW(NEWTSTR_ALLOCA(dat->szQuickSearch)); - - if (_tcsstr(lowered_name, lowered_search)) - cli.pfnAddContactToGroup(dat, group, hContact); - } - else if (!(style & CLS_NOHIDEOFFLINE) && (style & CLS_HIDEOFFLINE || group->hideOffline)) { - char *szProto = GetContactProto(hContact); - if (szProto == NULL) { - if (!cli.pfnIsHiddenMode(dat, ID_STATUS_OFFLINE)) - cli.pfnAddContactToGroup(dat, group, hContact); - } - else if (!cli.pfnIsHiddenMode(dat, db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE))) - cli.pfnAddContactToGroup(dat, group, hContact); - } - else cli.pfnAddContactToGroup(dat, group, hContact); - } - } - } - - if (style & CLS_HIDEEMPTYGROUPS) { - group = &dat->list; - group->scanIndex = 0; - for (;;) { - if (group->scanIndex == group->cl.count) { - group = group->parent; - if (group == NULL) - break; - } - else if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) { - if (group->cl.items[group->scanIndex]->group->cl.count == 0) { - group = cli.pfnRemoveItemFromGroup(hwnd, group, group->cl.items[group->scanIndex], 0); - } - else { - group = group->cl.items[group->scanIndex]->group; - group->scanIndex = 0; - } - continue; - } - group->scanIndex++; - } - } - - cli.pfnSortCLC(hwnd, dat, 0); - cli.pfnSetAllExtraIcons(0); -} - -int fnGetGroupContentsCount(ClcGroup *group, int visibleOnly) -{ - int count = group->cl.count; - ClcGroup *topgroup = group; - - group->scanIndex = 0; - for (;;) { - if (group->scanIndex == group->cl.count) { - if (group == topgroup) - break; - group = group->parent; - } - else if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP && (!visibleOnly || group->cl.items[group->scanIndex]->group->expanded)) { - group = group->cl.items[group->scanIndex]->group; - group->scanIndex = 0; - count += group->cl.count; - continue; - } - group->scanIndex++; - } - return count; -} - -static int __cdecl GroupSortProc(const void* p1, const void* p2) -{ - ClcContact **contact1 = (ClcContact**)p1, **contact2 = (ClcContact**)p2; - - return mir_tstrcmpi(contact1[0]->szText, contact2[0]->szText); -} - -static int __cdecl ContactSortProc(const void* p1, const void* p2) -{ - ClcContact **contact1 = (ClcContact**)p1, **contact2 = (ClcContact**)p2; - - int result = cli.pfnCompareContacts(contact1[0], contact2[0]); - if (result) - return result; - //nothing to distinguish them, so make sure they stay in the same order - return (int)((INT_PTR) contact2[0]->hContact - (INT_PTR) contact1[0]->hContact); -} - -static void InsertionSort(ClcContact **pContactArray, int nArray, int (*CompareProc) (const void *, const void *)) -{ - int i, j; - ClcContact* testElement; - - for (i = 1; i < nArray; i++) { - if (CompareProc(&pContactArray[i - 1], &pContactArray[i]) > 0) { - testElement = pContactArray[i]; - for (j = i - 2; j >= 0; j--) - if (CompareProc(&pContactArray[j], &testElement) <= 0) - break; - j++; - memmove(&pContactArray[j + 1], &pContactArray[j], sizeof(void*) * (i - j)); - pContactArray[j] = testElement; - } - } -} - -static void SortGroup(struct ClcData *dat, ClcGroup *group, int useInsertionSort) -{ - int i, sortCount; - - for (i = group->cl.count - 1; i >= 0; i--) { - if (group->cl.items[i]->type == CLCIT_DIVIDER) { - mir_free(group->cl.items[i]); - List_Remove((SortedList*)&group->cl, i); - } - } - - for (i=0; i < group->cl.count; i++) - if (group->cl.items[i]->type != CLCIT_INFO) - break; - if (i > group->cl.count - 2) - return; - if (group->cl.items[i]->type == CLCIT_GROUP) { - if (dat->exStyle & CLS_EX_SORTGROUPSALPHA) { - for (sortCount = 0; i + sortCount < group->cl.count; sortCount++) - if (group->cl.items[i + sortCount]->type != CLCIT_GROUP) - break; - qsort(group->cl.items + i, sortCount, sizeof(void*), GroupSortProc); - i = i + sortCount; - } - for (; i < group->cl.count; i++) - if (group->cl.items[i]->type == CLCIT_CONTACT) - break; - if (group->cl.count - i < 2) - return; - } - for (sortCount = 0; i + sortCount < group->cl.count; sortCount++) - if (group->cl.items[i + sortCount]->type != CLCIT_CONTACT) - break; - if (useInsertionSort) - InsertionSort(group->cl.items + i, sortCount, ContactSortProc); - else - qsort(group->cl.items + i, sortCount, sizeof(void*), ContactSortProc); - if (dat->exStyle & CLS_EX_DIVIDERONOFF) { - int prevContactOnline = 0; - for (i=0; i < group->cl.count; i++) { - if (group->cl.items[i]->type != CLCIT_CONTACT) - continue; - if (group->cl.items[i]->flags & CONTACTF_ONLINE) - prevContactOnline = 1; - else { - if (prevContactOnline) { - i = cli.pfnAddItemToGroup(group, i); - group->cl.items[i]->type = CLCIT_DIVIDER; - mir_tstrcpy(group->cl.items[i]->szText, TranslateT("Offline")); - } - break; - } - } - } -} - -void fnSortCLC(HWND hwnd, struct ClcData *dat, int useInsertionSort) -{ - ClcContact *selcontact; - ClcGroup *group = &dat->list, *selgroup; - MCONTACT hSelItem; - - if (dat->needsResort) { - if (cli.pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) == -1) - hSelItem = NULL; - else - hSelItem = (MCONTACT)cli.pfnContactToHItem(selcontact); - group->scanIndex = 0; - SortGroup(dat, group, useInsertionSort); - for (;;) { - if (group->scanIndex == group->cl.count) { - group = group->parent; - if (group == NULL) - break; - } - else if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) { - group = group->cl.items[group->scanIndex]->group; - group->scanIndex = 0; - SortGroup(dat, group, useInsertionSort); - continue; - } - group->scanIndex++; - } - if (hSelItem) - if (cli.pfnFindItem(hwnd, dat, hSelItem, &selcontact, &selgroup, NULL)) - dat->selection = cli.pfnGetRowsPriorTo(&dat->list, selgroup, List_IndexOf((SortedList*)&selgroup->cl, selcontact)); - - cli.pfnRecalcScrollBar(hwnd, dat); - } - dat->needsResort = 0; - cli.pfnInvalidateRect(hwnd, NULL, FALSE); -} - -struct SavedContactState_t -{ - MCONTACT hContact; - WORD iExtraImage[EXTRA_ICON_COUNT]; - int checked; -}; - -struct SavedGroupState_t -{ - int groupId, expanded; -}; - -struct SavedInfoState_t -{ - int parentId; - ClcContact contact; -}; - -void fnSaveStateAndRebuildList(HWND hwnd, struct ClcData *dat) -{ - NMCLISTCONTROL nm; - int i, j; - ClcGroup *group; - ClcContact *contact; - - cli.pfnHideInfoTip(hwnd, dat); - KillTimer(hwnd, TIMERID_INFOTIP); - KillTimer(hwnd, TIMERID_RENAME); - cli.pfnEndRename(hwnd, dat, 1); - - OBJLIST saveContact(10, NumericKeySortT); - OBJLIST saveGroup(100, NumericKeySortT); - OBJLIST saveInfo(10, NumericKeySortT); - - dat->needsResort = 1; - group = &dat->list; - group->scanIndex = 0; - for (;;) { - if (group->scanIndex == group->cl.count) { - group = group->parent; - if (group == NULL) - break; - } - else if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) { - group = group->cl.items[group->scanIndex]->group; - group->scanIndex = 0; - - SavedGroupState_t* p = new SavedGroupState_t; - p->groupId = group->groupId; - p->expanded = group->expanded; - saveGroup.insert(p); - continue; - } - else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT) { - SavedContactState_t* p = new SavedContactState_t; - p->hContact = group->cl.items[group->scanIndex]->hContact; - memcpy(p->iExtraImage, group->cl.items[group->scanIndex]->iExtraImage, sizeof(p->iExtraImage)); - p->checked = group->cl.items[group->scanIndex]->flags & CONTACTF_CHECKED; - saveContact.insert(p); - } - else if (group->cl.items[group->scanIndex]->type == CLCIT_INFO) { - SavedInfoState_t* p = new SavedInfoState_t; - p->parentId = (group->parent == NULL) ? -1 : group->groupId; - p->contact = *group->cl.items[group->scanIndex]; - saveInfo.insert(p); - } - group->scanIndex++; - } - - cli.pfnFreeGroup(&dat->list); - cli.pfnRebuildEntireList(hwnd, dat); - - group = &dat->list; - group->scanIndex = 0; - for (;;) { - if (group->scanIndex == group->cl.count) { - group = group->parent; - if (group == NULL) - break; - } - else if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) { - group = group->cl.items[group->scanIndex]->group; - group->scanIndex = 0; - - SavedGroupState_t tmp, *p; - tmp.groupId = group->groupId; - if ((p = saveGroup.find(&tmp)) != NULL) - group->expanded = p->expanded; - continue; - } - else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT) { - SavedContactState_t tmp, *p; - tmp.hContact = group->cl.items[group->scanIndex]->hContact; - if ((p = saveContact.find(&tmp)) != NULL) { - memcpy(group->cl.items[group->scanIndex]->iExtraImage, p->iExtraImage, sizeof(p->iExtraImage)); - if (p->checked) - group->cl.items[group->scanIndex]->flags |= CONTACTF_CHECKED; - } - } - - group->scanIndex++; - } - - for (i=0; i < saveInfo.getCount(); i++) { - if (saveInfo[i].parentId == -1) - group = &dat->list; - else { - if (!cli.pfnFindItem(hwnd, dat, saveInfo[i].parentId | HCONTACT_ISGROUP, &contact, NULL, NULL)) - continue; - group = contact->group; - } - j = cli.pfnAddInfoItemToGroup(group, saveInfo[i].contact.flags, _T("")); - *group->cl.items[j] = saveInfo[i].contact; - } - - cli.pfnRecalculateGroupCheckboxes(hwnd, dat); - - cli.pfnRecalcScrollBar(hwnd, dat); - nm.hdr.code = CLN_LISTREBUILT; - nm.hdr.hwndFrom = hwnd; - nm.hdr.idFrom = GetDlgCtrlID(hwnd); - SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm); -} diff --git a/src/modules/clist/clcmsgs.cpp b/src/modules/clist/clcmsgs.cpp deleted file mode 100644 index 557c48c8cd..0000000000 --- a/src/modules/clist/clcmsgs.cpp +++ /dev/null @@ -1,474 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -//processing of all the CLM_ messages incoming - -LRESULT fnProcessExternalMessages(HWND hwnd, struct ClcData *dat, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case CLM_ADDCONTACT: - cli.pfnAddContactToTree(hwnd, dat, wParam, 1, 0); - cli.pfnRecalcScrollBar(hwnd, dat); - cli.pfnSortCLC(hwnd, dat, 1); - break; - - case CLM_ADDGROUP: - { - DWORD groupFlags; - TCHAR *szName = cli.pfnGetGroupName(wParam, &groupFlags); - if (szName == NULL) - break; - cli.pfnAddGroup(hwnd, dat, szName, groupFlags, wParam, 0); - cli.pfnRecalcScrollBar(hwnd, dat); - break; - } - - case CLM_ADDINFOITEMA: - case CLM_ADDINFOITEMW: - { - int i; - ClcContact *groupContact; - ClcGroup *group; - CLCINFOITEM *cii = (CLCINFOITEM *)lParam; - if (cii == NULL || cii->cbSize != sizeof(CLCINFOITEM)) - return NULL; - if (cii->hParentGroup == NULL) - group = &dat->list; - else { - if (!cli.pfnFindItem(hwnd, dat, int(cii->hParentGroup) | HCONTACT_ISGROUP, &groupContact, NULL, NULL)) - return NULL; - group = groupContact->group; - } - if (msg == CLM_ADDINFOITEMA) - { WCHAR* wszText = mir_a2u((char*)cii->pszText); - i = cli.pfnAddInfoItemToGroup(group, cii->flags, wszText); - mir_free(wszText); - } - else i = cli.pfnAddInfoItemToGroup(group, cii->flags, cii->pszText); - cli.pfnRecalcScrollBar(hwnd, dat); - return (LRESULT)group->cl.items[i]->hContact | HCONTACT_ISINFO; - } - - case CLM_AUTOREBUILD: - KillTimer(hwnd, TIMERID_REBUILDAFTER); - cli.pfnSaveStateAndRebuildList(hwnd, dat); - cli.bAutoRebuild = false; - break; - - case CLM_DELETEITEM: - cli.pfnDeleteItemFromTree(hwnd, wParam); - cli.pfnSortCLC(hwnd, dat, 1); - cli.pfnRecalcScrollBar(hwnd, dat); - break; - - case CLM_EDITLABEL: - SendMessage(hwnd, CLM_SELECTITEM, wParam, 0); - cli.pfnBeginRenameSelection(hwnd, dat); - break; - - case CLM_ENDEDITLABELNOW: - cli.pfnEndRename(hwnd, dat, wParam); - break; - - case CLM_ENSUREVISIBLE: - { - ClcContact *contact; - ClcGroup *group, *tgroup; - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, &group, NULL)) - break; - for (tgroup = group; tgroup; tgroup = tgroup->parent) - cli.pfnSetGroupExpand(hwnd, dat, tgroup, 1); - cli.pfnEnsureVisible(hwnd, dat, cli.pfnGetRowsPriorTo(&dat->list, group, List_IndexOf((SortedList*)&group->cl, contact)), 0); - break; - } - - case CLM_EXPAND: - { - ClcContact *contact; - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - break; - if (contact->type != CLCIT_GROUP) - break; - cli.pfnSetGroupExpand(hwnd, dat, contact->group, lParam); - break; - } - - case CLM_FINDCONTACT: - if (!cli.pfnFindItem(hwnd, dat, wParam, NULL, NULL, NULL)) - return NULL; - return wParam; - - case CLM_FINDGROUP: - if (!cli.pfnFindItem(hwnd, dat, wParam | HCONTACT_ISGROUP, NULL, NULL, NULL)) - return NULL; - return wParam | HCONTACT_ISGROUP; - - case CLM_GETBKCOLOR: - return dat->bkColour; - - case CLM_GETCHECKMARK: - { - ClcContact *contact; - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - return 0; - return (contact->flags & CONTACTF_CHECKED) != 0; - } - - case CLM_GETCOUNT: - return cli.pfnGetGroupContentsCount(&dat->list, 0); - - case CLM_GETEDITCONTROL: - return (LRESULT)dat->hwndRenameEdit; - - case CLM_GETEXPAND: - { - ClcContact *contact; - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - return CLE_INVALID; - if (contact->type != CLCIT_GROUP) - return CLE_INVALID; - return contact->group->expanded; - } - - case CLM_SETEXTRASPACE: - dat->extraColumnSpacing = (int)wParam; - cli.pfnInvalidateRect(hwnd,NULL,FALSE); - return 0; - - case CLM_GETEXTRACOLUMNS: - return dat->extraColumnsCount; - - case CLM_GETEXTRAIMAGE: - if (LOWORD(lParam) < dat->extraColumnsCount) { - ClcContact *contact; - if (cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - return contact->iExtraImage[LOWORD(lParam)]; - } - return EMPTY_EXTRA_ICON; - - case CLM_GETEXTRAIMAGELIST: - return (LRESULT)dat->himlExtraColumns; - - case CLM_GETFONT: - if (wParam > FONTID_MAX) - return 0; - return (LRESULT)dat->fontInfo[wParam].hFont; - - case CLM_GETHIDEOFFLINEROOT: - return db_get_b(NULL, "CLC", "HideOfflineRoot", 0); - - case CLM_GETINDENT: - return dat->groupIndent; - - case CLM_GETISEARCHSTRING: - mir_tstrcpy((TCHAR*) lParam, dat->szQuickSearch); - return mir_tstrlen(dat->szQuickSearch); - - case CLM_GETITEMTEXT: - { - ClcContact *contact; - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - return 0; - mir_tstrcpy((TCHAR*) lParam, contact->szText); - return mir_tstrlen(contact->szText); - } - - case CLM_GETITEMTYPE: - { - ClcContact *contact; - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - return CLCIT_INVALID; - return contact->type; - } - - case CLM_GETLEFTMARGIN: - return dat->leftMargin; - - case CLM_GETNEXTITEM: - { - if (wParam == CLGN_ROOT) { - if (dat->list.cl.count) - return (LRESULT)cli.pfnContactToHItem(dat->list.cl.items[0]); - return NULL; - } - - ClcContact *contact; - ClcGroup *group; - if (!cli.pfnFindItem(hwnd, dat, lParam, &contact, &group, NULL)) - return NULL; - - int i = List_IndexOf((SortedList*)&group->cl, contact); - switch (wParam) { - case CLGN_CHILD: - if (contact->type != CLCIT_GROUP) - return NULL; - group = contact->group; - if (group->cl.count == 0) - return NULL; - return (LRESULT)cli.pfnContactToHItem(group->cl.items[0]); - - case CLGN_PARENT: - return group->groupId | HCONTACT_ISGROUP; - - case CLGN_NEXT: - do { - if (++i >= group->cl.count) - return NULL; - } - while (group->cl.items[i]->type == CLCIT_DIVIDER); - return (LRESULT)cli.pfnContactToHItem(group->cl.items[i]); - - case CLGN_PREVIOUS: - do { - if (--i < 0) - return NULL; - } - while (group->cl.items[i]->type == CLCIT_DIVIDER); - return (LRESULT)cli.pfnContactToHItem(group->cl.items[i]); - - case CLGN_NEXTCONTACT: - for (i++; i < group->cl.count; i++) - if (group->cl.items[i]->type == CLCIT_CONTACT) - break; - if (i >= group->cl.count) - return NULL; - return (LRESULT)cli.pfnContactToHItem(group->cl.items[i]); - - case CLGN_PREVIOUSCONTACT: - if (i >= group->cl.count) - return NULL; - for (i--; i >= 0; i--) - if (group->cl.items[i]->type == CLCIT_CONTACT) - break; - if (i < 0) - return NULL; - return (LRESULT)cli.pfnContactToHItem(group->cl.items[i]); - - case CLGN_NEXTGROUP: - for (i++; i < group->cl.count; i++) - if (group->cl.items[i]->type == CLCIT_GROUP) - break; - if (i >= group->cl.count) - return NULL; - return (LRESULT)cli.pfnContactToHItem(group->cl.items[i]); - - case CLGN_PREVIOUSGROUP: - if (i >= group->cl.count) - return NULL; - for (i--; i >= 0; i--) - if (group->cl.items[i]->type == CLCIT_GROUP) - break; - if (i < 0) - return NULL; - return (LRESULT)cli.pfnContactToHItem(group->cl.items[i]); - } - return NULL; - } - - case CLM_GETSCROLLTIME: - return dat->scrollTime; - - case CLM_GETSELECTION: - { - ClcContact *contact; - if (cli.pfnGetRowByIndex(dat, dat->selection, &contact, NULL) == -1) - return NULL; - return (LRESULT)cli.pfnContactToHItem(contact); - } - - case CLM_GETTEXTCOLOR: - if (wParam > FONTID_MAX) - return 0; - return (LRESULT)dat->fontInfo[wParam].colour; - - case CLM_HITTEST: - { - ClcContact *contact; - DWORD hitFlags; - int hit = cli.pfnHitTest(hwnd, dat, (short) LOWORD(lParam), (short) HIWORD(lParam), &contact, NULL, &hitFlags); - if (wParam) - *(PDWORD) wParam = hitFlags; - if (hit == -1) - return NULL; - return (LRESULT)cli.pfnContactToHItem(contact); - } - - case CLM_SELECTITEM: - { - ClcContact *contact; - ClcGroup *group, *tgroup; - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, &group, NULL)) - break; - for (tgroup = group; tgroup; tgroup = tgroup->parent) - cli.pfnSetGroupExpand(hwnd, dat, tgroup, 1); - dat->selection = cli.pfnGetRowsPriorTo(&dat->list, group, List_IndexOf((SortedList*)&group->cl, contact)); - cli.pfnEnsureVisible(hwnd, dat, dat->selection, 0); - break; - } - - case CLM_SETBKBITMAP: - if (dat->hBmpBackground) { - DeleteObject(dat->hBmpBackground); - dat->hBmpBackground = NULL; - } - dat->hBmpBackground = (HBITMAP)lParam; - dat->backgroundBmpUse = wParam; - dat->bkChanged = 1; - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - break; - - case CLM_SETBKCOLOR: - if (dat->hBmpBackground) { - DeleteObject(dat->hBmpBackground); - dat->hBmpBackground = NULL; - } - dat->bkColour = wParam; - dat->bkChanged = 1; - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - break; - - case CLM_SETCHECKMARK: - { - ClcContact *contact; - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - return 0; - if (lParam) - contact->flags |= CONTACTF_CHECKED; - else - contact->flags &= ~CONTACTF_CHECKED; - cli.pfnRecalculateGroupCheckboxes(hwnd, dat); - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - break; - } - - case CLM_SETEXTRACOLUMNS: - if (wParam > EXTRA_ICON_COUNT) - return 0; - - dat->extraColumnsCount = wParam; - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - break; - - case CLM_SETEXTRAIMAGE: - if ( LOWORD(lParam) < dat->extraColumnsCount) { - ClcContact *contact; - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - return 0; - - contact->iExtraImage[LOWORD(lParam)] = HIWORD(lParam); - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - } - break; - - case CLM_SETEXTRAIMAGELIST: - dat->himlExtraColumns = (HIMAGELIST) lParam; - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - break; - - case CLM_SETFONT: - if (HIWORD(lParam) > FONTID_MAX) - return 0; - - dat->fontInfo[HIWORD(lParam)].hFont = (HFONT) wParam; - dat->fontInfo[HIWORD(lParam)].changed = 1; - { - SIZE fontSize; - HDC hdc = GetDC(hwnd); - SelectObject(hdc, (HFONT) wParam); - GetTextExtentPoint32A(hdc, "x", 1, &fontSize); - dat->fontInfo[HIWORD(lParam)].fontHeight = fontSize.cy; - if (dat->rowHeight < fontSize.cy + 2) - dat->rowHeight = fontSize.cy + 2; - ReleaseDC(hwnd, hdc); - } - if (LOWORD(lParam)) - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - break; - - case CLM_SETGREYOUTFLAGS: - dat->greyoutFlags = wParam; - break; - - case CLM_SETHIDEEMPTYGROUPS: - if (wParam) - SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) | CLS_HIDEEMPTYGROUPS); - else - SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~CLS_HIDEEMPTYGROUPS); - cli.pfnInitAutoRebuild(hwnd); - break; - - case CLM_SETHIDEOFFLINEROOT: - db_set_b(NULL, "CLC", "HideOfflineRoot", (BYTE) wParam); - cli.pfnInitAutoRebuild(hwnd); - break; - - case CLM_SETINDENT: - dat->groupIndent = wParam; - cli.pfnInitAutoRebuild(hwnd); - break; - - case CLM_SETITEMTEXT: - { - ClcContact *contact; - if (!cli.pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL)) - break; - mir_tstrncpy(contact->szText, (TCHAR*)lParam, SIZEOF(contact->szText)); - cli.pfnSortCLC(hwnd, dat, 1); - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - break; - } - - case CLM_SETLEFTMARGIN: - dat->leftMargin = wParam; - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - break; - - case CLM_SETOFFLINEMODES: - dat->offlineModes = wParam; - cli.pfnInitAutoRebuild(hwnd); - break; - - case CLM_SETSCROLLTIME: - dat->scrollTime = wParam; - break; - - case CLM_SETTEXTCOLOR: - if (wParam > FONTID_MAX) - break; - dat->fontInfo[wParam].colour = lParam; - break; - - case CLM_SETUSEGROUPS: - if (wParam) - SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) | CLS_USEGROUPS); - else - SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~CLS_USEGROUPS); - cli.pfnInitAutoRebuild(hwnd); - break; - } - return 0; -} diff --git a/src/modules/clist/clcutils.cpp b/src/modules/clist/clcutils.cpp deleted file mode 100644 index f82cfa27a7..0000000000 --- a/src/modules/clist/clcutils.cpp +++ /dev/null @@ -1,877 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -//loads of stuff that didn't really fit anywhere else - -extern HANDLE hHideInfoTipEvent; - -TCHAR* fnGetGroupCountsText(struct ClcData *dat, ClcContact *contact) -{ - if (contact->type != CLCIT_GROUP || !(dat->exStyle & CLS_EX_SHOWGROUPCOUNTS)) - return _T(""); - - ClcGroup *group = contact->group, *topgroup = group; - int onlineCount = 0; - int totalCount = group->totalMembers; - group->scanIndex = 0; - for (;;) { - if (group->scanIndex == group->cl.count) { - if (group == topgroup) - break; - group = group->parent; - } - else if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) { - group = group->cl.items[group->scanIndex]->group; - group->scanIndex = 0; - totalCount += group->totalMembers; - continue; - } - else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT) - if (group->cl.items[group->scanIndex]->flags & CONTACTF_ONLINE) - onlineCount++; - group->scanIndex++; - } - if (onlineCount == 0 && dat->exStyle & CLS_EX_HIDECOUNTSWHENEMPTY) - return _T(""); - - static TCHAR szName[32]; - mir_sntprintf(szName, _T("(%u/%u)"), onlineCount, totalCount); - return szName; -} - -int fnHitTest(HWND hwnd, struct ClcData *dat, int testx, int testy, ClcContact **contact, ClcGroup **group, DWORD * flags) -{ - ClcContact *hitcontact = NULL; - ClcGroup *hitgroup = NULL; - int indent, i; - DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE); - - if (flags) - *flags = 0; - - POINT pt; - pt.x = testx; - pt.y = testy; - ClientToScreen(hwnd, &pt); - - HWND hwndParent = hwnd, hwndTemp; - do { - hwndTemp = hwndParent; - hwndParent = (HWND)GetWindowLongPtr(hwndTemp, GWLP_HWNDPARENT); - - POINT pt1 = pt; - ScreenToClient(hwndParent, &pt1); - HWND h = ChildWindowFromPointEx(hwndParent ? hwndParent : GetDesktopWindow(), pt1, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT); - if (h != hwndTemp) - if (!hwndParent || !(GetWindowLongPtr(hwndTemp, GWL_STYLE) & BS_GROUPBOX)) - return -1; - } - while (hwndParent); - - RECT clRect; - GetClientRect(hwnd, &clRect); - if (testx < 0 || testy < 0 || testy >= clRect.bottom || testx >= clRect.right) { - if (flags) { - if (testx < 0) - *flags |= CLCHT_TOLEFT; - else if (testx >= clRect.right) - *flags |= CLCHT_TORIGHT; - if (testy < 0) - *flags |= CLCHT_ABOVE; - else if (testy >= clRect.bottom) - *flags |= CLCHT_BELOW; - } - return -1; - } - if (testx < dat->leftMargin) { - if (flags) - *flags |= CLCHT_INLEFTMARGIN | CLCHT_NOWHERE; - return -1; - } - int hit = cli.pfnRowHitTest(dat, dat->yScroll + testy); - if (hit != -1) - hit = cli.pfnGetRowByIndex(dat, hit, &hitcontact, &hitgroup); - if (hit == -1) { - if (flags) - *flags |= CLCHT_NOWHERE | CLCHT_BELOWITEMS; - return -1; - } - if (contact) - *contact = hitcontact; - if (group) - *group = hitgroup; - for (indent = 0; hitgroup->parent; indent++, hitgroup = hitgroup->parent); - if (testx < dat->leftMargin + indent * dat->groupIndent) { - if (flags) - *flags |= CLCHT_ONITEMINDENT; - return hit; - } - int checkboxWidth = 0; - if (style & CLS_CHECKBOXES && hitcontact->type == CLCIT_CONTACT) - checkboxWidth = dat->checkboxSize + 2; - if (style & CLS_GROUPCHECKBOXES && hitcontact->type == CLCIT_GROUP) - checkboxWidth = dat->checkboxSize + 2; - if (hitcontact->type == CLCIT_INFO && hitcontact->flags & CLCIIF_CHECKBOX) - checkboxWidth = dat->checkboxSize + 2; - if (testx < dat->leftMargin + indent * dat->groupIndent + checkboxWidth) { - if (flags) - *flags |= CLCHT_ONITEMCHECK; - return hit; - } - if (testx < dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace) { - if (flags) - *flags |= CLCHT_ONITEMICON; - return hit; - } - - int eiOffset = 0; - for (i = dat->extraColumnsCount-1; i >= 0; i--) { - if (hitcontact->iExtraImage[i] == EMPTY_EXTRA_ICON) - continue; - - eiOffset += dat->extraColumnSpacing; - if (testx >= clRect.right - eiOffset && testx < clRect.right - eiOffset + g_IconWidth) { - if (flags) - *flags |= CLCHT_ONITEMEXTRA | (i << 24); - return hit; - } - } - - HDC hdc = GetDC(hwnd); - HFONT hFont = (HFONT)SelectObject(hdc, dat->fontInfo[hitcontact->type == CLCIT_GROUP ? FONTID_GROUPS : FONTID_CONTACTS].hFont); - - SIZE textSize; - GetTextExtentPoint32(hdc, hitcontact->szText, (int)mir_tstrlen(hitcontact->szText), &textSize); - int width = textSize.cx; - if (hitcontact->type == CLCIT_GROUP) { - TCHAR *szCounts; - szCounts = cli.pfnGetGroupCountsText(dat, hitcontact); - if (szCounts[0]) { - GetTextExtentPoint32(hdc, _T(" "), 1, &textSize); - width += textSize.cx; - SelectObject(hdc, dat->fontInfo[FONTID_GROUPCOUNTS].hFont); - GetTextExtentPoint32(hdc, szCounts, (int)mir_tstrlen(szCounts), &textSize); - width += textSize.cx; - } - } - SelectObject(hdc, hFont); - ReleaseDC(hwnd, hdc); - if (testx < dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace + width + 4) { - if (flags) - *flags |= CLCHT_ONITEMLABEL; - return hit; - } - if (flags) - *flags |= CLCHT_NOWHERE; - return -1; -} - -void fnScrollTo(HWND hwnd, struct ClcData *dat, int desty, int noSmooth) -{ - DWORD startTick, nowTick; - int oldy = dat->yScroll; - RECT clRect, rcInvalidate; - int maxy, previousy; - - if (dat->iHotTrack != -1 && dat->yScroll != desty) { - cli.pfnInvalidateItem(hwnd, dat, dat->iHotTrack); - dat->iHotTrack = -1; - ReleaseCapture(); - } - GetClientRect(hwnd, &clRect); - rcInvalidate = clRect; - maxy = cli.pfnGetRowTotalHeight(dat) - clRect.bottom; - if (desty > maxy) - desty = maxy; - if (desty < 0) - desty = 0; - if (abs(desty - dat->yScroll) < 4) - noSmooth = 1; - if (!noSmooth && dat->exStyle & CLS_EX_NOSMOOTHSCROLLING) - noSmooth = 1; - previousy = dat->yScroll; - if (!noSmooth) { - startTick = GetTickCount(); - for (;;) { - nowTick = GetTickCount(); - if (nowTick >= startTick + dat->scrollTime) - break; - dat->yScroll = oldy + (desty - oldy) * (int)(nowTick - startTick) / dat->scrollTime; - if (dat->backgroundBmpUse & CLBF_SCROLL || dat->hBmpBackground == NULL) - ScrollWindowEx(hwnd, 0, previousy - dat->yScroll, NULL, NULL, NULL, NULL, SW_INVALIDATE); - else - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - previousy = dat->yScroll; - SetScrollPos(hwnd, SB_VERT, dat->yScroll, TRUE); - UpdateWindow(hwnd); - } - } - dat->yScroll = desty; - if (dat->backgroundBmpUse & CLBF_SCROLL || dat->hBmpBackground == NULL) - ScrollWindowEx(hwnd, 0, previousy - dat->yScroll, NULL, NULL, NULL, NULL, SW_INVALIDATE); - else - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - SetScrollPos(hwnd, SB_VERT, dat->yScroll, TRUE); -} - -void fnEnsureVisible(HWND hwnd, struct ClcData *dat, int iItem, int partialOk) -{ - int itemy = cli.pfnGetRowTopY(dat, iItem), itemh = cli.pfnGetRowHeight(dat, iItem), newY = 0; - int moved = 0; - RECT clRect; - - GetClientRect(hwnd, &clRect); - if (partialOk) { - if (itemy + itemh - 1 < dat->yScroll) { - newY = itemy; - moved = 1; - } - else if (itemy >= dat->yScroll + clRect.bottom) { - newY = itemy - clRect.bottom + itemh; - moved = 1; - } - } - else { - if (itemy < dat->yScroll) { - newY = itemy; - moved = 1; - } - else if (itemy >= dat->yScroll + clRect.bottom - itemh) { - newY = itemy - clRect.bottom + itemh; - moved = 1; - } - } - if (moved) - cli.pfnScrollTo(hwnd, dat, newY, 0); -} - -void fnRecalcScrollBar(HWND hwnd, struct ClcData *dat) -{ - SCROLLINFO si = { 0 }; - RECT clRect; - NMCLISTCONTROL nm; - - GetClientRect(hwnd, &clRect); - si.cbSize = sizeof(si); - si.fMask = SIF_ALL; - si.nMin = 0; - si.nMax = cli.pfnGetRowTotalHeight(dat)-1; - si.nPage = clRect.bottom; - si.nPos = dat->yScroll; - - if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_CONTACTLIST) { - if (dat->noVScrollbar == 0) - SetScrollInfo(hwnd, SB_VERT, &si, TRUE); - } - else SetScrollInfo(hwnd, SB_VERT, &si, TRUE); - - cli.pfnScrollTo(hwnd, dat, dat->yScroll, 1); - nm.hdr.code = CLN_LISTSIZECHANGE; - nm.hdr.hwndFrom = hwnd; - nm.hdr.idFrom = GetDlgCtrlID(hwnd); - nm.pt.y = si.nMax; - SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm); -} - -void fnSetGroupExpand(HWND hwnd, struct ClcData *dat, ClcGroup *group, int newState) -{ - int contentCount; - int groupy; - int newY, posY; - RECT clRect; - NMCLISTCONTROL nm; - - if (newState == -1) - group->expanded ^= 1; - else { - if (group->expanded == (newState != 0)) - return; - group->expanded = newState != 0; - } - cli.pfnInvalidateRect(hwnd, NULL, FALSE); - contentCount = cli.pfnGetGroupContentsCount(group, 1); - groupy = cli.pfnGetRowsPriorTo(&dat->list, group, -1); - if (dat->selection > groupy && dat->selection < groupy + contentCount) - dat->selection = groupy; - GetClientRect(hwnd, &clRect); - newY = dat->yScroll; - posY = cli.pfnGetRowBottomY(dat, groupy + contentCount); - if (posY >= newY + clRect.bottom) - newY = posY - clRect.bottom; - posY = cli.pfnGetRowTopY(dat, groupy); - if (newY > posY) - newY = posY; - cli.pfnRecalcScrollBar(hwnd, dat); - if (group->expanded) - cli.pfnScrollTo(hwnd, dat, newY, 0); - nm.hdr.code = CLN_EXPANDED; - nm.hdr.hwndFrom = hwnd; - nm.hdr.idFrom = GetDlgCtrlID(hwnd); - nm.hItem = (HANDLE) group->groupId; - nm.action = group->expanded; - SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm); -} - -void fnDoSelectionDefaultAction(HWND hwnd, struct ClcData *dat) -{ - ClcContact *contact; - - if (dat->selection == -1) - return; - dat->szQuickSearch[0] = 0; - if (cli.pfnGetRowByIndex(dat, dat->selection, &contact, NULL) == -1) - return; - if (contact->type == CLCIT_GROUP) - cli.pfnSetGroupExpand(hwnd, dat, contact->group, -1); - if (contact->type == CLCIT_CONTACT) - CallService(MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM) contact->hContact, 0); -} - -int fnFindRowByText(HWND hwnd, struct ClcData *dat, const TCHAR *text, int prefixOk) -{ - ClcGroup *group = &dat->list; - size_t testlen = mir_tstrlen(text); - - group->scanIndex = 0; - for (;;) { - if (group->scanIndex == group->cl.count) { - group = group->parent; - if (group == NULL) - break; - group->scanIndex++; - continue; - } - if (group->cl.items[group->scanIndex]->type != CLCIT_DIVIDER) { - bool show; - if (dat->filterSearch) { - TCHAR *lowered_szText = CharLowerW(NEWTSTR_ALLOCA(group->cl.items[group->scanIndex]->szText)); - TCHAR *lowered_text = CharLowerW(NEWTSTR_ALLOCA(text)); - show = _tcsstr(lowered_szText, lowered_text) != NULL; - } - else show = ((prefixOk && !_tcsnicmp(text, group->cl.items[group->scanIndex]->szText, testlen)) || (!prefixOk && !mir_tstrcmpi(text, group->cl.items[group->scanIndex]->szText))); - - if (show) { - ClcGroup *contactGroup = group; - int contactScanIndex = group->scanIndex; - for (; group; group = group->parent) - cli.pfnSetGroupExpand(hwnd, dat, group, 1); - return cli.pfnGetRowsPriorTo(&dat->list, contactGroup, contactScanIndex); - } - if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) { - if (!(dat->exStyle & CLS_EX_QUICKSEARCHVISONLY) || group->cl.items[group->scanIndex]->group->expanded) { - group = group->cl.items[group->scanIndex]->group; - group->scanIndex = 0; - continue; - } - } - } - group->scanIndex++; - } - return -1; -} - -void fnEndRename(HWND, struct ClcData *dat, int save) -{ - HWND hwndEdit = dat->hwndRenameEdit; - if (hwndEdit == NULL) - return; - - dat->hwndRenameEdit = NULL; - if (save) { - TCHAR text[120]; text[0] = 0; - GetWindowText(hwndEdit, text, SIZEOF(text)); - - ClcContact *contact; - if (cli.pfnGetRowByIndex(dat, dat->selection, &contact, NULL) != -1) { - if (mir_tstrcmp(contact->szText, text) && !_tcsstr(text, _T("\\"))) { - if (contact->type == CLCIT_GROUP) { - if (contact->group->parent && contact->group->parent->parent) { - TCHAR szFullName[256]; - mir_sntprintf(szFullName, SIZEOF(szFullName), _T("%s\\%s"), - cli.pfnGetGroupName(contact->group->parent->groupId, NULL), text); - cli.pfnRenameGroup(contact->groupId, szFullName); - } - else - cli.pfnRenameGroup(contact->groupId, text); - } - else if (contact->type == CLCIT_CONTACT) { - cli.pfnInvalidateDisplayNameCacheEntry(contact->hContact); - TCHAR* otherName = cli.pfnGetContactDisplayName(contact->hContact, GCDNF_NOMYHANDLE); - if (!text[0] || !mir_tstrcmp(otherName, text)) - db_unset(contact->hContact, "CList", "MyHandle"); - else - db_set_ts(contact->hContact, "CList", "MyHandle", text); - mir_free(otherName); - } - } - } - } - DestroyWindow(hwndEdit); -} - -void fnDeleteFromContactList(HWND hwnd, struct ClcData *dat) -{ - ClcContact *contact; - if (dat->selection == -1) - return; - dat->szQuickSearch[0] = 0; - if (cli.pfnGetRowByIndex(dat, dat->selection, &contact, NULL) == -1) - return; - switch (contact->type) { - case CLCIT_GROUP: - CallService(MS_CLIST_GROUPDELETE, (WPARAM)contact->groupId, 0); - break; - case CLCIT_CONTACT: - CallService("CList/DeleteContactCommand", (WPARAM)contact->hContact, (LPARAM)hwnd); - break; - } -} - -static LRESULT CALLBACK RenameEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_KEYDOWN: - switch (wParam) { - case VK_RETURN: - cli.pfnEndRename(GetParent(hwnd), (struct ClcData *) GetWindowLongPtr(GetParent(hwnd), 0), 1); - return 0; - case VK_ESCAPE: - cli.pfnEndRename(GetParent(hwnd), (struct ClcData *) GetWindowLongPtr(GetParent(hwnd), 0), 0); - return 0; - } - break; - case WM_GETDLGCODE: - if (lParam) { - MSG *msg = (MSG *) lParam; - if (msg->message == WM_KEYDOWN && msg->wParam == VK_TAB) - return 0; - if (msg->message == WM_CHAR && msg->wParam == '\t') - return 0; - } - return DLGC_WANTMESSAGE; - case WM_KILLFOCUS: - cli.pfnEndRename(GetParent(hwnd), (struct ClcData *) GetWindowLongPtr(GetParent(hwnd), 0), 1); - return 0; - } - return mir_callNextSubclass(hwnd, RenameEditSubclassProc, msg, wParam, lParam); -} - -void fnBeginRenameSelection(HWND hwnd, struct ClcData *dat) -{ - ClcContact *contact; - ClcGroup *group; - POINT pt; - - KillTimer(hwnd, TIMERID_RENAME); - ReleaseCapture(); - dat->iHotTrack = -1; - dat->selection = cli.pfnGetRowByIndex(dat, dat->selection, &contact, &group); - if (dat->selection == -1) - return; - if (contact->type != CLCIT_CONTACT && contact->type != CLCIT_GROUP) - return; - - RECT clRect; - GetClientRect(hwnd, &clRect); - cli.pfnCalcEipPosition(dat, contact, group, &pt); - int h = cli.pfnGetRowHeight(dat, dat->selection); - dat->hwndRenameEdit = CreateWindow(_T("EDIT"), contact->szText, WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, pt.x, pt.y, clRect.right - pt.x, h, hwnd, NULL, cli.hInst, NULL); - mir_subclassWindow(dat->hwndRenameEdit, RenameEditSubclassProc); - SendMessage(dat->hwndRenameEdit, WM_SETFONT, (WPARAM) (contact->type == CLCIT_GROUP ? dat->fontInfo[FONTID_GROUPS].hFont : dat->fontInfo[FONTID_CONTACTS].hFont), 0); - SendMessage(dat->hwndRenameEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN | EC_USEFONTINFO, 0); - SendMessage(dat->hwndRenameEdit, EM_SETSEL, 0, (LPARAM) (-1)); - ShowWindow(dat->hwndRenameEdit, SW_SHOW); - SetFocus(dat->hwndRenameEdit); -} - -void fnCalcEipPosition(struct ClcData *dat, ClcContact *, ClcGroup *group, POINT *result) -{ - int indent; - for (indent = 0; group->parent; indent++, group = group->parent); - result->x = indent * dat->groupIndent + dat->iconXSpace - 2; - result->y = cli.pfnGetRowTopY(dat, dat->selection) - dat->yScroll; -} - -int fnGetDropTargetInformation(HWND hwnd, struct ClcData *dat, POINT pt) -{ - RECT clRect; - GetClientRect(hwnd, &clRect); - dat->selection = dat->iDragItem; - dat->iInsertionMark = -1; - if (!PtInRect(&clRect, pt)) - return DROPTARGET_OUTSIDE; - - ClcContact *contact, *movecontact; - ClcGroup *group, *movegroup; - DWORD hitFlags; - int hit = cli.pfnHitTest(hwnd, dat, pt.x, pt.y, &contact, &group, &hitFlags); - cli.pfnGetRowByIndex(dat, dat->iDragItem, &movecontact, &movegroup); - if (hit == dat->iDragItem) - return DROPTARGET_ONSELF; - if (hit == -1 || hitFlags & CLCHT_ONITEMEXTRA) - return DROPTARGET_ONNOTHING; - - if (movecontact->type == CLCIT_GROUP) { - ClcContact *bottomcontact = NULL, *topcontact = NULL; - ClcGroup *topgroup = NULL; - int topItem = -1, bottomItem = -1; - int ok = 0; - if (pt.y + dat->yScroll < cli.pfnGetRowTopY(dat, hit) + dat->insertionMarkHitHeight) { - //could be insertion mark (above) - topItem = hit - 1; - bottomItem = hit; - bottomcontact = contact; - topItem = cli.pfnGetRowByIndex(dat, topItem, &topcontact, &topgroup); - ok = 1; - } - if (pt.y + dat->yScroll >= cli.pfnGetRowBottomY(dat, hit+1) - dat->insertionMarkHitHeight) { - //could be insertion mark (below) - topItem = hit; - bottomItem = hit + 1; - topcontact = contact; - topgroup = group; - bottomItem = cli.pfnGetRowByIndex(dat, bottomItem, &bottomcontact, NULL); - ok = 1; - } - if (ok) { - ok = 0; - if (bottomItem == -1 || bottomcontact->type != CLCIT_GROUP) { //need to special-case moving to end - if (topItem != dat->iDragItem) { - for (; topgroup; topgroup = topgroup->parent) { - if (topgroup == movecontact->group) - break; - if (topgroup == movecontact->group->parent) { - ok = 1; - break; - } - } - if (ok) - bottomItem = topItem + 1; - } - } - else if (bottomItem != dat->iDragItem && bottomcontact->type == CLCIT_GROUP && bottomcontact->group->parent == movecontact->group->parent) { - if (bottomcontact != movecontact + 1) - ok = 1; - } - if (ok) { - dat->iInsertionMark = bottomItem; - dat->selection = -1; - return DROPTARGET_INSERTION; - } - } - } - if (contact->type == CLCIT_GROUP) { - if (dat->iInsertionMark == -1) { - if (movecontact->type == CLCIT_GROUP) { //check not moving onto its own subgroup - for (; group; group = group->parent) - if (group == movecontact->group) - return DROPTARGET_ONSELF; - } - dat->selection = hit; - return DROPTARGET_ONGROUP; - } - } - return DROPTARGET_ONCONTACT; -} - -int fnClcStatusToPf2(int status) -{ - switch(status) { - case ID_STATUS_ONLINE: return PF2_ONLINE; - case ID_STATUS_AWAY: return PF2_SHORTAWAY; - case ID_STATUS_DND: return PF2_HEAVYDND; - case ID_STATUS_NA: return PF2_LONGAWAY; - case ID_STATUS_OCCUPIED: return PF2_LIGHTDND; - case ID_STATUS_FREECHAT: return PF2_FREECHAT; - case ID_STATUS_INVISIBLE: return PF2_INVISIBLE; - case ID_STATUS_ONTHEPHONE: return PF2_ONTHEPHONE; - case ID_STATUS_OUTTOLUNCH: return PF2_OUTTOLUNCH; - case ID_STATUS_OFFLINE: return MODEF_OFFLINE; - } - return 0; -} - -int fnIsHiddenMode(struct ClcData *dat, int status) -{ - return dat->offlineModes & cli.pfnClcStatusToPf2(status); -} - -void fnHideInfoTip(HWND, struct ClcData *dat) -{ - if (dat->hInfoTipItem == NULL) - return; - - CLCINFOTIP it = { 0 }; - it.isGroup = IsHContactGroup(dat->hInfoTipItem); - it.hItem = (HANDLE) ((UINT_PTR) dat->hInfoTipItem & ~HCONTACT_ISGROUP); - it.cbSize = sizeof(it); - dat->hInfoTipItem = NULL; - NotifyEventHooks(hHideInfoTipEvent, 0, (LPARAM) & it); -} - -void fnNotifyNewContact(HWND hwnd, MCONTACT hContact) -{ - NMCLISTCONTROL nm; - nm.hdr.code = CLN_NEWCONTACT; - nm.hdr.hwndFrom = hwnd; - nm.hdr.idFrom = GetDlgCtrlID(hwnd); - nm.flags = 0; - nm.hItem = (HANDLE)hContact; - SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) & nm); -} - -DWORD fnGetDefaultExStyle(void) -{ - BOOL param; - DWORD ret = CLCDEFAULT_EXSTYLE; - if (SystemParametersInfo(SPI_GETLISTBOXSMOOTHSCROLLING, 0, ¶m, FALSE) && !param) - ret |= CLS_EX_NOSMOOTHSCROLLING; - if (SystemParametersInfo(SPI_GETHOTTRACKING, 0, ¶m, FALSE) && !param) - ret &= ~CLS_EX_TRACKSELECT; - return ret; -} - -#define DBFONTF_BOLD 1 -#define DBFONTF_ITALIC 2 -#define DBFONTF_UNDERLINE 4 - -void fnGetDefaultFontSetting(int i, LOGFONT* lf, COLORREF* colour) -{ - SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), lf, FALSE); - *colour = GetSysColor(COLOR_WINDOWTEXT); - lf->lfHeight = 8; - switch (i) { - case FONTID_GROUPS: - lf->lfWeight = FW_BOLD; - break; - case FONTID_GROUPCOUNTS: - *colour = GetSysColor(COLOR_3DSHADOW); - break; - case FONTID_OFFINVIS: - case FONTID_INVIS: - lf->lfItalic = !lf->lfItalic; - break; - case FONTID_DIVIDERS: - break; - case FONTID_NOTONLIST: - *colour = GetSysColor(COLOR_3DSHADOW); - break; - } -} - -void fnGetFontSetting(int i, LOGFONT* lf, COLORREF* colour) -{ - cli.pfnGetDefaultFontSetting(i, lf, colour); - - char idstr[20]; - mir_snprintf(idstr, "Font%dName", i); - ptrT tszFace(db_get_tsa(NULL, "CLC", idstr)); - if (tszFace) - mir_tstrcpy(lf->lfFaceName, tszFace); - - mir_snprintf(idstr, "Font%dCol", i); - *colour = db_get_dw(NULL, "CLC", idstr, *colour); - - mir_snprintf(idstr, "Font%dSize", i); - lf->lfHeight = (char)db_get_b(NULL, "CLC", idstr, lf->lfHeight); - - mir_snprintf(idstr, "Font%dSty", i); - BYTE style = (BYTE)db_get_b(NULL, "CLC", idstr, (lf->lfWeight == FW_NORMAL ? 0 : DBFONTF_BOLD) | (lf->lfItalic ? DBFONTF_ITALIC : 0) | (lf->lfUnderline ? DBFONTF_UNDERLINE : 0)); - lf->lfWidth = lf->lfEscapement = lf->lfOrientation = 0; - lf->lfWeight = style & DBFONTF_BOLD ? FW_BOLD : FW_NORMAL; - lf->lfItalic = (style & DBFONTF_ITALIC) != 0; - lf->lfUnderline = (style & DBFONTF_UNDERLINE) != 0; - lf->lfStrikeOut = 0; - - mir_snprintf(idstr, "Font%dSet", i); - lf->lfCharSet = db_get_b(NULL, "CLC", idstr, lf->lfCharSet); - lf->lfOutPrecision = OUT_DEFAULT_PRECIS; - lf->lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf->lfQuality = DEFAULT_QUALITY; - lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; -} - -void fnLoadClcOptions(HWND hwnd, struct ClcData *dat, BOOL bFirst) -{ - dat->rowHeight = db_get_b(NULL, "CLC", "RowHeight", CLCDEFAULT_ROWHEIGHT); - - dat->leftMargin = db_get_b(NULL, "CLC", "LeftMargin", CLCDEFAULT_LEFTMARGIN); - dat->exStyle = db_get_dw(NULL, "CLC", "ExStyle", cli.pfnGetDefaultExStyle()); - dat->scrollTime = db_get_w(NULL, "CLC", "ScrollTime", CLCDEFAULT_SCROLLTIME); - dat->groupIndent = db_get_b(NULL, "CLC", "GroupIndent", CLCDEFAULT_GROUPINDENT); - dat->gammaCorrection = db_get_b(NULL, "CLC", "GammaCorrect", CLCDEFAULT_GAMMACORRECT); - dat->showIdle = db_get_b(NULL, "CLC", "ShowIdle", CLCDEFAULT_SHOWIDLE); - dat->noVScrollbar = db_get_b(NULL, "CLC", "NoVScrollBar", 0); - dat->filterSearch = db_get_b(NULL, "CLC", "FilterSearch", 1); - SendMessage(hwnd, INTM_SCROLLBARCHANGED, 0, 0); - - dat->greyoutFlags = db_get_dw(NULL, "CLC", "GreyoutFlags", CLCDEFAULT_GREYOUTFLAGS); - dat->offlineModes = db_get_dw(NULL, "CLC", "OfflineModes", CLCDEFAULT_OFFLINEMODES); - dat->selBkColour = db_get_dw(NULL, "CLC", "SelBkColour", CLCDEFAULT_SELBKCOLOUR); - dat->selTextColour = db_get_dw(NULL, "CLC", "SelTextColour", CLCDEFAULT_SELTEXTCOLOUR); - dat->hotTextColour = db_get_dw(NULL, "CLC", "HotTextColour", CLCDEFAULT_HOTTEXTCOLOUR); - dat->quickSearchColour = db_get_dw(NULL, "CLC", "QuickSearchColour", CLCDEFAULT_QUICKSEARCHCOLOUR); - dat->useWindowsColours = db_get_b(NULL, "CLC", "UseWinColours", CLCDEFAULT_USEWINDOWSCOLOURS); - - if (cli.hwndContactTree != NULL && hwnd != cli.hwndContactTree) { - dat->bkChanged = true; // block custom background - dat->bkColour = GetSysColor(COLOR_WINDOW); - if (dat->hBmpBackground) { - DeleteObject(dat->hBmpBackground); - dat->hBmpBackground = NULL; - } - - dat->greyoutFlags = 0; - dat->leftMargin = 4; - dat->groupIndent = 10; - - LPARAM dwColor = GetSysColor(COLOR_WINDOWTEXT); - for (int i=0; i <= FONTID_MAX; i++) - SendMessage(hwnd, CLM_SETTEXTCOLOR, i, dwColor); - } - - if (!dat->bkChanged) { - dat->bkColour = db_get_dw(NULL, "CLC", "BkColour", CLCDEFAULT_BKCOLOUR); - if (dat->hBmpBackground) { - DeleteObject(dat->hBmpBackground); - dat->hBmpBackground = NULL; - } - if (db_get_b(NULL, "CLC", "UseBitmap", CLCDEFAULT_USEBITMAP)) { - ptrT tszBitmap(db_get_tsa(NULL, "CLC", "BkBitmap")); - if (tszBitmap) - dat->hBmpBackground = Bitmap_Load(tszBitmap); - } - dat->backgroundBmpUse = db_get_w(NULL, "CLC", "BkBmpUse", CLCDEFAULT_BKBMPUSE); - } - - NMHDR hdr; - hdr.code = CLN_OPTIONSCHANGED; - hdr.hwndFrom = hwnd; - hdr.idFrom = (bFirst) ? 0 : GetDlgCtrlID(hwnd); - SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)&hdr); - - SendMessage(hwnd, WM_SIZE, 0, 0); -} - -#define GSIF_HASMEMBERS 0x80000000 -#define GSIF_ALLCHECKED 0x40000000 -#define GSIF_INDEXMASK 0x3FFFFFFF - -void fnRecalculateGroupCheckboxes(HWND, struct ClcData *dat) -{ - ClcGroup *group = &dat->list; - group->scanIndex = GSIF_ALLCHECKED; - for (;;) { - if ((group->scanIndex & GSIF_INDEXMASK) == group->cl.count) { - int check = (group->scanIndex & (GSIF_HASMEMBERS | GSIF_ALLCHECKED)) == (GSIF_HASMEMBERS | GSIF_ALLCHECKED); - if (group->parent == NULL) - break; - group->parent->scanIndex |= group->scanIndex & GSIF_HASMEMBERS; - group = group->parent; - if (check) - group->cl.items[(group->scanIndex & GSIF_INDEXMASK)]->flags |= CONTACTF_CHECKED; - else { - group->cl.items[(group->scanIndex & GSIF_INDEXMASK)]->flags &= ~CONTACTF_CHECKED; - group->scanIndex &= ~GSIF_ALLCHECKED; - } - } - else if (group->cl.items[(group->scanIndex & GSIF_INDEXMASK)]->type == CLCIT_GROUP) { - group = group->cl.items[(group->scanIndex & GSIF_INDEXMASK)]->group; - group->scanIndex = GSIF_ALLCHECKED; - continue; - } - else if (group->cl.items[(group->scanIndex & GSIF_INDEXMASK)]->type == CLCIT_CONTACT) { - group->scanIndex |= GSIF_HASMEMBERS; - if (!(group->cl.items[(group->scanIndex & GSIF_INDEXMASK)]->flags & CONTACTF_CHECKED)) - group->scanIndex &= ~GSIF_ALLCHECKED; - } - group->scanIndex++; - } -} - -void fnSetContactCheckboxes(ClcContact *cc, int checked) -{ - if (checked) - cc->flags |= CONTACTF_CHECKED; - else - cc->flags &= ~CONTACTF_CHECKED; -} - -void fnSetGroupChildCheckboxes(ClcGroup *group, int checked) -{ - for (int i=0; i < group->cl.count; i++) { - ClcContact *cc = group->cl.items[i]; - if (cc->type == CLCIT_GROUP) { - cli.pfnSetGroupChildCheckboxes(cc->group, checked); - cli.pfnSetContactCheckboxes(cc, checked); - } - else if (cc->type == CLCIT_CONTACT) - cli.pfnSetContactCheckboxes(cc, checked); - } -} - -void fnInvalidateItem(HWND hwnd, struct ClcData *dat, int iItem) -{ - if (iItem == -1) - return; - - RECT rc; - GetClientRect(hwnd, &rc); - rc.top = cli.pfnGetRowTopY(dat, iItem) - dat->yScroll; - rc.bottom = rc.top + cli.pfnGetRowHeight(dat, iItem); - cli.pfnInvalidateRect(hwnd, &rc, FALSE); -} - -/////////////////////////////////////////////////////////////////////////////// -// row coord functions - -int fnGetRowTopY(struct ClcData *dat, int item) -{ - return item * dat->rowHeight; -} - -int fnGetRowBottomY(struct ClcData *dat, int item) -{ - return (item+1) * dat->rowHeight; -} - -int fnGetRowTotalHeight(struct ClcData *dat) -{ - return dat->rowHeight * cli.pfnGetGroupContentsCount(&dat->list, 1); -} - -int fnGetRowHeight(struct ClcData *dat, int) -{ - return dat->rowHeight; -} - -int fnRowHitTest(struct ClcData *dat, int y) -{ - if (!dat->rowHeight) - return y; - return y / dat->rowHeight; -} diff --git a/src/modules/clist/clistcore.cpp b/src/modules/clist/clistcore.cpp deleted file mode 100644 index 976525e4a2..0000000000 --- a/src/modules/clist/clistcore.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" -#include "genmenu.h" -#include "..\extraicons\extraicons.h" - -CLIST_INTERFACE cli = { 0 }; - -static TCHAR szTip[MAX_TIP_SIZE+1]; - -int LoadContactListModule2(void); -int LoadCLCModule(void); -void BuildProtoMenus(void); - -static int interfaceInited = 0; - -static void fnPaintClc(HWND, ClcData*, HDC, RECT*) -{ -} - -static ClcContact* fnCreateClcContact(void) -{ - return (ClcContact*)mir_calloc(sizeof(ClcContact)); -} - -static BOOL fnInvalidateRect(HWND hwnd, CONST RECT* lpRect, BOOL bErase) -{ - return InvalidateRect(hwnd, lpRect, bErase); -} - -static void fnOnCreateClc(void) -{ -} - -static void fnReloadProtoMenus(void) -{ - RebuildMenuOrder(); - if (db_get_b(NULL, "CList", "MoveProtoMenus", TRUE)) - BuildProtoMenus(); - cli.pfnCluiProtocolStatusChanged(0, 0); -} - -static INT_PTR srvRetrieveInterface(WPARAM, LPARAM) -{ - int rc; - - if (interfaceInited == 0) { - cli.version = 6; - cli.bDisplayLocked = TRUE; - - cli.pfnClcOptionsChanged = fnClcOptionsChanged; - cli.pfnClcBroadcast = fnClcBroadcast; - cli.pfnContactListControlWndProc = fnContactListControlWndProc; - cli.pfnBuildGroupPopupMenu = fnBuildGroupPopupMenu; - - cli.pfnRegisterFileDropping = fnRegisterFileDropping; - cli.pfnUnregisterFileDropping = fnUnregisterFileDropping; - - cli.pfnGetRowsPriorTo = fnGetRowsPriorTo; - cli.pfnFindItem = fnFindItem; - cli.pfnGetRowByIndex = fnGetRowByIndex; - cli.pfnContactToHItem = fnContactToHItem; - cli.pfnContactToItemHandle = fnContactToItemHandle; - - cli.pfnAddGroup = fnAddGroup; - cli.pfnAddItemToGroup = fnAddItemToGroup; - cli.pfnCreateClcContact = fnCreateClcContact; - cli.pfnRemoveItemFromGroup = fnRemoveItemFromGroup; - cli.pfnFreeContact = fnFreeContact; - cli.pfnFreeGroup = fnFreeGroup; - cli.pfnAddInfoItemToGroup = fnAddInfoItemToGroup; - cli.pfnAddContactToGroup = fnAddContactToGroup; - cli.pfnAddContactToTree = fnAddContactToTree; - cli.pfnDeleteItemFromTree = fnDeleteItemFromTree; - cli.pfnRebuildEntireList = fnRebuildEntireList; - cli.pfnGetGroupContentsCount = fnGetGroupContentsCount; - cli.pfnSortCLC = fnSortCLC; - cli.pfnSaveStateAndRebuildList = fnSaveStateAndRebuildList; - - cli.pfnProcessExternalMessages = fnProcessExternalMessages; - - cli.pfnPaintClc = fnPaintClc; - - cli.pfnGetGroupCountsText = fnGetGroupCountsText; - cli.pfnHitTest = fnHitTest; - cli.pfnScrollTo = fnScrollTo; - cli.pfnEnsureVisible = fnEnsureVisible; - cli.pfnRecalcScrollBar = fnRecalcScrollBar; - cli.pfnSetGroupExpand = fnSetGroupExpand; - cli.pfnDoSelectionDefaultAction = fnDoSelectionDefaultAction; - cli.pfnFindRowByText = fnFindRowByText; - cli.pfnEndRename = fnEndRename; - cli.pfnDeleteFromContactList = fnDeleteFromContactList; - cli.pfnBeginRenameSelection = fnBeginRenameSelection; - cli.pfnCalcEipPosition = fnCalcEipPosition; - cli.pfnGetDropTargetInformation = fnGetDropTargetInformation; - cli.pfnClcStatusToPf2 = fnClcStatusToPf2; - cli.pfnIsHiddenMode = fnIsHiddenMode; - cli.pfnHideInfoTip = fnHideInfoTip; - cli.pfnNotifyNewContact = fnNotifyNewContact; - cli.pfnGetDefaultExStyle = fnGetDefaultExStyle; - cli.pfnGetDefaultFontSetting = fnGetDefaultFontSetting; - cli.pfnGetFontSetting = fnGetFontSetting; - cli.pfnLoadClcOptions = fnLoadClcOptions; - cli.pfnRecalculateGroupCheckboxes = fnRecalculateGroupCheckboxes; - cli.pfnSetGroupChildCheckboxes = fnSetGroupChildCheckboxes; - cli.pfnSetContactCheckboxes = fnSetContactCheckboxes; - cli.pfnInvalidateItem = fnInvalidateItem; - cli.pfnGetRowBottomY = fnGetRowBottomY; - cli.pfnGetRowHeight = fnGetRowHeight; - cli.pfnGetRowTopY = fnGetRowTopY; - cli.pfnGetRowTotalHeight = fnGetRowTotalHeight; - cli.pfnRowHitTest = fnRowHitTest; - - cli.pfnAddEvent = fnAddEvent; - cli.pfnCreateEvent = fnCreateEvent; - cli.pfnEventsProcessContactDoubleClick = fnEventsProcessContactDoubleClick; - cli.pfnEventsProcessTrayDoubleClick = fnEventsProcessTrayDoubleClick; - cli.pfnFreeEvent = fnFreeEvent; - cli.pfnGetEvent = fnGetEvent; - cli.pfnGetImlIconIndex = fnGetImlIconIndex; - cli.pfnRemoveEvent = fnRemoveEvent; - - cli.pfnGetContactDisplayName = fnGetContactDisplayName; - cli.pfnInvalidateDisplayNameCacheEntry = fnInvalidateDisplayNameCacheEntry; - cli.pfnCreateCacheItem = fnCreateCacheItem; - cli.pfnCheckCacheItem = fnCheckCacheItem; - cli.pfnFreeCacheItem = fnFreeCacheItem; - cli.pfnGetCacheEntry = fnGetCacheEntry; - - cli.szTip = szTip; - cli.pfnInitTray = fnInitTray; - cli.pfnUninitTray = fnUninitTray; - - cli.pfnTrayCycleTimerProc = fnTrayCycleTimerProc; - cli.pfnTrayIconAdd = fnTrayIconAdd; - cli.pfnTrayIconDestroy = fnTrayIconDestroy; - cli.pfnTrayIconIconsChanged = fnTrayIconIconsChanged; - cli.pfnTrayIconInit = fnTrayIconInit; - cli.pfnTrayIconMakeTooltip = fnTrayIconMakeTooltip; - cli.pfnTrayIconPauseAutoHide = fnTrayIconPauseAutoHide; - cli.pfnTrayIconProcessMessage = fnTrayIconProcessMessage; - cli.pfnTrayIconRemove = fnTrayIconRemove; - cli.pfnTrayIconSetBaseInfo = fnTrayIconSetBaseInfo; - cli.pfnTrayIconSetToBase = fnTrayIconSetToBase; - cli.pfnTrayIconTaskbarCreated = fnTrayIconTaskbarCreated; - cli.pfnTrayIconUpdate = fnTrayIconUpdate; - cli.pfnTrayIconUpdateBase = fnTrayIconUpdateBase; - cli.pfnTrayCalcChanged = fnTrayCalcChanged; - cli.pfnTrayIconUpdateWithImageList = fnTrayIconUpdateWithImageList; - cli.pfnCListTrayNotify = fnCListTrayNotify; - - cli.pfnContactListWndProc = fnContactListWndProc; - cli.pfnLoadCluiGlobalOpts = fnLoadCluiGlobalOpts; - cli.pfnCluiProtocolStatusChanged = fnCluiProtocolStatusChanged; - cli.pfnDrawMenuItem = fnDrawMenuItem; - cli.pfnInvalidateRect = fnInvalidateRect; - cli.pfnOnCreateClc = fnOnCreateClc; - - cli.pfnChangeContactIcon = fnChangeContactIcon; - cli.pfnLoadContactTree = fnLoadContactTree; - cli.pfnCompareContacts = fnCompareContacts; - cli.pfnSortContacts = fnSortContacts; - cli.pfnSetHideOffline = fnSetHideOffline; - - cli.pfnDocking_ProcessWindowMessage = fnDocking_ProcessWindowMessage; - - cli.pfnGetIconFromStatusMode = fnGetIconFromStatusMode; - cli.pfnGetWindowVisibleState = fnGetWindowVisibleState; - cli.pfnIconFromStatusMode = fnIconFromStatusMode; - cli.pfnShowHide = fnShowHide; - cli.pfnGetStatusModeDescription = fnGetStatusModeDescription; - - cli.pfnGetGroupName = fnGetGroupName; - cli.pfnRenameGroup = fnRenameGroup; - - cli.pfnHotKeysRegister = fnHotKeysRegister; - cli.pfnHotKeysUnregister = fnHotKeysUnregister; - cli.pfnHotKeysProcess = fnHotKeysProcess; - cli.pfnHotkeysProcessMessage = fnHotkeysProcessMessage; - - cli.pfnGetProtocolVisibility = fnGetProtocolVisibility; - cli.pfnGetProtoIndexByPos = fnGetProtoIndexByPos; - cli.pfnReloadProtoMenus = fnReloadProtoMenus; - cli.pfnGetAccountIndexByPos = fnGetAccountIndexByPos; - cli.pfnGetProtocolMenu = fnGetProtocolMenu; - cli.pfnConvertMenu = fnConvertMenu; - - cli.pfnReloadExtraIcons = fnReloadExtraIcons; - cli.pfnSetAllExtraIcons = fnSetAllExtraIcons; - - cli.pfnGetContactIcon = fnGetContactIcon; - cli.pfnGetAverageMode = fnGetAverageMode; - cli.pfnInitAutoRebuild = fnInitAutoRebuild; - - rc = LoadContactListModule2(); - if (rc == 0) - rc = LoadCLCModule(); - interfaceInited = 1; - } - - return (LPARAM)&cli; -} - -int LoadContactListModule() -{ - CreateServiceFunction(MS_CLIST_RETRIEVE_INTERFACE, srvRetrieveInterface); - return 0; -} diff --git a/src/modules/clist/clistevents.cpp b/src/modules/clist/clistevents.cpp deleted file mode 100644 index defb917c23..0000000000 --- a/src/modules/clist/clistevents.cpp +++ /dev/null @@ -1,423 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -struct CListEvent -{ - int imlIconIndex; - int flashesDone; - CLISTEVENT cle; -}; - -struct CListImlIcon -{ - int index; - HICON hIcon; -}; -static struct CListImlIcon *imlIcon; -static int imlIconCount; - -extern HIMAGELIST hCListImages; - -static UINT_PTR flashTimerId; -static int iconsOn; -static int disableTrayFlash; -static int disableIconFlash; - -int fnGetImlIconIndex(HICON hIcon) -{ - int i; - for (i=0; i < imlIconCount; i++) - if (imlIcon[i].hIcon == hIcon) - return imlIcon[i].index; - - imlIcon = (struct CListImlIcon *) mir_realloc(imlIcon, sizeof(struct CListImlIcon) * (imlIconCount + 1)); - imlIconCount++; - imlIcon[i].hIcon = hIcon; - imlIcon[i].index = ImageList_AddIcon(hCListImages, hIcon); - return imlIcon[i].index; -} - -static char * GetEventProtocol(int idx) -{ - if (!cli.events.count || idx < 0 && idx >= cli.events.count) - return NULL; - - CListEvent *ev = cli.events.items[idx]; - if (ev->cle.hContact != NULL) - return GetContactProto(ev->cle.hContact); - - return (ev->cle.flags & CLEF_PROTOCOLGLOBAL) ? ev->cle.lpszProtocol : NULL; -} - -static void ShowOneEventInTray(int idx) -{ - cli.pfnTrayIconUpdateWithImageList((iconsOn || disableTrayFlash) ? cli.events.items[idx]->imlIconIndex : 0, cli.events.items[idx]->cle.ptszTooltip, GetEventProtocol(idx)); -} - -static void ShowEventsInTray() -{ - int nTrayCnt = cli.trayIconCount; - if (!cli.events.count || !nTrayCnt) return; - if (cli.events.count == 1 || nTrayCnt == 1) { - ShowOneEventInTray(0); //for only one icon in tray show topmost event - return; - } - - // in case if we have several icons in tray and several events with different protocols - // lets use several icon to show events from protocols in different icons - mir_cslock lck(trayLockCS); - char **pTrayProtos = (char**)_alloca(sizeof(char*)*cli.trayIconCount); - int nTrayProtoCnt = 0; - for (int i = 0; i < cli.trayIconCount; i++) - if (cli.trayIcon[i].id != 0 && cli.trayIcon[i].szProto) - pTrayProtos[nTrayProtoCnt++] = cli.trayIcon[i].szProto; - - for (int i = 0; i < cli.events.count; i++) { - char *iEventProto = GetEventProtocol(i); - - int j; - for (j = 0; j < nTrayProtoCnt; j++) - if (iEventProto && pTrayProtos[j] && !mir_strcmp(pTrayProtos[j], iEventProto)) - break; - if (j >= nTrayProtoCnt) // event was not found so assume first icon - j = 0; - if (pTrayProtos[j]) // if not already set - ShowOneEventInTray(i); // show it - pTrayProtos[j] = NULL; // and clear slot - } -} - -static VOID CALLBACK IconFlashTimer(HWND, UINT, UINT_PTR idEvent, DWORD) -{ - ShowEventsInTray(); - - for (int i=0; i < cli.events.count; i++) { - int j; - for (j = 0; j < i; j++) - if (cli.events.items[j]->cle.hContact == cli.events.items[i]->cle.hContact) - break; - if (j >= i) - cli.pfnChangeContactIcon(cli.events.items[i]->cle.hContact, iconsOn || disableIconFlash ? cli.events.items[i]->imlIconIndex : 0, 0); - - // decrease eflashes in any case - no need to collect all events - if (cli.events.items[i]->cle.flags & CLEF_ONLYAFEW) - if (0 >= --cli.events.items[i]->flashesDone) - cli.pfnRemoveEvent(cli.events.items[i]->cle.hContact, cli.events.items[i]->cle.hDbEvent); - } - - if (cli.events.count == 0) { - KillTimer(NULL, idEvent); - cli.pfnTrayIconSetToBase(NULL); - } - - iconsOn = !iconsOn; -} - -CListEvent* fnAddEvent(CLISTEVENT *cle) -{ - int i; - - if (cle == NULL || cle->cbSize != sizeof(CLISTEVENT)) - return NULL; - - if (cle->flags & CLEF_URGENT) { - for (i=0; i < cli.events.count; i++) - if (!(cli.events.items[i]->cle.flags & CLEF_URGENT)) - break; - } - else i = cli.events.count; - - CListEvent *p = cli.pfnCreateEvent(); - if (p == NULL) - return NULL; - - List_Insert((SortedList*)&cli.events, p, i); - p->cle = *cle; - p->imlIconIndex = fnGetImlIconIndex(cli.events.items[i]->cle.hIcon); - p->flashesDone = 12; - p->cle.pszService = mir_strdup(cli.events.items[i]->cle.pszService); - if (p->cle.flags & CLEF_UNICODE) - p->cle.ptszTooltip = mir_tstrdup(p->cle.ptszTooltip); - else - p->cle.ptszTooltip = mir_a2u(p->cle.pszTooltip); //if no flag defined it handled as unicode - if (cli.events.count == 1) { - char *szProto; - if (cle->hContact == NULL) { - if (cle->flags & CLEF_PROTOCOLGLOBAL) - szProto = cle->lpszProtocol; - else - szProto = NULL; - } - else szProto = GetContactProto(cle->hContact); - - iconsOn = 1; - flashTimerId = SetTimer(NULL, 0, db_get_w(NULL, "CList", "IconFlashTime", 550), IconFlashTimer); - cli.pfnTrayIconUpdateWithImageList(p->imlIconIndex, p->cle.ptszTooltip, szProto); - } - cli.pfnChangeContactIcon(cle->hContact, p->imlIconIndex, 1); - cli.pfnSortContacts(); - return p; -} - -// Removes an event from the contact list's queue -// Returns 0 if the event was successfully removed, or nonzero if the event was not found -int fnRemoveEvent(MCONTACT hContact, MEVENT dbEvent) -{ - // Find the event that should be removed - int i; - for (i=0; i < cli.events.count; i++) - if ((cli.events.items[i]->cle.hContact == hContact) && (cli.events.items[i]->cle.hDbEvent == dbEvent)) - break; - - // Event was not found - if (i == cli.events.count) - return 1; - - // Update contact's icon - char *szProto = GetContactProto(hContact); - cli.pfnChangeContactIcon(cli.events.items[i]->cle.hContact, - CallService(MS_CLIST_GETCONTACTICON, (WPARAM)cli.events.items[i]->cle.hContact, 1), 0); - - // Free any memory allocated to the event - cli.pfnFreeEvent(cli.events.items[i]); - List_Remove((SortedList*)&cli.events, i); - - //count same protocoled events - int nSameProto = 0; - char *szEventProto; - for (int i = 0; i < cli.events.count; i++) { - if (cli.events.items[i]->cle.hContact) - szEventProto = GetContactProto((cli.events.items[i]->cle.hContact)); - else if (cli.events.items[i]->cle.flags & CLEF_PROTOCOLGLOBAL) - szEventProto = (char *)cli.events.items[i]->cle.lpszProtocol; - else - szEventProto = NULL; - if (szEventProto && szProto && !mir_strcmp(szEventProto, szProto)) - nSameProto++; - } - - if (cli.events.count == 0 || nSameProto == 0) { - if (cli.events.count == 0) - KillTimer(NULL, flashTimerId); - cli.pfnTrayIconSetToBase(hContact == NULL ? NULL : szProto); - } - else { - if (cli.events.items[0]->cle.hContact == NULL) - szProto = NULL; - else - szProto = GetContactProto(cli.events.items[0]->cle.hContact); - cli.pfnTrayIconUpdateWithImageList(iconsOn ? cli.events.items[0]->imlIconIndex : 0, cli.events.items[0]->cle.ptszTooltip, szProto); - } - - return 0; -} - -CLISTEVENT* fnGetEvent(MCONTACT hContact, int idx) -{ - if (hContact == INVALID_CONTACT_ID) { - if (idx >= cli.events.count) - return NULL; - return &cli.events.items[idx]->cle; - } - - for (int i=0; i < cli.events.count; i++) - if (cli.events.items[i]->cle.hContact == hContact) - if (idx-- == 0) - return &cli.events.items[i]->cle; - return NULL; -} - -int fnEventsProcessContactDoubleClick(MCONTACT hContact) -{ - for (int i = 0; i < cli.events.count; i++) { - if (cli.events.items[i]->cle.hContact == hContact) { - MEVENT hDbEvent = cli.events.items[i]->cle.hDbEvent; - CallService(cli.events.items[i]->cle.pszService, (WPARAM)(HWND)NULL, (LPARAM)& cli.events.items[i]->cle); - cli.pfnRemoveEvent(hContact, hDbEvent); - return 0; - } - } - - return 1; -} - -int fnEventsProcessTrayDoubleClick(int index) -{ - BOOL click_in_first_icon = FALSE; - if (cli.events.count == 0) - return 1; - - int eventIndex = 0; - - mir_cslockfull lck(trayLockCS); - if (cli.trayIconCount > 1 && index > 0) { - int i; - char *szProto = NULL; - for (i = 0; i < cli.trayIconCount; i++) { - if (cli.trayIcon[i].id == index) { - szProto = cli.trayIcon[i].szProto; - if (i == 0) - click_in_first_icon = TRUE; - break; - } - } - if (szProto) { - for (i = 0; i < cli.events.count; i++) { - char *eventProto = NULL; - if (cli.events.items[i]->cle.hContact) - eventProto = GetContactProto(cli.events.items[i]->cle.hContact); - if (!eventProto) - eventProto = cli.events.items[i]->cle.lpszProtocol; - - if (!eventProto || !_strcmpi(eventProto, szProto)) { - eventIndex = i; - break; - } - } - - // let's process backward try to find first event without desired proto in tray - if (i == cli.events.count) { - if (click_in_first_icon) { - for (i = 0; i < cli.events.count; i++) { - char *eventProto = NULL; - if (cli.events.items[i]->cle.hContact) - eventProto = GetContactProto(cli.events.items[i]->cle.hContact); - if (!eventProto) - eventProto = cli.events.items[i]->cle.lpszProtocol; - if (!eventProto) - continue; - - int j; - for (j = 0; j < cli.trayIconCount; j++) - if (cli.trayIcon[j].szProto && !_strcmpi(eventProto, cli.trayIcon[j].szProto)) - break; - - if (j == cli.trayIconCount) { - eventIndex = i; - break; - } - } - } - if (i == cli.events.count) //not found - return 1; //continue processing to show contact list - } - } - } - lck.unlock(); - - MCONTACT hContact = cli.events.items[eventIndex]->cle.hContact; - MEVENT hDbEvent = cli.events.items[eventIndex]->cle.hDbEvent; - // ; may be better to show send msg? - CallService(cli.events.items[eventIndex]->cle.pszService, 0, (LPARAM)& cli.events.items[eventIndex]->cle); - cli.pfnRemoveEvent(hContact, hDbEvent); - return 0; -} - -static int RemoveEventsForContact(WPARAM wParam, LPARAM) -{ - int j, hit; - - /* - the for (;;) loop is used here since the cli.events.count can not be relied upon to take us - thru the cli.events.items[] array without suffering from shortsightedness about how many unseen - events remain, e.g. three events, we remove the first, we're left with 2, the event - loop exits at 2 and we never see the real new 2. - */ - - for (; cli.events.count > 0;) { - for (hit = 0, j = 0; j < cli.events.count; j++) { - if (cli.events.items[j]->cle.hContact == wParam) { - cli.pfnRemoveEvent(wParam, cli.events.items[j]->cle.hDbEvent); - hit = 1; - } - } - if (j == cli.events.count && hit == 0) - return 0; /* got to the end of the array and didnt remove anything */ - } - - return 0; -} - -static int CListEventSettingsChanged(WPARAM hContact, LPARAM lParam) -{ - DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam; - if (hContact == NULL && cws && cws->szModule && cws->szSetting && mir_strcmp(cws->szModule, "CList") == 0) { - if (mir_strcmp(cws->szSetting, "DisableTrayFlash") == 0) - disableTrayFlash = (int)cws->value.bVal; - else if (mir_strcmp(cws->szSetting, "NoIconBlink") == 0) - disableIconFlash = (int)cws->value.bVal; - } - return 0; -} - -/***************************************************************************************/ - -INT_PTR AddEventSyncStub(WPARAM wParam, LPARAM lParam) { return CallServiceSync(MS_CLIST_ADDEVENT"_SYNC", wParam, lParam); } -INT_PTR AddEventStub(WPARAM, LPARAM lParam) { return cli.pfnAddEvent((CLISTEVENT*)lParam) == NULL; } -INT_PTR RemoveEventStub(WPARAM wParam, LPARAM lParam) { return cli.pfnRemoveEvent(wParam, lParam); } -INT_PTR GetEventStub(WPARAM wParam, LPARAM lParam) { return (INT_PTR)cli.pfnGetEvent(wParam, (int)lParam); } - -int InitCListEvents(void) -{ - memset(&cli.events, 0, sizeof(cli.events)); - cli.events.increment = 10; - - disableTrayFlash = db_get_b(NULL, "CList", "DisableTrayFlash", 0); - disableIconFlash = db_get_b(NULL, "CList", "NoIconBlink", 0); - CreateServiceFunction(MS_CLIST_ADDEVENT, AddEventSyncStub); //need to be called through sync to keep flash timer workable - CreateServiceFunction(MS_CLIST_ADDEVENT"_SYNC", AddEventStub); - CreateServiceFunction(MS_CLIST_REMOVEEVENT, RemoveEventStub); - CreateServiceFunction(MS_CLIST_GETEVENT, GetEventStub); - HookEvent(ME_DB_CONTACT_DELETED, RemoveEventsForContact); - HookEvent(ME_DB_CONTACT_SETTINGCHANGED, CListEventSettingsChanged); - return 0; -} - -CListEvent* fnCreateEvent(void) -{ - return (CListEvent*)mir_calloc(sizeof(CListEvent)); -} - -void fnFreeEvent(CListEvent *p) -{ - mir_free(p->cle.pszService); - mir_free(p->cle.pszTooltip); - mir_free(p); -} - -void UninitCListEvents(void) -{ - if (cli.events.count) - KillTimer(NULL, flashTimerId); - - for (int i=0; i < cli.events.count; i++) - cli.pfnFreeEvent((CListEvent*)cli.events.items[i]); - List_Destroy((SortedList*)&cli.events); - - if (imlIcon != NULL) - mir_free(imlIcon); -} diff --git a/src/modules/clist/clistmenus.cpp b/src/modules/clist/clistmenus.cpp deleted file mode 100644 index a2ab028c3a..0000000000 --- a/src/modules/clist/clistmenus.cpp +++ /dev/null @@ -1,1351 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#pragma hdrstop - -#include "m_hotkeys.h" - -#include "clc.h" -#include "genmenu.h" - -#define MS_CLIST_HKSTATUS "Clist/HK/SetStatus" - -#define FIRSTCUSTOMMENUITEMID 30000 -#define MENU_CUSTOMITEMMAIN 0x80000000 -//#define MENU_CUSTOMITEMCONTEXT 0x40000000 -//#define MENU_CUSTOMITEMFRAME 0x20000000 - -typedef struct { - WORD id; - int iconId; - CLISTMENUITEM mi; -} - CListIntMenuItem, *lpCListIntMenuItem; - -//new menu sys -HANDLE hMainMenuObject = 0; -HANDLE hContactMenuObject = 0; -HANDLE hStatusMenuObject = 0; -int UnloadMoveToGroup(void); - -int statustopos(int status); -void Proto_SetStatus(const char *szProto, unsigned status); - -bool prochotkey; - -HANDLE hPreBuildMainMenuEvent, hStatusModeChangeEvent, hPreBuildContactMenuEvent; - -static HMENU hMainMenu, hStatusMenu = 0; -static const int statusModeList[MAX_STATUS_COUNT] = -{ - ID_STATUS_OFFLINE, ID_STATUS_ONLINE, ID_STATUS_AWAY, ID_STATUS_NA, ID_STATUS_OCCUPIED, - ID_STATUS_DND, ID_STATUS_FREECHAT, ID_STATUS_INVISIBLE, ID_STATUS_ONTHEPHONE, ID_STATUS_OUTTOLUNCH -}; - -static const int skinIconStatusList[MAX_STATUS_COUNT] = -{ - SKINICON_STATUS_OFFLINE, SKINICON_STATUS_ONLINE, SKINICON_STATUS_AWAY, SKINICON_STATUS_NA, SKINICON_STATUS_OCCUPIED, - SKINICON_STATUS_DND, SKINICON_STATUS_FREE4CHAT, SKINICON_STATUS_INVISIBLE, SKINICON_STATUS_ONTHEPHONE, SKINICON_STATUS_OUTTOLUNCH -}; - -static const int statusModePf2List[MAX_STATUS_COUNT] = -{ - 0xFFFFFFFF, PF2_ONLINE, PF2_SHORTAWAY, PF2_LONGAWAY, PF2_LIGHTDND, - PF2_HEAVYDND, PF2_FREECHAT, PF2_INVISIBLE, PF2_ONTHEPHONE, PF2_OUTTOLUNCH -}; - -static INT_PTR statusHotkeys[MAX_STATUS_COUNT]; - -PMO_IntMenuItem* hStatusMainMenuHandles; -int hStatusMainMenuHandlesCnt; - -typedef struct -{ - int protoindex; - int protostatus[MAX_STATUS_COUNT]; - PMO_IntMenuItem menuhandle[MAX_STATUS_COUNT]; -} -tStatusMenuHandles, *lpStatusMenuHandles; - -lpStatusMenuHandles hStatusMenuHandles; -int hStatusMenuHandlesCnt; - -//mainmenu exec param(ownerdata) -struct MainMenuExecParam -{ - char *szServiceName; - TCHAR *szMenuName; - int Param1; -}; - -//contactmenu exec param(ownerdata) -//also used in checkservice -struct ContactMenuExecParam -{ - char *szServiceName; - char *pszContactOwner;//for check proc - int param; -}; - -struct BuildContactParam -{ - char *szProto; - int isOnList; - int isOnline; -}; - -struct StatusMenuExecParam -{ - char *proto; //This is unique protoname - int protoindex; - int status; - - BOOL custom; - char *svc; - HANDLE hMenuItem; -}; - -struct MenuItemData -{ - HMENU OwnerMenu; - int position; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// service functions - -void FreeMenuProtos(void) -{ - if (cli.menuProtos) { - for (int i = 0; i < cli.menuProtoCount; i++) - mir_free(cli.menuProtos[i].szProto); - mir_free(cli.menuProtos); - cli.menuProtos = NULL; - } - cli.menuProtoCount = 0; -} - -////////////////////////////////////////////////////////////////////////// - -int fnGetAverageMode(int *pNetProtoCount) -{ - int netProtoCount = 0, averageMode = 0; - - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (cli.pfnGetProtocolVisibility(pa->szModuleName) == 0 || Proto_IsAccountLocked(pa)) - continue; - - netProtoCount++; - - if (averageMode == 0) - averageMode = CallProtoServiceInt(NULL, pa->szModuleName, PS_GETSTATUS, 0, 0); - else if (averageMode > 0 && averageMode != CallProtoServiceInt(NULL, pa->szModuleName, PS_GETSTATUS, 0, 0)) { - averageMode = -1; - if (pNetProtoCount == NULL) - break; - } - } - - if (pNetProtoCount) *pNetProtoCount = netProtoCount; - return averageMode; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MAIN MENU - -static INT_PTR BuildMainMenu(WPARAM, LPARAM) -{ - ListParam param = { 0 }; - param.MenuObjectHandle = hMainMenuObject; - - NotifyEventHooks(hPreBuildMainMenuEvent, 0, 0); - - CallService(MO_BUILDMENU, (WPARAM)hMainMenu, (LPARAM)¶m); - DrawMenuBar((HWND)CallService("CLUI/GetHwnd", 0, 0)); - return (INT_PTR)hMainMenu; -} - -static INT_PTR AddMainMenuItem(WPARAM, LPARAM lParam) -{ - TMO_MenuItem tmi; - CLISTMENUITEM *mi = (CLISTMENUITEM*)lParam; - if (!cli.pfnConvertMenu(mi, &tmi)) - return 0; - - MainMenuExecParam *mmep = (MainMenuExecParam*)mir_alloc(sizeof(MainMenuExecParam)); - if (mmep == NULL) - return 0; - - //we need just one parametr. - mmep->szServiceName = mir_strdup(mi->pszService); - mmep->Param1 = mi->popupPosition; - mmep->szMenuName = tmi.ptszName; - tmi.ownerdata = mmep; - - PMO_IntMenuItem pimi = MO_AddNewMenuItem(hMainMenuObject, &tmi); - - char* name; - bool needFree = false; - - if (mi->pszService) - name = mi->pszService; - else if (mi->flags & CMIF_UNICODE) { - name = mir_t2a(mi->ptszName); - needFree = true; - } - else name = mi->pszName; - - MO_SetOptionsMenuItem(pimi, OPT_MENUITEMSETUNIQNAME, (INT_PTR)name); - if (needFree) mir_free(name); - - return (INT_PTR)pimi; -} - -int MainMenuCheckService(WPARAM, LPARAM) -{ - return 0; -} - -//called with: -//wparam - ownerdata -//lparam - lparam from winproc -INT_PTR MainMenuExecService(WPARAM wParam, LPARAM lParam) -{ - MainMenuExecParam *mmep = (MainMenuExecParam*)wParam; - if (mmep != NULL) { - // bug in help.c, it used wparam as parent window handle without reason. - if (!mir_strcmp(mmep->szServiceName, "Help/AboutCommand")) - mmep->Param1 = 0; - - CallService(mmep->szServiceName, mmep->Param1, lParam); - } - return 1; -} - -INT_PTR FreeOwnerDataMainMenu(WPARAM, LPARAM lParam) -{ - MainMenuExecParam *mmep = (MainMenuExecParam*)lParam; - if (mmep != NULL) { - FreeAndNil((void**)&mmep->szServiceName); - FreeAndNil((void**)&mmep); - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// CONTACT MENU - -static INT_PTR AddContactMenuItem(WPARAM, LPARAM lParam) -{ - TMO_MenuItem tmi; - CLISTMENUITEM *mi = (CLISTMENUITEM*)lParam; - if (!cli.pfnConvertMenu(mi, &tmi)) - return 0; - - if (!(mi->flags & CMIF_ROOTHANDLE)) { - //old system - tmi.flags |= CMIF_ROOTHANDLE; - tmi.root = NULL; - } - - //owner data - ContactMenuExecParam *cmep = (ContactMenuExecParam*)mir_calloc(sizeof(ContactMenuExecParam)); - cmep->szServiceName = mir_strdup(mi->pszService); - if (mi->pszContactOwner != NULL) - cmep->pszContactOwner = mir_strdup(mi->pszContactOwner); - cmep->param = mi->popupPosition; - tmi.ownerdata = cmep; - - //may be need to change how UniqueName is formed? - PMO_IntMenuItem menuHandle = MO_AddNewMenuItem(hContactMenuObject, &tmi); - char buf[256]; - if (mi->pszService) - mir_snprintf(buf, "%s/%s", (mi->pszContactOwner) ? mi->pszContactOwner : "", (mi->pszService) ? mi->pszService : ""); - else if (mi->ptszName) { - if (tmi.flags & CMIF_UNICODE) - mir_snprintf(buf, "%s/NoService/%s", (mi->pszContactOwner) ? mi->pszContactOwner : "", _T2A(mi->ptszName)); - else - mir_snprintf(buf, "%s/NoService/%s", (mi->pszContactOwner) ? mi->pszContactOwner : "", mi->ptszName); - } - else buf[0] = '\0'; - if (buf[0]) MO_SetOptionsMenuItem(menuHandle, OPT_MENUITEMSETUNIQNAME, (INT_PTR)buf); - return (INT_PTR)menuHandle; -} - -static INT_PTR BuildContactMenu(WPARAM hContact, LPARAM) -{ - NotifyEventHooks(hPreBuildContactMenuEvent, hContact, 0); - - char *szProto = GetContactProto(hContact); - - BuildContactParam bcp; - bcp.szProto = szProto; - bcp.isOnList = (db_get_b(hContact, "CList", "NotOnList", 0) == 0); - bcp.isOnline = (szProto != NULL && ID_STATUS_OFFLINE != db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE)); - - ListParam param = { 0 }; - param.MenuObjectHandle = hContactMenuObject; - param.wParam = (WPARAM)&bcp; - - HMENU hMenu = CreatePopupMenu(); - CallService(MO_BUILDMENU, (WPARAM)hMenu, (LPARAM)¶m); - - return (INT_PTR)hMenu; -} - -//called with: -//wparam - ownerdata -//lparam - lparam from winproc -INT_PTR ContactMenuExecService(WPARAM wParam, LPARAM lParam) -{ - if (wParam != 0) { - ContactMenuExecParam *cmep = (ContactMenuExecParam*)wParam; - //call with wParam = (MCONTACT)hContact, lparam = popupposition - CallService(cmep->szServiceName, lParam, cmep->param); - } - return 0; -} - -//true - ok, false ignore -INT_PTR ContactMenuCheckService(WPARAM wParam, LPARAM) -{ - PCheckProcParam pcpp = (PCheckProcParam)wParam; - if (pcpp == NULL) - return FALSE; - - BuildContactParam *bcp = (BuildContactParam*)pcpp->wParam; - if (bcp == NULL) - return FALSE; - - ContactMenuExecParam *cmep = (ContactMenuExecParam*)pcpp->MenuItemOwnerData; - if (cmep == NULL) //this is root...build it - return TRUE; - - if (cmep->pszContactOwner != NULL) { - if (bcp->szProto == NULL) return FALSE; - if (mir_strcmp(cmep->pszContactOwner, bcp->szProto)) return FALSE; - } - - TMO_MenuItem mi; - if (MO_GetMenuItem((WPARAM)pcpp->MenuItemHandle, (LPARAM)&mi) == 0) { - if (mi.flags & CMIF_HIDDEN) return FALSE; - if (mi.flags & CMIF_NOTONLIST && bcp->isOnList) return FALSE; - if (mi.flags & CMIF_NOTOFFLIST && !bcp->isOnList) return FALSE; - if (mi.flags & CMIF_NOTONLINE && bcp->isOnline) return FALSE; - if (mi.flags & CMIF_NOTOFFLINE && !bcp->isOnline) return FALSE; - } - return TRUE; -} - -INT_PTR FreeOwnerDataContactMenu(WPARAM, LPARAM lParam) -{ - ContactMenuExecParam *cmep = (ContactMenuExecParam*)lParam; - if (cmep != NULL) { - FreeAndNil((void**)&cmep->szServiceName); - FreeAndNil((void**)&cmep->pszContactOwner); - FreeAndNil((void**)&cmep); - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// STATUS MENU - -BOOL FindMenuHandleByGlobalID(HMENU hMenu, PMO_IntMenuItem id, MenuItemData* itdat) -{ - if (!itdat) - return FALSE; - - MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_SUBMENU | MIIM_DATA; - for (int i = GetMenuItemCount(hMenu) - 1; i >= 0; i--) { - GetMenuItemInfo(hMenu, i, TRUE, &mii); - if (mii.fType == MFT_SEPARATOR) - continue; - - BOOL inSub = FALSE; - if (mii.hSubMenu) - inSub = FindMenuHandleByGlobalID(mii.hSubMenu, id, itdat); - if (inSub) - return inSub; - - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)mii.dwItemData); - if (pimi != NULL) { - if (pimi == id) { - itdat->OwnerMenu = hMenu; - itdat->position = i; - return TRUE; - } - } - } - - return FALSE; -} - -INT_PTR StatusMenuCheckService(WPARAM wParam, LPARAM) -{ - PCheckProcParam pcpp = (PCheckProcParam)wParam; - if (!pcpp) - return TRUE; - - PMO_IntMenuItem timi = MO_GetIntMenuItem(pcpp->MenuItemHandle); - if (!timi) - return TRUE; - - StatusMenuExecParam *smep = (StatusMenuExecParam*)pcpp->MenuItemOwnerData; - if (smep && !smep->status && smep->custom) { - if (wildcmp(smep->svc, "*XStatus*")) { - int XStatus; - CUSTOM_STATUS cs = { sizeof(cs) }; - cs.flags = CSSF_MASK_STATUS; - cs.status = &XStatus; - if (CallProtoServiceInt(NULL, smep->proto, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&cs) != 0) - XStatus = 0; - - char buf[255]; - mir_snprintf(buf, "*XStatus%d", XStatus); - - bool check = wildcmp(smep->svc, buf) != 0; - bool reset = wildcmp(smep->svc, "*XStatus0") != 0; - - if (check) - timi->mi.flags |= CMIF_CHECKED; - else - timi->mi.flags &= ~CMIF_CHECKED; - - if (reset || check) { - PMO_IntMenuItem timiParent = MO_GetIntMenuItem(timi->mi.root); - if (timiParent) { - CLISTMENUITEM mi2 = { sizeof(mi2) }; - mi2.flags = CMIM_NAME | CMIF_TCHAR; - mi2.ptszName = TranslateTH(timi->mi.hLangpack, timi->mi.hIcon ? timi->mi.ptszName : LPGENT("Custom status")); - - timiParent = MO_GetIntMenuItem(timi->mi.root); - - MenuItemData it = { 0 }; - - if (FindMenuHandleByGlobalID(hStatusMenu, timiParent, &it)) { - MENUITEMINFO mi = { 0 }; - TCHAR d[100]; - GetMenuString(it.OwnerMenu, it.position, d, SIZEOF(d), MF_BYPOSITION); - - mi.cbSize = sizeof(mi); - mi.fMask = MIIM_STRING | MIIM_STATE; - if (timi->iconId != -1) { - mi.fMask |= MIIM_BITMAP; - if (IsWinVerVistaPlus() && IsThemeActive()) { - if (timi->hBmp == NULL) - timi->hBmp = ConvertIconToBitmap(NULL, timi->parent->m_hMenuIcons, timi->iconId); - mi.hbmpItem = timi->hBmp; - } - else mi.hbmpItem = HBMMENU_CALLBACK; - } - - mi.fState |= (check && !reset ? MFS_CHECKED : MFS_UNCHECKED); - mi.dwTypeData = mi2.ptszName; - SetMenuItemInfo(it.OwnerMenu, it.position, TRUE, &mi); - } - - Menu_ModifyItem(timi->mi.root, &mi2); - timiParent->iconId = timi->iconId; - if (timiParent->hBmp) DeleteObject(timiParent->hBmp); - timiParent->hBmp = NULL; - } - } - } - } - else if (smep && smep->status && !smep->custom) { - int curProtoStatus = (smep->proto) ? CallProtoServiceInt(NULL, smep->proto, PS_GETSTATUS, 0, 0) : cli.pfnGetAverageMode(NULL); - if (smep->status == curProtoStatus) - timi->mi.flags |= CMIF_CHECKED; - else - timi->mi.flags &= ~CMIF_CHECKED; - } - else if ((!smep || smep->proto) && timi->mi.pszName) { - int curProtoStatus = 0; - BOOL IconNeedDestroy = FALSE; - char* prot; - if (smep) - prot = smep->proto; - else { - char *prn = mir_u2a(timi->mi.ptszName); - prot = NEWSTR_ALLOCA(prn); - if (prn) mir_free(prn); - } - if (Proto_GetAccount(prot) == NULL) - return TRUE; - - if ((curProtoStatus = CallProtoServiceInt(NULL, prot, PS_GETSTATUS, 0, 0)) == CALLSERVICE_NOTFOUND) - curProtoStatus = 0; - - if (curProtoStatus >= ID_STATUS_OFFLINE && curProtoStatus < ID_STATUS_IDLE) - timi->mi.hIcon = LoadSkinProtoIcon(prot, curProtoStatus); - else { - timi->mi.hIcon = (HICON)CallProtoServiceInt(NULL, prot, PS_LOADICON, PLI_PROTOCOL | PLIF_SMALL, 0); - if (timi->mi.hIcon == (HICON)CALLSERVICE_NOTFOUND) - timi->mi.hIcon = NULL; - else - IconNeedDestroy = TRUE; - } - - if (timi->mi.hIcon) { - timi->mi.flags |= CMIM_ICON; - MO_ModifyMenuItem(timi, &timi->mi); - if (IconNeedDestroy) { - DestroyIcon(timi->mi.hIcon); - timi->mi.hIcon = NULL; - } - else IcoLib_ReleaseIcon(timi->mi.hIcon, 0); - } - } - - return TRUE; -} - -INT_PTR StatusMenuExecService(WPARAM wParam, LPARAM) -{ - StatusMenuExecParam *smep = (StatusMenuExecParam*)wParam; - if (smep == NULL) - return 0; - - if (smep->custom) { - if (smep->svc && *smep->svc) - CallService(smep->svc, 0, (LPARAM)smep->hMenuItem); - return 0; - } - - if (smep->status == 0 && smep->protoindex != 0 && smep->proto != NULL) { - char *prot = smep->proto; - char szHumanName[64] = { 0 }; - PROTOACCOUNT *acc = Proto_GetAccount(smep->proto); - bool bIsLocked = !Proto_IsAccountLocked(acc); - db_set_b(NULL, prot, "LockMainStatus", bIsLocked); - - CallProtoServiceInt(NULL, smep->proto, PS_GETNAME, (WPARAM)SIZEOF(szHumanName), (LPARAM)szHumanName); - - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)smep->protoindex); - if (pimi == NULL) - return 0; - - PMO_IntMenuItem root = (PMO_IntMenuItem)pimi->mi.root; - TCHAR buf[256], *ptszName; - if (bIsLocked) { - pimi->mi.flags |= CMIF_CHECKED; - if (cli.bDisplayLocked) { - mir_sntprintf(buf, TranslateT("%s (locked)"), acc->tszAccountName); - ptszName = buf; - } - else ptszName = acc->tszAccountName; - } - else { - ptszName = acc->tszAccountName; - pimi->mi.flags &= ~CMIF_CHECKED; - } - replaceStrT(pimi->mi.ptszName, ptszName); - replaceStrT(root->mi.ptszName, ptszName); - - if (cli.hwndStatus) - InvalidateRect(cli.hwndStatus, NULL, TRUE); - return 0; - } - - if (smep->proto != NULL) { - Proto_SetStatus(smep->proto, smep->status); - NotifyEventHooks(hStatusModeChangeEvent, smep->status, (LPARAM)smep->proto); - return 0; - } - - int MenusProtoCount = 0; - - for (int i = 0; i < accounts.getCount(); i++) - if (cli.pfnGetProtocolVisibility(accounts[i]->szModuleName)) - MenusProtoCount++; - - cli.currentDesiredStatusMode = smep->status; - - for (int j = 0; j < accounts.getCount(); j++) { - PROTOACCOUNT *pa = accounts[j]; - if (!Proto_IsAccountEnabled(pa)) - continue; - if (MenusProtoCount > 1 && Proto_IsAccountLocked(pa)) - continue; - - Proto_SetStatus(pa->szModuleName, cli.currentDesiredStatusMode); - } - NotifyEventHooks(hStatusModeChangeEvent, cli.currentDesiredStatusMode, 0); - db_set_w(NULL, "CList", "Status", (WORD)cli.currentDesiredStatusMode); - return 1; -} - -INT_PTR FreeOwnerDataStatusMenu(WPARAM, LPARAM lParam) -{ - StatusMenuExecParam *smep = (StatusMenuExecParam*)lParam; - if (smep != NULL) { - FreeAndNil((void**)&smep->proto); - FreeAndNil((void**)&smep->svc); - FreeAndNil((void**)&smep); - } - - return (0); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Other menu functions - -static INT_PTR ShowHideMenuItem(WPARAM wParam, LPARAM lParam) -{ - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)wParam); - if (pimi == NULL) - return 1; - - TMO_MenuItem tmi = { sizeof(tmi) }; - tmi.flags = CMIM_FLAGS + pimi->mi.flags; - if (lParam) - tmi.flags &= ~CMIF_HIDDEN; - else - tmi.flags |= CMIF_HIDDEN; - - return MO_ModifyMenuItem((PMO_IntMenuItem)wParam, &tmi); -} - -//wparam MenuItemHandle -static INT_PTR ModifyCustomMenuItem(WPARAM wParam, LPARAM lParam) -{ - TMO_MenuItem tmi; - CLISTMENUITEM *mi = (CLISTMENUITEM*)lParam; - if (!cli.pfnConvertMenu(mi, &tmi)) - return 0; - - return MO_ModifyMenuItem((PMO_IntMenuItem)wParam, &tmi); -} - -INT_PTR MenuProcessCommand(WPARAM wParam, LPARAM lParam) -{ - WORD cmd = LOWORD(wParam); - - if (HIWORD(wParam) & MPCF_MAINMENU) { - int hst = LOWORD(wParam); - if (hst >= ID_STATUS_OFFLINE && hst <= ID_STATUS_OUTTOLUNCH) { - int pos = statustopos(hst); - if (pos != -1 && hStatusMainMenuHandles != NULL) - return MO_ProcessCommand(hStatusMainMenuHandles[pos], lParam); - } - } - - if (!(cmd >= CLISTMENUIDMIN && cmd <= CLISTMENUIDMAX)) - return 0; // DO NOT process ids outside from clist menu id range v0.7.0.27+ - - //process old menu sys - if (HIWORD(wParam) & MPCF_CONTACTMENU) - return MO_ProcessCommandBySubMenuIdent((int)hContactMenuObject, LOWORD(wParam), lParam); - - //unknown old menu - return MO_ProcessCommandByMenuIdent(LOWORD(wParam), lParam); -} - -BOOL FindMenuHanleByGlobalID(HMENU hMenu, PMO_IntMenuItem id, MenuItemData* itdat) -{ - if (!itdat) - return FALSE; - - BOOL inSub = FALSE; - - MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_SUBMENU | MIIM_DATA; - for (int i = GetMenuItemCount(hMenu) - 1; i >= 0; i--) { - GetMenuItemInfo(hMenu, i, TRUE, &mii); - if (mii.fType == MFT_SEPARATOR) - continue; - - if (mii.hSubMenu) - inSub = FindMenuHanleByGlobalID(mii.hSubMenu, id, itdat); - if (inSub) - return inSub; - - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)mii.dwItemData); - if (pimi != NULL) { - if (pimi == id) { - itdat->OwnerMenu = hMenu; - itdat->position = i; - return TRUE; - } - } - } - - return FALSE; -} - -static INT_PTR MenuProcessHotkey(WPARAM vKey, LPARAM) -{ - prochotkey = true; - - bool res = - MO_ProcessHotKeys(hStatusMenuObject, vKey) || - MO_ProcessHotKeys(hMainMenuObject, vKey); - - prochotkey = false; - - return res; -} - -static int MenuIconsChanged(WPARAM, LPARAM) -{ - //just rebuild menu - RebuildMenuOrder(); - cli.pfnCluiProtocolStatusChanged(0, 0); - return 0; -} - -static INT_PTR MeasureMenuItem(WPARAM, LPARAM lParam) -{ - return MO_MeasureMenuItem((LPMEASUREITEMSTRUCT)lParam); -} - -static INT_PTR DrawMenuItem(WPARAM, LPARAM lParam) -{ - return MO_DrawMenuItem((LPDRAWITEMSTRUCT)lParam); -} - -int RecursiveDeleteMenu(HMENU hMenu) -{ - int cnt = GetMenuItemCount(hMenu); - for (int i = 0; i < cnt; i++) { - HMENU submenu = GetSubMenu(hMenu, 0); - if (submenu) DestroyMenu(submenu); - DeleteMenu(hMenu, 0, MF_BYPOSITION); - } - return 0; -} - -static INT_PTR MenuGetMain(WPARAM, LPARAM) -{ - RecursiveDeleteMenu(hMainMenu); - BuildMainMenu(0, 0); - return (INT_PTR)hMainMenu; -} - -static INT_PTR BuildStatusMenu(WPARAM, LPARAM) -{ - ListParam param = { 0 }; - param.MenuObjectHandle = hStatusMenuObject; - - RecursiveDeleteMenu(hStatusMenu); - CallService(MO_BUILDMENU, (WPARAM)hStatusMenu, (LPARAM)¶m); - return (INT_PTR)hStatusMenu; -} - -static INT_PTR SetStatusMode(WPARAM wParam, LPARAM) -{ - prochotkey = true; - MenuProcessCommand(MAKEWPARAM(LOWORD(wParam), MPCF_MAINMENU), 0); - prochotkey = false; - return 0; -} - -int fnGetProtocolVisibility(const char *accName) -{ - if (accName) { - PROTOACCOUNT *pa = Proto_GetAccount(accName); - if (pa && pa->bIsVisible && Proto_IsAccountEnabled(pa) && pa->ppro) { - PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(pa->szProtoName); - if (pd == NULL || pd->type != PROTOTYPE_PROTOCOL) - return FALSE; - - return (pa->ppro->GetCaps(PFLAGNUM_2, 0) & ~pa->ppro->GetCaps(PFLAGNUM_5, 0)); - } - } - - return FALSE; -} - -int fnGetProtoIndexByPos(PROTOCOLDESCRIPTOR **proto, int protoCnt, int Pos) -{ - char buf[10]; - _itoa(Pos, buf, 10); - - DBVARIANT dbv; - if (!db_get_s(NULL, "Protocols", buf, &dbv)) { - for (int p = 0; p < protoCnt; p++) { - if (mir_strcmp(proto[p]->szName, dbv.pszVal) == 0) { - db_free(&dbv); - return p; - } - } - - db_free(&dbv); - } - - return -1; -} - -int fnGetAccountIndexByPos(int Pos) -{ - for (int i = 0; i < accounts.getCount(); i++) - if (accounts[i]->iOrder == Pos) - return i; - - return -1; -} - -void RebuildMenuOrder(void) -{ - BYTE bHideStatusMenu = db_get_b(NULL, "CLUI", "DontHideStatusMenu", 0); // cool perversion, though - - //clear statusmenu - RecursiveDeleteMenu(hStatusMenu); - - //status menu - if (hStatusMenuObject != 0) { - CallService(MO_REMOVEMENUOBJECT, (WPARAM)hStatusMenuObject, 0); - mir_free(hStatusMainMenuHandles); - mir_free(hStatusMenuHandles); - } - - hStatusMenuObject = MO_CreateMenuObject("StatusMenu", LPGEN("Status menu"), "StatusMenuCheckService", "StatusMenuExecService"); - MO_SetOptionsMenuObject(hStatusMenuObject, OPT_MENUOBJECT_SET_FREE_SERVICE, (INT_PTR)"CLISTMENUS/FreeOwnerDataStatusMenu"); - - hStatusMainMenuHandles = (PMO_IntMenuItem*)mir_calloc(SIZEOF(statusModeList) * sizeof(PMO_IntMenuItem)); - hStatusMainMenuHandlesCnt = SIZEOF(statusModeList); - - hStatusMenuHandles = (tStatusMenuHandles*)mir_calloc(sizeof(tStatusMenuHandles)*accounts.getCount()); - hStatusMenuHandlesCnt = accounts.getCount(); - - FreeMenuProtos(); - - for (int s = 0; s < accounts.getCount(); s++) { - int i = cli.pfnGetAccountIndexByPos(s); - if (i == -1) - continue; - - PROTOACCOUNT *pa = accounts[i]; - int pos = 0; - if (!bHideStatusMenu && !cli.pfnGetProtocolVisibility(pa->szModuleName)) - continue; - - DWORD flags = pa->ppro->GetCaps(PFLAGNUM_2, 0) & ~pa->ppro->GetCaps(PFLAGNUM_5, 0); - HICON ic; - TCHAR tbuf[256]; - - //adding root - TMO_MenuItem tmi = { 0 }; - tmi.cbSize = sizeof(tmi); - tmi.flags = CMIF_TCHAR | CMIF_ROOTHANDLE | CMIF_KEEPUNTRANSLATED; - tmi.position = pos++; - tmi.hIcon = ic = (HICON)CallProtoServiceInt(NULL, pa->szModuleName, PS_LOADICON, PLI_PROTOCOL | PLIF_SMALL, 0); - - if (Proto_IsAccountLocked(pa) && cli.bDisplayLocked) { - mir_sntprintf(tbuf, SIZEOF(tbuf), TranslateT("%s (locked)"), pa->tszAccountName); - tmi.ptszName = tbuf; - } - else tmi.ptszName = pa->tszAccountName; - - //owner data - StatusMenuExecParam *smep = (StatusMenuExecParam*)mir_calloc(sizeof(StatusMenuExecParam)); - smep->proto = mir_strdup(pa->szModuleName); - tmi.ownerdata = smep; - - PMO_IntMenuItem rootmenu = MO_AddNewMenuItem(hStatusMenuObject, &tmi); - - memset(&tmi, 0, sizeof(tmi)); - tmi.cbSize = sizeof(tmi); - tmi.flags = CMIF_TCHAR | CMIF_ROOTHANDLE | CMIF_KEEPUNTRANSLATED; - tmi.root = rootmenu; - tmi.position = pos++; - tmi.hIcon = ic; - - //owner data - smep = (StatusMenuExecParam*)mir_calloc(sizeof(StatusMenuExecParam)); - smep->proto = mir_strdup(pa->szModuleName); - tmi.ownerdata = smep; - - if (Proto_IsAccountLocked(pa)) - tmi.flags |= CMIF_CHECKED; - - if ((tmi.flags & CMIF_CHECKED) && cli.bDisplayLocked) { - mir_sntprintf(tbuf, SIZEOF(tbuf), TranslateT("%s (locked)"), pa->tszAccountName); - tmi.ptszName = tbuf; - } - else tmi.ptszName = pa->tszAccountName; - - PMO_IntMenuItem menuHandle = MO_AddNewMenuItem(hStatusMenuObject, &tmi); - ((StatusMenuExecParam*)tmi.ownerdata)->protoindex = (int)menuHandle; - MO_ModifyMenuItem(menuHandle, &tmi); - - cli.menuProtos = (MenuProto*)mir_realloc(cli.menuProtos, sizeof(MenuProto)*(cli.menuProtoCount + 1)); - memset(&(cli.menuProtos[cli.menuProtoCount]), 0, sizeof(MenuProto)); - cli.menuProtos[cli.menuProtoCount].pMenu = rootmenu; - cli.menuProtos[cli.menuProtoCount].szProto = mir_strdup(pa->szModuleName); - - cli.menuProtoCount++; - - char buf[256]; - mir_snprintf(buf, "RootProtocolIcon_%s", pa->szModuleName); - MO_SetOptionsMenuItem(menuHandle, OPT_MENUITEMSETUNIQNAME, (INT_PTR)buf); - - DestroyIcon(ic); - pos += 500000; - - for (int j = 0; j < SIZEOF(statusModeList); j++) { - if (!(flags & statusModePf2List[j])) - continue; - - // adding - memset(&tmi, 0, sizeof(tmi)); - tmi.cbSize = sizeof(tmi); - tmi.flags = CMIF_ROOTHANDLE | CMIF_TCHAR; - if (statusModeList[j] == ID_STATUS_OFFLINE) - tmi.flags |= CMIF_CHECKED; - tmi.root = rootmenu; - tmi.position = pos++; - tmi.ptszName = cli.pfnGetStatusModeDescription(statusModeList[j], GSMDF_UNTRANSLATED); - tmi.hIcon = LoadSkinProtoIcon(pa->szModuleName, statusModeList[j]); - - // owner data - StatusMenuExecParam *smep = (StatusMenuExecParam*)mir_calloc(sizeof(StatusMenuExecParam)); - smep->custom = FALSE; - smep->status = statusModeList[j]; - smep->protoindex = i; - smep->proto = mir_strdup(pa->szModuleName); - tmi.ownerdata = smep; - - hStatusMenuHandles[i].protoindex = i; - hStatusMenuHandles[i].protostatus[j] = statusModeList[j]; - hStatusMenuHandles[i].menuhandle[j] = MO_AddNewMenuItem(hStatusMenuObject, &tmi); - - char buf[256]; - mir_snprintf(buf, "ProtocolIcon_%s_%s", pa->szModuleName, tmi.pszName); - MO_SetOptionsMenuItem(hStatusMenuHandles[i].menuhandle[j], OPT_MENUITEMSETUNIQNAME, (INT_PTR)buf); - - IcoLib_ReleaseIcon(tmi.hIcon, 0); - } - } - - NotifyEventHooks(cli.hPreBuildStatusMenuEvent, 0, 0); - int pos = 200000; - - // add to root menu - for (int j = 0; j < SIZEOF(statusModeList); j++) { - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (!bHideStatusMenu && !cli.pfnGetProtocolVisibility(pa->szModuleName)) - continue; - - DWORD flags = pa->ppro->GetCaps(PFLAGNUM_2, 0) & ~pa->ppro->GetCaps(PFLAGNUM_5, 0); - if (!(flags & statusModePf2List[j])) - continue; - - TMO_MenuItem tmi = { sizeof(tmi) }; - tmi.flags = CMIF_ROOTHANDLE | CMIF_TCHAR; - if (statusModeList[j] == ID_STATUS_OFFLINE) - tmi.flags |= CMIF_CHECKED; - - tmi.hIcon = LoadSkinIcon(skinIconStatusList[j]); - tmi.position = pos++; - tmi.hotKey = MAKELPARAM(MOD_CONTROL, '0' + j); - - //owner data - StatusMenuExecParam *smep = (StatusMenuExecParam*)mir_calloc(sizeof(StatusMenuExecParam)); - smep->status = statusModeList[j]; - tmi.ownerdata = smep; - { - TCHAR buf[256], hotkeyName[100]; - WORD hotKey = GetHotkeyValue(statusHotkeys[j]); - HotkeyToName(hotkeyName, SIZEOF(hotkeyName), HIBYTE(hotKey), LOBYTE(hotKey)); - mir_sntprintf(buf, _T("%s\t%s"), - cli.pfnGetStatusModeDescription(statusModeList[j], 0), hotkeyName); - tmi.ptszName = buf; - tmi.hotKey = MAKELONG(HIBYTE(hotKey), LOBYTE(hotKey)); - hStatusMainMenuHandles[j] = MO_AddNewMenuItem(hStatusMenuObject, &tmi); - } - - char buf[256]; - mir_snprintf(buf, "Root2ProtocolIcon_%s_%s", pa->szModuleName, tmi.pszName); - MO_SetOptionsMenuItem(hStatusMainMenuHandles[j], OPT_MENUITEMSETUNIQNAME, (INT_PTR)buf); - - IcoLib_ReleaseIcon(tmi.hIcon, 0); - break; - } - } - - BuildStatusMenu(0, 0); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static int sttRebuildHotkeys(WPARAM, LPARAM) -{ - TMO_MenuItem tmi = { sizeof(tmi) }; - tmi.flags = CMIM_HOTKEY | CMIM_NAME | CMIF_TCHAR; - - for (int j = 0; j < SIZEOF(statusModeList); j++) { - TCHAR buf[256], hotkeyName[100]; - WORD hotKey = GetHotkeyValue(statusHotkeys[j]); - HotkeyToName(hotkeyName, SIZEOF(hotkeyName), HIBYTE(hotKey), LOBYTE(hotKey)); - mir_sntprintf(buf, _T("%s\t%s"), cli.pfnGetStatusModeDescription(statusModeList[j], 0), hotkeyName); - tmi.ptszName = buf; - tmi.hotKey = MAKELONG(HIBYTE(hotKey), LOBYTE(hotKey)); - MO_ModifyMenuItem(hStatusMainMenuHandles[j], &tmi); - } - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -int statustopos(int status) -{ - for (int j = 0; j < SIZEOF(statusModeList); j++) - if (status == statusModeList[j]) - return j; - - return -1; -} - -static int MenuProtoAck(WPARAM, LPARAM lParam) -{ - ACKDATA *ack = (ACKDATA*)lParam; - if (ack->type != ACKTYPE_STATUS) return 0; - if (ack->result != ACKRESULT_SUCCESS) return 0; - if (hStatusMainMenuHandles == NULL) return 0; - if (cli.pfnGetProtocolVisibility(ack->szModule) == 0) return 0; - - int overallStatus = cli.pfnGetAverageMode(NULL); - - TMO_MenuItem tmi = { sizeof(tmi) }; - if (overallStatus >= ID_STATUS_OFFLINE) { - int pos = statustopos(cli.currentStatusMenuItem); - if (pos == -1) - pos = 0; - - // reset all current possible checked statuses - for (int pos2 = 0; pos2 < hStatusMainMenuHandlesCnt; pos2++) { - if (pos2 >= 0 && pos2 < hStatusMainMenuHandlesCnt) { - tmi.flags = CMIM_FLAGS | CMIF_ROOTHANDLE; - MO_ModifyMenuItem(hStatusMainMenuHandles[pos2], &tmi); - } - } - - cli.currentStatusMenuItem = overallStatus; - pos = statustopos(cli.currentStatusMenuItem); - if (pos >= 0 && pos < hStatusMainMenuHandlesCnt) { - tmi.flags = CMIM_FLAGS | CMIF_ROOTHANDLE | CMIF_CHECKED; - MO_ModifyMenuItem(hStatusMainMenuHandles[pos], &tmi); - } - } - else { - int pos = statustopos(cli.currentStatusMenuItem); - if (pos == -1) - pos = 0; - - if (pos >= 0 && pos < hStatusMainMenuHandlesCnt) { - tmi.flags = CMIM_FLAGS | CMIF_ROOTHANDLE; - MO_ModifyMenuItem(hStatusMainMenuHandles[pos], &tmi); - } - - cli.currentStatusMenuItem = 0; - } - - for (int i = 0; i < accounts.getCount(); i++) { - if (!mir_strcmp(accounts[i]->szModuleName, ack->szModule)) { - if (((int)ack->hProcess >= ID_STATUS_OFFLINE || (int)ack->hProcess == 0) && (int)ack->hProcess < ID_STATUS_OFFLINE + SIZEOF(statusModeList)) { - int pos = statustopos((int)ack->hProcess); - if (pos == -1) - pos = 0; - for (pos = 0; pos < SIZEOF(statusModeList); pos++) { - tmi.flags = CMIM_FLAGS | CMIF_ROOTHANDLE; - MO_ModifyMenuItem(hStatusMenuHandles[i].menuhandle[pos], &tmi); - } - } - - if (ack->lParam >= ID_STATUS_OFFLINE && ack->lParam < ID_STATUS_OFFLINE + SIZEOF(statusModeList)) { - int pos = statustopos((int)ack->lParam); - if (pos >= 0 && pos < SIZEOF(statusModeList)) { - tmi.flags = CMIM_FLAGS | CMIF_ROOTHANDLE | CMIF_CHECKED; - MO_ModifyMenuItem(hStatusMenuHandles[i].menuhandle[pos], &tmi); - } - } - break; - } - } - - //BuildStatusMenu(0, 0); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -int fnConvertMenu(CLISTMENUITEM *mi, TMO_MenuItem *pmi) -{ - if (mi == NULL || pmi == NULL) - return FALSE; - - if (mi->cbSize != sizeof(CLISTMENUITEM)) - return FALSE; - - memset(pmi, 0, sizeof(TMO_MenuItem)); - pmi->cbSize = sizeof(TMO_MenuItem); - pmi->root = mi->hParentMenu; - pmi->flags = mi->flags; - pmi->hIcon = mi->hIcon; - pmi->hotKey = mi->hotKey; - pmi->pszName = mi->pszName; - pmi->position = mi->position; - pmi->hLangpack = mi->hLangpack; - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static MenuProto* FindProtocolMenu(const char *proto) -{ - for (int i = 0; i < cli.menuProtoCount; i++) - if (cli.menuProtos[i].pMenu && !mir_strcmpi(cli.menuProtos[i].szProto, proto)) - return &cli.menuProtos[i]; - - if (cli.menuProtoCount == 1) - if (!mir_strcmpi(cli.menuProtos[0].szProto, proto)) - return &cli.menuProtos[0]; - - return NULL; -} - -HGENMENU fnGetProtocolMenu(const char* proto) -{ - MenuProto *mp = FindProtocolMenu(proto); - return (mp) ? mp->pMenu : NULL; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR AddStatusMenuItem(WPARAM wParam, LPARAM lParam) -{ - CLISTMENUITEM *mi = (CLISTMENUITEM*)lParam; - - TMO_MenuItem tmi; - if (!cli.pfnConvertMenu(mi, &tmi)) - return 0; - - // for new style menus the pszPopupName contains the root menu handle - PMO_IntMenuItem pRoot = NULL; - if (mi->flags & CMIF_ROOTHANDLE) - pRoot = MO_GetIntMenuItem(mi->hParentMenu); - - // for old style menus the pszPopupName really means the popup name - else { - MenuProto *mp = FindProtocolMenu(mi->pszContactOwner); - if (mp && mi->pszPopupName) { - if (mp->pMenu) { - TCHAR *ptszName = (mi->flags & CMIF_UNICODE) ? mir_tstrdup(mi->ptszPopupName) : mir_a2t(mi->pszPopupName); - pRoot = MO_RecursiveWalkMenu(mp->pMenu->submenu.first, FindRoot, ptszName); - mir_free(ptszName); - } - if (pRoot == NULL) { - TMO_MenuItem tmi = { 0 }; - tmi.cbSize = sizeof(tmi); - tmi.flags = (mi->flags & CMIF_UNICODE) | CMIF_ROOTHANDLE; - tmi.position = 1001; - tmi.root = mp->pMenu; - tmi.hIcon = NULL; - tmi.pszName = mi->pszPopupName; - pRoot = MO_AddNewMenuItem(hStatusMenuObject, &tmi); - } - - tmi.flags |= CMIF_ROOTHANDLE; - tmi.root = pRoot; - } - } - - if (wParam) { - int *res = (int*)wParam; - *res = (int)pRoot; - } - - // owner data - StatusMenuExecParam *smep = NULL; - if (mi->pszService) { - smep = (StatusMenuExecParam*)mir_calloc(sizeof(StatusMenuExecParam)); - smep->custom = TRUE; - smep->svc = mir_strdup(mi->pszService); - { - char *buf = mir_strdup(mi->pszService); - int i = 0; - while (buf[i] != '\0' && buf[i] != '/') i++; - buf[i] = '\0'; - smep->proto = mir_strdup(buf); - mir_free(buf); - } - tmi.ownerdata = smep; - } - - PMO_IntMenuItem menuHandle = MO_AddNewMenuItem(hStatusMenuObject, &tmi); - if (smep) - smep->hMenuItem = menuHandle; - - char buf[MAX_PATH + 64]; - char *p = (pRoot) ? mir_t2a(pRoot->mi.ptszName) : NULL; - mir_snprintf(buf, "%s/%s", (p) ? p : "", mi->pszService ? mi->pszService : ""); - mir_free(p); - - MO_SetOptionsMenuItem(menuHandle, OPT_MENUITEMSETUNIQNAME, (INT_PTR)buf); - return (INT_PTR)menuHandle; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR HotkeySetStatus(WPARAM wParam, LPARAM lParam) -{ - return SetStatusMode(lParam, 0); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// PROTOCOL MENU - -static INT_PTR AddProtoMenuItem(WPARAM wParam, LPARAM lParam) -{ - if (db_get_b(NULL, "CList", "MoveProtoMenus", TRUE)) - return AddStatusMenuItem(wParam, lParam); - - return AddMainMenuItem(wParam, lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void InitCustomMenus(void) -{ - CreateServiceFunction("MainMenuExecService", MainMenuExecService); - - CreateServiceFunction("ContactMenuExecService", ContactMenuExecService); - CreateServiceFunction("ContactMenuCheckService", ContactMenuCheckService); - - CreateServiceFunction("StatusMenuExecService", StatusMenuExecService); - CreateServiceFunction("StatusMenuCheckService", StatusMenuCheckService); - - //free services - CreateServiceFunction("CLISTMENUS/FreeOwnerDataMainMenu", FreeOwnerDataMainMenu); - CreateServiceFunction("CLISTMENUS/FreeOwnerDataContactMenu", FreeOwnerDataContactMenu); - CreateServiceFunction("CLISTMENUS/FreeOwnerDataStatusMenu", FreeOwnerDataStatusMenu); - - CreateServiceFunction(MS_CLIST_SETSTATUSMODE, SetStatusMode); - - CreateServiceFunction("CList/AddMainMenuItem", AddMainMenuItem); - CreateServiceFunction("CList/AddStatusMenuItem", AddStatusMenuItem); - CreateServiceFunction(MS_CLIST_MENUGETMAIN, MenuGetMain); - CreateServiceFunction(MS_CLIST_MENUBUILDMAIN, BuildMainMenu); - - CreateServiceFunction("CList/AddContactMenuItem", AddContactMenuItem); - CreateServiceFunction(MS_CLIST_MENUBUILDCONTACT, BuildContactMenu); - - CreateServiceFunction(MS_CLIST_SHOWHIDEMENUITEM, ShowHideMenuItem); - CreateServiceFunction(MS_CLIST_MODIFYMENUITEM, ModifyCustomMenuItem); - CreateServiceFunction(MS_CLIST_MENUMEASUREITEM, MeasureMenuItem); - CreateServiceFunction(MS_CLIST_MENUDRAWITEM, DrawMenuItem); - - CreateServiceFunction(MS_CLIST_MENUGETSTATUS, BuildStatusMenu); - CreateServiceFunction(MS_CLIST_MENUPROCESSCOMMAND, MenuProcessCommand); - CreateServiceFunction(MS_CLIST_MENUPROCESSHOTKEY, MenuProcessHotkey); - - CreateServiceFunction("CList/AddProtoMenuItem", AddProtoMenuItem); - - hPreBuildContactMenuEvent = CreateHookableEvent(ME_CLIST_PREBUILDCONTACTMENU); - hPreBuildMainMenuEvent = CreateHookableEvent(ME_CLIST_PREBUILDMAINMENU); - cli.hPreBuildStatusMenuEvent = CreateHookableEvent(ME_CLIST_PREBUILDSTATUSMENU); - hStatusModeChangeEvent = CreateHookableEvent(ME_CLIST_STATUSMODECHANGE); - - HookEvent(ME_PROTO_ACK, MenuProtoAck); - - hMainMenu = CreatePopupMenu(); - hStatusMenu = CreatePopupMenu(); - - hStatusMainMenuHandles = NULL; - hStatusMainMenuHandlesCnt = 0; - - hStatusMenuHandles = NULL; - hStatusMenuHandlesCnt = 0; - - // new menu sys - InitGenMenu(); - - // main menu - hMainMenuObject = MO_CreateMenuObject("MainMenu", LPGEN("Main menu"), 0, "MainMenuExecService"); - MO_SetOptionsMenuObject(hMainMenuObject, OPT_USERDEFINEDITEMS, TRUE); - MO_SetOptionsMenuObject(hMainMenuObject, OPT_MENUOBJECT_SET_FREE_SERVICE, (INT_PTR)"CLISTMENUS/FreeOwnerDataMainMenu"); - - // contact menu - hContactMenuObject = MO_CreateMenuObject("ContactMenu", LPGEN("Contact menu"), "ContactMenuCheckService", "ContactMenuExecService"); - MO_SetOptionsMenuObject(hContactMenuObject, OPT_USERDEFINEDITEMS, TRUE); - MO_SetOptionsMenuObject(hContactMenuObject, OPT_MENUOBJECT_SET_FREE_SERVICE, (INT_PTR)"CLISTMENUS/FreeOwnerDataContactMenu"); - - // initialize hotkeys - CreateServiceFunction(MS_CLIST_HKSTATUS, HotkeySetStatus); - - HOTKEYDESC hkd = { sizeof(hkd) }; - hkd.ptszSection = _T("Status"); - hkd.dwFlags = HKD_TCHAR; - for (int i = 0; i < SIZEOF(statusHotkeys); i++) { - char szName[30]; - mir_snprintf(szName, SIZEOF(szName), "StatusHotKey_%d", i); - hkd.pszName = szName; - hkd.lParam = statusModeList[i]; - hkd.ptszDescription = fnGetStatusModeDescription(hkd.lParam, 0); - hkd.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL, '0' + i) | HKF_MIRANDA_LOCAL; - hkd.pszService = MS_CLIST_HKSTATUS; - statusHotkeys[i] = Hotkey_Register(&hkd); - } - - HookEvent(ME_HOTKEYS_CHANGED, sttRebuildHotkeys); - - // add exit command to menu - - CLISTMENUITEM mi = { sizeof(mi) }; - mi.position = 0x7fffffff; - mi.pszService = "CloseAction"; - mi.pszName = LPGEN("E&xit"); - mi.icolibItem = GetSkinIconHandle(SKINICON_OTHER_EXIT); - AddMainMenuItem(0, (LPARAM)&mi); - - cli.currentStatusMenuItem = ID_STATUS_OFFLINE; - cli.currentDesiredStatusMode = ID_STATUS_OFFLINE; - - HookEvent(ME_SKIN_ICONSCHANGED, MenuIconsChanged); -} - -void UninitCustomMenus(void) -{ - mir_free(hStatusMainMenuHandles); - hStatusMainMenuHandles = NULL; - - mir_free(hStatusMenuHandles); - hStatusMenuHandles = NULL; - - if (hMainMenuObject) CallService(MO_REMOVEMENUOBJECT, (WPARAM)hMainMenuObject, 0); - if (hStatusMenuObject) CallService(MO_REMOVEMENUOBJECT, (WPARAM)hMainMenuObject, 0); - - UnloadMoveToGroup(); - FreeMenuProtos(); - - DestroyMenu(hMainMenu); - DestroyMenu(hStatusMenu); -} diff --git a/src/modules/clist/clistmod.cpp b/src/modules/clist/clistmod.cpp deleted file mode 100644 index 81be885ba7..0000000000 --- a/src/modules/clist/clistmod.cpp +++ /dev/null @@ -1,540 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -INT_PTR ContactChangeGroup(WPARAM wParam, LPARAM lParam); -int InitCListEvents(void); -void UninitCListEvents(void); -int ContactSettingChanged(WPARAM wParam, LPARAM lParam); -int ContactAdded(WPARAM wParam, LPARAM lParam); -int ContactDeleted(WPARAM wParam, LPARAM lParam); -INT_PTR GetContactDisplayName(WPARAM wParam, LPARAM lParam); -INT_PTR InvalidateDisplayName(WPARAM wParam, LPARAM lParam); -int InitGroupServices(void); -void LoadCluiServices(); -INT_PTR Docking_IsDocked(WPARAM wParam, LPARAM lParam); -int LoadCLUIModule(void); -int InitClistHotKeys(void); - -HANDLE hContactDoubleClicked, hContactIconChangedEvent; -HIMAGELIST hCListImages; - -extern BYTE nameOrder[]; - -struct ProtoIconIndex -{ - char *szProto; - int iIconBase; -}; - -OBJLIST protoIconIndex(5); - -TCHAR* fnGetStatusModeDescription(int mode, int flags) -{ - static TCHAR szMode[64]; - TCHAR* descr; - int noPrefixReqd = 0; - switch (mode) { - case ID_STATUS_OFFLINE: - descr = LPGENT("Offline"); - noPrefixReqd = 1; - break; - case ID_STATUS_CONNECTING: - descr = LPGENT("Connecting"); - noPrefixReqd = 1; - break; - case ID_STATUS_ONLINE: - descr = LPGENT("Online"); - noPrefixReqd = 1; - break; - case ID_STATUS_AWAY: - descr = LPGENT("Away"); - break; - case ID_STATUS_DND: - descr = LPGENT("DND"); - break; - case ID_STATUS_NA: - descr = LPGENT("NA"); - break; - case ID_STATUS_OCCUPIED: - descr = LPGENT("Occupied"); - break; - case ID_STATUS_FREECHAT: - descr = LPGENT("Free for chat"); - break; - case ID_STATUS_INVISIBLE: - descr = LPGENT("Invisible"); - break; - case ID_STATUS_OUTTOLUNCH: - descr = LPGENT("Out to lunch"); - break; - case ID_STATUS_ONTHEPHONE: - descr = LPGENT("On the phone"); - break; - case ID_STATUS_IDLE: - descr = LPGENT("Idle"); - break; - default: - if (IsStatusConnecting(mode)) { - const TCHAR* connFmt = LPGENT("Connecting (attempt %d)"); - mir_sntprintf(szMode, SIZEOF(szMode), (flags & GSMDF_UNTRANSLATED) ? connFmt : TranslateTS(connFmt), mode - ID_STATUS_CONNECTING + 1); - return szMode; - } - return NULL; - } - - return (flags & GSMDF_UNTRANSLATED) ? descr : TranslateTS(descr); -} - -static INT_PTR GetStatusModeDescription(WPARAM wParam, LPARAM lParam) -{ - TCHAR *buf1 = cli.pfnGetStatusModeDescription(wParam, lParam); - - if (!(lParam & GSMDF_TCHAR)) { - static char szMode[64]; - char *buf2 = mir_u2a(buf1); - strncpy_s(szMode, buf2, _TRUNCATE); - mir_free(buf2); - return (INT_PTR)szMode; - } - - return (INT_PTR)buf1; -} - -static int ProtocolAck(WPARAM, LPARAM lParam) -{ - ACKDATA *ack = (ACKDATA *) lParam; - if (ack->type != ACKTYPE_STATUS) - return 0; - - cli.pfnCluiProtocolStatusChanged(lParam, ack->szModule); - - if ((int)ack->hProcess < ID_STATUS_ONLINE && ack->lParam >= ID_STATUS_ONLINE) { - DWORD caps = (DWORD)CallProtoServiceInt(NULL,ack->szModule, PS_GETCAPS, PFLAGNUM_1, 0); - if (caps & PF1_SERVERCLIST) { - for (MCONTACT hContact = db_find_first(ack->szModule); hContact; ) { - MCONTACT hNext = db_find_next(hContact, ack->szModule); - if (db_get_b(hContact, "CList", "Delete", 0)) - CallService(MS_DB_CONTACT_DELETE, hContact, 0); - hContact = hNext; - } - } - } - - cli.pfnTrayIconUpdateBase(ack->szModule); - return 0; -} - -HICON fnGetIconFromStatusMode(MCONTACT hContact, const char *szProto, int status) -{ - return ImageList_GetIcon(hCListImages, cli.pfnIconFromStatusMode(szProto, status, hContact), ILD_NORMAL); -} - -int fnIconFromStatusMode(const char *szProto, int status, MCONTACT) -{ - int index, i; - - for (index = 0; index < SIZEOF(statusModeList); index++) - if (status == statusModeList[index]) - break; - - if (index == SIZEOF(statusModeList)) - index = 0; - if (szProto == NULL) - return index + 1; - for (i=0; i < protoIconIndex.getCount(); i++) { - if (mir_strcmp(szProto, protoIconIndex[i].szProto) == 0) - return protoIconIndex[i].iIconBase + index; - } - return 1; -} - -int fnGetContactIcon(MCONTACT hContact) -{ - char *szProto = GetContactProto(hContact); - return cli.pfnIconFromStatusMode(szProto, - szProto == NULL ? ID_STATUS_OFFLINE : db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE), hContact); -} - -static INT_PTR GetContactIcon(WPARAM wParam, LPARAM) -{ - return cli.pfnGetContactIcon(wParam); -} - -static void AddProtoIconIndex(PROTOACCOUNT *pa) -{ - ProtoIconIndex *pii = new ProtoIconIndex; - pii->szProto = pa->szModuleName; - for (int i=0; i < SIZEOF(statusModeList); i++) { - int iImg = ImageList_AddIcon_ProtoIconLibLoaded(hCListImages, pa->szModuleName, statusModeList[i]); - if (i == 0) - pii->iIconBase = iImg; - } - protoIconIndex.insert(pii); -} - -static void RemoveProtoIconIndex(PROTOACCOUNT *pa) -{ - for (int i=0; i < protoIconIndex.getCount(); i++) - if (mir_strcmp(protoIconIndex[i].szProto, pa->szModuleName) == 0) { - protoIconIndex.remove(i); - break; - } -} - -static int ContactListModulesLoaded(WPARAM, LPARAM) -{ - RebuildMenuOrder(); - for (int i=0; i < accounts.getCount(); i++) - AddProtoIconIndex(accounts[i]); - - cli.pfnLoadContactTree(); - - LoadCLUIModule(); - - InitClistHotKeys(); - - return 0; -} - -static int ContactListAccountsChanged(WPARAM eventCode, LPARAM lParam) -{ - switch (eventCode) { - case PRAC_ADDED: - AddProtoIconIndex((PROTOACCOUNT*)lParam); - break; - - case PRAC_REMOVED: - RemoveProtoIconIndex((PROTOACCOUNT*)lParam); - break; - } - cli.pfnReloadProtoMenus(); - cli.pfnTrayIconIconsChanged(); - cli.pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0); - cli.pfnClcBroadcast(INTM_INVALIDATE, 0, 0); - return 0; -} - -static INT_PTR ContactDoubleClicked(WPARAM wParam, LPARAM) -{ - // Try to process event myself - if (cli.pfnEventsProcessContactDoubleClick(wParam) == 0) - return 0; - - // Allow third-party plugins to process a dblclick - if (NotifyEventHooks(hContactDoubleClicked, wParam, 0)) - return 0; - - // Otherwise try to execute the default action - TryProcessDoubleClick(wParam); - return 0; -} - -static INT_PTR GetIconsImageList(WPARAM, LPARAM) -{ - return (INT_PTR)hCListImages; -} - -static INT_PTR ContactFilesDropped(WPARAM wParam, LPARAM lParam) -{ - CallService(MS_FILE_SENDSPECIFICFILES, wParam, lParam); - return 0; -} - -static int CListIconsChanged(WPARAM, LPARAM) -{ - int i, j; - - for (i=0; i < SIZEOF(statusModeList); i++) - ImageList_ReplaceIcon_IconLibLoaded(hCListImages, i + 1, LoadSkinIcon(skinIconStatusList[i])); - ImageList_ReplaceIcon_IconLibLoaded(hCListImages, IMAGE_GROUPOPEN, LoadSkinIcon(SKINICON_OTHER_GROUPOPEN)); - ImageList_ReplaceIcon_IconLibLoaded(hCListImages, IMAGE_GROUPSHUT, LoadSkinIcon(SKINICON_OTHER_GROUPSHUT)); - for (i=0; i < protoIconIndex.getCount(); i++) - for (j = 0; j < SIZEOF(statusModeList); j++) - ImageList_ReplaceIcon_IconLibLoaded(hCListImages, protoIconIndex[i].iIconBase + j, LoadSkinProtoIcon(protoIconIndex[i].szProto, statusModeList[j])); - cli.pfnTrayIconIconsChanged(); - cli.pfnInvalidateRect(cli.hwndContactList, NULL, TRUE); - return 0; -} - -/* -Begin of Hrk's code for bug -*/ -#define GWVS_HIDDEN 1 -#define GWVS_VISIBLE 2 -#define GWVS_COVERED 3 -#define GWVS_PARTIALLY_COVERED 4 - -int fnGetWindowVisibleState(HWND hWnd, int iStepX, int iStepY) -{ - RECT rc, rcWin, rcWorkArea; - POINT pt; - register int i, j, width, height, iCountedDots = 0, iNotCoveredDots = 0; - BOOL bPartiallyCovered = FALSE; - HWND hAux = 0; - - if (hWnd == NULL) { - SetLastError(0x00000006); //Wrong handle - return -1; - } - - //Some defaults now. The routine is designed for thin and tall windows. - if (iStepX <= 0) - iStepX = 4; - if (iStepY <= 0) - iStepY = 16; - - if (IsIconic(hWnd) || !IsWindowVisible(hWnd)) - return GWVS_HIDDEN; - - if (CallService(MS_CLIST_DOCKINGISDOCKED, 0, 0)) - return GWVS_VISIBLE; - - GetWindowRect(hWnd, &rcWin); - - SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE); - HMONITOR hMon = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); - MONITORINFO mi; - mi.cbSize = sizeof(mi); - if (GetMonitorInfo(hMon, &mi)) - rcWorkArea = mi.rcWork; - - IntersectRect(&rc, &rcWin, &rcWorkArea); - - width = rc.right - rc.left; - height = rc.bottom - rc.top; - - for (i = rc.top; i < rc.bottom; i += (height / iStepY)) { - pt.y = i; - for (j = rc.left; j < rc.right; j += (width / iStepX)) { - pt.x = j; - hAux = WindowFromPoint(pt); - while (GetParent(hAux) != NULL) - hAux = GetParent(hAux); - if (hAux != hWnd && hAux != NULL) //There's another window! - bPartiallyCovered = TRUE; - else - iNotCoveredDots++; //Let's count the not covered dots. - iCountedDots++; //Let's keep track of how many dots we checked. - } - } - - if (iNotCoveredDots == iCountedDots) //Every dot was not covered: the window is visible. - return GWVS_VISIBLE; - - if (iNotCoveredDots == 0) //They're all covered! - return GWVS_COVERED; - - //There are dots which are visible, but they are not as many as the ones we counted: it's partially covered. - return GWVS_PARTIALLY_COVERED; -} - -int fnShowHide(WPARAM, LPARAM) -{ - BOOL bShow = FALSE; - - int iVisibleState = cli.pfnGetWindowVisibleState(cli.hwndContactList, 0, 0); - - //bShow is FALSE when we enter the switch. - switch (iVisibleState) { - case GWVS_PARTIALLY_COVERED: - //If we don't want to bring it to top, we can use a simple break. This goes against readability ;-) but the comment explains it. - if (!db_get_b(NULL, "CList", "BringToFront", SETTING_BRINGTOFRONT_DEFAULT)) - break; - case GWVS_COVERED: //Fall through (and we're already falling) - case GWVS_HIDDEN: - bShow = TRUE; - break; - case GWVS_VISIBLE: //This is not needed, but goes for readability. - bShow = FALSE; - break; - case -1: //We can't get here, both cli.hwndContactList and iStepX and iStepY are right. - return 0; - } - - if (bShow == TRUE) { - RECT rcWindow; - - ShowWindow(cli.hwndContactList, SW_RESTORE); - if (!db_get_b(NULL, "CList", "OnTop", SETTING_ONTOP_DEFAULT)) - SetWindowPos(cli.hwndContactList, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); - else - SetWindowPos(cli.hwndContactList, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - - SetForegroundWindow(cli.hwndContactList); - db_set_b(NULL, "CList", "State", SETTING_STATE_NORMAL); - - //this forces the window onto the visible screen - GetWindowRect(cli.hwndContactList, &rcWindow); - if (AssertInsideScreen(rcWindow) == 1) { - MoveWindow(cli.hwndContactList, rcWindow.left, rcWindow.top, - rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, TRUE); - } - } - else { //It needs to be hidden - if (db_get_b(NULL, "CList", "ToolWindow", SETTING_TOOLWINDOW_DEFAULT) || - db_get_b(NULL, "CList", "Min2Tray", SETTING_MIN2TRAY_DEFAULT)) { - ShowWindow(cli.hwndContactList, SW_HIDE); - db_set_b(NULL, "CList", "State", SETTING_STATE_HIDDEN); - } - else { - ShowWindow(cli.hwndContactList, SW_MINIMIZE); - db_set_b(NULL, "CList", "State", SETTING_STATE_MINIMIZED); - } - - if (db_get_b(NULL, "CList", "DisableWorkingSet", 1)) - SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1); - } - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// old evil code. hopefully it will be deleted soon, cause nobody uses it now - -#define SAFESTRING(a) a?a:"" - -int GetStatusModeOrdering(int statusMode); -extern int sortByStatus, sortByProto; - -static INT_PTR CompareContacts(WPARAM wParam, LPARAM lParam) -{ - MCONTACT a = wParam, b = lParam; - TCHAR namea[128], *nameb; - int statusa, statusb; - char *szProto1, *szProto2; - int rc; - - szProto1 = GetContactProto(a); - szProto2 = GetContactProto(b); - statusa = db_get_w(a, SAFESTRING(szProto1), "Status", ID_STATUS_OFFLINE); - statusb = db_get_w(b, SAFESTRING(szProto2), "Status", ID_STATUS_OFFLINE); - - if (sortByProto) { - /* deal with statuses, online contacts have to go above offline */ - if ((statusa == ID_STATUS_OFFLINE) != (statusb == ID_STATUS_OFFLINE)) { - return 2 * (statusa == ID_STATUS_OFFLINE) - 1; - } - /* both are online, now check protocols */ - rc = mir_strcmp(SAFESTRING(szProto1), SAFESTRING(szProto2)); /* mir_strcmp() doesn't like NULL so feed in "" as needed */ - if (rc != 0 && (szProto1 != NULL && szProto2 != NULL)) - return rc; - /* protocols are the same, order by display name */ - } - - if (sortByStatus) { - int ordera, orderb; - ordera = GetStatusModeOrdering(statusa); - orderb = GetStatusModeOrdering(statusb); - if (ordera != orderb) - return ordera - orderb; - } - else { - //one is offline: offline goes below online - if ((statusa == ID_STATUS_OFFLINE) != (statusb == ID_STATUS_OFFLINE)) { - return 2 * (statusa == ID_STATUS_OFFLINE) - 1; - } - } - - nameb = cli.pfnGetContactDisplayName(a, 0); - _tcsncpy_s(namea, nameb, _TRUNCATE); - namea[ SIZEOF(namea)-1 ] = 0; - nameb = cli.pfnGetContactDisplayName(b, 0); - - //otherwise just compare names - return mir_tstrcmpi(namea, nameb); -} - -/***************************************************************************************/ - -static INT_PTR ShowHideStub(WPARAM wParam, LPARAM lParam) { return cli.pfnShowHide(wParam, lParam); } -static INT_PTR SetHideOfflineStub(WPARAM wParam, LPARAM lParam) { return cli.pfnSetHideOffline(wParam, lParam); } -static INT_PTR Docking_ProcessWindowMessageStub(WPARAM wParam, LPARAM lParam) { return cli.pfnDocking_ProcessWindowMessage(wParam, lParam); } -static INT_PTR HotkeysProcessMessageStub(WPARAM wParam, LPARAM lParam) { return cli.pfnHotkeysProcessMessage(wParam, lParam); } - -int LoadContactListModule2(void) -{ - HookEvent(ME_SYSTEM_MODULESLOADED, ContactListModulesLoaded); - HookEvent(ME_PROTO_ACCLISTCHANGED, ContactListAccountsChanged); - HookEvent(ME_DB_CONTACT_SETTINGCHANGED, ContactSettingChanged); - HookEvent(ME_DB_CONTACT_ADDED, ContactAdded); - HookEvent(ME_DB_CONTACT_DELETED, ContactDeleted); - HookEvent(ME_PROTO_ACK, ProtocolAck); - - hContactDoubleClicked = CreateHookableEvent(ME_CLIST_DOUBLECLICKED); - hContactIconChangedEvent = CreateHookableEvent(ME_CLIST_CONTACTICONCHANGED); - - LoadCluiServices(); - - CreateServiceFunction(MS_CLIST_CONTACTDOUBLECLICKED, ContactDoubleClicked); - CreateServiceFunction(MS_CLIST_CONTACTFILESDROPPED, ContactFilesDropped); - CreateServiceFunction(MS_CLIST_GETSTATUSMODEDESCRIPTION, GetStatusModeDescription); - CreateServiceFunction(MS_CLIST_GETCONTACTDISPLAYNAME, GetContactDisplayName); - CreateServiceFunction(MS_CLIST_INVALIDATEDISPLAYNAME, InvalidateDisplayName); - CreateServiceFunction(MS_CLIST_CONTACTSCOMPARE, CompareContacts); - CreateServiceFunction(MS_CLIST_CONTACTCHANGEGROUP, ContactChangeGroup); - CreateServiceFunction(MS_CLIST_SHOWHIDE, ShowHideStub); - CreateServiceFunction(MS_CLIST_SETHIDEOFFLINE, SetHideOfflineStub); - CreateServiceFunction(MS_CLIST_DOCKINGPROCESSMESSAGE, Docking_ProcessWindowMessageStub); - CreateServiceFunction(MS_CLIST_DOCKINGISDOCKED, Docking_IsDocked); - CreateServiceFunction(MS_CLIST_HOTKEYSPROCESSMESSAGE, HotkeysProcessMessageStub); - CreateServiceFunction(MS_CLIST_GETCONTACTICON, GetContactIcon); - - InitCListEvents(); - InitGroupServices(); - cli.pfnInitTray(); - - hCListImages = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 13, 0); - HookEvent(ME_SKIN_ICONSCHANGED, CListIconsChanged); - CreateServiceFunction(MS_CLIST_GETICONSIMAGELIST, GetIconsImageList); - - ImageList_AddIcon_NotShared(hCListImages, MAKEINTRESOURCE(IDI_BLANK)); - - //now all core skin icons are loaded via icon lib. so lets release them - for (int i=0; i < SIZEOF(statusModeList); i++) - ImageList_AddIcon_IconLibLoaded(hCListImages, skinIconStatusList[i]); - - //see IMAGE_GROUP... in clist.h if you add more images above here - ImageList_AddIcon_IconLibLoaded(hCListImages, SKINICON_OTHER_GROUPOPEN); - ImageList_AddIcon_IconLibLoaded(hCListImages, SKINICON_OTHER_GROUPSHUT); - return 0; -} - -void UnloadContactListModule() -{ - if (!hCListImages) - return; - - //remove transitory contacts - for (MCONTACT hContact = db_find_first(); hContact != NULL; ) { - MCONTACT hNext = db_find_next(hContact); - if (db_get_b(hContact, "CList", "NotOnList", 0)) - CallService(MS_DB_CONTACT_DELETE, hContact, 0); - hContact = hNext; - } - ImageList_Destroy(hCListImages); - UninitCListEvents(); - DestroyHookableEvent(hContactDoubleClicked); -} diff --git a/src/modules/clist/clistsettings.cpp b/src/modules/clist/clistsettings.cpp deleted file mode 100644 index fee76ff9eb..0000000000 --- a/src/modules/clist/clistsettings.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -static LIST clistCache(50, NumericKeySortT); - -void FreeDisplayNameCache(void) -{ - for (int i=0; i < clistCache.getCount(); i++) { - cli.pfnFreeCacheItem(clistCache[i]); - mir_free(clistCache[i]); - } - - clistCache.destroy(); -} - -// default handlers for the cache item creation and destruction - -ClcCacheEntry* fnCreateCacheItem(MCONTACT hContact) -{ - ClcCacheEntry* p = (ClcCacheEntry*)mir_calloc(sizeof(ClcCacheEntry)); - if (p == NULL) - return NULL; - - p->hContact = hContact; - return p; -} - -void fnCheckCacheItem(ClcCacheEntry *p) -{ - DBVARIANT dbv; - if (p->tszGroup == NULL) { - if (!db_get_ts(p->hContact, "CList", "Group", &dbv)) { - p->tszGroup = mir_tstrdup(dbv.ptszVal); - mir_free(dbv.ptszVal); - } - else p->tszGroup = mir_tstrdup(_T("")); - } - - if (p->bIsHidden == -1) - p->bIsHidden = db_get_b(p->hContact, "CList", "Hidden", 0); -} - -void fnFreeCacheItem(ClcCacheEntry *p) -{ - if (p->tszName) { mir_free(p->tszName); p->tszName = NULL; } - if (p->tszGroup) { mir_free(p->tszGroup); p->tszGroup = NULL; } - p->bIsHidden = -1; -} - -ClcCacheEntry* fnGetCacheEntry(MCONTACT hContact) -{ - ClcCacheEntry *p; - int idx = clistCache.getIndex((ClcCacheEntry*)&hContact); - if (idx == -1) { - if ((p = cli.pfnCreateCacheItem(hContact)) != NULL) { - clistCache.insert(p); - cli.pfnInvalidateDisplayNameCacheEntry(hContact); - } - } - else p = clistCache[idx]; - - cli.pfnCheckCacheItem(p); - return p; -} - -void fnInvalidateDisplayNameCacheEntry(MCONTACT hContact) -{ - if (hContact == INVALID_CONTACT_ID) { - FreeDisplayNameCache(); - cli.pfnInitAutoRebuild(cli.hwndContactTree); - } - else { - int idx = clistCache.getIndex((ClcCacheEntry*)&hContact); - if (idx != -1) - cli.pfnFreeCacheItem(clistCache[idx]); - } -} - -TCHAR* fnGetContactDisplayName(MCONTACT hContact, int mode) -{ - ClcCacheEntry *cacheEntry = NULL; - - if (mode & GCDNF_NOCACHE) - mode &= ~GCDNF_NOCACHE; - else if (mode != GCDNF_NOMYHANDLE) { - cacheEntry = cli.pfnGetCacheEntry(hContact); - if (cacheEntry->tszName) - return cacheEntry->tszName; - } - - CONTACTINFO ci; - memset(&ci, 0, sizeof(ci)); - ci.cbSize = sizeof(ci); - ci.hContact = hContact; - if (ci.hContact == NULL) - ci.szProto = "ICQ"; - ci.dwFlag = ((mode == GCDNF_NOMYHANDLE) ? CNF_DISPLAYNC : CNF_DISPLAY) | CNF_TCHAR; - if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) { - if (ci.type == CNFT_ASCIIZ) { - if (cacheEntry != NULL) - cacheEntry->tszName = ci.pszVal; - return ci.pszVal; - } - - if (ci.type == CNFT_DWORD) { - TCHAR *buffer = (TCHAR*) mir_alloc(15 * sizeof(TCHAR)); - _ltot(ci.dVal, buffer, 10); - if (cacheEntry != NULL) - cacheEntry->tszName = buffer; - return buffer; - } - } - - CallContactService(hContact, PSS_GETINFO, SGIF_MINIMAL, 0); - TCHAR *buffer = TranslateT("(Unknown contact)"); - return (cacheEntry == NULL) ? mir_tstrdup(buffer) : buffer; -} - -INT_PTR GetContactDisplayName(WPARAM hContact, LPARAM lParam) -{ - static char retVal[200]; - ClcCacheEntry *cacheEntry = NULL; - - if (lParam & GCDNF_UNICODE) - return (INT_PTR)cli.pfnGetContactDisplayName(hContact, lParam & ~GCDNF_UNICODE); - - if (lParam & GCDNF_NOCACHE) - lParam &= ~GCDNF_NOCACHE; - else if (lParam != GCDNF_NOMYHANDLE) { - cacheEntry = cli.pfnGetCacheEntry(hContact); - if (cacheEntry->tszName) { - strncpy_s(retVal, _T2A(cacheEntry->tszName), _TRUNCATE); - return (INT_PTR)retVal; - } - } - - CONTACTINFO ci = { 0 }; - ci.cbSize = sizeof(ci); - ci.hContact = hContact; - if (ci.hContact == NULL) // killme !!!!!!!!!! - ci.szProto = "ICQ"; - ci.dwFlag = ((lParam == GCDNF_NOMYHANDLE) ? CNF_DISPLAYNC : CNF_DISPLAY) | CNF_TCHAR; - if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) { - if (ci.type == CNFT_ASCIIZ) { - strncpy_s(retVal, _T2A(ci.pszVal), _TRUNCATE); - if (cacheEntry == NULL) { - mir_free(ci.pszVal); - return (INT_PTR)mir_strdup(retVal); - } - - cacheEntry->tszName = ci.pszVal; - return (INT_PTR)retVal; - } - if (ci.type == CNFT_DWORD) { - _ltoa(ci.dVal, retVal, 10); - if (cacheEntry == NULL) - return (INT_PTR)mir_strdup(retVal); - - cacheEntry->tszName = mir_a2u(retVal); - return (INT_PTR)retVal; - } - } - - CallContactService(hContact, PSS_GETINFO, SGIF_MINIMAL, 0); - char* result = Translate("(Unknown contact)"); - return (INT_PTR)((cacheEntry == NULL) ? mir_strdup(result) : result); -} - -INT_PTR InvalidateDisplayName(WPARAM wParam, LPARAM) -{ - cli.pfnInvalidateDisplayNameCacheEntry(wParam); - return 0; -} - -int ContactAdded(WPARAM wParam, LPARAM) -{ - cli.pfnChangeContactIcon(wParam, cli.pfnIconFromStatusMode(GetContactProto(wParam), ID_STATUS_OFFLINE, NULL), 1); - cli.pfnSortContacts(); - return 0; -} - -int ContactDeleted(WPARAM wParam, LPARAM) -{ - CallService(MS_CLUI_CONTACTDELETED, wParam, 0); - return 0; -} - -int ContactSettingChanged(WPARAM hContact, LPARAM lParam) -{ - DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam; - - // Early exit - if (hContact == NULL) - return 0; - - DBVARIANT dbv; - dbv.pszVal = NULL; - if (!db_get(hContact, "Protocol", "p", &dbv)) { - if (!mir_strcmp(cws->szModule, dbv.pszVal)) { - cli.pfnInvalidateDisplayNameCacheEntry(hContact); - if (!mir_strcmp(cws->szSetting, "UIN") || !mir_strcmp(cws->szSetting, "Nick") || !mir_strcmp(cws->szSetting, "FirstName") - || !mir_strcmp(cws->szSetting, "LastName") || !mir_strcmp(cws->szSetting, "e-mail")) - { - CallService(MS_CLUI_CONTACTRENAMED, hContact, 0); - } - else if (!mir_strcmp(cws->szSetting, "Status")) { - if (!db_get_b(hContact, "CList", "Hidden", 0)) { - if (db_get_b(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT)) { - // User's state is changing, and we are hideOffline-ing - if (cws->value.wVal == ID_STATUS_OFFLINE) { - cli.pfnChangeContactIcon(hContact, cli.pfnIconFromStatusMode(cws->szModule, cws->value.wVal, hContact), 0); - CallService(MS_CLUI_CONTACTDELETED, hContact, 0); - mir_free(dbv.pszVal); - return 0; - } - cli.pfnChangeContactIcon(hContact, cli.pfnIconFromStatusMode(cws->szModule, cws->value.wVal, hContact), 1); - } - cli.pfnChangeContactIcon(hContact, cli.pfnIconFromStatusMode(cws->szModule, cws->value.wVal, hContact), 0); - } - } - else { - mir_free(dbv.pszVal); - return 0; - } - cli.pfnSortContacts(); - } - } - - if (!mir_strcmp(cws->szModule, "CList")) { - if (!mir_strcmp(cws->szSetting, "Hidden")) { - if (cws->value.type == DBVT_DELETED || cws->value.bVal == 0) { - char *szProto = GetContactProto(hContact); - cli.pfnChangeContactIcon(hContact, cli.pfnIconFromStatusMode(szProto, szProto == NULL ? ID_STATUS_OFFLINE : db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE), hContact), 1); - } - else - CallService(MS_CLUI_CONTACTDELETED, hContact, 0); - } - if (!mir_strcmp(cws->szSetting, "MyHandle")) - cli.pfnInvalidateDisplayNameCacheEntry(hContact); - } - - if (!mir_strcmp(cws->szModule, "Protocol")) { - if (!mir_strcmp(cws->szSetting, "p")) { - char *szProto; - if (cws->value.type == DBVT_DELETED) - szProto = NULL; - else - szProto = cws->value.pszVal; - cli.pfnChangeContactIcon(hContact, - cli.pfnIconFromStatusMode(szProto, - szProto == NULL ? ID_STATUS_OFFLINE : db_get_w(hContact, szProto, "Status", - ID_STATUS_OFFLINE), hContact), 0); - } - } - - // Clean up - if (dbv.pszVal) - mir_free(dbv.pszVal); - - return 0; -} diff --git a/src/modules/clist/clisttray.cpp b/src/modules/clist/clisttray.cpp deleted file mode 100644 index 4a2d495b6d..0000000000 --- a/src/modules/clist/clisttray.cpp +++ /dev/null @@ -1,877 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -#define TOOLTIP_TOLERANCE 5 - -extern HIMAGELIST hCListImages; - -static UINT WM_TASKBARCREATED; -static UINT WM_TASKBARBUTTONCREATED; -static UINT_PTR RefreshTimerId = 0; /////by FYR - -mir_cs trayLockCS; - -static bool hasTips() -{ - return ServiceExists("mToolTip/ShowTip") && db_get_b(NULL, "Tipper", "TrayTip", 1); -} - -// don't move to win2k.h, need new and old versions to work on 9x/2000/XP -#define NIF_STATE 0x00000008 -#define NIF_INFO 0x00000010 - -#define initcheck if (!fTrayInited) return - -#define SIZEOFNID ((cli.shellVersion >= 5) ? NOTIFYICONDATA_V2_SIZE : NOTIFYICONDATA_V1_SIZE) - -static BOOL fTrayInited = FALSE; - -static TCHAR* sttGetXStatus(const char *szProto) -{ - if (CallProtoServiceInt(NULL, szProto, PS_GETSTATUS, 0, 0) > ID_STATUS_OFFLINE) { - TCHAR tszStatus[512]; - CUSTOM_STATUS cs = { sizeof(cs) }; - cs.flags = CSSF_MASK_MESSAGE | CSSF_TCHAR; - cs.ptszMessage = tszStatus; - if (CallProtoServiceInt(NULL, szProto, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&cs) == 0) - return mir_tstrdup(tszStatus); - } - - return NULL; -} - -static HICON lastTaskBarIcon; -static void SetTaskBarIcon(const HICON hIcon, const TCHAR *szNewTip) -{ - if (pTaskbarInterface) { - pTaskbarInterface->SetOverlayIcon(cli.hwndContactList, hIcon, szNewTip); - lastTaskBarIcon = hIcon; - } -} - -TCHAR* fnTrayIconMakeTooltip(const TCHAR *szPrefix, const char *szProto) -{ - initcheck NULL; - - mir_cslock lck(trayLockCS); - TCHAR *szSeparator = _T("\n"); - - if (szProto == NULL) { - if (accounts.getCount() == 0) - return NULL; - - if (accounts.getCount() == 1) - return cli.pfnTrayIconMakeTooltip(szPrefix, accounts[0]->szModuleName); - - CMString tszTip; - - if (szPrefix && szPrefix[0]) { - if (!db_get_b(NULL, "CList", "AlwaysStatus", SETTING_ALWAYSSTATUS_DEFAULT)) { - _tcsncpy_s(cli.szTip, MAX_TIP_SIZE, szPrefix, _TRUNCATE); - return cli.szTip; - } - tszTip.Append(szPrefix); - } - - for (int t = 0; t < accounts.getCount(); t++) { - int i = cli.pfnGetAccountIndexByPos(t); - if (i == -1) - continue; - - PROTOACCOUNT *pa = accounts[i]; - if (!cli.pfnGetProtocolVisibility(pa->szModuleName)) - continue; - - TCHAR *szStatus = cli.pfnGetStatusModeDescription(CallProtoServiceInt(NULL, pa->szModuleName, PS_GETSTATUS, 0, 0), 0); - if (!szStatus) - continue; - - if (!tszTip.IsEmpty()) - tszTip.AppendChar('\n'); - if (hasTips()) { - tszTip.AppendFormat(_T("%-12.12s\t%s"), pa->tszAccountName, szStatus); - - ptrT ProtoXStatus(sttGetXStatus(pa->szModuleName)); - if (ProtoXStatus != NULL) { - if (!tszTip.IsEmpty()) - tszTip.AppendChar('\n'); - tszTip.AppendFormat(_T("%-24.24s\n"), ProtoXStatus); - } - } - else tszTip.AppendFormat(_T("%s %s"), pa->tszAccountName, szStatus); - } - - _tcsncpy_s(cli.szTip, MAX_TIP_SIZE, tszTip, _TRUNCATE); - } - else { - PROTOACCOUNT *pa = Proto_GetAccount(szProto); - if (pa != NULL) { - ptrT ProtoXStatus(sttGetXStatus(szProto)); - TCHAR *szStatus = cli.pfnGetStatusModeDescription(CallProtoServiceInt(NULL, szProto, PS_GETSTATUS, 0, 0), 0); - if (szPrefix && szPrefix[0]) { - if (db_get_b(NULL, "CList", "AlwaysStatus", SETTING_ALWAYSSTATUS_DEFAULT)) { - if (hasTips()) { - if (ProtoXStatus != NULL) - mir_sntprintf(cli.szTip, MAX_TIP_SIZE, _T("%s%s%-12.12s\t%s%s%-24.24s"), szPrefix, szSeparator, pa->tszAccountName, szStatus, szSeparator, ProtoXStatus); - else - mir_sntprintf(cli.szTip, MAX_TIP_SIZE, _T("%s%s%-12.12s\t%s"), szPrefix, szSeparator, pa->tszAccountName, szStatus); - } - else mir_sntprintf(cli.szTip, MAX_TIP_SIZE, _T("%s%s%s %s"), szPrefix, szSeparator, pa->tszAccountName, szStatus); - } - else mir_tstrncpy(cli.szTip, szPrefix, MAX_TIP_SIZE); - } - else { - if (hasTips()) { - if (ProtoXStatus != NULL) - mir_sntprintf(cli.szTip, MAX_TIP_SIZE, _T("%-12.12s\t%s\n%-24.24s"), pa->tszAccountName, szStatus, ProtoXStatus); - else - mir_sntprintf(cli.szTip, MAX_TIP_SIZE, _T("%-12.12s\t%s"), pa->tszAccountName, szStatus); - } - else mir_sntprintf(cli.szTip, MAX_TIP_SIZE, _T("%s %s"), pa->tszAccountName, szStatus); - } - } - } - - return cli.szTip; -} - -int fnTrayIconAdd(HWND hwnd, const char *szProto, const char *szIconProto, int status) -{ - initcheck 0; - - mir_cslock lck(trayLockCS); - int i; - for (i = 0; i < cli.trayIconCount; i++) - if (cli.trayIcon[i].id == 0) - break; - - trayIconInfo_t &p = cli.trayIcon[i]; - p.id = TRAYICON_ID_BASE + i; - p.szProto = (char*)szProto; - p.hBaseIcon = cli.pfnGetIconFromStatusMode(NULL, szIconProto ? szIconProto : p.szProto, status); - - NOTIFYICONDATA nid = { SIZEOFNID }; - nid.hWnd = hwnd; - nid.uID = p.id; - nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; - nid.uCallbackMessage = TIM_CALLBACK; - nid.hIcon = p.hBaseIcon; - - if (cli.shellVersion >= 5) - nid.uFlags |= NIF_INFO; - - cli.pfnTrayIconMakeTooltip(NULL, p.szProto); - if (!hasTips()) - mir_tstrncpy(nid.szTip, cli.szTip, SIZEOF(nid.szTip)); - replaceStrT(p.ptszToolTip, cli.szTip); - - Shell_NotifyIcon(NIM_ADD, &nid); - p.isBase = 1; - - if (cli.trayIconCount == 1) - SetTaskBarIcon(cli.trayIcon[0].hBaseIcon, cli.szTip); - return i; -} - -void fnTrayIconRemove(HWND hwnd, const char *szProto) -{ - initcheck; - - mir_cslock lck(trayLockCS); - for (int i = 0; i < cli.trayIconCount; i++) { - trayIconInfo_t *pii = &cli.trayIcon[i]; - if (pii->id != 0 && !mir_strcmp(szProto, pii->szProto)) { - NOTIFYICONDATA nid = { SIZEOFNID }; - nid.hWnd = hwnd; - nid.uID = pii->id; - Shell_NotifyIcon(NIM_DELETE, &nid); - - DestroyIcon(pii->hBaseIcon); - mir_free(pii->ptszToolTip); pii->ptszToolTip = NULL; - pii->id = 0; - break; - } - } - - if (cli.trayIconCount == 1) - SetTaskBarIcon(NULL, NULL); -} - -int fnTrayIconInit(HWND hwnd) -{ - initcheck 0; - - mir_cslock lck(trayLockCS); - - int netProtoCount = 0; - int averageMode = cli.pfnGetAverageMode(&netProtoCount); - - if (cli.cycleTimerId) { - KillTimer(NULL, cli.cycleTimerId); - cli.cycleTimerId = 0; - } - - cli.trayIconCount = 1; - - if (netProtoCount) { - cli.trayIcon = (trayIconInfo_t*)mir_calloc(sizeof(trayIconInfo_t) * accounts.getCount()); - - int trayIconSetting = db_get_b(NULL, "CList", "TrayIcon", SETTING_TRAYICON_DEFAULT); - if (trayIconSetting == SETTING_TRAYICON_SINGLE) { - DBVARIANT dbv = { DBVT_DELETED }; - char *szProto; - if (!db_get_s(NULL, "CList", "PrimaryStatus", &dbv) && (averageMode < 0 || db_get_b(NULL, "CList", "AlwaysPrimary", 0))) - szProto = dbv.pszVal; - else - szProto = NULL; - - cli.pfnTrayIconAdd(hwnd, NULL, szProto, szProto ? CallProtoServiceInt(NULL, szProto, PS_GETSTATUS, 0, 0) : CallService(MS_CLIST_GETSTATUSMODE, 0, 0)); - db_free(&dbv); - } - else if (trayIconSetting == SETTING_TRAYICON_MULTI && (averageMode < 0 || db_get_b(NULL, "CList", "AlwaysMulti", SETTING_ALWAYSMULTI_DEFAULT))) { - cli.trayIconCount = netProtoCount; - for (int i = 0; i < accounts.getCount(); i++) { - int j = cli.pfnGetAccountIndexByPos(i); - if (j >= 0) { - PROTOACCOUNT *pa = accounts[j]; - if (cli.pfnGetProtocolVisibility(pa->szModuleName)) - cli.pfnTrayIconAdd(hwnd, pa->szModuleName, NULL, CallProtoServiceInt(NULL, pa->szModuleName, PS_GETSTATUS, 0, 0)); - } - } - } - else { - cli.pfnTrayIconAdd(hwnd, NULL, NULL, averageMode); - - if (trayIconSetting == SETTING_TRAYICON_CYCLE && averageMode < 0) - cli.cycleTimerId = SetTimer(NULL, 0, db_get_w(NULL, "CList", "CycleTime", SETTING_CYCLETIME_DEFAULT) * 1000, cli.pfnTrayCycleTimerProc); - } - } - else { - cli.trayIcon = (trayIconInfo_t*)mir_calloc(sizeof(trayIconInfo_t)); - cli.pfnTrayIconAdd(hwnd, NULL, NULL, CallService(MS_CLIST_GETSTATUSMODE, 0, 0)); - } - - return 0; -} - -int fnTrayIconDestroy(HWND hwnd) -{ - initcheck 0; - - mir_cslock lck(trayLockCS); - if (cli.trayIconCount == 1) - SetTaskBarIcon(NULL, NULL); - - NOTIFYICONDATA nid = { SIZEOFNID }; - nid.hWnd = hwnd; - for (int i = 0; i < cli.trayIconCount; i++) { - if (cli.trayIcon[i].id == 0) - continue; - nid.uID = cli.trayIcon[i].id; - Shell_NotifyIcon(NIM_DELETE, &nid); - DestroyIcon(cli.trayIcon[i].hBaseIcon); - mir_free(cli.trayIcon[i].ptszToolTip); - } - mir_free(cli.trayIcon); - cli.trayIcon = NULL; - cli.trayIconCount = 0; - return 0; -} - -// called when Explorer crashes and the taskbar is remade -void fnTrayIconTaskbarCreated(HWND hwnd) -{ - initcheck; - cli.pfnTrayIconDestroy(hwnd); - cli.pfnTrayIconInit(hwnd); -} - -static VOID CALLBACK RefreshTimerProc(HWND, UINT, UINT_PTR, DWORD) -{ - if (RefreshTimerId) { - KillTimer(NULL, RefreshTimerId); - RefreshTimerId = 0; - } - for (int i = 0; i < accounts.getCount(); i++) - cli.pfnTrayIconUpdateBase(accounts[i]->szModuleName); -} - -int fnTrayIconUpdate(HICON hNewIcon, const TCHAR *szNewTip, const char *szPreferredProto, int isBase) -{ - initcheck - 1; - mir_cslock lck(trayLockCS); - - NOTIFYICONDATA nid = { SIZEOFNID }; - nid.hWnd = cli.hwndContactList; - nid.uFlags = NIF_ICON | NIF_TIP; - nid.hIcon = hNewIcon; - if (!hNewIcon) - return -1; - - for (int i = 0; i < cli.trayIconCount; i++) { - if (cli.trayIcon[i].id == 0) - continue; - if (mir_strcmp(cli.trayIcon[i].szProto, szPreferredProto)) - continue; - - nid.uID = cli.trayIcon[i].id; - cli.pfnTrayIconMakeTooltip(szNewTip, cli.trayIcon[i].szProto); - mir_free(cli.trayIcon[i].ptszToolTip); - cli.trayIcon[i].ptszToolTip = mir_tstrdup(cli.szTip); - if (!hasTips()) - mir_tstrncpy(nid.szTip, cli.szTip, SIZEOF(nid.szTip)); - Shell_NotifyIcon(NIM_MODIFY, &nid); - - if (cli.trayIconCount == 1) - SetTaskBarIcon(hNewIcon, cli.szTip); - else - SetTaskBarIcon(NULL, NULL); - - cli.trayIcon[i].isBase = isBase; - return i; - } - - // if there wasn't a suitable icon, change all the icons - for (int i = 0; i < cli.trayIconCount; i++) { - if (cli.trayIcon[i].id == 0) - continue; - nid.uID = cli.trayIcon[i].id; - - cli.pfnTrayIconMakeTooltip(szNewTip, cli.trayIcon[i].szProto); - mir_free(cli.trayIcon[i].ptszToolTip); - cli.trayIcon[i].ptszToolTip = mir_tstrdup(cli.szTip); - if (!hasTips()) - mir_tstrncpy(nid.szTip, cli.szTip, SIZEOF(nid.szTip)); - Shell_NotifyIcon(NIM_MODIFY, &nid); - - if (cli.trayIconCount == 1) - SetTaskBarIcon(hNewIcon, cli.szTip); - else - SetTaskBarIcon(NULL, NULL); - - cli.trayIcon[i].isBase = isBase; - if (db_get_b(NULL, "CList", "TrayIcon", SETTING_TRAYICON_DEFAULT) == SETTING_TRAYICON_MULTI) { - DWORD time1 = db_get_w(NULL, "CList", "CycleTime", SETTING_CYCLETIME_DEFAULT) * 200; - DWORD time2 = db_get_w(NULL, "CList", "IconFlashTime", 550) + 1000; - DWORD time = max(max(2000, time1), time2); - if (RefreshTimerId) - KillTimer(NULL, RefreshTimerId); - - // if unknown base was changed - than show preffered proto icon for 2 sec - // and reset it to original one after timeout - RefreshTimerId = SetTimer(NULL, 0, time, RefreshTimerProc); - } - return i; - } - - return -1; -} - -int fnTrayIconSetBaseInfo(HICON hIcon, const char *szPreferredProto) -{ - if (!fTrayInited) { - LBL_Error: - DestroyIcon(hIcon); - return -1; - } - - mir_cslock lck(trayLockCS); - - if (szPreferredProto) { - for (int i = 0; i < cli.trayIconCount; i++) { - if (cli.trayIcon[i].id == 0) - continue; - if (mir_strcmp(cli.trayIcon[i].szProto, szPreferredProto)) - continue; - - DestroyIcon(cli.trayIcon[i].hBaseIcon); - cli.trayIcon[i].hBaseIcon = hIcon; - return i; - } - if ((cli.pfnGetProtocolVisibility(szPreferredProto)) && - (cli.pfnGetAverageMode(NULL) == -1) && - (db_get_b(NULL, "CList", "TrayIcon", SETTING_TRAYICON_DEFAULT) == SETTING_TRAYICON_MULTI) && - !(db_get_b(NULL, "CList", "AlwaysMulti", SETTING_ALWAYSMULTI_DEFAULT))) - goto LBL_Error; - } - - // if there wasn't a specific icon, there will only be one suitable - for (int i = 0; i < cli.trayIconCount; i++) { - if (cli.trayIcon[i].id == 0) - continue; - - DestroyIcon(cli.trayIcon[i].hBaseIcon); - cli.trayIcon[i].hBaseIcon = hIcon; - return i; - } - - goto LBL_Error; -} - -void fnTrayIconUpdateWithImageList(int iImage, const TCHAR *szNewTip, char *szPreferredProto) -{ - HICON hIcon = ImageList_GetIcon(hCListImages, iImage, ILD_NORMAL); - cli.pfnTrayIconUpdate(hIcon, szNewTip, szPreferredProto, 0); - DestroyIcon(hIcon); -} - -VOID CALLBACK fnTrayCycleTimerProc(HWND, UINT, UINT_PTR, DWORD) -{ - initcheck; - mir_cslock lck(trayLockCS); - - int i; - for (i = accounts.getCount() + 1; --i;) { - cli.cycleStep = (cli.cycleStep + 1) % accounts.getCount(); - if (cli.pfnGetProtocolVisibility(accounts[cli.cycleStep]->szModuleName)) - break; - } - - if (i) { - DestroyIcon(cli.trayIcon[0].hBaseIcon); - cli.trayIcon[0].hBaseIcon = cli.pfnGetIconFromStatusMode(NULL, accounts[cli.cycleStep]->szModuleName, - CallProtoServiceInt(NULL, accounts[cli.cycleStep]->szModuleName, PS_GETSTATUS, 0, 0)); - if (cli.trayIcon[0].isBase) - cli.pfnTrayIconUpdate(cli.trayIcon[0].hBaseIcon, NULL, NULL, 1); - } -} - -void fnTrayIconUpdateBase(const char *szChangedProto) -{ - initcheck; - if (szChangedProto == NULL) return; - if (!cli.pfnGetProtocolVisibility(szChangedProto)) return; - - int netProtoCount; - mir_cslock lck(trayLockCS); - int averageMode = cli.pfnGetAverageMode(&netProtoCount); - - if (cli.cycleTimerId) { - KillTimer(NULL, cli.cycleTimerId); - cli.cycleTimerId = 0; - } - - for (int i = 0; i < accounts.getCount(); i++) - if (!mir_strcmp(szChangedProto, accounts[i]->szModuleName)) - cli.cycleStep = i; - - int changed = cli.pfnTrayCalcChanged(szChangedProto, averageMode, netProtoCount); - if (changed != -1 && cli.trayIcon[changed].isBase) - cli.pfnTrayIconUpdate(cli.trayIcon[changed].hBaseIcon, NULL, cli.trayIcon[changed].szProto, 1); -} - -int fnTrayCalcChanged(const char *szChangedProto, int averageMode, int netProtoCount) -{ - if (netProtoCount == 0) - return cli.pfnTrayIconSetBaseInfo(ImageList_GetIcon(hCListImages, cli.pfnIconFromStatusMode(NULL, averageMode, NULL), ILD_NORMAL), NULL); - - int trayIconSetting = db_get_b(NULL, "CList", "TrayIcon", SETTING_TRAYICON_DEFAULT); - - if (averageMode > 0) { - if (trayIconSetting != SETTING_TRAYICON_MULTI) - return cli.pfnTrayIconSetBaseInfo(cli.pfnGetIconFromStatusMode(NULL, NULL, averageMode), NULL); - - if (db_get_b(NULL, "CList", "AlwaysMulti", SETTING_ALWAYSMULTI_DEFAULT)) - return cli.pfnTrayIconSetBaseInfo(cli.pfnGetIconFromStatusMode(NULL, szChangedProto, CallProtoServiceInt(NULL, szChangedProto, PS_GETSTATUS, 0, 0)), (char*)szChangedProto); - - if (cli.trayIcon == NULL || cli.trayIcon[0].szProto == NULL) - return cli.pfnTrayIconSetBaseInfo(cli.pfnGetIconFromStatusMode(NULL, NULL, averageMode), NULL); - - cli.pfnTrayIconDestroy(cli.hwndContactList); - cli.pfnTrayIconInit(cli.hwndContactList); - } - else { - switch (trayIconSetting) { - case SETTING_TRAYICON_CYCLE: - cli.cycleTimerId = SetTimer(NULL, 0, db_get_w(NULL, "CList", "CycleTime", SETTING_CYCLETIME_DEFAULT) * 1000, cli.pfnTrayCycleTimerProc); - return cli.pfnTrayIconSetBaseInfo(ImageList_GetIcon - (hCListImages, cli.pfnIconFromStatusMode(szChangedProto, CallProtoServiceInt(NULL, szChangedProto, PS_GETSTATUS, 0, 0), NULL), - ILD_NORMAL), NULL); - - case SETTING_TRAYICON_MULTI: - if (!cli.trayIcon) - cli.pfnTrayIconRemove(NULL, NULL); - else if ((cli.trayIconCount > 1 || netProtoCount == 1) || db_get_b(NULL, "CList", "AlwaysMulti", SETTING_ALWAYSMULTI_DEFAULT)) - return cli.pfnTrayIconSetBaseInfo(cli.pfnGetIconFromStatusMode(NULL, szChangedProto, CallProtoServiceInt(NULL, szChangedProto, PS_GETSTATUS, 0, 0)), (char*)szChangedProto); - else { - cli.pfnTrayIconDestroy(cli.hwndContactList); - cli.pfnTrayIconInit(cli.hwndContactList); - } - break; - - case SETTING_TRAYICON_SINGLE: - ptrA szProto(db_get_sa(NULL, "CList", "PrimaryStatus")); - return cli.pfnTrayIconSetBaseInfo(cli.pfnGetIconFromStatusMode(NULL, szProto, szProto ? - CallProtoServiceInt(NULL, szProto, PS_GETSTATUS, 0, 0) : - CallService(MS_CLIST_GETSTATUSMODE, 0, 0)), szProto); - } - } - - return -1; -} - -void fnTrayIconSetToBase(char *szPreferredProto) -{ - int i; - initcheck; - mir_cslock lck(trayLockCS); - - for (i = 0; i < cli.trayIconCount; i++) { - if (cli.trayIcon[i].id == 0) - continue; - if (mir_strcmp(cli.trayIcon[i].szProto, szPreferredProto)) - continue; - cli.pfnTrayIconUpdate(cli.trayIcon[i].hBaseIcon, NULL, szPreferredProto, 1); - return; - } - - // if there wasn't a specific icon, there will only be one suitable - for (i = 0; i < cli.trayIconCount; i++) { - if (cli.trayIcon[i].id == 0) - continue; - cli.pfnTrayIconUpdate(cli.trayIcon[i].hBaseIcon, NULL, szPreferredProto, 1); - return; - } -} - -void fnTrayIconIconsChanged(void) -{ - initcheck; - mir_cslock lck(trayLockCS); - - cli.pfnTrayIconDestroy(cli.hwndContactList); - cli.pfnTrayIconInit(cli.hwndContactList); -} - -static UINT_PTR autoHideTimerId; -static VOID CALLBACK TrayIconAutoHideTimer(HWND hwnd, UINT, UINT_PTR idEvent, DWORD) -{ - initcheck; - mir_cslock lck(trayLockCS); - - KillTimer(hwnd, idEvent); - HWND hwndClui = cli.hwndContactList; - if (GetActiveWindow() != hwndClui) { - ShowWindow(hwndClui, SW_HIDE); - SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1); - } -} - -int fnTrayIconPauseAutoHide(WPARAM, LPARAM) -{ - initcheck 0; - mir_cslock lck(trayLockCS); - - if (db_get_b(NULL, "CList", "AutoHide", SETTING_AUTOHIDE_DEFAULT)) { - if (GetActiveWindow() != cli.hwndContactList) { - KillTimer(NULL, autoHideTimerId); - autoHideTimerId = SetTimer(NULL, 0, 1000 * db_get_w(NULL, "CList", "HideTime", SETTING_HIDETIME_DEFAULT), TrayIconAutoHideTimer); - } - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// processes tray icon's messages - -static BYTE s_LastHoverIconID = 0; -static BOOL g_trayTooltipActive = FALSE; -static POINT tray_hover_pos = { 0 }; - -static void CALLBACK TrayHideToolTipTimerProc(HWND hwnd, UINT, UINT_PTR, DWORD) -{ - if (g_trayTooltipActive) { - POINT pt; - GetCursorPos(&pt); - if (abs(pt.x - tray_hover_pos.x) > TOOLTIP_TOLERANCE || abs(pt.y - tray_hover_pos.y) > TOOLTIP_TOLERANCE) { - CallService("mToolTip/HideTip", 0, 0); - g_trayTooltipActive = FALSE; - KillTimer(hwnd, TIMERID_TRAYHOVER_2); - } - } - else KillTimer(hwnd, TIMERID_TRAYHOVER_2); -} - -static void CALLBACK TrayToolTipTimerProc(HWND hwnd, UINT, UINT_PTR id, DWORD) -{ - if (!g_trayTooltipActive && !cli.bTrayMenuOnScreen) { - POINT pt; - GetCursorPos(&pt); - if (abs(pt.x - tray_hover_pos.x) <= TOOLTIP_TOLERANCE && abs(pt.y - tray_hover_pos.y) <= TOOLTIP_TOLERANCE) { - TCHAR* szTipCur = cli.szTip; - { - int n = s_LastHoverIconID - 100; - if (n >= 0 && n < cli.trayIconCount) - szTipCur = cli.trayIcon[n].ptszToolTip; - } - CLCINFOTIP ti = { sizeof(ti) }; - ti.rcItem.left = pt.x - 10; - ti.rcItem.right = pt.x + 10; - ti.rcItem.top = pt.y - 10; - ti.rcItem.bottom = pt.y + 10; - ti.isTreeFocused = GetFocus() == cli.hwndContactList ? 1 : 0; - if (CallService("mToolTip/ShowTipW", (WPARAM)szTipCur, (LPARAM)&ti) == CALLSERVICE_NOTFOUND) - CallService("mToolTip/ShowTip", (WPARAM)(char*)_T2A(szTipCur), (LPARAM)&ti); - - GetCursorPos(&tray_hover_pos); - SetTimer(cli.hwndContactList, TIMERID_TRAYHOVER_2, 600, TrayHideToolTipTimerProc); - g_trayTooltipActive = TRUE; - } - } - - KillTimer(hwnd, id); -} - -INT_PTR fnTrayIconProcessMessage(WPARAM wParam, LPARAM lParam) -{ - MSG *msg = (MSG *)wParam; - switch (msg->message) { - case WM_CREATE: { - WM_TASKBARCREATED = RegisterWindowMessage(_T("TaskbarCreated")); - WM_TASKBARBUTTONCREATED = RegisterWindowMessage(_T("TaskbarButtonCreated")); - PostMessage(msg->hwnd, TIM_CREATE, 0, 0); - break; - } - case TIM_CREATE: - cli.pfnTrayIconInit(msg->hwnd); - break; - - case WM_ACTIVATE: - if (db_get_b(NULL, "CList", "AutoHide", SETTING_AUTOHIDE_DEFAULT)) { - if (LOWORD(msg->wParam) == WA_INACTIVE) - autoHideTimerId = SetTimer(NULL, 0, 1000 * db_get_w(NULL, "CList", "HideTime", SETTING_HIDETIME_DEFAULT), TrayIconAutoHideTimer); - else - KillTimer(NULL, autoHideTimerId); - } - break; - - case WM_DESTROY: - cli.pfnTrayIconDestroy(msg->hwnd); - cli.pfnUninitTray(); - break; - - case TIM_CALLBACK: - if (msg->lParam == WM_RBUTTONDOWN || msg->lParam == WM_LBUTTONDOWN || msg->lParam == WM_RBUTTONDOWN && g_trayTooltipActive) { - CallService("mToolTip/HideTip", 0, 0); - g_trayTooltipActive = FALSE; - } - - if (msg->lParam == WM_MBUTTONUP) - cli.pfnShowHide(0, 0); - else if (msg->lParam == (db_get_b(NULL, "CList", "Tray1Click", SETTING_TRAY1CLICK_DEFAULT) ? WM_LBUTTONUP : WM_LBUTTONDBLCLK)) { - if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) { - POINT pt; - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS, 0, 0); - - for (int i = 0; i < cli.trayIconCount; i++) { - if ((unsigned)cli.trayIcon[i].id == msg->wParam) { - if (!cli.trayIcon[i].szProto) - break; - - int ind = 0; - for (int j = 0; j < accounts.getCount(); j++) { - int k = cli.pfnGetAccountIndexByPos(j); - if (k >= 0) { - if (!mir_strcmp(cli.trayIcon[i].szProto, accounts[k]->szModuleName)) { - HMENU hm = GetSubMenu(hMenu, ind); - if (hm) hMenu = hm; - break; - } - - if (cli.pfnGetProtocolVisibility(accounts[k]->szModuleName)) - ++ind; - } - } - break; - } - } - - SetForegroundWindow(msg->hwnd); - SetFocus(msg->hwnd); - GetCursorPos(&pt); - TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, msg->hwnd, NULL); - } - else if (cli.pfnEventsProcessTrayDoubleClick(msg->wParam)) - cli.pfnShowHide(0, 0); - } - else if (msg->lParam == WM_RBUTTONUP) { - HMENU hMainMenu = LoadMenu(cli.hInst, MAKEINTRESOURCE(IDR_CONTEXT)); - HMENU hMenu = GetSubMenu(hMainMenu, 0); - TranslateMenu(hMenu); - - MENUITEMINFO mi = { sizeof(mi) }; - mi.fMask = MIIM_SUBMENU | MIIM_TYPE; - mi.fType = MFT_STRING; - mi.hSubMenu = (HMENU)CallService(MS_CLIST_MENUGETMAIN, 0, 0); - mi.dwTypeData = TranslateT("&Main menu"); - InsertMenuItem(hMenu, 1, TRUE, &mi); - mi.hSubMenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS, 0, 0); - mi.dwTypeData = TranslateT("&Status"); - InsertMenuItem(hMenu, 2, TRUE, &mi); - SetMenuDefaultItem(hMenu, ID_TRAY_HIDE, FALSE); - - SetForegroundWindow(msg->hwnd); - SetFocus(msg->hwnd); - - POINT pt; - GetCursorPos(&pt); - TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN, pt.x, pt.y, 0, msg->hwnd, NULL); - - RemoveMenu(hMenu, 1, MF_BYPOSITION); - RemoveMenu(hMenu, 1, MF_BYPOSITION); - DestroyMenu(hMainMenu); - } - else if (msg->lParam == WM_MOUSEMOVE) { - s_LastHoverIconID = msg->wParam; - if (g_trayTooltipActive) { - POINT pt; - GetCursorPos(&pt); - if (abs(pt.x - tray_hover_pos.x) > TOOLTIP_TOLERANCE || abs(pt.y - tray_hover_pos.y) > TOOLTIP_TOLERANCE) { - CallService("mToolTip/HideTip", 0, 0); - g_trayTooltipActive = FALSE; - ReleaseCapture(); - } - } - else { - GetCursorPos(&tray_hover_pos); - SetTimer(cli.hwndContactList, TIMERID_TRAYHOVER, 600, TrayToolTipTimerProc); - } - break; - } - - *((LRESULT*)lParam) = 0; - return TRUE; - - default: - if (msg->message == WM_TASKBARCREATED) { - cli.pfnTrayIconTaskbarCreated(msg->hwnd); - *((LRESULT*)lParam) = 0; - return TRUE; - } - else if (msg->message == WM_TASKBARBUTTONCREATED) { - SetTaskBarIcon(lastTaskBarIcon, NULL); - *((LRESULT*)lParam) = 0; - return TRUE; - } - } - - return FALSE; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// processes tray icon's notifications - -int fnCListTrayNotify(MIRANDASYSTRAYNOTIFY* msn) -{ - if (msn == NULL) - return 1; - - if (msn->cbSize != sizeof(MIRANDASYSTRAYNOTIFY) || msn->szInfo == NULL || msn->szInfoTitle == NULL) - return 1; - - if (cli.trayIcon == NULL) - return 2; - - UINT iconId = 0; - if (msn->szProto) { - for (int j = 0; j < cli.trayIconCount; j++) { - if (cli.trayIcon[j].szProto != NULL) { - if (!mir_strcmp(msn->szProto, cli.trayIcon[j].szProto)) { - iconId = cli.trayIcon[j].id; - break; - } - } - else if (cli.trayIcon[j].isBase) { - iconId = cli.trayIcon[j].id; - break; - } - } - } - else iconId = cli.trayIcon[0].id; - - if (msn->dwInfoFlags & NIIF_INTERN_UNICODE) { - NOTIFYICONDATAW nid = { 0 }; - nid.cbSize = (cli.shellVersion >= 5) ? NOTIFYICONDATAW_V2_SIZE : NOTIFYICONDATAW_V1_SIZE; - nid.hWnd = cli.hwndContactList; - nid.uID = iconId; - nid.uFlags = NIF_INFO; - mir_wstrncpy(nid.szInfo, msn->tszInfo, SIZEOF(nid.szInfo)); - mir_wstrncpy(nid.szInfoTitle, msn->tszInfoTitle, SIZEOF(nid.szInfoTitle)); - nid.szInfo[SIZEOF(nid.szInfo) - 1] = 0; - nid.szInfoTitle[SIZEOF(nid.szInfoTitle) - 1] = 0; - nid.uTimeout = msn->uTimeout; - nid.dwInfoFlags = (msn->dwInfoFlags & ~NIIF_INTERN_UNICODE); - return Shell_NotifyIconW(NIM_MODIFY, &nid) == 0; - } - else { - NOTIFYICONDATAA nid = { 0 }; - nid.cbSize = (cli.shellVersion >= 5) ? NOTIFYICONDATAA_V2_SIZE : NOTIFYICONDATAA_V1_SIZE; - nid.hWnd = cli.hwndContactList; - nid.uID = iconId; - nid.uFlags = NIF_INFO; - strncpy_s(nid.szInfo, msn->szInfo, _TRUNCATE); - strncpy_s(nid.szInfoTitle, msn->szInfoTitle, _TRUNCATE); - nid.uTimeout = msn->uTimeout; - nid.dwInfoFlags = msn->dwInfoFlags; - return Shell_NotifyIconA(NIM_MODIFY, &nid) == 0; - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static DLLVERSIONINFO dviShell; - -static INT_PTR pfnCListTrayNotifyStub(WPARAM, LPARAM lParam) -{ - return cli.pfnCListTrayNotify((MIRANDASYSTRAYNOTIFY*)lParam); -} - -void fnInitTray(void) -{ - HMODULE hLib = GetModuleHandleA("shell32"); - if (hLib) { - DLLGETVERSIONPROC proc; - dviShell.cbSize = sizeof(dviShell); - proc = (DLLGETVERSIONPROC)GetProcAddress(hLib, "DllGetVersion"); - if (proc) { - proc(&dviShell); - cli.shellVersion = dviShell.dwMajorVersion; - } - FreeLibrary(hLib); - } - - if (cli.shellVersion >= 5) - CreateServiceFunction(MS_CLIST_SYSTRAY_NOTIFY, pfnCListTrayNotifyStub); - fTrayInited = TRUE; -} - -void fnUninitTray(void) -{ - fTrayInited = FALSE; -} - -#undef initcheck diff --git a/src/modules/clist/clui.cpp b/src/modules/clist/clui.cpp deleted file mode 100644 index 50a3b3f8d6..0000000000 --- a/src/modules/clist/clui.cpp +++ /dev/null @@ -1,1074 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "../database/profilemanager.h" -#include "clc.h" - -#define TM_AUTOALPHA 1 -#define MENU_MIRANDAMENU 0xFFFF1234 - -extern HANDLE hEventExtraClick; - -static HMODULE hUserDll; -static HANDLE hContactDraggingEvent, hContactDroppedEvent, hContactDragStopEvent; -static int transparentFocus = 1; -UINT uMsgProcessProfile; - -#define M_RESTORESTATUS (WM_USER+7) - -typedef struct { - int showsbar; - int showgrip; - int transparent; - int alpha; -} - CluiOpts; - -static CluiOpts cluiopt = {0}; - -void fnLoadCluiGlobalOpts() -{ - cluiopt.showsbar = db_get_b(NULL, "CLUI", "ShowSBar", 1); - cluiopt.showgrip = db_get_b(NULL, "CLUI", "ShowGrip", 1); - cluiopt.transparent = db_get_b(NULL, "CList", "Transparent", SETTING_TRANSPARENT_DEFAULT); - cluiopt.alpha = db_get_b(NULL, "CList", "Alpha", SETTING_ALPHA_DEFAULT); -} - -static int CluiModulesLoaded(WPARAM, LPARAM) -{ - if (cli.hMenuMain) { - MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_SUBMENU; - mii.hSubMenu = (HMENU) CallService(MS_CLIST_MENUGETMAIN, 0, 0); - SetMenuItemInfo(cli.hMenuMain, 0, TRUE, &mii); - mii.hSubMenu = (HMENU) CallService(MS_CLIST_MENUGETSTATUS, 0, 0); - SetMenuItemInfo(cli.hMenuMain, 1, TRUE, &mii); - } - return 0; -} - -// Disconnect all protocols. -// Happens on shutdown and standby. -static void DisconnectAll() -{ - for (int i = 0; i < accounts.getCount(); i++) - CallProtoServiceInt(NULL,accounts[i]->szModuleName, PS_SETSTATUS, ID_STATUS_OFFLINE, 0); -} - -static int CluiIconsChanged(WPARAM, LPARAM) -{ - DrawMenuBar(cli.hwndContactList); - return 0; -} - -static HGENMENU hRenameMenuItem; - -static int MenuItem_PreBuild(WPARAM, LPARAM) -{ - TCHAR cls[128]; - HWND hwndClist = GetFocus(); - GetClassName(hwndClist, cls, SIZEOF(cls)); - hwndClist = (!mir_tstrcmp( _T(CLISTCONTROL_CLASS), cls)) ? hwndClist : cli.hwndContactList; - HANDLE hItem = (HANDLE)SendMessage(hwndClist, CLM_GETSELECTION, 0, 0); - Menu_ShowItem(hRenameMenuItem, hItem != 0); - return 0; -} - -static INT_PTR MenuItem_RenameContact(WPARAM, LPARAM) -{ - TCHAR cls[128]; - HWND hwndClist = GetFocus(); - GetClassName(hwndClist, cls, SIZEOF(cls)); - // worst case scenario, the rename is sent to the main contact list - hwndClist = (!mir_tstrcmp( _T(CLISTCONTROL_CLASS), cls)) ? hwndClist : cli.hwndContactList; - HANDLE hItem = (HANDLE)SendMessage(hwndClist, CLM_GETSELECTION, 0, 0); - if (hItem) { - SetFocus(hwndClist); - SendMessage(hwndClist, CLM_EDITLABEL, (WPARAM) hItem, 0); - } - return 0; -} - -static INT_PTR CALLBACK AskForConfirmationDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hWnd); - { - LOGFONT lf; - HFONT hFont = (HFONT)SendDlgItemMessage(hWnd, IDYES, WM_GETFONT, 0, 0); - GetObject(hFont, sizeof(lf), &lf); - lf.lfWeight = FW_BOLD; - SendDlgItemMessage(hWnd, IDC_TOPLINE, WM_SETFONT, (WPARAM) CreateFontIndirect(&lf), 0); - - TCHAR szFormat[256], szFinal[256]; - GetDlgItemText(hWnd, IDC_TOPLINE, szFormat, SIZEOF(szFormat)); - mir_sntprintf(szFinal, SIZEOF(szFinal), szFormat, cli.pfnGetContactDisplayName(lParam, 0)); - SetDlgItemText(hWnd, IDC_TOPLINE, szFinal); - } - SetFocus( GetDlgItem(hWnd, IDNO)); - SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDYES: - if (IsDlgButtonChecked(hWnd, IDC_HIDE)) { - EndDialog(hWnd, IDC_HIDE); - break; - } - //fall through - case IDCANCEL: - case IDNO: - EndDialog(hWnd, LOWORD(wParam)); - break; - } - break; - - case WM_CLOSE: - SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(IDNO, BN_CLICKED), 0); - break; - - case WM_DESTROY: - DeleteObject((HFONT) SendDlgItemMessage(hWnd, IDC_TOPLINE, WM_GETFONT, 0, 0)); - break; - } - - return FALSE; -} - -static INT_PTR MenuItem_DeleteContact(WPARAM wParam, LPARAM lParam) -{ - //see notes about deleting contacts on PF1_SERVERCLIST servers in m_protosvc.h - UINT_PTR action; - - if (db_get_b(NULL, "CList", "ConfirmDelete", SETTING_CONFIRMDELETE_DEFAULT) && !(GetKeyState(VK_SHIFT) & 0x8000)) - // Ask user for confirmation, and if the contact should be archived (hidden, not deleted) - action = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_DELETECONTACT), (HWND) lParam, AskForConfirmationDlgProc, wParam); - else - action = IDYES; - - switch (action) { - case IDC_HIDE: // Archive contact - db_set_b(wParam, "CList", "Hidden", 1); - break; - - case IDYES: // Delete contact - char *szProto = GetContactProto(wParam); - if (szProto != NULL) { - // Check if protocol uses server side lists - DWORD caps = CallProtoServiceInt(NULL, szProto, PS_GETCAPS, PFLAGNUM_1, 0); - if (caps & PF1_SERVERCLIST) { - int status = CallProtoServiceInt(NULL, szProto, PS_GETSTATUS, 0, 0); - if (status == ID_STATUS_OFFLINE || IsStatusConnecting(status)) { - // Set a flag so we remember to delete the contact when the protocol goes online the next time - db_set_b(wParam, "CList", "Delete", 1); - MessageBox(NULL, - TranslateT("This contact is on an instant messaging system which stores its contact list on a central server. The contact will be removed from the server and from your contact list when you next connect to that network."), - TranslateT("Delete contact"), MB_ICONINFORMATION | MB_OK); - return 0; - } - } - } - - CallService(MS_DB_CONTACT_DELETE, wParam, 0); - break; - } - - return 0; -} - -static INT_PTR MenuItem_AddContactToList(WPARAM hContact, LPARAM) -{ - ADDCONTACTSTRUCT acs = { 0 }; - acs.hContact = hContact; - acs.handleType = HANDLE_CONTACT; - acs.szProto = ""; - CallService(MS_ADDCONTACT_SHOW, NULL, (LPARAM)&acs); - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// this is the smallest available window procedure - -#ifndef CS_DROPSHADOW -#define CS_DROPSHADOW 0x00020000 -#endif - -LRESULT CALLBACK ContactListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - LRESULT result; - MSG m; - m.hwnd = hwnd; - m.message = msg; - m.wParam = wParam; - m.lParam = lParam; - if (cli.pfnDocking_ProcessWindowMessage((WPARAM)&m, (LPARAM)&result)) - return result; - if (cli.pfnTrayIconProcessMessage((WPARAM)&m, (LPARAM)&result)) - return result; - if (cli.pfnHotkeysProcessMessage((WPARAM)&m, (LPARAM)&result)) - return result; - - return cli.pfnContactListWndProc(hwnd, msg, wParam, lParam); -} - -int LoadCLUIModule(void) -{ - DBVARIANT dbv; - TCHAR titleText[256]; - - uMsgProcessProfile = RegisterWindowMessage(_T("Miranda::ProcessProfile")); - cli.pfnLoadCluiGlobalOpts(); - - HookEvent(ME_SYSTEM_MODULESLOADED, CluiModulesLoaded); - HookEvent(ME_SKIN_ICONSCHANGED, CluiIconsChanged); - - hContactDraggingEvent = CreateHookableEvent(ME_CLUI_CONTACTDRAGGING); - hContactDroppedEvent = CreateHookableEvent(ME_CLUI_CONTACTDROPPED); - hContactDragStopEvent = CreateHookableEvent(ME_CLUI_CONTACTDRAGSTOP); - - WNDCLASSEX wndclass; - wndclass.cbSize = sizeof(wndclass); - wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS; - wndclass.lpfnWndProc = cli.pfnContactListControlWndProc; - wndclass.cbClsExtra = 0; - wndclass.cbWndExtra = sizeof(void *); - wndclass.hInstance = cli.hInst; - wndclass.hIcon = NULL; - wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); - wndclass.hbrBackground = NULL; - wndclass.lpszMenuName = NULL; - wndclass.lpszClassName = _T(CLISTCONTROL_CLASS); - wndclass.hIconSm = NULL; - RegisterClassEx(&wndclass); - - wndclass.style = CS_HREDRAW | CS_VREDRAW | ((db_get_b(NULL, "CList", "WindowShadow", 0) == 1) ? CS_DROPSHADOW : 0); - wndclass.lpfnWndProc = ContactListWndProc; - wndclass.cbClsExtra = 0; - wndclass.cbWndExtra = 0; - wndclass.hInstance = cli.hInst; - wndclass.hIcon = LoadSkinIcon(SKINICON_OTHER_MIRANDA, true); - wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); - wndclass.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1); - wndclass.lpszMenuName = MAKEINTRESOURCE(IDR_CLISTMENU); - wndclass.lpszClassName = _T(MIRANDACLASS); - wndclass.hIconSm = LoadSkinIcon(SKINICON_OTHER_MIRANDA); - RegisterClassEx(&wndclass); - - if (db_get_ts(NULL, "CList", "TitleText", &dbv)) - mir_tstrncpy(titleText, _T(MIRANDANAME), SIZEOF(titleText)); - else { - mir_tstrncpy(titleText, dbv.ptszVal, SIZEOF(titleText)); - db_free(&dbv); - } - - RECT pos; - pos.left = (int)db_get_dw(NULL, "CList", "x", 700); - pos.top = (int)db_get_dw(NULL, "CList", "y", 221); - pos.right = pos.left + (int)db_get_dw(NULL, "CList", "Width", 108); - pos.bottom = pos.top + (int)db_get_dw(NULL, "CList", "Height", 310); - - AssertInsideScreen(pos); - - cli.hwndContactList = CreateWindowEx( - (db_get_b(NULL, "CList", "ToolWindow", SETTING_TOOLWINDOW_DEFAULT) ? WS_EX_TOOLWINDOW : WS_EX_APPWINDOW), - _T(MIRANDACLASS), - titleText, - WS_POPUPWINDOW | WS_THICKFRAME | WS_CLIPCHILDREN | - (db_get_b(NULL, "CLUI", "ShowCaption", SETTING_SHOWCAPTION_DEFAULT) ? WS_CAPTION | WS_SYSMENU | - (db_get_b(NULL, "CList", "Min2Tray", SETTING_MIN2TRAY_DEFAULT) ? 0 : WS_MINIMIZEBOX) : 0), - pos.left, pos.top, pos.right - pos.left, pos.bottom - pos.top, - NULL, NULL, cli.hInst, NULL); - - if (db_get_b(NULL, "CList", "OnDesktop", 0)) { - HWND hProgMan = FindWindow(_T("Progman"), NULL); - if (IsWindow(hProgMan)) - SetParent(cli.hwndContactList, hProgMan); - } - - cli.pfnOnCreateClc(); - - PostMessage(cli.hwndContactList, M_RESTORESTATUS, 0, 0); - - int state = db_get_b(NULL, "CList", "State", SETTING_STATE_NORMAL); - cli.hMenuMain = GetMenu(cli.hwndContactList); - if (!db_get_b(NULL, "CLUI", "ShowMainMenu", SETTING_SHOWMAINMENU_DEFAULT)) - SetMenu(cli.hwndContactList, NULL); - if (state == SETTING_STATE_NORMAL) - ShowWindow(cli.hwndContactList, SW_SHOW); - else if (state == SETTING_STATE_MINIMIZED) - ShowWindow(cli.hwndContactList, SW_SHOWMINIMIZED); - SetWindowPos(cli.hwndContactList, - db_get_b(NULL, "CList", "OnTop", SETTING_ONTOP_DEFAULT) ? HWND_TOPMOST : HWND_NOTOPMOST, - 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); - - CLISTMENUITEM mi = { sizeof(mi) }; - - CreateServiceFunction("CList/DeleteContactCommand", MenuItem_DeleteContact); - mi.position = 2000070000; - mi.icolibItem = GetSkinIconHandle(SKINICON_OTHER_DELETE); - mi.pszName = LPGEN("De&lete"); - mi.pszService = "CList/DeleteContactCommand"; - Menu_AddContactMenuItem(&mi); - - CreateServiceFunction("CList/RenameContactCommand", MenuItem_RenameContact); - mi.position = 2000050000; - mi.icolibItem = GetSkinIconHandle(SKINICON_OTHER_RENAME); - mi.pszName = LPGEN("&Rename"); - mi.pszService = "CList/RenameContactCommand"; - hRenameMenuItem = Menu_AddContactMenuItem(&mi); - - CreateServiceFunction("CList/AddToListContactCommand", MenuItem_AddContactToList); - mi.position = -2050000000; - mi.flags |= CMIF_NOTONLIST; - mi.icolibItem = GetSkinIconHandle(SKINICON_OTHER_ADDCONTACT); - mi.pszName = LPGEN("&Add permanently to list"); - mi.pszService = "CList/AddToListContactCommand"; - Menu_AddContactMenuItem(&mi); - - HookEvent(ME_CLIST_PREBUILDCONTACTMENU, MenuItem_PreBuild); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// default contact list window procedure - -void fnDrawMenuItem(DRAWITEMSTRUCT *dis, HICON hIcon, HICON eventIcon) -{ - HBRUSH hBr; - BOOL bfm = FALSE; - SystemParametersInfo(SPI_GETFLATMENU, 0, &bfm, 0); - if (bfm) { - /* flat menus: fill with COLOR_MENUHILIGHT and outline with COLOR_HIGHLIGHT, otherwise use COLOR_MENUBAR */ - if (dis->itemState & ODS_SELECTED || dis->itemState & ODS_HOTLIGHT) { - /* selected or hot lighted, no difference */ - hBr = GetSysColorBrush(COLOR_MENUHILIGHT); - FillRect(dis->hDC, &dis->rcItem, hBr); - DeleteObject(hBr); - /* draw the frame */ - hBr = GetSysColorBrush(COLOR_HIGHLIGHT); - FrameRect(dis->hDC, &dis->rcItem, hBr); - DeleteObject(hBr); - } else { - /* flush the DC with the menu bar colour (only supported on XP) and then draw the icon */ - hBr = GetSysColorBrush(COLOR_MENUBAR); - FillRect(dis->hDC, &dis->rcItem, hBr); - DeleteObject(hBr); - } //if - /* draw the icon */ - if (eventIcon != 0) { - DrawState(dis->hDC, NULL, NULL, (LPARAM) eventIcon, 0, 2, (dis->rcItem.bottom + dis->rcItem.top - g_IconHeight) / 2 + (dis->itemState & ODS_SELECTED ? 1 : 0), 0, 0, DST_ICON | (dis->itemState & ODS_INACTIVE ? DSS_DISABLED : DSS_NORMAL)); - DrawState(dis->hDC, NULL, NULL, (LPARAM) hIcon, 0, 4 + g_IconWidth, (dis->rcItem.bottom + dis->rcItem.top - g_IconHeight) / 2 + (dis->itemState & ODS_SELECTED ? 1 : 0), 0, 0, DST_ICON | (dis->itemState & ODS_INACTIVE ? DSS_DISABLED : DSS_NORMAL)); - } - else DrawState(dis->hDC, NULL, NULL, (LPARAM) hIcon, 0, (dis->rcItem.right + dis->rcItem.left - g_IconWidth) / 2 + (dis->itemState & ODS_SELECTED ? 1 : 0), (dis->rcItem.bottom + dis->rcItem.top - g_IconHeight) / 2 + (dis->itemState & ODS_SELECTED ? 1 : 0), 0, 0, DST_ICON | (dis->itemState & ODS_INACTIVE ? DSS_DISABLED : DSS_NORMAL)); - } - else { - /* non-flat menus, flush the DC with a normal menu colour */ - FillRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_MENU)); - if (dis->itemState & ODS_HOTLIGHT) - DrawEdge(dis->hDC, &dis->rcItem, BDR_RAISEDINNER, BF_RECT); - else if (dis->itemState & ODS_SELECTED) - DrawEdge(dis->hDC, &dis->rcItem, BDR_SUNKENOUTER, BF_RECT); - - if (eventIcon != 0) { - DrawState(dis->hDC, NULL, NULL, (LPARAM) eventIcon, 0, 2, (dis->rcItem.bottom + dis->rcItem.top - g_IconHeight) / 2 + (dis->itemState & ODS_SELECTED ? 1 : 0), 0, 0, DST_ICON | (dis->itemState & ODS_INACTIVE ? DSS_DISABLED : DSS_NORMAL)); - DrawState(dis->hDC, NULL, NULL, (LPARAM) hIcon, 0, 4 + g_IconWidth, (dis->rcItem.bottom + dis->rcItem.top - g_IconHeight) / 2 + (dis->itemState & ODS_SELECTED ? 1 : 0), 0, 0, DST_ICON | (dis->itemState & ODS_INACTIVE ? DSS_DISABLED : DSS_NORMAL)); - } - else DrawState(dis->hDC, NULL, NULL, (LPARAM) hIcon, 0, (dis->rcItem.right + dis->rcItem.left - g_IconWidth) / 2 + (dis->itemState & ODS_SELECTED ? 1 : 0), (dis->rcItem.bottom + dis->rcItem.top - g_IconHeight) / 2 + (dis->itemState & ODS_SELECTED ? 1 : 0), 0, 0, DST_ICON | (dis->itemState & ODS_INACTIVE ? DSS_DISABLED : DSS_NORMAL)); - } - - DestroyIcon(hIcon); - return; -} - -LRESULT CALLBACK fnContactListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static int noRecurse = 0; - - if (msg == uMsgProcessProfile) { - TCHAR profile[MAX_PATH]; - int rc; - // wParam = (ATOM)hProfileAtom, lParam = 0 - if (GlobalGetAtomName((ATOM) wParam, profile, SIZEOF(profile))) { - rc = mir_tstrcmpi(profile, VARST(_T("%miranda_userdata%\\%miranda_profilename%.dat"))) == 0; - ReplyMessage(rc); - if (rc) { - ShowWindow(hwnd, SW_RESTORE); - ShowWindow(hwnd, SW_SHOW); - SetForegroundWindow(hwnd); - SetFocus(hwnd); - } - } - return 0; - } - - switch (msg) { - case WM_NCCREATE: - { - MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_TYPE | MIIM_DATA; - mii.dwItemData = MENU_MIRANDAMENU; - mii.fType = MFT_OWNERDRAW; - SetMenuItemInfo(GetMenu(hwnd), 0, TRUE, &mii); - } - return DefWindowProc(hwnd, msg, wParam, lParam); - - case WM_CREATE: - TranslateMenu(GetMenu(hwnd)); - DrawMenuBar(hwnd); - - //create the status wnd - { - int flags = WS_CHILD | CCS_BOTTOM; - flags |= cluiopt.showsbar ? WS_VISIBLE : 0; - flags |= cluiopt.showgrip ? SBARS_SIZEGRIP : 0; - cli.hwndStatus = CreateWindow(STATUSCLASSNAME, NULL, flags, 0, 0, 0, 0, hwnd, NULL, cli.hInst, NULL); - } - cli.pfnCluiProtocolStatusChanged(0, 0); - - //delay creation of CLC so that it can get the status icons right the first time (needs protocol modules loaded) - PostMessage(hwnd, M_CREATECLC, 0, 0); - - if (cluiopt.transparent) { - SetWindowLongPtr(hwnd, GWL_EXSTYLE, GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); - SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), (BYTE) cluiopt.alpha, LWA_ALPHA); - } - transparentFocus = 1; - return FALSE; - - case M_CREATECLC: - cli.hwndContactTree = CreateWindow( _T(CLISTCONTROL_CLASS), _T(""), - WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN - | CLS_CONTACTLIST - | (db_get_b(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT) ? CLS_USEGROUPS : 0) - | (db_get_b(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT) ? CLS_HIDEOFFLINE : 0) - | (db_get_b(NULL, "CList", "HideEmptyGroups", SETTING_HIDEEMPTYGROUPS_DEFAULT) ? - CLS_HIDEEMPTYGROUPS : 0), 0, 0, 0, 0, hwnd, NULL, cli.hInst, NULL); - SendMessage(hwnd, WM_SIZE, 0, 0); - break; - - case M_RESTORESTATUS: - #ifndef _DEBUG - { - int nStatus = db_get_w(NULL, "CList", "Status", ID_STATUS_OFFLINE); - if (nStatus != ID_STATUS_OFFLINE) CallService(MS_CLIST_SETSTATUSMODE, nStatus, 0); - } - #endif - break; - - // Power management - case WM_POWERBROADCAST: - switch ((DWORD) wParam) { - case PBT_APMSUSPEND: - // Computer is suspending, disconnect all protocols - DisconnectAll(); - break; - - case PBT_APMRESUMEAUTOMATIC: - case PBT_APMRESUMESUSPEND: - // Computer is resuming, restore all protocols - PostMessage(hwnd, M_RESTORESTATUS, 0, 0); - break; - } - break; - - case WM_SYSCOLORCHANGE: - SendMessage(cli.hwndContactTree, msg, wParam, lParam); - SendMessage(cli.hwndStatus, msg, wParam, lParam); - // XXX: only works with 4.71 with 95, IE4. - SendMessage(cli.hwndStatus, SB_SETBKCOLOR, 0, GetSysColor(COLOR_3DFACE)); - break; - - case WM_SIZE: - if (IsZoomed(hwnd)) - ShowWindow(hwnd, SW_SHOWNORMAL); - { - RECT rect, rcStatus; - GetClientRect(hwnd, &rect); - if (cluiopt.showsbar) { - SetWindowPos(cli.hwndStatus, NULL, 0, rect.bottom - 20, rect.right - rect.left, 20, SWP_NOZORDER); - GetWindowRect(cli.hwndStatus, &rcStatus); - cli.pfnCluiProtocolStatusChanged(0, 0); - } - else - rcStatus.top = rcStatus.bottom = 0; - SetWindowPos(cli.hwndContactTree, NULL, 0, 0, rect.right, rect.bottom - (rcStatus.bottom - rcStatus.top), SWP_NOZORDER); - } - if (wParam == SIZE_MINIMIZED) { - if ((GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) || db_get_b(NULL, "CList", "Min2Tray", SETTING_MIN2TRAY_DEFAULT)) { - ShowWindow(hwnd, SW_HIDE); - db_set_b(NULL, "CList", "State", SETTING_STATE_HIDDEN); - } - else db_set_b(NULL, "CList", "State", SETTING_STATE_MINIMIZED); - - if (db_get_b(NULL, "CList", "DisableWorkingSet", 1)) - SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1); - } - // drop thru - case WM_MOVE: - if (!IsIconic(hwnd)) { - RECT rc; - GetWindowRect(hwnd, &rc); - - //if docked, dont remember pos (except for width) - if (!CallService(MS_CLIST_DOCKINGISDOCKED, 0, 0)) { - db_set_dw(NULL, "CList", "Height", (DWORD) (rc.bottom - rc.top)); - db_set_dw(NULL, "CList", "x", (DWORD) rc.left); - db_set_dw(NULL, "CList", "y", (DWORD) rc.top); - } - db_set_dw(NULL, "CList", "Width", (DWORD) (rc.right - rc.left)); - } - return FALSE; - - case WM_SETFOCUS: - SetFocus(cli.hwndContactTree); - return 0; - - case WM_ACTIVATE: - if (wParam == WA_INACTIVE) { - if ((HWND) wParam != hwnd) - if (cluiopt.transparent) - if (transparentFocus) - SetTimer(hwnd, TM_AUTOALPHA, 250, NULL); - } - else { - if (cluiopt.transparent) { - KillTimer(hwnd, TM_AUTOALPHA); - SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), (BYTE) cluiopt.alpha, LWA_ALPHA); - transparentFocus = 1; - } - } - return DefWindowProc(hwnd, msg, wParam, lParam); - - case WM_SETCURSOR: - if (cluiopt.transparent) { - if (!transparentFocus && GetForegroundWindow() != hwnd) { - SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), (BYTE)cluiopt.alpha, LWA_ALPHA); - transparentFocus = 1; - SetTimer(hwnd, TM_AUTOALPHA, 250, NULL); - } - } - return DefWindowProc(hwnd, msg, wParam, lParam); - - case WM_NCHITTEST: - { - LRESULT result; - result = DefWindowProc(hwnd, WM_NCHITTEST, wParam, lParam); - if (result == HTSIZE || result == HTTOP || result == HTTOPLEFT || result == HTTOPRIGHT || - result == HTBOTTOM || result == HTBOTTOMRIGHT || result == HTBOTTOMLEFT) - if (db_get_b(NULL, "CLUI", "AutoSize", 0)) - return HTCLIENT; - return result; - } - - case WM_TIMER: - if (wParam == TM_AUTOALPHA) { - int inwnd; - - if (GetForegroundWindow() == hwnd) { - KillTimer(hwnd, TM_AUTOALPHA); - inwnd = 1; - } - else { - POINT pt; - HWND hwndPt; - pt.x = (short) LOWORD(GetMessagePos()); - pt.y = (short) HIWORD(GetMessagePos()); - hwndPt = WindowFromPoint(pt); - inwnd = (hwndPt == hwnd || GetParent(hwndPt) == hwnd); - } - if (inwnd != transparentFocus) { //change - transparentFocus = inwnd; - if (transparentFocus) - SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), (BYTE) cluiopt.alpha, LWA_ALPHA); - else - SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), (BYTE) db_get_b(NULL, "CList", "AutoAlpha", SETTING_AUTOALPHA_DEFAULT), LWA_ALPHA); - } - if (!transparentFocus) - KillTimer(hwnd, TM_AUTOALPHA); - } - return TRUE; - - case WM_SHOWWINDOW: - if (lParam) - break; - if (noRecurse) - break; - if (!db_get_b(NULL, "CLUI", "FadeInOut", 0)) - break; - if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) { - DWORD thisTick, startTick; - int sourceAlpha, destAlpha; - if (wParam) { - sourceAlpha = 0; - destAlpha = (BYTE) cluiopt.alpha; - SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 0, LWA_ALPHA); - noRecurse = 1; - ShowWindow(hwnd, SW_SHOW); - noRecurse = 0; - } - else { - sourceAlpha = (BYTE) cluiopt.alpha; - destAlpha = 0; - } - for (startTick = GetTickCount();;) { - thisTick = GetTickCount(); - if (thisTick >= startTick + 200) - break; - SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), - (BYTE) (sourceAlpha + (destAlpha - sourceAlpha) * (int)(thisTick - startTick) / 200), LWA_ALPHA); - } - SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), (BYTE) destAlpha, LWA_ALPHA); - } - else { - if (wParam) - SetForegroundWindow(hwnd); - AnimateWindow(hwnd, 200, AW_BLEND | (wParam ? 0 : AW_HIDE)); - SetWindowPos(cli.hwndContactTree, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); - } - break; - - case WM_MENURBUTTONUP: /* this API is so badly documented at MSDN!! */ - { - UINT id = 0; - - id = GetMenuItemID((HMENU) lParam, LOWORD(wParam)); /* LOWORD(wParam) contains the menu pos in its parent menu */ - if (id != (-1)) - SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(id, 0), 0); - } - return DefWindowProc(hwnd, msg, wParam, lParam); - - case WM_SYSCOMMAND: - switch (wParam) { - case SC_MAXIMIZE: - return 0; - - case SC_MINIMIZE: - case SC_CLOSE: - if ((GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) || - db_get_b(NULL, "CList", "Min2Tray", SETTING_MIN2TRAY_DEFAULT)) - { - ShowWindow(hwnd, SW_HIDE); - db_set_b(NULL, "CList", "State", SETTING_STATE_HIDDEN); - - if (db_get_b(NULL, "CList", "DisableWorkingSet", 1)) - SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1); - - return 0; - } - else if (wParam == SC_CLOSE) - wParam = SC_MINIMIZE; - } - return DefWindowProc(hwnd, msg, wParam, lParam); - - case WM_COMMAND: - if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_MAINMENU), (LPARAM) (HANDLE) NULL)) - break; - - switch (LOWORD(wParam)) { - case ID_TRAY_EXIT: - case ID_ICQ_EXIT: - if (CallService(MS_SYSTEM_OKTOEXIT, 0, 0)) - DestroyWindow(hwnd); - break; - - case ID_TRAY_HIDE: - CallService(MS_CLIST_SHOWHIDE, 0, 0); - break; - - case POPUP_NEWGROUP: - SendMessage(cli.hwndContactTree, CLM_SETHIDEEMPTYGROUPS, 0, 0); - CallService(MS_CLIST_GROUPCREATE, 0, 0); - break; - - case POPUP_HIDEOFFLINE: - CallService(MS_CLIST_SETHIDEOFFLINE, (WPARAM) (-1), 0); - break; - - case POPUP_HIDEOFFLINEROOT: - SendMessage(cli.hwndContactTree, CLM_SETHIDEOFFLINEROOT, !SendMessage(cli.hwndContactTree, CLM_GETHIDEOFFLINEROOT, 0, 0), 0); - break; - - case POPUP_HIDEEMPTYGROUPS: - { - int newVal = !(GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & CLS_HIDEEMPTYGROUPS); - db_set_b(NULL, "CList", "HideEmptyGroups", (BYTE) newVal); - SendMessage(cli.hwndContactTree, CLM_SETHIDEEMPTYGROUPS, newVal, 0); - } - break; - - case POPUP_DISABLEGROUPS: - { - int newVal = !(GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & CLS_USEGROUPS); - db_set_b(NULL, "CList", "UseGroups", (BYTE) newVal); - SendMessage(cli.hwndContactTree, CLM_SETUSEGROUPS, newVal, 0); - } - break; - - case POPUP_HIDEMIRANDA: - CallService(MS_CLIST_SHOWHIDE, 0, 0); - break; - } - return FALSE; - - case WM_KEYDOWN: - CallService(MS_CLIST_MENUPROCESSHOTKEY, wParam, MPCF_MAINMENU | MPCF_CONTACTMENU); - break; - - case WM_GETMINMAXINFO: - DefWindowProc(hwnd, msg, wParam, lParam); - ((LPMINMAXINFO) lParam)->ptMinTrackSize.x = 16 + GetSystemMetrics(SM_CXHTHUMB); - ((LPMINMAXINFO) lParam)->ptMinTrackSize.y = 16; - return 0; - - case WM_SETTINGCHANGE: - if (wParam == SPI_SETWORKAREA && (GetWindowLongPtr(hwnd, GWL_STYLE) & (WS_VISIBLE | WS_MINIMIZE)) == WS_VISIBLE && - !CallService(MS_CLIST_DOCKINGISDOCKED, 0, 0)) - { - RECT rc; - GetWindowRect(hwnd, &rc); - if (AssertInsideScreen(rc) == 1) - MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); - } - return DefWindowProc(hwnd, msg, wParam, lParam); - - case WM_DISPLAYCHANGE: - DefWindowProc(hwnd, msg, wParam, lParam); - SendMessage(cli.hwndContactTree, WM_SIZE, 0, 0); //forces it to send a cln_listsizechanged - break; - - //MSG FROM CHILD CONTROL - case WM_NOTIFY: - if (((LPNMHDR) lParam)->hwndFrom == cli.hwndContactTree) { - NMCLISTCONTROL *nmc = (NMCLISTCONTROL*)lParam; - switch (((LPNMHDR) lParam)->code) { - case CLN_EXPANDED: - CallService(MS_CLIST_GROUPSETEXPANDED, (WPARAM) nmc->hItem, nmc->action); - return FALSE; - - case CLN_DRAGGING: - ClientToScreen(hwnd, &nmc->pt); - if (!(nmc->flags & CLNF_ISGROUP)) - if (NotifyEventHooks(hContactDraggingEvent, (WPARAM) nmc->hItem, MAKELPARAM(nmc->pt.x, nmc->pt.y))) { - SetCursor(LoadCursor(cli.hInst, MAKEINTRESOURCE(IDC_DROPUSER))); - return TRUE; - } - break; - - case CLN_DRAGSTOP: - if (!(nmc->flags & CLNF_ISGROUP)) - NotifyEventHooks(hContactDragStopEvent, (WPARAM) nmc->hItem, 0); - break; - - case CLN_DROPPED: - ClientToScreen(hwnd, &nmc->pt); - if (!(nmc->flags & CLNF_ISGROUP)) - if (NotifyEventHooks(hContactDroppedEvent, (WPARAM) nmc->hItem, MAKELPARAM(nmc->pt.x, nmc->pt.y))) { - SetCursor(LoadCursor(cli.hInst, MAKEINTRESOURCE(IDC_DROPUSER))); - return TRUE; - } - break; - - case CLN_NEWCONTACT: - if (nmc != NULL) - cli.pfnSetAllExtraIcons((MCONTACT)nmc->hItem); - return TRUE; - - case CLN_LISTREBUILT: - cli.pfnSetAllExtraIcons(NULL); - return(FALSE); - - case NM_KEYDOWN: - return CallService(MS_CLIST_MENUPROCESSHOTKEY, ((NMKEY*)lParam)->nVKey, MPCF_MAINMENU | MPCF_CONTACTMENU); - - case CLN_LISTSIZECHANGE: - { - RECT rcWindow, rcTree, rcWorkArea; - int maxHeight, newHeight; - - if (!db_get_b(NULL, "CLUI", "AutoSize", 0)) - break; - if (CallService(MS_CLIST_DOCKINGISDOCKED, 0, 0)) - break; - maxHeight = db_get_b(NULL, "CLUI", "MaxSizeHeight", 75); - GetWindowRect(hwnd, &rcWindow); - GetWindowRect(cli.hwndContactTree, &rcTree); - - SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE); - HMONITOR hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); - MONITORINFO mi; - mi.cbSize = sizeof(mi); - if (GetMonitorInfo(hMon, &mi)) - rcWorkArea = mi.rcWork; - - newHeight = max(nmc->pt.y, 9) + 1 + (rcWindow.bottom - rcWindow.top) - (rcTree.bottom - rcTree.top); - if (newHeight > (rcWorkArea.bottom - rcWorkArea.top) * maxHeight / 100) - newHeight = (rcWorkArea.bottom - rcWorkArea.top) * maxHeight / 100; - if (db_get_b(NULL, "CLUI", "AutoSizeUpward", 0)) { - rcWindow.top = rcWindow.bottom - newHeight; - if (rcWindow.top < rcWorkArea.top) - rcWindow.top = rcWorkArea.top; - } - else { - rcWindow.bottom = rcWindow.top + newHeight; - if (rcWindow.bottom > rcWorkArea.bottom) - rcWindow.bottom = rcWorkArea.bottom; - } - SetWindowPos(hwnd, 0, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, - SWP_NOZORDER | SWP_NOACTIVATE); - break; - } - case NM_CLICK: - { - DWORD hitFlags; - HANDLE hItem = (HANDLE)SendMessage(cli.hwndContactTree, CLM_HITTEST, (WPARAM)&hitFlags, MAKELPARAM(nmc->pt.x, nmc->pt.y)); - if (hItem) { - if (hitFlags & CLCHT_ONITEMEXTRA) { - if (!IsHContactGroup(hItem) && !IsHContactInfo(hItem)) - if (cli.pfnGetCacheEntry((MCONTACT)nmc->hItem)) - NotifyEventHooks(hEventExtraClick, (WPARAM)nmc->hItem, nmc->iColumn+1); - } - break; - } - - if ((hitFlags & (CLCHT_NOWHERE | CLCHT_INLEFTMARGIN | CLCHT_BELOWITEMS)) == 0) - break; - - if (db_get_b(NULL, "CLUI", "ClientAreaDrag", SETTING_CLIENTDRAG_DEFAULT)) { - POINT pt = nmc->pt; - ClientToScreen(cli.hwndContactTree, &pt); - return SendMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y)); - } - } - break; - } - } - else if (((LPNMHDR) lParam)->hwndFrom == cli.hwndStatus) { - if (((LPNMHDR) lParam)->code == NM_CLICK) { - unsigned int nParts, nPanel; - NMMOUSE *nm = (NMMOUSE *) lParam; - HMENU hMenu; - RECT rc; - POINT pt; - - hMenu = (HMENU) CallService(MS_CLIST_MENUGETSTATUS, 0, 0); - nParts = SendMessage(cli.hwndStatus, SB_GETPARTS, 0, 0); - if (nm->dwItemSpec == 0xFFFFFFFE) { - nPanel = nParts - 1; - SendMessage(cli.hwndStatus, SB_GETRECT, nPanel, (LPARAM) & rc); - if (nm->pt.x < rc.left) - return FALSE; - } - else nPanel = nm->dwItemSpec; - - if (nParts > 0) { - unsigned int cpnl = 0; - int mcnt = GetMenuItemCount(hMenu); - for (int i=0; iitemData == MENU_MIRANDAMENU) { - ((LPMEASUREITEMSTRUCT) lParam)->itemWidth = g_IconWidth * 4 / 3; - ((LPMEASUREITEMSTRUCT) lParam)->itemHeight = 0; - return TRUE; - } - return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); - - case WM_DRAWITEM: - { - LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam; - if (dis->hwndItem == cli.hwndStatus) { - char *szProto = (char *) dis->itemData; - if (szProto == NULL) return 0; - int status, x; - SIZE textSize; - BYTE showOpts = db_get_b(NULL, "CLUI", "SBarShow", 1); - status = CallProtoServiceInt(NULL,szProto, PS_GETSTATUS, 0, 0); - SetBkMode(dis->hDC, TRANSPARENT); - x = dis->rcItem.left; - if (showOpts & 1) { - HICON hIcon = LoadSkinProtoIcon(szProto, status); - DrawIconEx(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - g_IconHeight) >> 1, hIcon, - g_IconWidth, g_IconHeight, 0, NULL, DI_NORMAL); - IcoLib_ReleaseIcon(hIcon, 0); - if (Proto_IsAccountLocked(Proto_GetAccount(szProto))) { - hIcon = LoadSkinnedIcon(SKINICON_OTHER_STATUS_LOCKED); - if (hIcon != NULL) { - DrawIconEx(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - g_IconHeight) >> 1, hIcon, - g_IconWidth, g_IconHeight, 0, NULL, DI_NORMAL); - IcoLib_ReleaseIcon(hIcon, 0); - } - - } - x += g_IconWidth + 2; - } - else - x += 2; - if (showOpts & 2) { - PROTOACCOUNT *pa; - TCHAR tszName[64]; - if ((pa = Proto_GetAccount(szProto)) != NULL) - mir_sntprintf(tszName, SIZEOF(tszName), _T("%s "), pa->tszAccountName); - else - tszName[0] = 0; - - GetTextExtentPoint32(dis->hDC, tszName, (int)mir_tstrlen(tszName), &textSize); - TextOut(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - textSize.cy) >> 1, tszName, (int)mir_tstrlen(tszName)); - x += textSize.cx; - } - if (showOpts & 4) { - TCHAR* szStatus = cli.pfnGetStatusModeDescription(status, 0); - if (!szStatus) - szStatus = _T(""); - GetTextExtentPoint32(dis->hDC, szStatus, (int)mir_tstrlen(szStatus), &textSize); - TextOut(dis->hDC, x, (dis->rcItem.top + dis->rcItem.bottom - textSize.cy) >> 1, szStatus, (int)mir_tstrlen(szStatus)); - } - } - else if (dis->CtlType == ODT_MENU) { - if (dis->itemData == MENU_MIRANDAMENU) { - HICON hIcon = LoadSkinnedIcon(SKINICON_OTHER_MAINMENU); - fnDrawMenuItem(dis, CopyIcon(hIcon), NULL); - IcoLib_ReleaseIcon(hIcon, NULL); - return TRUE; - } - return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); - } - } - return 0; - - case WM_CLOSE: - if (CallService(MS_SYSTEM_OKTOEXIT, 0, 0)) - DestroyWindow(hwnd); - return FALSE; - - case WM_DESTROY: - if (!IsIconic(hwnd)) { - RECT rc; - GetWindowRect(hwnd, &rc); - - //if docked, dont remember pos (except for width) - if (!CallService(MS_CLIST_DOCKINGISDOCKED, 0, 0)) { - db_set_dw(NULL, "CList", "Height", (DWORD) (rc.bottom - rc.top)); - db_set_dw(NULL, "CList", "x", (DWORD) rc.left); - db_set_dw(NULL, "CList", "y", (DWORD) rc.top); - } - db_set_dw(NULL, "CList", "Width", (DWORD) (rc.right - rc.left)); - } - - RemoveMenu(cli.hMenuMain, 0, MF_BYPOSITION); - RemoveMenu(cli.hMenuMain, 0, MF_BYPOSITION); - - if (cli.hwndStatus) { - DestroyWindow(cli.hwndStatus); - cli.hwndStatus = NULL; - } - - // Disconnect all protocols - DisconnectAll(); - - ShowWindow(hwnd, SW_HIDE); - DestroyWindow(cli.hwndContactTree); - FreeLibrary(hUserDll); - PostQuitMessage(0); - - default: - return DefWindowProc(hwnd, msg, wParam, lParam); - } - - return TRUE; -} diff --git a/src/modules/clist/cluiservices.cpp b/src/modules/clist/cluiservices.cpp deleted file mode 100644 index b9bf086843..0000000000 --- a/src/modules/clist/cluiservices.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -static INT_PTR GetHwnd(WPARAM, LPARAM) -{ - return (INT_PTR)cli.hwndContactList; -} - -static INT_PTR GetHwndTree(WPARAM, LPARAM) -{ - return (INT_PTR)cli.hwndContactTree; -} - -static INT_PTR GroupAdded(WPARAM wParam, LPARAM lParam) -{ - //CLC does this automatically unless it's a new group - if (lParam) { - HANDLE hItem; - TCHAR szFocusClass[64]; - HWND hwndFocus = GetFocus(); - - GetClassName(hwndFocus, szFocusClass, SIZEOF(szFocusClass)); - if (!mir_tstrcmp(szFocusClass, _T(CLISTCONTROL_CLASS))) { - hItem = (HANDLE) SendMessage(hwndFocus, CLM_FINDGROUP, wParam, 0); - if (hItem) - SendMessage(hwndFocus, CLM_EDITLABEL, (WPARAM) hItem, 0); - } - } - return 0; -} - -static INT_PTR ContactSetIcon(WPARAM, LPARAM) -{ - //unnecessary: CLC does this automatically - return 0; -} - -static INT_PTR ContactDeleted(WPARAM, LPARAM) -{ - //unnecessary: CLC does this automatically - return 0; -} - -static INT_PTR ContactAdded(WPARAM, LPARAM) -{ - //unnecessary: CLC does this automatically - return 0; -} - -static INT_PTR ListBeginRebuild(WPARAM, LPARAM) -{ - //unnecessary: CLC does this automatically - return 0; -} - -static INT_PTR ListEndRebuild(WPARAM, LPARAM) -{ - int rebuild = 0; - //CLC does this automatically, but we need to force it if hideoffline or hideempty has changed - if ((db_get_b(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT) == 0) != ((GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & CLS_HIDEOFFLINE) == 0)) { - if (db_get_b(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT)) - SetWindowLongPtr(cli.hwndContactTree, GWL_STYLE, GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) | CLS_HIDEOFFLINE); - else - SetWindowLongPtr(cli.hwndContactTree, GWL_STYLE, GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & ~CLS_HIDEOFFLINE); - rebuild = 1; - } - if ((db_get_b(NULL, "CList", "HideEmptyGroups", SETTING_HIDEEMPTYGROUPS_DEFAULT) == 0) != ((GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & CLS_HIDEEMPTYGROUPS) == 0)) { - if (db_get_b(NULL, "CList", "HideEmptyGroups", SETTING_HIDEEMPTYGROUPS_DEFAULT)) - SetWindowLongPtr(cli.hwndContactTree, GWL_STYLE, GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) | CLS_HIDEEMPTYGROUPS); - else - SetWindowLongPtr(cli.hwndContactTree, GWL_STYLE, GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & ~CLS_HIDEEMPTYGROUPS); - rebuild = 1; - } - if ((db_get_b(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT) == 0) != ((GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & CLS_USEGROUPS) == 0)) { - if (db_get_b(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT)) - SetWindowLongPtr(cli.hwndContactTree, GWL_STYLE, GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) | CLS_USEGROUPS); - else - SetWindowLongPtr(cli.hwndContactTree, GWL_STYLE, GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & ~CLS_USEGROUPS); - rebuild = 1; - } - if (rebuild) - cli.pfnInitAutoRebuild(cli.hwndContactTree); - return 0; -} - -static INT_PTR ContactRenamed(WPARAM, LPARAM) -{ - //unnecessary: CLC does this automatically - return 0; -} - -static INT_PTR GetCaps(WPARAM wParam, LPARAM) -{ - switch (wParam) { - case CLUICAPS_FLAGS1: - return CLUIF_HIDEEMPTYGROUPS | CLUIF_DISABLEGROUPS | CLUIF_HASONTOPOPTION | CLUIF_HASAUTOHIDEOPTION; - case CLUICAPS_FLAGS2: - return MAKELONG(EXTRA_ICON_COUNT,1); - } - return 0; -} - -void LoadCluiServices(void) -{ - CreateServiceFunction(MS_CLUI_GETHWND, GetHwnd); - CreateServiceFunction(MS_CLUI_GETHWNDTREE, GetHwndTree); - CreateServiceFunction(MS_CLUI_GROUPADDED, GroupAdded); - CreateServiceFunction(MS_CLUI_CONTACTSETICON, ContactSetIcon); - CreateServiceFunction(MS_CLUI_CONTACTADDED, ContactAdded); - CreateServiceFunction(MS_CLUI_CONTACTDELETED, ContactDeleted); - CreateServiceFunction(MS_CLUI_CONTACTRENAMED, ContactRenamed); - CreateServiceFunction(MS_CLUI_LISTBEGINREBUILD, ListBeginRebuild); - CreateServiceFunction(MS_CLUI_LISTENDREBUILD, ListEndRebuild); - CreateServiceFunction(MS_CLUI_GETCAPS, GetCaps); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// default protocol status notification handler - -void fnCluiProtocolStatusChanged(int, const char*) -{ - int i, *partWidths; - int borders[3]; - int flags = 0; - - if (cli.menuProtoCount == 0) { - SendMessage(cli.hwndStatus, SB_SETPARTS, 0, 0); - SendMessage(cli.hwndStatus, SB_SETTEXT, SBT_OWNERDRAW, 0); - return; - } - - SendMessage(cli.hwndStatus, SB_GETBORDERS, 0, (LPARAM)&borders); - - partWidths = (int*)alloca(cli.menuProtoCount * sizeof(int)); - if (db_get_b(NULL, "CLUI", "EqualSections", 0)) { - RECT rc; - GetClientRect(cli.hwndStatus, &rc); - rc.right -= borders[0] * 2 + (db_get_b(NULL, "CLUI", "ShowGrip", 1) ? GetSystemMetrics(SM_CXVSCROLL) : 0); - for (i=0; i < cli.menuProtoCount; i++) - partWidths[ i ] = (i+1) * rc.right / cli.menuProtoCount - (borders[2] >> 1); - } - else { - HDC hdc; - HFONT hFont; - SIZE textSize; - BYTE showOpts = db_get_b(NULL, "CLUI", "SBarShow", 1); - - hdc = GetDC(NULL); - hFont = (HFONT)SelectObject(hdc, (HFONT) SendMessage(cli.hwndStatus, WM_GETFONT, 0, 0)); - for (i=0; i < cli.menuProtoCount; i++) { //count down since built in ones tend to go at the end - int x = 2; - if (showOpts & 1) - x += g_IconWidth; - if (showOpts & 2) { - TCHAR tszName[64]; - PROTOACCOUNT *pa = Proto_GetAccount(cli.menuProtos[i].szProto); - if (pa) - mir_sntprintf(tszName, SIZEOF(tszName), _T("%s "), pa->tszAccountName); - else - tszName[0] = 0; - - if (showOpts & 4 && mir_tstrlen(tszName) < SIZEOF(tszName)-1) - mir_tstrcat(tszName, _T(" ")); - GetTextExtentPoint32(hdc, tszName, (int)mir_tstrlen(tszName), &textSize); - x += textSize.cx; - x += GetSystemMetrics(SM_CXBORDER) * 4; // The SB panel doesnt allocate enough room - } - if (showOpts & 4) { - TCHAR* modeDescr = cli.pfnGetStatusModeDescription(CallProtoServiceInt(NULL,cli.menuProtos[i].szProto, PS_GETSTATUS, 0, 0), 0); - GetTextExtentPoint32(hdc, modeDescr, (int)mir_tstrlen(modeDescr), &textSize); - x += textSize.cx; - x += GetSystemMetrics(SM_CXBORDER) * 4; // The SB panel doesnt allocate enough room - } - partWidths[ i ] = (i ? partWidths[ i-1] : 0) + x + 2; - } - SelectObject(hdc, hFont); - ReleaseDC(NULL, hdc); - } - - partWidths[ cli.menuProtoCount-1 ] = -1; - SendMessage(cli.hwndStatus, SB_SETMINHEIGHT, g_IconHeight, 0); - SendMessage(cli.hwndStatus, SB_SETPARTS, cli.menuProtoCount, (LPARAM)partWidths); - flags = SBT_OWNERDRAW; - if (db_get_b(NULL, "CLUI", "SBarBevel", 1) == 0) - flags |= SBT_NOBORDERS; - for (i=0; i < cli.menuProtoCount; i++) { - SendMessage(cli.hwndStatus, SB_SETTEXT, i | flags, (LPARAM)cli.menuProtos[i].szProto); - } -} diff --git a/src/modules/clist/contact.cpp b/src/modules/clist/contact.cpp deleted file mode 100644 index 661d3040cf..0000000000 --- a/src/modules/clist/contact.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -extern HANDLE hContactIconChangedEvent; -extern HANDLE hGroupChangeEvent; - -int sortByStatus; -int sortByProto; - -static const struct { - int status, order; -} statusModeOrder[] = { - {ID_STATUS_OFFLINE, 500}, - {ID_STATUS_ONLINE, 10}, - {ID_STATUS_AWAY, 200}, - {ID_STATUS_DND, 110}, - {ID_STATUS_NA, 450}, - {ID_STATUS_OCCUPIED, 100}, - {ID_STATUS_FREECHAT, 0}, - {ID_STATUS_INVISIBLE, 20}, - {ID_STATUS_ONTHEPHONE, 150}, - {ID_STATUS_OUTTOLUNCH, 425}}; - -static int GetContactStatus(MCONTACT hContact) -{ - char *szProto = GetContactProto(hContact); - if (szProto == NULL) - return ID_STATUS_OFFLINE; - return db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); -} - -void fnChangeContactIcon(MCONTACT hContact, int iIcon, int add) -{ - CallService(add ? MS_CLUI_CONTACTADDED : MS_CLUI_CONTACTSETICON, hContact, iIcon); - NotifyEventHooks(hContactIconChangedEvent, hContact, iIcon); -} - -int GetStatusModeOrdering(int statusMode) -{ - int i; - for (i=0; i < SIZEOF(statusModeOrder); i++) - if (statusModeOrder[i].status == statusMode) - return statusModeOrder[i].order; - return 1000; -} - -void fnLoadContactTree(void) -{ - CallService(MS_CLUI_LISTBEGINREBUILD, 0, 0); - for (int i = 1;; i++) { - if (cli.pfnGetGroupName(i, NULL) == NULL) - break; - CallService(MS_CLUI_GROUPADDED, i, 0); - } - - int hideOffline = db_get_b(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT); - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - int status = GetContactStatus(hContact); - if ((!hideOffline || status != ID_STATUS_OFFLINE) && !db_get_b(hContact, "CList", "Hidden", 0)) - cli.pfnChangeContactIcon(hContact, cli.pfnIconFromStatusMode(GetContactProto(hContact), status, hContact), 1); - } - sortByStatus = db_get_b(NULL, "CList", "SortByStatus", SETTING_SORTBYSTATUS_DEFAULT); - sortByProto = db_get_b(NULL, "CList", "SortByProto", SETTING_SORTBYPROTO_DEFAULT); - CallService(MS_CLUI_LISTENDREBUILD, 0, 0); -} - -int fnCompareContacts(const ClcContact* c1, const ClcContact* c2) -{ - MCONTACT a = c1->hContact, b = c2->hContact; - TCHAR namea[128], *nameb; - int statusa, statusb; - int rc; - - statusa = db_get_w(a, c1->proto, "Status", ID_STATUS_OFFLINE); - statusb = db_get_w(b, c2->proto, "Status", ID_STATUS_OFFLINE); - - if (sortByProto) { - /* deal with statuses, online contacts have to go above offline */ - if ((statusa == ID_STATUS_OFFLINE) != (statusb == ID_STATUS_OFFLINE)) { - return 2 * (statusa == ID_STATUS_OFFLINE) - 1; - } - /* both are online, now check protocols */ - if (c1->proto != NULL && c2->proto != NULL) { - rc = mir_strcmp(c1->proto, c2->proto); - if (rc != 0) - return rc; - } - /* protocols are the same, order by display name */ - } - - if (sortByStatus) { - int ordera = GetStatusModeOrdering(statusa); - int orderb = GetStatusModeOrdering(statusb); - if (ordera != orderb) - return ordera - orderb; - } - else { - //one is offline: offline goes below online - if ((statusa == ID_STATUS_OFFLINE) != (statusb == ID_STATUS_OFFLINE)) - return 2 * (statusa == ID_STATUS_OFFLINE) - 1; - } - - nameb = cli.pfnGetContactDisplayName(a, 0); - _tcsncpy_s(namea, nameb, _TRUNCATE); - namea[ SIZEOF(namea)-1 ] = 0; - nameb = cli.pfnGetContactDisplayName(b, 0); - - //otherwise just compare names - return mir_tstrcmpi(namea, nameb); -} - -void fnSortContacts(void) -{ - //avoid doing lots of resorts in quick succession - sortByStatus = db_get_b(NULL, "CList", "SortByStatus", SETTING_SORTBYSTATUS_DEFAULT); - sortByProto = db_get_b(NULL, "CList", "SortByProto", SETTING_SORTBYPROTO_DEFAULT); -} - -INT_PTR ContactChangeGroup(WPARAM wParam, LPARAM lParam) -{ - CLISTGROUPCHANGE grpChg = { sizeof(CLISTGROUPCHANGE), NULL, NULL }; - - CallService(MS_CLUI_CONTACTDELETED, wParam, 0); - if ((HANDLE) lParam == NULL) - db_unset(wParam, "CList", "Group"); - else { - grpChg.pszNewName = cli.pfnGetGroupName(lParam, NULL); - db_set_ts(wParam, "CList", "Group", grpChg.pszNewName); - } - CallService(MS_CLUI_CONTACTADDED, wParam, - cli.pfnIconFromStatusMode(GetContactProto(wParam), GetContactStatus(wParam), wParam)); - - NotifyEventHooks(hGroupChangeEvent, wParam, (LPARAM)&grpChg); - return 0; -} - -int fnSetHideOffline(WPARAM wParam, LPARAM) -{ - switch((int)wParam) { - case 0: - db_set_b(NULL, "CList", "HideOffline", 0); - break; - case 1: - db_set_b(NULL, "CList", "HideOffline", 1); - break; - case -1: - db_set_b(NULL, "CList", "HideOffline", !db_get_b(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT)); - break; - } - cli.pfnLoadContactTree(); - return 0; -} diff --git a/src/modules/clist/contacts.cpp b/src/modules/clist/contacts.cpp deleted file mode 100644 index 9995bf219b..0000000000 --- a/src/modules/clist/contacts.cpp +++ /dev/null @@ -1,452 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#define NAMEORDERCOUNT 9 -static TCHAR* nameOrderDescr[ NAMEORDERCOUNT ] = -{ - LPGENT("My custom name (not movable)"), - LPGENT("Nick"), - LPGENT("FirstName"), - LPGENT("E-mail"), - LPGENT("LastName"), - LPGENT("Username"), - LPGENT("FirstName LastName"), - LPGENT("LastName FirstName"), - LPGENT("'(Unknown contact)' (not movable)") -}; - -BYTE nameOrder[NAMEORDERCOUNT]; - -static int GetDatabaseString(CONTACTINFO *ci, const char* setting, DBVARIANT* dbv) -{ - if (mir_strcmp(ci->szProto, "CList") && CallProtoService(ci->szProto, PS_GETCAPS, PFLAGNUM_4, 0) & PF4_INFOSETTINGSVC) { - DBCONTACTGETSETTING cgs = { ci->szProto, setting, dbv }; - dbv->type = (ci->dwFlag & CNF_UNICODE) ? DBVT_WCHAR : DBVT_ASCIIZ; - - int res = CallProtoService(ci->szProto, PS_GETINFOSETTING, (WPARAM)ci->hContact, (LPARAM)&cgs); - if (res != CALLSERVICE_NOTFOUND) - return res; - } - - if (ci->dwFlag & CNF_UNICODE) - return db_get_ws(ci->hContact, ci->szProto, setting, dbv); - - return db_get_s(ci->hContact, ci->szProto, setting, dbv); -} - -static int ProcessDatabaseValueDefault(CONTACTINFO *ci, const char* setting) -{ - DBVARIANT dbv; - if (!GetDatabaseString(ci, setting, &dbv)) { - switch (dbv.type) { - case DBVT_ASCIIZ: - if (!dbv.pszVal[0]) break; - case DBVT_WCHAR: - if (!dbv.pwszVal[0]) break; - ci->type = CNFT_ASCIIZ; - ci->pszVal = dbv.ptszVal; - return 0; - } - db_free(&dbv); - } - - if (db_get(ci->hContact, ci->szProto, setting, &dbv)) - return 1; - - switch (dbv.type) { - case DBVT_BYTE: - ci->type = CNFT_BYTE; - ci->bVal = dbv.bVal; - return 0; - case DBVT_WORD: - ci->type = CNFT_WORD; - ci->wVal = dbv.wVal; - return 0; - case DBVT_DWORD: - ci->type = CNFT_DWORD; - ci->dVal = dbv.dVal; - return 0; - } - - db_free(&dbv); - return 1; -} - -static INT_PTR GetContactInfo(WPARAM, LPARAM lParam) -{ - DBVARIANT dbv; - CONTACTINFO *ci = (CONTACTINFO*)lParam; - if (ci == NULL) return 1; - if (ci->szProto == NULL) ci->szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEACCOUNT, (WPARAM)ci->hContact, 0); - if (ci->szProto == NULL) return 1; - - ci->type = 0; - switch (ci->dwFlag & 0x7F) { - case CNF_FIRSTNAME: return ProcessDatabaseValueDefault(ci, "FirstName"); - case CNF_LASTNAME: return ProcessDatabaseValueDefault(ci, "LastName"); - case CNF_NICK: return ProcessDatabaseValueDefault(ci, "Nick"); - case CNF_EMAIL: return ProcessDatabaseValueDefault(ci, "e-mail"); - case CNF_CITY: return ProcessDatabaseValueDefault(ci, "City"); - case CNF_STATE: return ProcessDatabaseValueDefault(ci, "State"); - case CNF_PHONE: return ProcessDatabaseValueDefault(ci, "Phone"); - case CNF_HOMEPAGE: return ProcessDatabaseValueDefault(ci, "Homepage"); - case CNF_ABOUT: return ProcessDatabaseValueDefault(ci, "About"); - case CNF_AGE: return ProcessDatabaseValueDefault(ci, "Age"); - case CNF_GENDER: return ProcessDatabaseValueDefault(ci, "Gender"); - case CNF_FAX: return ProcessDatabaseValueDefault(ci, "Fax"); - case CNF_CELLULAR: return ProcessDatabaseValueDefault(ci, "Cellular"); - case CNF_BIRTHDAY: return ProcessDatabaseValueDefault(ci, "BirthDay"); - case CNF_BIRTHMONTH: return ProcessDatabaseValueDefault(ci, "BirthMonth"); - case CNF_BIRTHYEAR: return ProcessDatabaseValueDefault(ci, "BirthYear"); - case CNF_STREET: return ProcessDatabaseValueDefault(ci, "Street"); - case CNF_ZIP: return ProcessDatabaseValueDefault(ci, "ZIP"); - case CNF_LANGUAGE1: return ProcessDatabaseValueDefault(ci, "Language1"); - case CNF_LANGUAGE2: return ProcessDatabaseValueDefault(ci, "Language2"); - case CNF_LANGUAGE3: return ProcessDatabaseValueDefault(ci, "Language3"); - case CNF_CONAME: return ProcessDatabaseValueDefault(ci, "Company"); - case CNF_CODEPT: return ProcessDatabaseValueDefault(ci, "CompanyDepartment"); - case CNF_COPOSITION: return ProcessDatabaseValueDefault(ci, "CompanyPosition"); - case CNF_COSTREET: return ProcessDatabaseValueDefault(ci, "CompanyStreet"); - case CNF_COCITY: return ProcessDatabaseValueDefault(ci, "CompanyCity"); - case CNF_COSTATE: return ProcessDatabaseValueDefault(ci, "CompanyState"); - case CNF_COZIP: return ProcessDatabaseValueDefault(ci, "CompanyZIP"); - case CNF_COHOMEPAGE: return ProcessDatabaseValueDefault(ci, "CompanyHomepage"); - - case CNF_CUSTOMNICK: - { - char* saveProto = ci->szProto; ci->szProto = "CList"; - if (ci->hContact != NULL && !ProcessDatabaseValueDefault(ci, "MyHandle")) { - ci->szProto = saveProto; - return 0; - } - ci->szProto = saveProto; - } - break; - - case CNF_COUNTRY: - case CNF_COCOUNTRY: - if (!GetDatabaseString(ci, (ci->dwFlag & 0x7F) == CNF_COUNTRY ? "CountryName" : "CompanyCountryName", &dbv)) - return 0; - - if (!db_get(ci->hContact, ci->szProto, (ci->dwFlag & 0x7F) == CNF_COUNTRY ? "Country" : "CompanyCountry", &dbv)) { - if (dbv.type == DBVT_WORD) { - int i, countryCount; - struct CountryListEntry *countries; - CallService(MS_UTILS_GETCOUNTRYLIST, (WPARAM)&countryCount, (LPARAM)&countries); - for (i = 0; i < countryCount; i++) { - if (countries[i].id != dbv.wVal) continue; - - if (ci->dwFlag & CNF_UNICODE) { - int cbLen = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)countries[i].szName, -1, NULL, 0); - WCHAR* buf = (WCHAR*)mir_alloc(sizeof(WCHAR)*(cbLen + 1)); - if (buf != NULL) - MultiByteToWideChar(CP_ACP, 0, (LPCSTR)countries[i].szName, -1, buf, cbLen); - ci->pszVal = (TCHAR*)buf; - } - else ci->pszVal = (TCHAR*)mir_strdup(countries[i].szName); - - ci->type = CNFT_ASCIIZ; - db_free(&dbv); - return 0; - } - } - else return ProcessDatabaseValueDefault(ci, (ci->dwFlag & 0x7F) == CNF_COUNTRY ? "Country" : "CompanyCountry"); - db_free(&dbv); - } - break; - - case CNF_FIRSTLAST: - if (!GetDatabaseString(ci, "FirstName", &dbv)) { - DBVARIANT dbv2; - if (!GetDatabaseString(ci, "LastName", &dbv2)) { - ci->type = CNFT_ASCIIZ; - if (ci->dwFlag & CNF_UNICODE) { - size_t len = mir_wstrlen(dbv.pwszVal) + mir_wstrlen(dbv2.pwszVal) + 2; - WCHAR* buf = (WCHAR*)mir_alloc(sizeof(WCHAR)*len); - if (buf != NULL) - mir_wstrcat(mir_wstrcat(mir_wstrcpy(buf, dbv.pwszVal), L" "), dbv2.pwszVal); - ci->pszVal = (TCHAR*)buf; - } - else { - size_t len = mir_strlen(dbv.pszVal) + mir_strlen(dbv2.pszVal) + 2; - char* buf = (char*)mir_alloc(len); - if (buf != NULL) - mir_strcat(mir_strcat(mir_strcpy(buf, dbv.pszVal), " "), dbv2.pszVal); - ci->pszVal = (TCHAR*)buf; - } - db_free(&dbv); - db_free(&dbv2); - return 0; - } - db_free(&dbv); - } - break; - - case CNF_UNIQUEID: - { - if (db_mc_isMeta(ci->hContact)) { - TCHAR buf[40]; - _itot(ci->hContact, buf, 10); - ci->pszVal = mir_tstrdup(buf); - ci->type = CNFT_ASCIIZ; - return 0; - } - - char *uid = (char*)CallProtoService(ci->szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); - if ((INT_PTR)uid != CALLSERVICE_NOTFOUND && uid) - if (!ProcessDatabaseValueDefault(ci, uid)) - return 0; - } - break; - - case CNF_DISPLAYUID: - { - if (!ProcessDatabaseValueDefault(ci, "display_uid")) - return 0; - char *uid = (char*)CallProtoService(ci->szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); - if ((INT_PTR)uid != CALLSERVICE_NOTFOUND && uid) - if (!ProcessDatabaseValueDefault(ci, uid)) - return 0; - - } - break; - - case CNF_DISPLAYNC: - case CNF_DISPLAY: - for (int i = 0; i < NAMEORDERCOUNT; i++) { - switch (nameOrder[i]) { - case 0: // custom name - // make sure we aren't in CNF_DISPLAYNC mode - // don't get custom name for NULL contact - { - char *saveProto = ci->szProto; ci->szProto = "CList"; - if (ci->hContact != NULL && (ci->dwFlag & 0x7F) == CNF_DISPLAY && !ProcessDatabaseValueDefault(ci, "MyHandle")) { - ci->szProto = saveProto; - return 0; - } - ci->szProto = saveProto; - } - break; - case 1: - if (!ProcessDatabaseValueDefault(ci, "Nick")) // nick - return 0; - break; - case 2: - if (!ProcessDatabaseValueDefault(ci, "FirstName")) // First Name - return 0; - break; - case 3: - if (!ProcessDatabaseValueDefault(ci, "e-mail")) // E-mail - return 0; - break; - case 4: - if (!ProcessDatabaseValueDefault(ci, "LastName")) // Last Name - return 0; - break; - case 5: // Unique id - { - // protocol must define a PFLAG_UNIQUEIDSETTING - char *uid = (char*)CallProtoService(ci->szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); - if ((INT_PTR)uid != CALLSERVICE_NOTFOUND && uid) { - if (!GetDatabaseString(ci, uid, &dbv)) { - if (dbv.type == DBVT_BYTE || dbv.type == DBVT_WORD || dbv.type == DBVT_DWORD) { - long value = (dbv.type == DBVT_BYTE) ? dbv.bVal : (dbv.type == DBVT_WORD ? dbv.wVal : dbv.dVal); - if (ci->dwFlag & CNF_UNICODE) { - WCHAR buf[40]; - _ltow(value, buf, 10); - ci->pszVal = (TCHAR*)mir_wstrdup(buf); - } - else { - char buf[40]; - _ltoa(value, buf, 10); - ci->pszVal = (TCHAR*)mir_strdup(buf); - } - ci->type = CNFT_ASCIIZ; - return 0; - } - if (dbv.type == DBVT_ASCIIZ && !(ci->dwFlag & CNF_UNICODE)) { - ci->type = CNFT_ASCIIZ; - ci->pszVal = dbv.ptszVal; - return 0; - } - if (dbv.type == DBVT_WCHAR && (ci->dwFlag & CNF_UNICODE)) { - ci->type = CNFT_ASCIIZ; - ci->pszVal = dbv.ptszVal; - return 0; - } - } - } - } - break; - case 6: // first + last name - case 7: // last + first name - if (!GetDatabaseString(ci, nameOrder[i] == 6 ? "FirstName" : "LastName", &dbv)) { - DBVARIANT dbv2; - if (!GetDatabaseString(ci, nameOrder[i] == 6 ? "LastName" : "FirstName", &dbv2)) { - ci->type = CNFT_ASCIIZ; - - if (ci->dwFlag & CNF_UNICODE) { - size_t len = mir_wstrlen(dbv.pwszVal) + mir_wstrlen(dbv2.pwszVal) + 2; - WCHAR* buf = (WCHAR*)mir_alloc(sizeof(WCHAR)*len); - if (buf != NULL) - mir_wstrcat(mir_wstrcat(mir_wstrcpy(buf, dbv.pwszVal), L" "), dbv2.pwszVal); - ci->pszVal = (TCHAR*)buf; - } - else { - size_t len = mir_strlen(dbv.pszVal) + mir_strlen(dbv2.pszVal) + 2; - char* buf = (char*)mir_alloc(len); - if (buf != NULL) - mir_strcat(mir_strcat(mir_strcpy(buf, dbv.pszVal), " "), dbv2.pszVal); - ci->pszVal = (TCHAR*)buf; - } - - db_free(&dbv); - db_free(&dbv2); - return 0; - } - db_free(&dbv); - } - break; - - case 8: - if (ci->dwFlag & CNF_UNICODE) - ci->pszVal = (TCHAR*)mir_wstrdup(TranslateW(L"'(Unknown contact)'")); - else - ci->pszVal = (TCHAR*)mir_strdup(Translate("'(Unknown contact)'")); - ci->type = CNFT_ASCIIZ; - return 0; - } - } - break; - - case CNF_TIMEZONE: - { - HANDLE hTz = tmi.createByContact(ci->hContact, 0, TZF_KNOWNONLY); - if (hTz) { - LPTIME_ZONE_INFORMATION tzi = tmi.getTzi(hTz); - int offset = tzi->Bias + tzi->StandardBias; - - char str[80]; - mir_snprintf(str, offset ? "UTC%+d:%02d" : "UTC", offset / -60, abs(offset % 60)); - ci->pszVal = ci->dwFlag & CNF_UNICODE ? (TCHAR*)mir_a2u(str) : (TCHAR*)mir_strdup(str); - ci->type = CNFT_ASCIIZ; - return 0; - } - } - break; - - case CNF_MYNOTES: - char* saveProto = ci->szProto; ci->szProto = "UserInfo"; - if (!ProcessDatabaseValueDefault(ci, "MyNotes")) { - ci->szProto = saveProto; - return 0; - } - ci->szProto = saveProto; - break; - } - - return 1; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Options dialog - -class CContactOptsDlg : public CDlgBase -{ - CCtrlTreeView m_nameOrder; - -public: - CContactOptsDlg() : - CDlgBase(hInst, IDD_OPT_CONTACT), - m_nameOrder(this, IDC_NAMEORDER) - { - m_nameOrder.SetFlags(MTREE_DND); - m_nameOrder.OnBeginDrag = Callback(this, &CContactOptsDlg::OnBeginDrag); - } - - virtual void OnInitDialog() - { - TVINSERTSTRUCT tvis; - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_TEXT | TVIF_PARAM; - for (int i = 0; i < SIZEOF(nameOrderDescr); i++) { - tvis.item.lParam = nameOrder[i]; - tvis.item.pszText = TranslateTS(nameOrderDescr[nameOrder[i]]); - m_nameOrder.InsertItem(&tvis); - } - } - - virtual void OnApply() - { - TVITEMEX tvi; - tvi.hItem = m_nameOrder.GetRoot(); - int i = 0; - while (tvi.hItem != NULL) { - tvi.mask = TVIF_PARAM | TVIF_HANDLE; - m_nameOrder.GetItem(&tvi); - nameOrder[i++] = (BYTE)tvi.lParam; - tvi.hItem = m_nameOrder.GetNextSibling(tvi.hItem); - } - db_set_blob(NULL, "Contact", "NameOrder", nameOrder, SIZEOF(nameOrderDescr)); - CallService(MS_CLIST_INVALIDATEDISPLAYNAME, (WPARAM)INVALID_HANDLE_VALUE, 0); - } - - void OnBeginDrag(CCtrlTreeView::TEventInfo *evt) - { - LPNMTREEVIEW pNotify = evt->nmtv; - if (pNotify->itemNew.lParam == 0 || pNotify->itemNew.lParam == SIZEOF(nameOrderDescr) - 1) - pNotify->hdr.code = 0; // deny dragging - } -}; - -static int ContactOptInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.position = -1000000000; - odp.pszGroup = LPGEN("Contact list"); - odp.pszTitle = LPGEN("Contact names"); - odp.pDialog = new CContactOptsDlg(); - odp.flags = ODPF_BOLDGROUPS; - Options_AddPage(wParam, &odp); - return 0; -} - -int LoadContactsModule(void) -{ - for (BYTE i = 0; i < NAMEORDERCOUNT; i++) - nameOrder[i] = i; - - DBVARIANT dbv; - if (!db_get(NULL, "Contact", "NameOrder", &dbv)) { - memcpy(nameOrder, dbv.pbVal, dbv.cpbVal); - db_free(&dbv); - } - - CreateServiceFunction(MS_CONTACT_GETCONTACTINFO, GetContactInfo); - HookEvent(ME_OPT_INITIALISE, ContactOptInit); - return 0; -} diff --git a/src/modules/clist/genmenu.cpp b/src/modules/clist/genmenu.cpp deleted file mode 100644 index c8ea4e0c33..0000000000 --- a/src/modules/clist/genmenu.cpp +++ /dev/null @@ -1,1236 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "genmenu.h" - -static bool bIsGenMenuInited; -bool bIconsDisabled; -static mir_cs csMenuHook; - -static int NextObjectId = 0x100, NextObjectMenuItemId = CLISTMENUIDMIN; - -#if defined(_DEBUG) -static void DumpMenuItem(TMO_IntMenuItem* pParent, int level = 0) -{ - char temp[ 30 ]; - memset(temp, '\t', level); - temp[ level ] = 0; - - for (PMO_IntMenuItem pimi = pParent; pimi != NULL; pimi = pimi->next) { - Netlib_Logf(NULL, "%sMenu item %08p [%08p]: %S", temp, pimi, pimi->mi.root, pimi->mi.ptszName); - - PMO_IntMenuItem submenu = pimi->submenu.first; - if (submenu) - DumpMenuItem(submenu, level+1); - } -} - -#endif - -static int CompareMenus(const TIntMenuObject* p1, const TIntMenuObject* p2) -{ - return mir_strcmp(p1->pszName, p2->pszName); -} - -LIST g_menus(10, CompareMenus); - -void FreeAndNil(void **p) -{ - if (p == NULL) - return; - - if (*p != NULL) { - mir_free(*p); - *p = NULL; - } -} - -int GetMenuObjbyId(const int id) -{ - for (int i = 0; i < g_menus.getCount(); i++) - if (g_menus[i]->id == id) - return i; - - return -1; -} - -LPTSTR GetMenuItemText(PMO_IntMenuItem pimi) -{ - if (pimi->mi.flags & CMIF_KEEPUNTRANSLATED) - return pimi->mi.ptszName; - - return TranslateTH(pimi->mi.hLangpack, pimi->mi.ptszName); -} - -/////////////////////////////////////////////////////////////////////////////// - -PMO_IntMenuItem MO_RecursiveWalkMenu(PMO_IntMenuItem parent, pfnWalkFunc func, void* param) -{ - if (parent == NULL) - return FALSE; - - PMO_IntMenuItem pnext; - for (PMO_IntMenuItem pimi = parent; pimi != NULL; pimi = pnext) { - PMO_IntMenuItem submenu = pimi->submenu.first; - pnext = pimi->next; - if (func(pimi, param)) // it can destroy the menu item - return pimi; - - if (submenu) { - PMO_IntMenuItem res = MO_RecursiveWalkMenu(submenu, func, param); - if (res) - return res; - } - } - - return FALSE; -} - -/////////////////////////////////////////////////////////////////////////////// -// wparam = 0 -// lparam = LPMEASUREITEMSTRUCT - -int MO_MeasureMenuItem(LPMEASUREITEMSTRUCT mis) -{ - if (!bIsGenMenuInited) - return -1; - - if (mis == NULL) - return FALSE; - - // prevent win9x from ugly menus displaying when there is no icon - mis->itemWidth = 0; - mis->itemHeight = 0; - - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)mis->itemData); - if (pimi == NULL) - return FALSE; - - if (pimi->iconId == -1) - return FALSE; - - mis->itemWidth = max(0, GetSystemMetrics(SM_CXSMICON) - GetSystemMetrics(SM_CXMENUCHECK) + 4); - mis->itemHeight = GetSystemMetrics(SM_CYSMICON) + 2; - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// wparam = 0 -// lparam = LPDRAWITEMSTRUCT - -int MO_DrawMenuItem(LPDRAWITEMSTRUCT dis) -{ - if (!bIsGenMenuInited) - return -1; - - if (dis == NULL) - return FALSE; - - mir_cslock lck(csMenuHook); - - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)dis->itemData); - if (pimi == NULL || pimi->iconId == -1) - return FALSE; - - int y = (dis->rcItem.bottom - dis->rcItem.top - GetSystemMetrics(SM_CYSMICON)) / 2 + 1; - if (dis->itemState & ODS_SELECTED) { - if (dis->itemState & ODS_CHECKED) { - RECT rc; - rc.left = 2; rc.right = GetSystemMetrics(SM_CXSMICON) + 2; - rc.top = y; rc.bottom = rc.top + GetSystemMetrics(SM_CYSMICON) + 2; - FillRect(dis->hDC, &rc, GetSysColorBrush(COLOR_HIGHLIGHT)); - ImageList_DrawEx(pimi->parent->m_hMenuIcons, pimi->iconId, dis->hDC, 2, y, 0, 0, CLR_NONE, CLR_DEFAULT, ILD_SELECTED); - } - else ImageList_DrawEx(pimi->parent->m_hMenuIcons, pimi->iconId, dis->hDC, 2, y, 0, 0, CLR_NONE, CLR_DEFAULT, ILD_FOCUS); - } - else { - if (dis->itemState & ODS_CHECKED) { - RECT rc; - rc.left = 0; rc.right = GetSystemMetrics(SM_CXSMICON) + 4; - rc.top = y - 2; rc.bottom = rc.top + GetSystemMetrics(SM_CYSMICON) + 4; - DrawEdge(dis->hDC, &rc, BDR_SUNKENOUTER, BF_RECT); - InflateRect(&rc, -1, -1); - COLORREF menuCol = GetSysColor(COLOR_MENU); - COLORREF hiliteCol = GetSysColor(COLOR_3DHIGHLIGHT); - HBRUSH hBrush = CreateSolidBrush(RGB((GetRValue(menuCol) + GetRValue(hiliteCol)) / 2, (GetGValue(menuCol) + GetGValue(hiliteCol)) / 2, (GetBValue(menuCol) + GetBValue(hiliteCol)) / 2)); - FillRect(dis->hDC, &rc, GetSysColorBrush(COLOR_MENU)); - DeleteObject(hBrush); - ImageList_DrawEx(pimi->parent->m_hMenuIcons, pimi->iconId, dis->hDC, 2, y, 0, 0, CLR_NONE, GetSysColor(COLOR_MENU), ILD_BLEND50); - } - else ImageList_DrawEx(pimi->parent->m_hMenuIcons, pimi->iconId, dis->hDC, 2, y, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); - } - return TRUE; -} - -int MO_RemoveAllObjects() -{ - for (int i = 0; i < g_menus.getCount(); i++) - delete g_menus[i]; - g_menus.destroy(); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// wparam = MenuObjectHandle - -INT_PTR MO_RemoveMenuObject(WPARAM wParam, LPARAM) -{ - if (!bIsGenMenuInited) - return -1; - - mir_cslock lck(csMenuHook); - int objidx = GetMenuObjbyId((int)wParam); - if (objidx == -1) - return -1; - - delete g_menus[objidx]; - g_menus.remove(objidx); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// wparam = MenuObjectHandle -// lparam = vKey - -INT_PTR MO_ProcessHotKeys(HANDLE menuHandle, INT_PTR vKey) -{ - if (!bIsGenMenuInited) - return -1; - - mir_cslock lck(csMenuHook); - int objidx = GetMenuObjbyId((int)menuHandle); - if (objidx == -1) - return FALSE; - - for (PMO_IntMenuItem pimi = g_menus[objidx]->m_items.first; pimi != NULL; pimi = pimi->next) { - if (pimi->mi.hotKey == 0) continue; - if (HIWORD(pimi->mi.hotKey) != vKey) continue; - if (!(LOWORD(pimi->mi.hotKey) & MOD_ALT) != !(GetKeyState(VK_MENU) & 0x8000)) continue; - if (!(LOWORD(pimi->mi.hotKey) & MOD_CONTROL) != !(GetKeyState(VK_CONTROL) & 0x8000)) continue; - if (!(LOWORD(pimi->mi.hotKey) & MOD_SHIFT) != !(GetKeyState(VK_SHIFT) & 0x8000)) continue; - - MO_ProcessCommand(pimi, 0); - return TRUE; - } - - return FALSE; -} - -INT_PTR MO_GetProtoRootMenu(WPARAM wParam, LPARAM lParam) -{ - char *szProto = (char*)wParam; - if (szProto == NULL) - return 0; - - if (db_get_b(NULL, "CList", "MoveProtoMenus", TRUE)) - return (INT_PTR)cli.pfnGetProtocolMenu(szProto); - - int objidx = GetMenuObjbyId((int)hMainMenuObject); - if (objidx == -1) - return NULL; - - mir_cslock lck(csMenuHook); - - TIntMenuObject* pmo = g_menus[objidx]; - for (PMO_IntMenuItem p = pmo->m_items.first; p != NULL; p = p->next) - if (!mir_strcmp(p->UniqName, szProto)) - return (INT_PTR)p; - - return NULL; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// wparam = MenuItemHandle -// lparam = PMO_MenuItem -INT_PTR MO_GetMenuItem(WPARAM wParam, LPARAM lParam) -{ - PMO_MenuItem mi = (PMO_MenuItem)lParam; - if (!bIsGenMenuInited || mi == NULL) - return -1; - - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)wParam); - mir_cslock lck(csMenuHook); - if (pimi == NULL) - return -1; - - *mi = pimi->mi; - return 0; -} - -static int FindDefaultItem(PMO_IntMenuItem pimi, void*) -{ - if (pimi->mi.flags & (CMIF_GRAYED | CMIF_HIDDEN)) - return FALSE; - - return (pimi->mi.flags & CMIF_DEFAULT) ? TRUE : FALSE; -} - -INT_PTR MO_GetDefaultMenuItem(WPARAM wParam, LPARAM) -{ - if (!bIsGenMenuInited) - return -1; - - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)wParam); - mir_cslock lck(csMenuHook); - return (pimi) ? (INT_PTR)MO_RecursiveWalkMenu(pimi, FindDefaultItem, NULL) : NULL; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// wparam MenuItemHandle -// lparam PMO_MenuItem - -int MO_ModifyMenuItem(PMO_IntMenuItem menuHandle, PMO_MenuItem pmi) -{ - int oldflags; - - if (!bIsGenMenuInited || pmi == NULL || pmi->cbSize != sizeof(TMO_MenuItem)) - return -1; - - mir_cslock lck(csMenuHook); - - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)menuHandle); - if (pimi == NULL) - return -1; - - if (pmi->flags & CMIM_NAME) { - FreeAndNil((void**)&pimi->mi.pszName); - - if (pmi->flags & CMIF_UNICODE) - pimi->mi.ptszName = mir_tstrdup(pmi->ptszName); - else - pimi->mi.ptszName = mir_a2t(pmi->pszName); - } - - if (pmi->flags & CMIM_FLAGS) { - oldflags = (pimi->mi.flags & CMIF_ROOTHANDLE); - pimi->mi.flags = (pmi->flags & ~CMIM_ALL) | oldflags; - } - - if ((pmi->flags & CMIM_ICON) && !bIconsDisabled) { - HANDLE hIcolibItem = IcoLib_IsManaged(pmi->hIcon); - if (hIcolibItem) { - HICON hIcon = IcoLib_GetIconByHandle(hIcolibItem, false); - if (hIcon != NULL) { - pimi->hIcolibItem = hIcolibItem; - pimi->iconId = ImageList_ReplaceIcon(pimi->parent->m_hMenuIcons, pimi->iconId, hIcon); - IcoLib_ReleaseIcon(hIcon, 0); - } - else pimi->iconId = -1, pimi->hIcolibItem = NULL; - } - else { - pimi->mi.hIcon = pmi->hIcon; - if (pmi->hIcon != NULL) - pimi->iconId = ImageList_ReplaceIcon(pimi->parent->m_hMenuIcons, pimi->iconId, pmi->hIcon); - else - pimi->iconId = -1; //fixme, should remove old icon & shuffle all iconIds - } - if (pimi->hBmp) { - DeleteObject(pimi->hBmp); - pimi->hBmp = NULL; - } - } - - if (pmi->flags & CMIM_HOTKEY) - pimi->mi.hotKey = pmi->hotKey; - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// wparam MenuItemHandle -// return ownerdata useful to free ownerdata before delete menu item, -// NULL on error. - -INT_PTR MO_MenuItemGetOwnerData(WPARAM wParam, LPARAM) -{ - if (!bIsGenMenuInited) - return -1; - - mir_cslock lck(csMenuHook); - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)wParam); - return (pimi) ? (INT_PTR)pimi->mi.ownerdata : -1; -} - -PMO_IntMenuItem MO_GetIntMenuItem(HGENMENU wParam) -{ - PMO_IntMenuItem result = (PMO_IntMenuItem)wParam; - if (result == NULL || wParam == (HGENMENU)0xffff1234 || wParam == HGENMENU_ROOT) - return NULL; - - __try { - if (result->signature != MENUITEM_SIGNATURE) - result = NULL; - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - result = NULL; - } - - return result; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// LOWORD(wparam) menuident - -static int FindMenuByCommand(PMO_IntMenuItem pimi, void* pCommand) -{ - return (pimi->iCommand == (int)pCommand); -} - -int MO_ProcessCommandBySubMenuIdent(int menuID, int command, LPARAM lParam) -{ - if (!bIsGenMenuInited) - return -1; - - PMO_IntMenuItem pimi; - { - mir_cslock lck(csMenuHook); - int objidx = GetMenuObjbyId(menuID); - if (objidx == -1) - return -1; - - pimi = MO_RecursiveWalkMenu(g_menus[objidx]->m_items.first, FindMenuByCommand, (void*)command); - } - - return (pimi) ? MO_ProcessCommand(pimi, lParam) : -1; -} - -INT_PTR MO_ProcessCommandByMenuIdent(WPARAM wParam, LPARAM lParam) -{ - if (!bIsGenMenuInited) - return -1; - - PMO_IntMenuItem pimi = NULL; - { - mir_cslock lck(csMenuHook); - for (int i = 0; i < g_menus.getCount(); i++) - if ((pimi = MO_RecursiveWalkMenu(g_menus[i]->m_items.first, FindMenuByCommand, (void*)wParam)) != NULL) - break; - } - - return (pimi) ? MO_ProcessCommand(pimi, lParam) : FALSE; -} - -int MO_ProcessCommand(PMO_IntMenuItem aHandle, LPARAM lParam) -{ - if (!bIsGenMenuInited) - return -1; - - PMO_IntMenuItem pimi; - { - mir_cslock lck(csMenuHook); - if ((pimi = MO_GetIntMenuItem(aHandle)) == NULL) - return -1; - } - - LPCSTR srvname = pimi->parent->ExecService; - void *ownerdata = pimi->mi.ownerdata; - CallService(srvname, (WPARAM)ownerdata, lParam); - return 1; -} - -int MO_SetOptionsMenuItem(PMO_IntMenuItem aHandle, int setting, INT_PTR value) -{ - if (!bIsGenMenuInited) - return -1; - - mir_cslock lck(csMenuHook); - PMO_IntMenuItem pimi = MO_GetIntMenuItem(aHandle); - if (pimi == NULL) - return -1; - - if (setting == OPT_MENUITEMSETUNIQNAME) { - mir_free(pimi->UniqName); - pimi->UniqName = mir_strdup((char*)value); - } - - return 1; -} - -int MO_SetOptionsMenuObject(HANDLE handle, int setting, INT_PTR value) -{ - if (!bIsGenMenuInited) - return -1; - - mir_cslock lck(csMenuHook); - - int pimoidx = GetMenuObjbyId((int)handle); - int res = pimoidx != -1; - if (res) { - TIntMenuObject* pmo = g_menus[pimoidx]; - - switch (setting) { - case OPT_MENUOBJECT_SET_ONADD_SERVICE: - FreeAndNil((void**)&pmo->onAddService); - pmo->onAddService = mir_strdup((char*)value); - break; - - case OPT_MENUOBJECT_SET_FREE_SERVICE: - FreeAndNil((void**)&pmo->FreeService); - pmo->FreeService = mir_strdup((char*)value); - break; - - case OPT_MENUOBJECT_SET_CHECK_SERVICE: - FreeAndNil((void**)&pmo->CheckService); - pmo->CheckService = mir_strdup((char*)value); - break; - - case OPT_USERDEFINEDITEMS: - pmo->m_bUseUserDefinedItems = (BOOL)value; - break; - } - } - - return res; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// wparam = LPCSTR szDisplayName; -// lparam = PMenuParam; -// result = MenuObjectHandle - -INT_PTR MO_CreateNewMenuObject(WPARAM wParam, LPARAM lParam) -{ - TMenuParam *pmp = (TMenuParam *)lParam; - if (!bIsGenMenuInited || pmp == NULL) - return -1; - - mir_cslock lck(csMenuHook); - - TIntMenuObject* p = new TIntMenuObject(); - p->id = NextObjectId++; - p->pszName = mir_strdup(pmp->name); - p->ptszDisplayName = mir_a2t(LPCSTR(wParam)); - p->CheckService = mir_strdup(pmp->CheckService); - p->ExecService = mir_strdup(pmp->ExecService); - p->m_hMenuIcons = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 15, 100); - g_menus.insert(p); - return p->id; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// wparam = MenuItemHandle -// lparam = 0 - -static int FreeMenuItem(TMO_IntMenuItem* pimi, void*) -{ - pimi->parent->freeItem(pimi); - return FALSE; -} - -static int FindParent(TMO_IntMenuItem* pimi, void* p) -{ - return pimi->next == p; -} - -INT_PTR MO_RemoveMenuItem(WPARAM wParam, LPARAM) -{ - mir_cslock lck(csMenuHook); - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)wParam); - if (pimi == NULL) - return -1; - - if (pimi->submenu.first) { - MO_RecursiveWalkMenu(pimi->submenu.first, FreeMenuItem, NULL); - pimi->submenu.first = NULL; - } - - PMO_IntMenuItem prev = MO_RecursiveWalkMenu(pimi->owner->first, FindParent, pimi); - if (prev) - prev->next = pimi->next; - if (pimi->owner->first == pimi) - pimi->owner->first = pimi->next; - if (pimi->owner->last == pimi) - pimi->owner->last = prev; - - pimi->signature = 0; // invalidate all future calls to that object - pimi->parent->freeItem(pimi); - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// - -struct KillMenuItemsParam -{ - KillMenuItemsParam(int _hLangpack) : - hLangpack(_hLangpack), - arItems(10) - {} - - int hLangpack; - LIST arItems; -}; - -int KillMenuItems(PMO_IntMenuItem pimi, KillMenuItemsParam* param) -{ - if (pimi->hLangpack == param->hLangpack) - param->arItems.insert(pimi); - return FALSE; -} - -void KillModuleMenus(int hLangpack) -{ - if (!bIsGenMenuInited) - return; - - KillMenuItemsParam param(hLangpack); - - mir_cslock lck(csMenuHook); - for (int i = 0; i < g_menus.getCount(); i++) - MO_RecursiveWalkMenu(g_menus[i]->m_items.first, (pfnWalkFunc)KillMenuItems, ¶m); - - for (int k = 0; k < param.arItems.getCount(); k++) - MO_RemoveMenuItem((WPARAM)param.arItems[k], 0); -} - -/////////////////////////////////////////////////////////////////////////////// -// we presume that this function is being called inside csMenuHook only - -static int PackMenuItems(PMO_IntMenuItem pimi, void*) -{ - pimi->iCommand = NextObjectMenuItemId++; - return FALSE; -} - -static int GetNextObjectMenuItemId() -{ - // if menu commands are exausted, pack the menu array - if (NextObjectMenuItemId >= CLISTMENUIDMAX) { - NextObjectMenuItemId = CLISTMENUIDMIN; - for (int i = 0; i < g_menus.getCount(); i++) - MO_RecursiveWalkMenu(g_menus[i]->m_items.first, PackMenuItems, NULL); - } - - return NextObjectMenuItemId++; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// wparam = MenuObjectHandle -// lparam = PMO_MenuItem -// return MenuItemHandle - -PMO_IntMenuItem MO_AddNewMenuItem(HANDLE menuobjecthandle, PMO_MenuItem pmi) -{ - if (!bIsGenMenuInited || pmi == NULL || pmi->cbSize != sizeof(TMO_MenuItem)) - return NULL; - - // old mode - if (!(pmi->flags & CMIF_ROOTHANDLE)) - return MO_AddOldNewMenuItem(menuobjecthandle, pmi); - - mir_cslock lck(csMenuHook); - int objidx = GetMenuObjbyId((int)menuobjecthandle); - if (objidx == -1) - return NULL; - - TIntMenuObject* pmo = g_menus[objidx]; - - TMO_IntMenuItem* p = (TMO_IntMenuItem*)mir_calloc(sizeof(TMO_IntMenuItem)); - p->parent = pmo; - p->signature = MENUITEM_SIGNATURE; - p->iCommand = GetNextObjectMenuItemId(); - p->mi = *pmi; - p->iconId = -1; - p->OverrideShow = TRUE; - p->originalPosition = pmi->position; - p->hLangpack = pmi->hLangpack; - - if (pmi->flags & CMIF_UNICODE) - p->mi.ptszName = mir_tstrdup(pmi->ptszName); - else - p->mi.ptszName = mir_a2u(pmi->pszName); - - if (pmi->hIcon != NULL && !bIconsDisabled) { - HANDLE hIcolibItem = IcoLib_IsManaged(pmi->hIcon); - if (hIcolibItem != NULL) { - HICON hIcon = IcoLib_GetIconByHandle(hIcolibItem, false); - p->iconId = ImageList_AddIcon(pmo->m_hMenuIcons, hIcon); - p->hIcolibItem = hIcolibItem; - IcoLib_ReleaseIcon(hIcon, 0); - } - else p->iconId = ImageList_AddIcon(pmo->m_hMenuIcons, pmi->hIcon); - } - - if (p->mi.root == HGENMENU_ROOT) - p->mi.root = NULL; - - PMO_IntMenuItem pRoot = (p->mi.root != NULL) ? MO_GetIntMenuItem(p->mi.root) : NULL; - if (pRoot) - p->owner = &pRoot->submenu; - else - p->owner = &pmo->m_items; - - if (!p->owner->first) - p->owner->first = p; - if (p->owner->last) - p->owner->last->next = p; - p->owner->last = p; - return p; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// wparam = MenuObjectHandle -// lparam = PMO_MenuItem - -int FindRoot(PMO_IntMenuItem pimi, void* param) -{ - if (pimi->mi.pszName != NULL) - if (pimi->submenu.first && !mir_tstrcmp(pimi->mi.ptszName, (TCHAR*)param)) - return TRUE; - - return FALSE; -} - -PMO_IntMenuItem MO_AddOldNewMenuItem(HANDLE menuobjecthandle, PMO_MenuItem pmi) -{ - if (!bIsGenMenuInited || pmi == NULL) - return NULL; - - int objidx = GetMenuObjbyId((int)menuobjecthandle); - if (objidx == -1) - return NULL; - - if (pmi->cbSize != sizeof(TMO_MenuItem)) - return NULL; - - if (pmi->flags & CMIF_ROOTHANDLE) - return NULL; - - //is item with popup or not - if (pmi->root == 0) { - // yes, this without popup - pmi->root = NULL; //first level - } - else { // no, search for needed root and create it if need - TCHAR* tszRoot; - if (pmi->flags & CMIF_UNICODE) - tszRoot = mir_tstrdup((TCHAR*)pmi->root); - else - tszRoot = mir_a2t((char*)pmi->root); - - PMO_IntMenuItem oldroot = MO_RecursiveWalkMenu(g_menus[objidx]->m_items.first, FindRoot, tszRoot); - mir_free(tszRoot); - - if (oldroot == NULL) { - // not found, creating root - TMO_MenuItem tmi = *pmi; - tmi.flags |= CMIF_ROOTHANDLE; - tmi.ownerdata = 0; - tmi.root = NULL; - // copy pszPopupName - tmi.ptszName = (TCHAR*)pmi->root; - if ((oldroot = MO_AddNewMenuItem(menuobjecthandle, &tmi)) != NULL) - MO_SetOptionsMenuItem(oldroot, OPT_MENUITEMSETUNIQNAME, (INT_PTR)pmi->root); - } - pmi->root = oldroot; - - // popup will be created in next commands - } - pmi->flags |= CMIF_ROOTHANDLE; - // add popup(root allready exists) - return MO_AddNewMenuItem(menuobjecthandle, pmi); -} - -static int WhereToPlace(HMENU hMenu, PMO_MenuItem mi) -{ - MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_SUBMENU | MIIM_DATA; - for (int i = GetMenuItemCount(hMenu) - 1; i >= 0; i--) { - GetMenuItemInfo(hMenu, i, TRUE, &mii); - if (mii.fType != MFT_SEPARATOR) { - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)mii.dwItemData); - if (pimi != NULL) - if (pimi->mi.position <= mi->position) - return i + 1; - } - } - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static DWORD GetMenuItemType(HMENU hMenu, int uItem) -{ - MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_TYPE; - GetMenuItemInfo(hMenu, uItem, TRUE, &mii); - return mii.fType; -} - -static UINT GetMenuItemTypeData(HMENU hMenu, int uItem, PMO_IntMenuItem& p) -{ - MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_DATA | MIIM_TYPE; - GetMenuItemInfo(hMenu, uItem, TRUE, &mii); - p = MO_GetIntMenuItem((HGENMENU)mii.dwItemData); - return mii.fType; -} - -static void InsertSeparator(HMENU hMenu, int uItem) -{ - MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_TYPE; - mii.fType = MFT_SEPARATOR; - InsertMenuItem(hMenu, uItem, TRUE, &mii); -} - -static void InsertMenuItemWithSeparators(HMENU hMenu, int uItem, MENUITEMINFO *lpmii) -{ - PMO_IntMenuItem pimi = MO_GetIntMenuItem((HGENMENU)lpmii->dwItemData), p; - if (pimi == NULL) - return; - - // check for separator before - if (uItem) { - UINT fType = GetMenuItemTypeData(hMenu, uItem - 1, p); - if (p != NULL && fType != MFT_SEPARATOR) { - if ((p->mi.position / SEPARATORPOSITIONINTERVAL) != (pimi->mi.position / SEPARATORPOSITIONINTERVAL)) { - // but might be supposed to be after the next one instead - if (!(uItem < GetMenuItemCount(hMenu) && GetMenuItemType(hMenu, uItem) == MFT_SEPARATOR)) - InsertSeparator(hMenu, uItem); - uItem++; - } - } - } - - // check for separator after - if (uItem < GetMenuItemCount(hMenu)) { - UINT fType = GetMenuItemTypeData(hMenu, uItem, p); - if (p != NULL && fType != MFT_SEPARATOR) - if ((p->mi.position / SEPARATORPOSITIONINTERVAL) != (pimi->mi.position / SEPARATORPOSITIONINTERVAL)) - InsertSeparator(hMenu, uItem); - } - - // create local copy *lpmii so we can change some flags - MENUITEMINFO mii = *lpmii; - - int count = GetMenuItemCount(hMenu); - if (count != 0 && (count % 33) == 0 && pimi->mi.root != NULL) { - if (!(mii.fMask & MIIM_FTYPE)) - mii.fType = 0; - mii.fMask |= MIIM_FTYPE; - mii.fType |= MFT_MENUBARBREAK; - } - - if (!pimi->CustomName) - mii.dwTypeData = GetMenuItemText(pimi); - - InsertMenuItem(hMenu, uItem, TRUE, &mii); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// wparam started hMenu -// lparam ListParam* -// result hMenu - -INT_PTR MO_BuildMenu(WPARAM wParam, LPARAM lParam) -{ - if (!bIsGenMenuInited) - return -1; - - mir_cslock lck(csMenuHook); - - ListParam *lp = (ListParam*)lParam; - int pimoidx = GetMenuObjbyId((int)lp->MenuObjectHandle); - if (pimoidx == -1) - return 0; - - #if defined(_DEBUG) - // DumpMenuItem(g_menus[pimoidx]->m_items.first); - #endif - - return (INT_PTR)BuildRecursiveMenu((HMENU)wParam, g_menus[pimoidx]->m_items.first, (ListParam*)lParam); -} - -#ifdef _DEBUG -#define PUTPOSITIONSONMENU -#endif - -void GetMenuItemName(PMO_IntMenuItem pMenuItem, char* pszDest, size_t cbDestSize) -{ - if (pMenuItem->UniqName) - mir_snprintf(pszDest, cbDestSize, "{%s}", pMenuItem->UniqName); - else if (pMenuItem->mi.flags & CMIF_UNICODE) - mir_snprintf(pszDest, cbDestSize, "{%s}", (char*)_T2A(pMenuItem->mi.ptszName)); - else - mir_snprintf(pszDest, cbDestSize, "{%s}", pMenuItem->mi.pszName); -} - -HMENU BuildRecursiveMenu(HMENU hMenu, PMO_IntMenuItem pRootMenu, ListParam *param) -{ - if (param == NULL || pRootMenu == NULL) - return NULL; - - TIntMenuObject* pmo = pRootMenu->parent; - - int rootlevel = (param->rootlevel == -1) ? 0 : param->rootlevel; - - ListParam localparam = *param; - - while (rootlevel == 0 && GetMenuItemCount(hMenu) > 0) - DeleteMenu(hMenu, 0, MF_BYPOSITION); - - for (PMO_IntMenuItem pmi = pRootMenu; pmi != NULL; pmi = pmi->next) { - PMO_MenuItem mi = &pmi->mi; - if (mi->cbSize != sizeof(TMO_MenuItem)) - continue; - - if (mi->flags & CMIF_HIDDEN) - continue; - - if (pmo->CheckService != NULL) { - TCheckProcParam CheckParam; - CheckParam.lParam = param->lParam; - CheckParam.wParam = param->wParam; - CheckParam.MenuItemOwnerData = mi->ownerdata; - CheckParam.MenuItemHandle = pmi; - if (CallService(pmo->CheckService, (WPARAM)&CheckParam, 0) == FALSE) - continue; - } - - /**************************************/ - if (rootlevel == 0 && mi->root == NULL && pmo->m_bUseUserDefinedItems) { - char DBString[256]; - DBVARIANT dbv = { 0 }; - int pos; - char MenuNameItems[256]; - mir_snprintf(MenuNameItems, SIZEOF(MenuNameItems), "%s_Items", pmo->pszName); - - char menuItemName[256]; - GetMenuItemName(pmi, menuItemName, sizeof(menuItemName)); - - // check if it visible - mir_snprintf(DBString, SIZEOF(DBString), "%s_visible", menuItemName); - if (db_get_b(NULL, MenuNameItems, DBString, -1) == -1) - db_set_b(NULL, MenuNameItems, DBString, 1); - - pmi->OverrideShow = TRUE; - if (!db_get_b(NULL, MenuNameItems, DBString, 1)) { - pmi->OverrideShow = FALSE; - continue; // find out what value to return if not getting added - } - - // mi.pszName - mir_snprintf(DBString, SIZEOF(DBString), "%s_name", menuItemName); - if (!db_get_ts(NULL, MenuNameItems, DBString, &dbv)) { - if (mir_tstrlen(dbv.ptszVal) > 0) - replaceStrT(pmi->CustomName, dbv.ptszVal); - db_free(&dbv); - } - - mir_snprintf(DBString, SIZEOF(DBString), "%s_pos", menuItemName); - if ((pos = db_get_dw(NULL, MenuNameItems, DBString, -1)) == -1) { - db_set_dw(NULL, MenuNameItems, DBString, mi->position); - if (pmi->submenu.first) - mi->position = 0; - } - else mi->position = pos; - } - - /**************************************/ - - if (rootlevel != (int)pmi->mi.root) - continue; - - int i = WhereToPlace(hMenu, mi); - - MENUITEMINFO mii = { sizeof(mii) }; - mii.dwItemData = (LPARAM)pmi; - mii.fMask = MIIM_DATA | MIIM_ID | MIIM_STRING; - if (pmi->iconId != -1) { - mii.fMask |= MIIM_BITMAP; - if (IsWinVerVistaPlus() && IsThemeActive()) { - if (pmi->hBmp == NULL) - pmi->hBmp = ConvertIconToBitmap(NULL, pmi->parent->m_hMenuIcons, pmi->iconId); - mii.hbmpItem = pmi->hBmp; - } - else mii.hbmpItem = HBMMENU_CALLBACK; - } - - mii.fMask |= MIIM_STATE; - mii.fState = ((pmi->mi.flags & CMIF_GRAYED) ? MFS_GRAYED : MFS_ENABLED); - mii.fState |= ((pmi->mi.flags & CMIF_CHECKED) ? MFS_CHECKED : MFS_UNCHECKED); - if (pmi->mi.flags & CMIF_DEFAULT) - mii.fState |= MFS_DEFAULT; - - mii.dwTypeData = (pmi->CustomName) ? pmi->CustomName : mi->ptszName; - - // it's a submenu - if (pmi->submenu.first) { - mii.fMask |= MIIM_SUBMENU; - mii.hSubMenu = CreatePopupMenu(); - - #ifdef PUTPOSITIONSONMENU - if (GetKeyState(VK_CONTROL) & 0x8000) { - TCHAR str[256]; - mir_sntprintf(str, SIZEOF(str), _T("%s (%d, id %x)"), mi->pszName, mi->position, mii.dwItemData); - mii.dwTypeData = str; - } - #endif - - InsertMenuItemWithSeparators(hMenu, i, &mii); - localparam.rootlevel = LPARAM(pmi); - BuildRecursiveMenu(mii.hSubMenu, pmi->submenu.first, &localparam); - } - else { - mii.wID = pmi->iCommand; - - #ifdef PUTPOSITIONSONMENU - if (GetKeyState(VK_CONTROL) & 0x8000) { - TCHAR str[256]; - mir_sntprintf(str, SIZEOF(str), _T("%s (%d, id %x)"), mi->pszName, mi->position, mii.dwItemData); - mii.dwTypeData = str; - } - #endif - - if (pmo->onAddService != NULL) - if (CallService(pmo->onAddService, (WPARAM)&mii, (LPARAM)pmi) == FALSE) - continue; - - InsertMenuItemWithSeparators(hMenu, i, &mii); - } - } - - return hMenu; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// iconlib in menu - -static int MO_ReloadIcon(PMO_IntMenuItem pmi, void*) -{ - if (pmi->hIcolibItem) { - HICON newIcon = IcoLib_GetIconByHandle(pmi->hIcolibItem, false); - if (newIcon) - ImageList_ReplaceIcon(pmi->parent->m_hMenuIcons, pmi->iconId, newIcon); - - IcoLib_ReleaseIcon(newIcon, 0); - } - - return FALSE; -} - -int OnIconLibChanges(WPARAM, LPARAM) -{ - { - mir_cslock lck(csMenuHook); - for (int mo = 0; mo < g_menus.getCount(); mo++) - if ((int)hStatusMenuObject != g_menus[mo]->id) //skip status menu - MO_RecursiveWalkMenu(g_menus[mo]->m_items.first, MO_ReloadIcon, 0); - } - - cli.pfnReloadProtoMenus(); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static int MO_RegisterIcon(PMO_IntMenuItem pmi, void*) -{ - TCHAR *uname = (pmi->UniqName) ? mir_a2t(pmi->UniqName) : mir_tstrdup(pmi->CustomName), - *descr = GetMenuItemText(pmi); - - if (!uname && !descr) - return FALSE; - - if (!pmi->hIcolibItem) { - HICON hIcon = ImageList_GetIcon(pmi->parent->m_hMenuIcons, pmi->iconId, 0); - - TCHAR sectionName[256]; - mir_sntprintf(sectionName, SIZEOF(sectionName), LPGENT("Menu icons") _T("/%s"), TranslateTS(pmi->parent->ptszDisplayName)); - - char iconame[256]; - mir_snprintf(iconame, SIZEOF(iconame), "genmenu_%s_%s", pmi->parent->pszName, uname && *uname ? uname : descr); - - // remove '&' - if (descr) { - descr = NEWTSTR_ALLOCA(descr); - - for (TCHAR *p = descr; *p; p++) { - if ((p = _tcschr(p, '&')) == NULL) - break; - - memmove(p, p + 1, sizeof(TCHAR)*(mir_tstrlen(p + 1) + 1)); - if (*p == '\0') - p++; - } - } - - SKINICONDESC sid = { 0 }; - sid.flags = SIDF_TCHAR; - sid.section.t = sectionName; - sid.pszName = iconame; - sid.description.t = descr; - sid.hDefaultIcon = hIcon; - pmi->hIcolibItem = IcoLib_AddNewIcon(0, &sid); - - Safe_DestroyIcon(hIcon); - if (hIcon = Skin_GetIcon(iconame)) { - ImageList_ReplaceIcon(pmi->parent->m_hMenuIcons, pmi->iconId, hIcon); - IcoLib_ReleaseIcon(hIcon, 0); - } - } - - mir_free(uname); - return FALSE; -} - -int RegisterAllIconsInIconLib() -{ - // register all icons - for (int mo = 0; mo < g_menus.getCount(); mo++) { - if ((int)hStatusMenuObject == g_menus[mo]->id) //skip status menu - continue; - - MO_RecursiveWalkMenu(g_menus[mo]->m_items.first, MO_RegisterIcon, 0); - } - - return 0; -} - -int TryProcessDoubleClick(MCONTACT hContact) -{ - int iMenuID = GetMenuObjbyId((int)hContactMenuObject); - if (iMenuID != -1) { - NotifyEventHooks(hPreBuildContactMenuEvent, hContact, 0); - - PMO_IntMenuItem pimi = (PMO_IntMenuItem)MO_GetDefaultMenuItem((WPARAM)g_menus[iMenuID]->m_items.first, 0); - if (pimi != NULL) { - MO_ProcessCommand(pimi, hContact); - return 0; - } - } - - return 1; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Static services - -int posttimerid; - -static VOID CALLBACK PostRegisterIcons(HWND, UINT, UINT_PTR, DWORD) -{ - KillTimer(0, posttimerid); - RegisterAllIconsInIconLib(); -} - -static int OnModulesLoaded(WPARAM, LPARAM) -{ - posttimerid = SetTimer((HWND)NULL, 0, 5, (TIMERPROC)PostRegisterIcons); - HookEvent(ME_SKIN2_ICONSCHANGED, OnIconLibChanges); - return 0; -} - -static INT_PTR SRVMO_SetOptionsMenuObject(WPARAM, LPARAM lParam) -{ - lpOptParam lpop = (lpOptParam)lParam; - if (lpop == NULL) - return 0; - - return MO_SetOptionsMenuObject(lpop->Handle, lpop->Setting, lpop->Value); -} - -static INT_PTR SRVMO_SetOptionsMenuItem(WPARAM, LPARAM lParam) -{ - lpOptParam lpop = (lpOptParam)lParam; - if (lpop == NULL) - return 0; - - return MO_SetOptionsMenuItem((PMO_IntMenuItem)lpop->Handle, lpop->Setting, lpop->Value); -} - -int InitGenMenu() -{ - CreateServiceFunction(MO_BUILDMENU, MO_BuildMenu); - - CreateServiceFunction(MO_PROCESSCOMMAND, (MIRANDASERVICE)MO_ProcessCommand); - CreateServiceFunction("MO/CreateNewMenuObject", MO_CreateNewMenuObject); - CreateServiceFunction(MO_REMOVEMENUITEM, MO_RemoveMenuItem); - CreateServiceFunction(MO_ADDNEWMENUITEM, (MIRANDASERVICE)MO_AddNewMenuItem); - CreateServiceFunction(MO_MENUITEMGETOWNERDATA, MO_MenuItemGetOwnerData); - CreateServiceFunction(MO_MODIFYMENUITEM, (MIRANDASERVICE)MO_ModifyMenuItem); - CreateServiceFunction(MO_GETMENUITEM, MO_GetMenuItem); - CreateServiceFunction(MO_GETDEFAULTMENUITEM, MO_GetDefaultMenuItem); - CreateServiceFunction(MO_PROCESSCOMMANDBYMENUIDENT, MO_ProcessCommandByMenuIdent); - CreateServiceFunction(MO_PROCESSHOTKEYS, (MIRANDASERVICE)MO_ProcessHotKeys); - CreateServiceFunction(MO_REMOVEMENUOBJECT, MO_RemoveMenuObject); - CreateServiceFunction(MO_GETPROTOROOTMENU, MO_GetProtoRootMenu); - - CreateServiceFunction(MO_SRV_SETOPTIONSMENUOBJECT, SRVMO_SetOptionsMenuObject); - CreateServiceFunction(MO_SETOPTIONSMENUITEM, SRVMO_SetOptionsMenuItem); - - bIconsDisabled = db_get_b(NULL, "CList", "DisableMenuIcons", 0) != 0; - - bIsGenMenuInited = true; - - HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); - HookEvent(ME_OPT_INITIALISE, GenMenuOptInit); - return 0; -} - -int UnitGenMenu() -{ - if (bIsGenMenuInited) { - mir_cslock lck(csMenuHook); - MO_RemoveAllObjects(); - bIsGenMenuInited = false; - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -TIntMenuObject::TIntMenuObject() -{ -} - -TIntMenuObject::~TIntMenuObject() -{ - MO_RecursiveWalkMenu(m_items.first, FreeMenuItem, NULL); - - FreeAndNil((void**)&FreeService); - FreeAndNil((void**)&onAddService); - FreeAndNil((void**)&CheckService); - FreeAndNil((void**)&ExecService); - FreeAndNil((void**)&ptszDisplayName); - FreeAndNil((void**)&pszName); - - ImageList_Destroy(m_hMenuIcons); -} - -void TIntMenuObject::freeItem(TMO_IntMenuItem *p) -{ - if (FreeService) - CallService(FreeService, (WPARAM)p, (LPARAM)p->mi.ownerdata); - - p->signature = 0; - FreeAndNil((void**)&p->mi.pszName); - FreeAndNil((void**)&p->UniqName); - FreeAndNil((void**)&p->CustomName); - if (p->hBmp) DeleteObject(p->hBmp); - mir_free(p); -} diff --git a/src/modules/clist/genmenu.h b/src/modules/clist/genmenu.h deleted file mode 100644 index 198d5417bc..0000000000 --- a/src/modules/clist/genmenu.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 GENMENU_H -#define GENMENU_H -//general menu object module -#include "m_genmenu.h" - -/* genmenu structs */ - -#define MENUITEM_SIGNATURE 0xDEADBEEF - -typedef struct -{ - struct _tagIntMenuItem *first, // first element of submenu, or NULL - *last; // last element of submenu, or NULL -} - TMO_LinkedList; - -typedef struct _tagIntMenuItem -{ - DWORD signature; - int iCommand; - int iconId; // icon index in the section's image list - TMO_MenuItem mi; // user-defined data - BOOL OverrideShow; - char* UniqName; // unique name - TCHAR* CustomName; - HANDLE hIcolibItem; // handle of iconlib item - HBITMAP hBmp; - int originalPosition; - int hLangpack; - - struct _tagIntMenuItem *next; // next item in list - struct TIntMenuObject *parent; - TMO_LinkedList *owner; - TMO_LinkedList submenu; -} - TMO_IntMenuItem, *PMO_IntMenuItem; - -struct TIntMenuObject : public MZeroedObject -{ - TIntMenuObject(); - ~TIntMenuObject(); - - char *pszName; - TCHAR *ptszDisplayName; - int id; - - //ExecService - //LPARAM lParam;//owner data - //WPARAM wParam;//allways lparam from winproc - LPCSTR ExecService; - - //CheckService called when building menu - //return false to skip item. - //LPARAM lParam;//0 - //WPARAM wParam;//CheckParam - LPCSTR CheckService;//analog to check_proc - - //LPARAM lParam;//ownerdata - //WPARAM wParam;//menuitemhandle - LPCSTR FreeService;//callback service used to free ownerdata for menuitems - - //LPARAM lParam;//MENUITEMINFO filled with all needed data - //WPARAM wParam;//menuitemhandle - LPCSTR onAddService;//called just before add MENUITEMINFO to hMenu - - TMO_LinkedList m_items; - HIMAGELIST m_hMenuIcons; - BOOL m_bUseUserDefinedItems; - - void freeItem(TMO_IntMenuItem*); -}; - -extern LIST g_menus; - -#define SEPARATORPOSITIONINTERVAL 100000 - -//internal usage -HMENU BuildRecursiveMenu(HMENU hMenu, PMO_IntMenuItem, ListParam *param); -void GetMenuItemName(PMO_IntMenuItem pMenuItem, char* pszDest, size_t cbDestSize); - -PMO_IntMenuItem MO_GetIntMenuItem(HGENMENU); - -PMO_IntMenuItem MO_AddNewMenuItem(HANDLE menuobjecthandle, PMO_MenuItem pmi); -PMO_IntMenuItem MO_AddOldNewMenuItem(HANDLE menuobjecthandle, PMO_MenuItem pmi); - -int MO_DrawMenuItem(LPDRAWITEMSTRUCT dis); -int MO_MeasureMenuItem(LPMEASUREITEMSTRUCT mis); -int MO_ModifyMenuItem(PMO_IntMenuItem menuHandle, PMO_MenuItem pmiparam); -int MO_ProcessCommand(PMO_IntMenuItem pimi, LPARAM lParam); -INT_PTR MO_ProcessHotKeys(HANDLE menuHandle, INT_PTR vKey); -int MO_SetOptionsMenuItem(PMO_IntMenuItem menuobjecthandle, int setting, INT_PTR value); -int MO_SetOptionsMenuObject(HANDLE menuobjecthandle, int setting, INT_PTR value); - -INT_PTR MO_ProcessCommandByMenuIdent(WPARAM wParam, LPARAM lParam); -int MO_ProcessCommandBySubMenuIdent(int menuID, int command, LPARAM lParam); - -// function returns TRUE if the walk should be immediately stopped -typedef int (*pfnWalkFunc)(PMO_IntMenuItem, void*); - -// returns the item, on which pfnWalkFunc returned TRUE -PMO_IntMenuItem MO_RecursiveWalkMenu(PMO_IntMenuItem, pfnWalkFunc, void*); - -//general stuff -int InitGenMenu(); -int UnitGenMenu(); - -int FindRoot(PMO_IntMenuItem pimi, void* param); - -TMO_IntMenuItem * GetMenuItemByGlobalID(int globalMenuID); -BOOL FindMenuHanleByGlobalID(HMENU hMenu, int globalID, struct _MenuItemHandles * dat); //GenMenu.c - -LPTSTR GetMenuItemText(PMO_IntMenuItem); - -int GenMenuOptInit(WPARAM wParam, LPARAM); -int GetMenuObjbyId(const int id); -int GetMenuItembyId(const int objpos, const int id); - -int ProtocolOrderOptInit(WPARAM wParam, LPARAM); - -INT_PTR MO_GetMenuItem(WPARAM wParam, LPARAM lParam); -void FreeAndNil(void **p); -#endif diff --git a/src/modules/clist/genmenuopt.cpp b/src/modules/clist/genmenuopt.cpp deleted file mode 100644 index 3299a17818..0000000000 --- a/src/modules/clist/genmenuopt.cpp +++ /dev/null @@ -1,481 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "genmenu.h" - -#define STR_SEPARATOR _T("-----------------------------------") - -extern bool bIconsDisabled; -extern int DefaultImageListColorDepth; -void RebuildProtoMenus(int); - -///////////////////////////////////////////////////////////////////////////////////////// - -struct MenuItemOptData : public MZeroedObject -{ - ~MenuItemOptData() {} - - int pos; - - ptrT name; - ptrT defname; - ptrA uniqname; - - bool bShow; - int id; - - PMO_IntMenuItem pimi; -}; - -static int SortMenuItems(const MenuItemOptData *p1, const MenuItemOptData *p2) -{ - if (p1->pos < p2->pos) return -1; - if (p1->pos > p2->pos) return 1; - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -class CGenMenuOptionsPage : public CDlgBase -{ - int iInitMenuValue; - bool bRebuild; - - void SaveTree() - { - int MenuObjectId; - if (!GetCurrentMenuObjectID(MenuObjectId)) - return; - - TCHAR idstr[100]; - - TVITEMEX tvi; - tvi.hItem = m_menuItems.GetRoot(); - tvi.cchTextMax = SIZEOF(idstr); - tvi.mask = TVIF_TEXT | TVIF_PARAM | TVIF_HANDLE | TVIF_IMAGE; - tvi.pszText = idstr; - - int count = 0; - int menupos = GetMenuObjbyId(MenuObjectId); - if (menupos == -1) - return; - - TIntMenuObject *pimo = g_menus[menupos]; - - char MenuNameItems[256]; - mir_snprintf(MenuNameItems, SIZEOF(MenuNameItems), "%s_Items", pimo->pszName); - int runtimepos = 100; - - while (tvi.hItem != NULL) { - m_menuItems.GetItem(&tvi); - MenuItemOptData *iod = (MenuItemOptData*)tvi.lParam; - if (iod->pimi) { - char menuItemName[256], DBString[300]; - GetMenuItemName(iod->pimi, menuItemName, sizeof(menuItemName)); - - mir_snprintf(DBString, SIZEOF(DBString), "%s_visible", menuItemName); - db_set_b(NULL, MenuNameItems, DBString, tvi.iImage != 0); - - mir_snprintf(DBString, SIZEOF(DBString), "%s_pos", menuItemName); - db_set_dw(NULL, MenuNameItems, DBString, runtimepos); - - mir_snprintf(DBString, SIZEOF(DBString), "%s_name", menuItemName); - if (iod->name != NULL && iod->defname != NULL && - mir_tstrcmp(iod->name, iod->defname) != 0) - db_set_ts(NULL, MenuNameItems, DBString, iod->name); - else - db_unset(NULL, MenuNameItems, DBString); - - runtimepos += 100; - } - - if (iod->name && !mir_tstrcmp(iod->name, STR_SEPARATOR) && tvi.iImage) - runtimepos += SEPARATORPOSITIONINTERVAL; - - tvi.hItem = m_menuItems.GetNextSibling(tvi.hItem); - count++; - } - } - - void FreeTreeData() - { - HTREEITEM hItem = m_menuItems.GetRoot(); - while (hItem != NULL) { - TVITEMEX tvi; - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - tvi.hItem = hItem; - m_menuItems.GetItem(&tvi); - delete (MenuItemOptData *)tvi.lParam; - - tvi.lParam = 0; - m_menuItems.SetItem(&tvi); - - hItem = m_menuItems.GetNextSibling(hItem); - } - } - - void RebuildCurrent() - { - int MenuObjectID; - if (GetCurrentMenuObjectID(MenuObjectID)) - BuildTree(MenuObjectID, true); - } - - bool BuildTree(int MenuObjectId, bool bReread) - { - FreeTreeData(); - - int menupos = GetMenuObjbyId(MenuObjectId); - if (menupos == -1) - return false; - - TIntMenuObject* pimo = g_menus[menupos]; - if (pimo->m_items.first == NULL) - return false; - - char menuItemName[256], MenuNameItems[256]; - mir_snprintf(MenuNameItems, SIZEOF(MenuNameItems), "%s_Items", pimo->pszName); - - LIST arItems(10, SortMenuItems); - - for (PMO_IntMenuItem p = pimo->m_items.first; p != NULL; p = p->next) { - if (p->mi.root != (HGENMENU)-1 && p->mi.root != NULL) - continue; - - MenuItemOptData *PD = new MenuItemOptData(); - GetMenuItemName(p, menuItemName, sizeof(menuItemName)); - - char buf[256]; - mir_snprintf(buf, "%s_name", menuItemName); - ptrT tszName(db_get_tsa(NULL, MenuNameItems, buf)); - if (tszName != 0) - PD->name = tszName.detach(); - else - PD->name = mir_tstrdup(GetMenuItemText(p)); - - PD->pimi = p; - PD->defname = mir_tstrdup(GetMenuItemText(p)); - - mir_snprintf(buf, "%s_visible", menuItemName); - PD->bShow = db_get_b(NULL, MenuNameItems, buf, 1) != 0; - - if (bReread) { - mir_snprintf(buf, "%s_pos", menuItemName); - PD->pos = db_get_dw(NULL, MenuNameItems, buf, 1); - } - else PD->pos = (PD->pimi) ? PD->pimi->originalPosition : 0; - - PD->id = p->iCommand; - - if (p->UniqName) - PD->uniqname = mir_strdup(p->UniqName); - - arItems.insert(PD); - } - - bRebuild = true; - m_menuItems.SendMsg(WM_SETREDRAW, FALSE, 0); - m_menuItems.DeleteAllItems(); - - int lastpos = 0; - bool bIsFirst = TRUE; - - TVINSERTSTRUCT tvis; - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - - for (int i = 0; i < arItems.getCount(); i++) { - MenuItemOptData *PD = arItems[i]; - if (PD->pos - lastpos >= SEPARATORPOSITIONINTERVAL) { - MenuItemOptData *sep = new MenuItemOptData(); - sep->id = -1; - sep->name = mir_tstrdup(STR_SEPARATOR); - sep->pos = PD->pos - 1; - - tvis.item.lParam = (LPARAM)sep; - tvis.item.pszText = sep->name; - tvis.item.iImage = tvis.item.iSelectedImage = 1; - m_menuItems.InsertItem(&tvis); - } - - tvis.item.lParam = (LPARAM)PD; - tvis.item.pszText = PD->name; - tvis.item.iImage = tvis.item.iSelectedImage = PD->bShow; - - HTREEITEM hti = m_menuItems.InsertItem(&tvis); - if (bIsFirst) { - m_menuItems.SelectItem(hti); - bIsFirst = false; - } - - lastpos = PD->pos; - } - - m_menuItems.SendMsg(WM_SETREDRAW, TRUE, 0); - bRebuild = false; - - ShowWindow(m_warning.GetHwnd(), (pimo->m_bUseUserDefinedItems) ? SW_HIDE : SW_SHOW); - m_menuItems.Enable(pimo->m_bUseUserDefinedItems); - m_btnInsert.Enable(pimo->m_bUseUserDefinedItems); - return 1; - } - - bool GetCurrentMenuObjectID(int &result) - { - int iItem = m_menuObjects.GetCurSel(); - if (iItem == -1) - return false; - - result = (int)m_menuObjects.GetItemData(iItem); - return true; - } - - CCtrlListBox m_menuObjects; - CCtrlTreeView m_menuItems; - CCtrlCheck m_radio1, m_radio2, m_enableIcons; - CCtrlEdit m_customName, m_service; - CCtrlButton m_btnInsert, m_btnReset, m_btnSet, m_btnDefault; - CCtrlBase m_warning; - -public: - CGenMenuOptionsPage() : - CDlgBase(hInst, IDD_OPT_GENMENU), - m_menuItems(this, IDC_MENUITEMS), - m_menuObjects(this, IDC_MENUOBJECTS), - m_radio1(this, IDC_RADIO1), - m_radio2(this, IDC_RADIO2), - m_enableIcons(this, IDC_DISABLEMENUICONS), - m_btnInsert(this, IDC_INSERTSEPARATOR), - m_btnReset(this, IDC_RESETMENU), - m_btnSet(this, IDC_GENMENU_SET), - m_btnDefault(this, IDC_GENMENU_DEFAULT), - m_customName(this, IDC_GENMENU_CUSTOMNAME), - m_service(this, IDC_GENMENU_SERVICE), - m_warning(this, IDC_NOTSUPPORTWARNING), - bRebuild(false) - { - m_btnSet.OnClick = Callback(this, &CGenMenuOptionsPage::btnSet_Clicked); - m_btnReset.OnClick = Callback(this, &CGenMenuOptionsPage::btnReset_Clicked); - m_btnInsert.OnClick = Callback(this, &CGenMenuOptionsPage::btnInsert_Clicked); - m_btnDefault.OnClick = Callback(this, &CGenMenuOptionsPage::btnDefault_Clicked); - - m_menuObjects.OnSelChange = Callback(this, &CGenMenuOptionsPage::onMenuObjectChanged); - - m_menuItems.SetFlags(MTREE_CHECKBOX | MTREE_DND | MTREE_MULTISELECT); - m_menuItems.OnSelChanged = Callback(this, &CGenMenuOptionsPage::onMenuItemChanged); - - m_customName.SetSilent(); - m_service.SetSilent(); - } - - //---- init dialog ------------------------------------------- - virtual void OnInitDialog() - { - iInitMenuValue = db_get_b(NULL, "CList", "MoveProtoMenus", TRUE); - - HIMAGELIST himlCheckBoxes = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 2, 2); - ImageList_AddIcon_IconLibLoaded(himlCheckBoxes, SKINICON_OTHER_NOTICK); - ImageList_AddIcon_IconLibLoaded(himlCheckBoxes, SKINICON_OTHER_TICK); - m_menuItems.SetImageList(himlCheckBoxes, TVSIL_NORMAL); - - if (iInitMenuValue) - m_radio2.SetState(true); - else - m_radio1.SetState(true); - - m_enableIcons.SetState(!bIconsDisabled); - - //---- init menu object list -------------------------------------- - for (int i = 0; i < g_menus.getCount(); i++) { - TIntMenuObject *p = g_menus[i]; - if (p->id != (int)hStatusMenuObject && p->m_bUseUserDefinedItems) - m_menuObjects.AddString(TranslateTS(p->ptszDisplayName), p->id); - } - - m_menuObjects.SetCurSel(0); - RebuildCurrent(); - } - - virtual void OnApply() - { - bIconsDisabled = m_enableIcons.GetState() == 0; - db_set_b(NULL, "CList", "DisableMenuIcons", bIconsDisabled); - SaveTree(); - - int iNewMenuValue = !m_radio1.GetState(); - if (iNewMenuValue != iInitMenuValue) { - db_set_b(NULL, "CList", "MoveProtoMenus", iNewMenuValue); - - RebuildProtoMenus(iNewMenuValue); - iInitMenuValue = iNewMenuValue; - } - RebuildCurrent(); - } - - virtual void OnDestroy() - { - ImageList_Destroy(m_menuItems.GetImageList(TVSIL_NORMAL)); - FreeTreeData(); - } - - void btnInsert_Clicked(CCtrlButton*) - { - HTREEITEM hti = m_menuItems.GetSelection(); - if (hti == NULL) - return; - - TVITEMEX tvi = { 0 }; - tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT; - tvi.hItem = hti; - if (!m_menuItems.GetItem(&tvi)) - return; - - MenuItemOptData *PD = new MenuItemOptData(); - PD->id = -1; - PD->name = mir_tstrdup(STR_SEPARATOR); - PD->pos = ((MenuItemOptData *)tvi.lParam)->pos - 1; - - TVINSERTSTRUCT tvis = { 0 }; - tvis.item.lParam = (LPARAM)PD; - tvis.item.pszText = PD->name; - tvis.item.iImage = tvis.item.iSelectedImage = 1; - tvis.hInsertAfter = hti; - tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - m_menuItems.InsertItem(&tvis); - - NotifyChange(); - } - - void btnReset_Clicked(CCtrlButton*) - { - int MenuObjectID; - if (GetCurrentMenuObjectID(MenuObjectID)) { - BuildTree(MenuObjectID, false); - NotifyChange(); - } - } - - void btnDefault_Clicked(CCtrlButton*) - { - HTREEITEM hti = m_menuItems.GetSelection(); - if (hti == NULL) - return; - - TVITEMEX tvi; - tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; - tvi.hItem = hti; - m_menuItems.GetItem(&tvi); - - MenuItemOptData *iod = (MenuItemOptData *)tvi.lParam; - if (iod->name && _tcsstr(iod->name, STR_SEPARATOR)) - return; - - iod->name = mir_tstrdup(iod->defname); - - SaveTree(); - RebuildCurrent(); - NotifyChange(); - } - - void btnSet_Clicked(CCtrlButton*) - { - HTREEITEM hti = m_menuItems.GetSelection(); - if (hti == NULL) - return; - - TVITEMEX tvi; - tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; - tvi.hItem = hti; - m_menuItems.GetItem(&tvi); - - MenuItemOptData *iod = (MenuItemOptData *)tvi.lParam; - if (iod->name && _tcsstr(iod->name, STR_SEPARATOR)) - return; - - iod->name = m_customName.GetText(); - - SaveTree(); - RebuildCurrent(); - NotifyChange(); - } - - void onMenuObjectChanged(void*) - { - m_initialized = false; - RebuildCurrent(); - m_initialized = true; - } - - void onMenuItemChanged(void*) - { - if (bRebuild) - return; - - m_customName.SetTextA(""); - m_service.SetTextA(""); - - m_btnDefault.Enable(false); - m_btnSet.Enable(false); - m_customName.Enable(false); - - HTREEITEM hti = m_menuItems.GetSelection(); - if (hti == NULL) - return; - - TVITEMEX tvi; - tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; - tvi.hItem = hti; - m_menuItems.GetItem(&tvi); - if (tvi.lParam == 0) - return; - - MenuItemOptData *iod = (MenuItemOptData *)tvi.lParam; - if (iod->name && _tcsstr(iod->name, STR_SEPARATOR)) - return; - - m_customName.SetText(iod->name); - - if (iod->pimi->submenu.first == NULL && iod->uniqname) - m_service.SetTextA(iod->uniqname); - - m_btnDefault.Enable(mir_tstrcmp(iod->name, iod->defname) != 0); - m_btnSet.Enable(true); - m_customName.Enable(true); - } -}; - -int GenMenuOptInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.position = -1000000000; - odp.pszTitle = LPGEN("Menus"); - odp.pszGroup = LPGEN("Customize"); - odp.flags = ODPF_BOLDGROUPS; - odp.pDialog = new CGenMenuOptionsPage(); - Options_AddPage(wParam, &odp); - - return ProtocolOrderOptInit(wParam, 0); -} diff --git a/src/modules/clist/groups.cpp b/src/modules/clist/groups.cpp deleted file mode 100644 index 53dfd6a659..0000000000 --- a/src/modules/clist/groups.cpp +++ /dev/null @@ -1,587 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -HANDLE hGroupChangeEvent; - -static INT_PTR RenameGroup(WPARAM wParam, LPARAM lParam); -static INT_PTR MoveGroupBefore(WPARAM wParam, LPARAM lParam); - -static int CountGroups(void) -{ - for (int i=0;; i++) { - char str[33]; - _itoa(i, str, 10); - ptrT grpName( db_get_tsa(NULL, "CListGroups", str)); - if (grpName == NULL) - return i; - } -} - -static int GroupNameExists(const TCHAR *name, int skipGroup) -{ - for (int i=0;; i++) { - if (i == skipGroup) - continue; - - char idstr[33]; - _itoa(i, idstr, 10); - ptrT grpName( db_get_tsa(NULL, "CListGroups", idstr)); - if (grpName == NULL) - break; - - if (!mir_tstrcmp((TCHAR*)grpName+1, name)) - return i+1; - } - return 0; -} - -static INT_PTR GroupExists(WPARAM, LPARAM lParam) -{ - if (lParam == 0) - return FALSE; - - return GroupNameExists((LPCTSTR)lParam, -1); -} - -static INT_PTR CreateGroupInternal(INT_PTR iParent, const TCHAR *ptszName) -{ - int newId = CountGroups(); - TCHAR newBaseName[127], newName[128]; - char str[33]; - int i; - - const TCHAR* grpName = ptszName ? ptszName : TranslateT("New group"); - if (iParent) { - _itoa(iParent - 1, str, 10); - DBVARIANT dbv; - if (db_get_ts(NULL, "CListGroups", str, &dbv)) - return 0; - - mir_sntprintf(newBaseName, SIZEOF(newBaseName), _T("%s\\%s"), dbv.ptszVal + 1, grpName); - mir_free(dbv.pszVal); - } - else mir_tstrncpy(newBaseName, grpName, SIZEOF(newBaseName)); - - _itoa(newId, str, 10); - mir_tstrncpy(newName + 1, newBaseName, SIZEOF(newName) - 1); - if (ptszName) { - i = GroupNameExists(newBaseName, -1); - if (i) newId = i - 1; - i = !i; - } - else { - i = 1; - while (GroupNameExists(newName + 1, -1)) - mir_sntprintf(newName + 1, SIZEOF(newName) - 1, _T("%s (%d)"), newBaseName, i++); - } - if (i) { - const CLISTGROUPCHANGE grpChg = { sizeof(CLISTGROUPCHANGE), NULL, newName }; - - newName[0] = 1 | GROUPF_EXPANDED; //1 is required so we never get '\0' - db_set_ts(NULL, "CListGroups", str, newName); - CallService(MS_CLUI_GROUPADDED, newId + 1, 1); - - NotifyEventHooks(hGroupChangeEvent, 0, (LPARAM)&grpChg); - } - - return newId + 1; -} - -static INT_PTR CreateGroup(WPARAM wParam, LPARAM lParam) -{ - if (lParam == 0) - return CreateGroupInternal(wParam, NULL); - - LPCTSTR ptszName = (LPCTSTR)lParam; - if (ptszName == NULL || ptszName[0] == '\0' || ptszName[0] == '\\') - return 0; - - TCHAR *tszName = NEWTSTR_ALLOCA(ptszName); - for (TCHAR *p = tszName; *p; p++) { - if (*p == '\\') { - *p = '\0'; - CreateGroupInternal(wParam, tszName); - *p = '\\'; - } - } - return CreateGroupInternal(wParam, tszName); -} - -static INT_PTR GetGroupName2(WPARAM wParam, LPARAM lParam) -{ - char idstr[33]; - DBVARIANT dbv; - static char name[128]; - - _itoa(wParam - 1, idstr, 10); - if (db_get_s(NULL, "CListGroups", idstr, &dbv)) - return (INT_PTR) (char *) NULL; - mir_strncpy(name, dbv.pszVal + 1, SIZEOF(name)); - if ((DWORD *) lParam != NULL) - *(DWORD *) lParam = dbv.pszVal[0]; - db_free(&dbv); - return (INT_PTR) name; -} - -TCHAR* fnGetGroupName(int idx, DWORD* pdwFlags) -{ - char idstr[33]; - DBVARIANT dbv; - static TCHAR name[128]; - - _itoa(idx-1, idstr, 10); - if (db_get_ts(NULL, "CListGroups", idstr, &dbv)) - return NULL; - - mir_tstrncpy(name, dbv.ptszVal + 1, SIZEOF(name)); - if (pdwFlags != NULL) - *pdwFlags = dbv.ptszVal[0]; - db_free(&dbv); - return name; -} - -static INT_PTR GetGroupName(WPARAM wParam, LPARAM lParam) -{ - INT_PTR ret; - ret = GetGroupName2(wParam, lParam); - if ((int *) lParam) - *(int *) lParam = 0 != (*(int *) lParam & GROUPF_EXPANDED); - return ret; -} - -static INT_PTR DeleteGroup(WPARAM wParam, LPARAM) -{ - int i; - char str[33]; - DBVARIANT dbv; - MCONTACT hContact; - TCHAR name[256], szNewParent[256], *pszLastBackslash; - - //get the name - _itoa(wParam - 1, str, 10); - if (db_get_ts(NULL, "CListGroups", str, &dbv)) - return 1; - mir_tstrncpy(name, dbv.ptszVal + 1, SIZEOF(name)); - db_free(&dbv); - if (db_get_b(NULL, "CList", "ConfirmDelete", SETTING_CONFIRMDELETE_DEFAULT)) - { - TCHAR szQuestion[256+100]; - mir_sntprintf(szQuestion, SIZEOF(szQuestion), TranslateT("Are you sure you want to delete group '%s'? This operation cannot be undone."), name); - if (MessageBox(cli.hwndContactList, szQuestion, TranslateT("Delete group"), MB_YESNO|MB_ICONQUESTION) == IDNO) - return 1; - } - SetCursor(LoadCursor(NULL, IDC_WAIT)); - //must remove setting from all child contacts too - //children are demoted to the next group up, not deleted. - mir_tstrcpy(szNewParent, name); - pszLastBackslash = _tcsrchr(szNewParent, '\\'); - if (pszLastBackslash) - pszLastBackslash[0] = '\0'; - else - szNewParent[0] = '\0'; - - CLISTGROUPCHANGE grpChg = { sizeof(CLISTGROUPCHANGE), NULL, NULL }; - - for (hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - if (db_get_ts(hContact, "CList", "Group", &dbv)) - continue; - - if (mir_tstrcmp(dbv.ptszVal, name)) - { - db_free(&dbv); - continue; - } - db_free(&dbv); - - if (szNewParent[0]) - { - db_set_ts(hContact, "CList", "Group", szNewParent); - grpChg.pszNewName = szNewParent; - } - else - { - db_unset(hContact, "CList", "Group"); - grpChg.pszNewName = NULL; - } - NotifyEventHooks(hGroupChangeEvent, hContact, (LPARAM)&grpChg); - } - //shuffle list of groups up to fill gap - for (i = wParam - 1;; i++) { - _itoa(i + 1, str, 10); - if (db_get_utf(NULL, "CListGroups", str, &dbv)) - break; - _itoa(i, str, 10); - db_set_utf(NULL, "CListGroups", str, dbv.pszVal); - db_free(&dbv); - } - _itoa(i, str, 10); - db_unset(NULL, "CListGroups", str); - //rename subgroups - { - TCHAR szNewName[256]; - size_t len = mir_tstrlen(name); - for (i=0;; i++) { - _itoa(i, str, 10); - if (db_get_ts(NULL, "CListGroups", str, &dbv)) - break; - if (!_tcsncmp(dbv.ptszVal + 1, name, len) && dbv.pszVal[len + 1] == '\\' && _tcschr(dbv.ptszVal + len + 2, '\\') == NULL) { - if (szNewParent[0]) - mir_sntprintf(szNewName, SIZEOF(szNewName), _T("%s\\%s"), szNewParent, dbv.ptszVal + len + 2); - else - mir_tstrncpy(szNewName, dbv.ptszVal + len + 2, SIZEOF(szNewName)); - cli.pfnRenameGroup(i + 1, szNewName); - } - db_free(&dbv); - } - } - SetCursor(LoadCursor(NULL, IDC_ARROW)); - cli.pfnLoadContactTree(); - - { - const CLISTGROUPCHANGE grpChg = { sizeof(CLISTGROUPCHANGE), name, NULL }; - NotifyEventHooks(hGroupChangeEvent, 0, (LPARAM)&grpChg); - } - return 0; -} - -static int RenameGroupWithMove(int groupId, const TCHAR *szName, int move) -{ - char idstr[33]; - TCHAR str[256], oldName[256]; - DBVARIANT dbv; - - if (GroupNameExists(szName, groupId)) { - MessageBox(NULL, TranslateT("You already have a group with that name. Please enter a unique name for the group."), TranslateT("Rename group"), MB_ICONERROR | MB_OK); - return 1; - } - - //do the change - _itoa(groupId, idstr, 10); - if (db_get_ts(NULL, "CListGroups", idstr, &dbv)) - return 1; - str[0] = dbv.pszVal[0] & 0x7F; - mir_tstrncpy(oldName, dbv.ptszVal + 1, SIZEOF(oldName)); - db_free(&dbv); - mir_tstrncpy(str + 1, szName, SIZEOF(str) - 1); - db_set_ts(NULL, "CListGroups", idstr, str); - - //must rename setting in all child contacts too - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - ClcCacheEntry *cache = cli.pfnGetCacheEntry(hContact); - if (!mir_tstrcmp(cache->tszGroup, oldName)) { - db_set_ts(hContact, "CList", "Group", szName); - mir_free(cache->tszGroup); - cache->tszGroup = 0; - cli.pfnCheckCacheItem(cache); - } - } - - //rename subgroups - { - TCHAR szNewName[256]; - size_t len = mir_tstrlen(oldName); - for (int i=0;; i++) { - if (i == groupId) - continue; - _itoa(i, idstr, 10); - if (db_get_ts(NULL, "CListGroups", idstr, &dbv)) - break; - if (!_tcsncmp(dbv.ptszVal + 1, oldName, len) && dbv.ptszVal[len + 1] == '\\' && _tcschr(dbv.ptszVal + len + 2, '\\') == NULL) { - mir_sntprintf(szNewName, SIZEOF(szNewName), _T("%s\\%s"), szName, dbv.ptszVal + len + 2); - RenameGroupWithMove(i, szNewName, 0); //luckily, child groups will never need reordering - } - db_free(&dbv); - } - } - - //finally must make sure it's after any parent items - if (move) { - TCHAR *pszLastBackslash; - int i; - - mir_tstrncpy(str, szName, SIZEOF(str)); - pszLastBackslash = _tcsrchr(str, '\\'); - if (pszLastBackslash != NULL) { - *pszLastBackslash = '\0'; - for (i=0;; i++) { - _itoa(i, idstr, 10); - if (db_get_ts(NULL, "CListGroups", idstr, &dbv)) - break; - if (!mir_tstrcmp(dbv.ptszVal + 1, str)) { - if (i < groupId) - break; //is OK - MoveGroupBefore(groupId + 1, i + 2); - break; - } - db_free(&dbv); - } - } - } - { - const CLISTGROUPCHANGE grpChg = { sizeof(CLISTGROUPCHANGE), oldName, (TCHAR*)szName }; - NotifyEventHooks(hGroupChangeEvent, 0, (LPARAM)&grpChg); - } - return 0; -} - -int fnRenameGroup(int groupID, TCHAR* newName) -{ - return -1 != RenameGroupWithMove(groupID-1, newName, 1); -} - -static INT_PTR RenameGroup(WPARAM wParam, LPARAM lParam) -{ - WCHAR* temp = mir_a2u((char*)lParam); - int result = (-1 != RenameGroupWithMove(wParam - 1, temp, 1)); - mir_free(temp); - return result; -} - -static INT_PTR SetGroupExpandedState(WPARAM wParam, LPARAM lParam) -{ - char idstr[33]; - DBVARIANT dbv; - - _itoa(wParam - 1, idstr, 10); - if (db_get_utf(NULL, "CListGroups", idstr, &dbv)) - return 1; - if (lParam) - dbv.pszVal[0] |= GROUPF_EXPANDED; - else - dbv.pszVal[0] = dbv.pszVal[0] & ~GROUPF_EXPANDED; - db_set_utf(NULL, "CListGroups", idstr, dbv.pszVal); - db_free(&dbv); - return 0; -} - -static INT_PTR SetGroupFlags(WPARAM wParam, LPARAM lParam) -{ - char idstr[33]; - DBVARIANT dbv; - int flags, oldval, newval; - - _itoa(wParam - 1, idstr, 10); - if (db_get_utf(NULL, "CListGroups", idstr, &dbv)) - return 1; - flags = LOWORD(lParam) & HIWORD(lParam); - oldval = dbv.pszVal[0]; - newval = dbv.pszVal[0] = ((oldval & ~HIWORD(lParam)) | flags) & 0x7f; - db_set_utf(NULL, "CListGroups", idstr, dbv.pszVal); - db_free(&dbv); - if ((oldval & GROUPF_HIDEOFFLINE) != (newval & GROUPF_HIDEOFFLINE)) - cli.pfnLoadContactTree(); - return 0; -} - -static INT_PTR MoveGroupBefore(WPARAM wParam, LPARAM lParam) -{ - int i, shuffleFrom, shuffleTo, shuffleDir; - char str[33]; - TCHAR *szMoveName; - DBVARIANT dbv; - - if (wParam == 0 || (LPARAM) wParam == lParam) - return 0; - _itoa(wParam - 1, str, 10); - if (db_get_ts(NULL, "CListGroups", str, &dbv)) - return 0; - szMoveName = dbv.ptszVal; - //shuffle list of groups up to fill gap - if (lParam == 0) { - shuffleFrom = wParam - 1; - shuffleTo = -1; - shuffleDir = -1; - } - else { - if ((LPARAM) wParam < lParam) { - shuffleFrom = wParam - 1; - shuffleTo = lParam - 2; - shuffleDir = -1; - } - else { - shuffleFrom = wParam - 1; - shuffleTo = lParam - 1; - shuffleDir = 1; - } - } - if (shuffleDir == -1) { - for (i = shuffleFrom; i != shuffleTo; i++) { - _itoa(i + 1, str, 10); - if (db_get_utf(NULL, "CListGroups", str, &dbv)) { - shuffleTo = i; - break; - } - _itoa(i, str, 10); - db_set_utf(NULL, "CListGroups", str, dbv.pszVal); - db_free(&dbv); - } - } - else { - for (i = shuffleFrom; i != shuffleTo; i--) { - _itoa(i - 1, str, 10); - if (db_get_utf(NULL, "CListGroups", str, &dbv)) { - mir_free(szMoveName); - return 1; - } //never happens - _itoa(i, str, 10); - db_set_utf(NULL, "CListGroups", str, dbv.pszVal); - db_free(&dbv); - } - } - _itoa(shuffleTo, str, 10); - db_set_ts(NULL, "CListGroups", str, szMoveName); - mir_free(szMoveName); - return shuffleTo + 1; -} - -static INT_PTR BuildGroupMenu(WPARAM, LPARAM) -{ - char idstr[33]; - DBVARIANT dbv; - int groupId; - HMENU hRootMenu, hThisMenu; - int nextMenuId = 100; - TCHAR *pBackslash, *pNextField, szThisField[128], szThisMenuItem[128]; - int menuId, compareResult, menuItemCount; - - if (db_get_utf(NULL, "CListGroups", "0", &dbv)) - return (INT_PTR) (HMENU) NULL; - db_free(&dbv); - hRootMenu = CreateMenu(); - for (groupId = 0;; groupId++) { - _itoa(groupId, idstr, 10); - if (db_get_ts(NULL, "CListGroups", idstr, &dbv)) - break; - - pNextField = dbv.ptszVal + 1; - hThisMenu = hRootMenu; - - MENUITEMINFO mii = { sizeof(mii) }; - do { - pBackslash = _tcschr(pNextField, '\\'); - if (pBackslash == NULL) { - mir_tstrncpy(szThisField, pNextField, SIZEOF(szThisField)); - pNextField = NULL; - } - else { - mir_tstrncpy(szThisField, pNextField, min(SIZEOF(szThisField), pBackslash - pNextField + 1)); - pNextField = pBackslash + 1; - } - compareResult = 1; - menuItemCount = GetMenuItemCount(hThisMenu); - for (menuId = 0; menuId < menuItemCount; menuId++) { - mii.fMask = MIIM_TYPE | MIIM_SUBMENU | MIIM_DATA; - mii.cch = SIZEOF(szThisMenuItem); - mii.dwTypeData = szThisMenuItem; - GetMenuItemInfo(hThisMenu, menuId, TRUE, &mii); - compareResult = mir_tstrcmp(szThisField, szThisMenuItem); - if (compareResult == 0) { - if (pNextField == NULL) { - mii.fMask = MIIM_DATA; - mii.dwItemData = groupId + 1; - SetMenuItemInfo(hThisMenu, menuId, TRUE, &mii); - } - else { - if (mii.hSubMenu == NULL) { - mii.fMask = MIIM_SUBMENU; - mii.hSubMenu = CreateMenu(); - SetMenuItemInfo(hThisMenu, menuId, TRUE, &mii); - mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_ID; - //dwItemData doesn't change - mii.fType = MFT_STRING; - mii.dwTypeData = TranslateT("This group"); - mii.wID = nextMenuId++; - InsertMenuItem(mii.hSubMenu, 0, TRUE, &mii); - mii.fMask = MIIM_TYPE; - mii.fType = MFT_SEPARATOR; - InsertMenuItem(mii.hSubMenu, 1, TRUE, &mii); - } - hThisMenu = mii.hSubMenu; - } - break; - } - if ((int)mii.dwItemData - 1 > groupId) - break; - } - if (compareResult) { - mii.fMask = MIIM_TYPE | MIIM_ID; - mii.wID = nextMenuId++; - mii.dwTypeData = szThisField; - mii.fType = MFT_STRING; - if (pNextField) { - mii.fMask |= MIIM_SUBMENU; - mii.hSubMenu = CreateMenu(); - } - else { - mii.fMask |= MIIM_DATA; - mii.dwItemData = groupId + 1; - } - InsertMenuItem(hThisMenu, menuId, TRUE, &mii); - if (pNextField) { - hThisMenu = mii.hSubMenu; - } - } - } while (pNextField); - - db_free(&dbv); - } - return (INT_PTR) hRootMenu; -} - -int InitGroupServices(void) -{ - for (int i=0;; i++) - { - char str[32]; - _itoa(i, str, 10); - - DBVARIANT dbv; - if (db_get_utf(NULL, "CListGroups", str, &dbv)) - break; - if (dbv.pszVal[0] & 0x80) - { - dbv.pszVal[0] &= 0x7f; - db_set_utf(NULL, "CListGroups", str, dbv.pszVal); - } - db_free(&dbv); - } - - CreateServiceFunction(MS_CLIST_GROUPEXISTS, GroupExists); - CreateServiceFunction(MS_CLIST_GROUPCREATE, CreateGroup); - CreateServiceFunction(MS_CLIST_GROUPDELETE, DeleteGroup); - CreateServiceFunction(MS_CLIST_GROUPRENAME, RenameGroup); - CreateServiceFunction(MS_CLIST_GROUPGETNAME, GetGroupName); - CreateServiceFunction(MS_CLIST_GROUPGETNAME2, GetGroupName2); - CreateServiceFunction(MS_CLIST_GROUPSETEXPANDED, SetGroupExpandedState); - CreateServiceFunction(MS_CLIST_GROUPSETFLAGS, SetGroupFlags); - CreateServiceFunction(MS_CLIST_GROUPMOVEBEFORE, MoveGroupBefore); - CreateServiceFunction(MS_CLIST_GROUPBUILDMENU, BuildGroupMenu); - - hGroupChangeEvent = CreateHookableEvent(ME_CLIST_GROUPCHANGE); - - return 0; -} diff --git a/src/modules/clist/keyboard.cpp b/src/modules/clist/keyboard.cpp deleted file mode 100644 index 343d7906ef..0000000000 --- a/src/modules/clist/keyboard.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" -#include - -static INT_PTR hkHideShow(WPARAM, LPARAM) -{ - cli.pfnShowHide(0, 0); - return 0; -} - -static INT_PTR hkRead(WPARAM, LPARAM) -{ - if (cli.pfnEventsProcessTrayDoubleClick(0) == 0) return TRUE; - SetForegroundWindow(cli.hwndContactList); - SetFocus(cli.hwndContactList); - return 0; -} - -static INT_PTR hkOpts(WPARAM, LPARAM) -{ - CallService("Options/OptionsCommand", 0, 0); - return 0; -} - -int InitClistHotKeys(void) -{ - CreateServiceFunction("CLIST/HK/SHOWHIDE", hkHideShow); - CreateServiceFunction("CLIST/HK/Opts", hkOpts); - CreateServiceFunction("CLIST/HK/Read", hkRead); - - HOTKEYDESC shk = { sizeof(shk) }; - shk.dwFlags = HKD_TCHAR; - shk.ptszDescription = LPGENT("Show/Hide contact list"); - shk.pszName = "ShowHide"; - shk.ptszSection = _T("Main"); - shk.pszService = "CLIST/HK/SHOWHIDE"; - shk.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, 'A'); - Hotkey_Register(&shk); - - shk.ptszDescription = LPGENT("Read message"); - shk.pszName = "ReadMessage"; - shk.ptszSection = _T("Main"); - shk.pszService = "CLIST/HK/Read"; - shk.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, 'I'); - Hotkey_Register(&shk); - - shk.ptszDescription = LPGENT("Open Options page"); - shk.pszName = "ShowOptions"; - shk.ptszSection = _T("Main"); - shk.pszService = "CLIST/HK/Opts"; - shk.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, 'O') | HKF_MIRANDA_LOCAL; - Hotkey_Register(&shk); - - shk.ptszDescription = LPGENT("Open logging options"); - shk.pszName = "ShowLogOptions"; - shk.ptszSection = _T("Main"); - shk.pszService = "Netlib/Log/Win"; - shk.DefHotKey = 0; - Hotkey_Register(&shk); - - shk.ptszDescription = LPGENT("Open 'Find user' dialog"); - shk.pszName = "FindUsers"; - shk.ptszSection = _T("Main"); - shk.pszService = "FindAdd/FindAddCommand"; - shk.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, 'F') | HKF_MIRANDA_LOCAL; - Hotkey_Register(&shk); - return 0; -} - - -int fnHotKeysRegister(HWND) -{ - return 0; -} - -void fnHotKeysUnregister(HWND) -{ -} - -int fnHotKeysProcess(HWND, WPARAM, LPARAM) -{ - return TRUE; -} - -int fnHotkeysProcessMessage(WPARAM, LPARAM) -{ - return FALSE; -} diff --git a/src/modules/clist/movetogroup.cpp b/src/modules/clist/movetogroup.cpp deleted file mode 100644 index c01474d7bd..0000000000 --- a/src/modules/clist/movetogroup.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -HGENMENU hMoveToGroupItem = 0, hPriorityItem = 0, hFloatingItem = 0; - -LIST lphGroupsItems(5); - -//service -//wparam - hcontact -//lparam .popupposition from CLISTMENUITEM - -#define MTG_MOVE "MoveToGroup/Move" - -struct GroupItemSort -{ - TCHAR* name; - int position; - - GroupItemSort(TCHAR* pname, int pos) - : name(mir_tstrdup(pname)), position(pos) {} - - ~GroupItemSort() { mir_free(name); } - - static int compare(const GroupItemSort* d1, const GroupItemSort* d2) - { return _tcscoll(d1->name, d2->name); } -}; - -static TCHAR* PrepareGroupName(TCHAR* str) -{ - TCHAR* p = _tcschr(str, '&'), *d; - if (p == NULL) - return mir_tstrdup(str); - - d = p = (TCHAR*)mir_alloc(sizeof(TCHAR)*(2*mir_tstrlen(str)+1)); - while (*str) { - if (*str == '&') - *d++='&'; - *d++=*str++; - } - - *d++=0; - return p; -} - -static void AddGroupItem(HGENMENU hRoot, TCHAR* name, int pos, WPARAM param, bool checked) -{ - CLISTMENUITEM mi = { sizeof(mi) }; - mi.hParentMenu = hRoot; - mi.popupPosition = param; // param to pszService - only with CMIF_CHILDPOPUP !!!!!! - mi.position = pos; - mi.ptszName = PrepareGroupName(name); - mi.flags = CMIF_ROOTHANDLE | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED; - if (checked) - mi.flags |= CMIF_CHECKED; - mi.pszService = MTG_MOVE; - HANDLE result = Menu_AddContactMenuItem(&mi); - mir_free(mi.ptszName); - - lphGroupsItems.insert((HANDLE*)result); -} - -static int OnContactMenuBuild(WPARAM wParam, LPARAM) -{ - int i; - OBJLIST groups(10, GroupItemSort::compare); - - if (!hMoveToGroupItem) { - CLISTMENUITEM mi = { sizeof(mi) }; - mi.position = 100000; - mi.pszName = LPGEN("&Move to group"); - mi.flags = CMIF_ROOTHANDLE; - mi.icolibItem = GetSkinIconHandle(SKINICON_OTHER_GROUP); - - hMoveToGroupItem = Menu_AddContactMenuItem(&mi); - } - - for (i=0; i < lphGroupsItems.getCount(); i++) - CallService(MO_REMOVEMENUITEM, (WPARAM)lphGroupsItems[i], 0); - lphGroupsItems.destroy(); - - ptrT szContactGroup(db_get_tsa(wParam, "CList", "Group")); - - int pos = 1000; - - AddGroupItem(hMoveToGroupItem, TranslateT(""), pos, -1, !szContactGroup); - - pos += 100000; // Separator - - for (i=0; ; i++) { - char intname[20]; - _itoa(i, intname, 10); - - DBVARIANT dbv; - if (db_get_ts(NULL, "CListGroups", intname, &dbv)) - break; - - if (dbv.ptszVal[0]) - groups.insert(new GroupItemSort(dbv.ptszVal + 1, i + 1)); - - mir_free(dbv.ptszVal); - } - - for (i=0; i < groups.getCount(); i++) { - bool checked = szContactGroup && !mir_tstrcmp(szContactGroup, groups[i].name); - AddGroupItem(hMoveToGroupItem, groups[i].name, ++pos, groups[i].position, checked); - } - - return 0; -} - -static INT_PTR MTG_DOMOVE(WPARAM wParam, LPARAM lParam) -{ - CallService(MS_CLIST_CONTACTCHANGEGROUP, wParam, lParam < 0 ? 0 : lParam); - return 0; -} - -void MTG_OnmodulesLoad() -{ - HookEvent(ME_CLIST_PREBUILDCONTACTMENU, OnContactMenuBuild); - CreateServiceFunction(MTG_MOVE, MTG_DOMOVE); -} - -int UnloadMoveToGroup(void) -{ - return 0; -} diff --git a/src/modules/clist/protocolorder.cpp b/src/modules/clist/protocolorder.cpp deleted file mode 100644 index 274ae0dce6..0000000000 --- a/src/modules/clist/protocolorder.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "clc.h" - -struct ProtocolData -{ - char *RealName; - int enabled; -}; - -int isProtoSuitable(PROTO_INTERFACE* ppi) -{ - if (ppi == NULL) - return TRUE; - - return ppi->GetCaps(PFLAGNUM_2, 0) & ~ppi->GetCaps(PFLAGNUM_5, 0); -} - -bool CheckProtocolOrder(void) -{ - bool changed = false; - int i, id = 0; - - for (;;) { - // Find account with this id - for (i = 0; i < accounts.getCount(); i++) - if (accounts[i]->iOrder == id) break; - - // Account with id not found - if (i == accounts.getCount()) { - // Check if this is skipped id, if it is decrement all other ids - bool found = false; - for (i = 0; i < accounts.getCount(); i++) { - if (accounts[i]->iOrder < 1000000 && accounts[i]->iOrder > id) { - --accounts[i]->iOrder; - found = true; - } - } - if (found) changed = true; - else break; - } - else id++; - } - - if (id < accounts.getCount()) { - // Remove huge ids - for (i = 0; i < accounts.getCount(); i++) - if (accounts[i]->iOrder >= 1000000) - accounts[i]->iOrder = id++; - - changed = true; - } - - if (id < accounts.getCount()) { - // Remove duplicate ids - for (i = 0; i < accounts.getCount(); i++) { - bool found = false; - for (int j = 0; j < accounts.getCount(); j++) { - if (accounts[j]->iOrder == i) { - if (found) accounts[j]->iOrder = id++; - else found = true; - } - } - } - changed = true; - } - - return changed; -} - -static bool ProtoToInclude(PROTOACCOUNT *pa) -{ - if (!Proto_IsAccountEnabled(pa)) - return false; - - PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(pa->szProtoName); - return (pd != NULL && pd->type == PROTOTYPE_PROTOCOL); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -class CProtocolOrderOpts : public CDlgBase -{ - void FillTree() - { - m_order.DeleteAllItems(); - - TVINSERTSTRUCT tvis; - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - - for (int i = 0; i < accounts.getCount(); i++) { - int idx = cli.pfnGetAccountIndexByPos(i); - if (idx == -1) - continue; - - PROTOACCOUNT *pa = accounts[idx]; - if (!ProtoToInclude(pa)) - continue; - - ProtocolData *PD = (ProtocolData*)mir_alloc(sizeof(ProtocolData)); - PD->RealName = pa->szModuleName; - PD->enabled = Proto_IsAccountEnabled(pa) && isProtoSuitable(pa->ppro); - - tvis.item.lParam = (LPARAM)PD; - tvis.item.pszText = pa->tszAccountName; - tvis.item.iImage = tvis.item.iSelectedImage = PD->enabled ? pa->bIsVisible : 100; - m_order.InsertItem(&tvis); - } - } - - bool m_bDragging; - HTREEITEM m_hDragItem; - - CCtrlTreeView m_order; - CCtrlButton m_btnReset; - -public: - CProtocolOrderOpts() : - CDlgBase(hInst, IDD_OPT_PROTOCOLORDER), - m_order(this, IDC_PROTOCOLORDER), - m_btnReset(this, IDC_RESETPROTOCOLDATA), - m_bDragging(false), - m_hDragItem(NULL) - { - m_btnReset.OnClick = Callback(this, &CProtocolOrderOpts::onReset_Click); - - m_order.SetFlags(MTREE_CHECKBOX | MTREE_DND); - m_order.OnDeleteItem = Callback(this, &CProtocolOrderOpts::onOrder_DeleteItem); - } - - virtual void OnInitDialog() - { - HIMAGELIST himlCheckBoxes = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 2, 2); - ImageList_AddIcon_IconLibLoaded(himlCheckBoxes, SKINICON_OTHER_NOTICK); - ImageList_AddIcon_IconLibLoaded(himlCheckBoxes, SKINICON_OTHER_TICK); - m_order.SetImageList(himlCheckBoxes, TVSIL_NORMAL); - - FillTree(); - } - - virtual void OnApply() - { - int idx = 0; - - TVITEMEX tvi; - tvi.hItem = m_order.GetRoot(); - tvi.mask = TVIF_PARAM | TVIF_HANDLE | TVIF_IMAGE; - while (tvi.hItem != NULL) { - m_order.GetItem(&tvi); - - if (tvi.lParam != 0) { - ProtocolData *ppd = (ProtocolData*)tvi.lParam; - PROTOACCOUNT *pa = Proto_GetAccount(ppd->RealName); - if (pa != NULL) { - while (idx < accounts.getCount() && !ProtoToInclude(accounts[idx])) - idx++; - pa->iOrder = idx++; - if (ppd->enabled) - pa->bIsVisible = tvi.iImage != 0; - } - } - - tvi.hItem = m_order.GetNextSibling(tvi.hItem); - } - - WriteDbAccounts(); - cli.pfnReloadProtoMenus(); - cli.pfnTrayIconIconsChanged(); - cli.pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0); - cli.pfnClcBroadcast(INTM_INVALIDATE, 0, 0); - } - - virtual void OnDestroy() - { - ImageList_Destroy(m_order.GetImageList(TVSIL_NORMAL)); - } - - void onReset_Click(CCtrlButton*) - { - for (int i = 0; i < accounts.getCount(); i++) - accounts[i]->iOrder = i; - - FillTree(); - NotifyChange(); - } - - void onOrder_DeleteItem(CCtrlTreeView::TEventInfo *env) - { - NMTREEVIEW *pnmtv = env->nmtv; - if (pnmtv) - mir_free((ProtocolData*)pnmtv->itemOld.lParam); - } -}; - -int ProtocolOrderOptInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.position = -10000000; - odp.groupPosition = 1000000; - odp.pszTitle = LPGEN("Accounts"); - odp.pszGroup = LPGEN("Contact list"); - odp.pDialog = new CProtocolOrderOpts(); - odp.flags = ODPF_BOLDGROUPS; - Options_AddPage(wParam, &odp); - return 0; -} diff --git a/src/modules/crypt/encrypt.cpp b/src/modules/crypt/encrypt.cpp deleted file mode 100644 index 4bdc393358..0000000000 --- a/src/modules/crypt/encrypt.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -///////////////////////////////////////////////////////////////////////////////////////// - -static int CompareFunc(const CRYPTO_PROVIDER *p1, const CRYPTO_PROVIDER *p2) -{ - return mir_strcmp(p1->pszName, p2->pszName); -} - -static LIST arProviders(5, CompareFunc); - -static INT_PTR srvRegister(WPARAM wParam, LPARAM lParam) -{ - CRYPTO_PROVIDER *p = (CRYPTO_PROVIDER*)lParam; - if (p == NULL || p->dwSize != sizeof(CRYPTO_PROVIDER)) - return 1; - - CRYPTO_PROVIDER *pNew = new CRYPTO_PROVIDER(*p); - pNew->pszName = mir_strdup(p->pszName); - if (pNew->dwFlags & CPF_UNICODE) - pNew->ptszDescr = mir_u2t(TranslateW_LP(p->pwszDescr, wParam)); - else - pNew->ptszDescr = mir_a2t(TranslateA_LP(p->pszDescr, wParam)); - arProviders.insert(pNew); - return 0; -} - -static INT_PTR srvEnumProviders(WPARAM wParam, LPARAM lParam) -{ - if (wParam && lParam) { - *(int*)wParam = arProviders.getCount(); - *(CRYPTO_PROVIDER***)lParam = arProviders.getArray(); - } - return 0; -} - -static INT_PTR srvGetProvider(WPARAM wParam, LPARAM lParam) -{ - if (lParam == 0) - return 0; - - CRYPTO_PROVIDER tmp; - tmp.pszName = (LPSTR)lParam; - return (INT_PTR)arProviders.find(&tmp); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -int InitCrypt(void) -{ - CreateServiceFunction(MS_CRYPTO_REGISTER_ENGINE, srvRegister); - CreateServiceFunction(MS_CRYPTO_ENUM_PROVIDERS, srvEnumProviders); - CreateServiceFunction(MS_CRYPTO_GET_PROVIDER, srvGetProvider); - return 0; -} - -void UninitCrypt(void) -{ - for (int i = 0; i < arProviders.getCount(); i++) { - CRYPTO_PROVIDER *p = arProviders[i]; - mir_free(p->pszName); - mir_free(p->pszDescr); - delete p; - } -} diff --git a/src/modules/database/database.cpp b/src/modules/database/database.cpp deleted file mode 100644 index 0fdb7f7174..0000000000 --- a/src/modules/database/database.cpp +++ /dev/null @@ -1,538 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "profilemanager.h" - -// contains the location of mirandaboot.ini -bool g_bDbCreated; -TCHAR g_profileDir[MAX_PATH], g_profileName[MAX_PATH], g_shortProfileName[MAX_PATH]; -TCHAR* g_defaultProfile; -void EnsureCheckerLoaded(bool); - -void LoadDatabaseServices(); - -bool fileExist(const TCHAR *fname) -{ - if (*fname == 0) - return false; - - FILE *fp = _tfopen(fname, _T("r+")); - bool res = (fp != NULL); - if (fp) fclose(fp); - return res; -} - -static void fillProfileName(const TCHAR* ptszFileName) -{ - const TCHAR* p = _tcsrchr(ptszFileName, '\\'); - if (p == NULL) - p = ptszFileName; - else - p++; - - _tcsncpy_s(g_profileName, p, _TRUNCATE); - - _tcsncpy_s(g_shortProfileName, p, _TRUNCATE); - TCHAR *pos = _tcsrchr(g_shortProfileName, '.'); - if (mir_tstrcmpi(pos, _T(".dat")) == 0) - *pos = 0; -} - -bool IsInsideRootDir(TCHAR* profiledir, bool exact) -{ - VARST pfd( _T("%miranda_path%")); - if (exact) - return mir_tstrcmpi(profiledir, pfd) == 0; - - return _tcsnicmp(profiledir, pfd, mir_tstrlen(pfd)) == 0; -} - -// returns 1 if the profile path was returned, without trailing slash -int getProfilePath(TCHAR *buf, size_t cch) -{ - TCHAR profiledir[MAX_PATH]; - GetPrivateProfileString(_T("Database"), _T("ProfileDir"), _T(""), profiledir, SIZEOF(profiledir), mirandabootini); - - if (profiledir[0] == 0) - mir_tstrcpy(profiledir, _T("%miranda_path%\\Profiles")); - - size_t len = PathToAbsoluteT( VARST(profiledir), buf); - - if (buf[len-1] == '/' || buf[len-1] == '\\') - buf[len-1] = 0; - - return 0; -} - -// returns 1 if *.dat spec is matched -int isValidProfileName(const TCHAR *name) -{ - size_t len = mir_tstrlen(name) - 4; - return len > 0 && mir_tstrcmpi(&name[len], _T(".dat")) == 0; -} - -// returns 1 if the profile manager should be shown -static bool showProfileManager(void) -{ - TCHAR Mgr[32]; - // is control pressed? - if (GetAsyncKeyState(VK_CONTROL) & 0x8000) - return 1; - - // wanna show it? - GetPrivateProfileString(_T("Database"), _T("ShowProfileMgr"), _T("never"), Mgr, SIZEOF(Mgr), mirandabootini); - return (mir_tstrcmpi(Mgr, _T("yes")) == 0); -} - -bool shouldAutoCreate(TCHAR *szProfile) -{ - if (szProfile[0] == 0) - return false; - - TCHAR ac[32]; - GetPrivateProfileString(_T("Database"), _T("AutoCreate"), _T(""), ac, SIZEOF(ac), mirandabootini); - return mir_tstrcmpi(ac, _T("yes")) == 0; -} - -static void getDefaultProfile(TCHAR *szProfile, size_t cch) -{ - TCHAR defaultProfile[MAX_PATH]; - GetPrivateProfileString(_T("Database"), _T("DefaultProfile"), _T(""), defaultProfile, SIZEOF(defaultProfile), mirandabootini); - - if (defaultProfile[0] == 0) - return; - - VARST res(defaultProfile); - if (res) - mir_sntprintf(szProfile, cch, _T("%s\\%s\\%s%s"), g_profileDir, (TCHAR*)res, (TCHAR*)res, isValidProfileName(res) ? _T("") : _T(".dat")); - else - szProfile[0] = 0; -} - -// returns 1 if something that looks like a profile is there -static void loadProfileByShortName(const TCHAR* src, TCHAR *szProfile, size_t cch) -{ - TCHAR buf[MAX_PATH]; - _tcsncpy_s(buf, src, _TRUNCATE); - - TCHAR *p = _tcsrchr(buf, '\\'); if (p) ++p; else p = buf; - if (!isValidProfileName(buf) && *p) - mir_tstrcat(buf, _T(".dat")); - - TCHAR profileName[MAX_PATH], newProfileDir[MAX_PATH]; - _tcsncpy_s(profileName, p, _TRUNCATE); - if (!isValidProfileName(profileName) && *p) - mir_tstrcat(profileName, _T(".dat")); - - _tcsncpy_s(profileName, p, _TRUNCATE); - p = _tcsrchr(profileName, '.'); if (p) *p = 0; - - mir_sntprintf(newProfileDir, cch, _T("%s\\%s\\"), g_profileDir, profileName); - PathToAbsoluteT(buf, szProfile, newProfileDir); - - if ( _tcschr(buf, '\\')) { - _tcsncpy_s(g_profileDir, szProfile, _TRUNCATE); - if (profileName[0]) { - p = _tcsrchr(g_profileDir, '\\'); *p = 0; - p = _tcsrchr(g_profileDir, '\\'); - if (p && mir_tstrcmpi(p + 1, profileName) == 0) - *p = 0; - } - else szProfile[0] = 0; - } -} - -void getProfileCmdLine(TCHAR *szProfile, size_t cch) -{ - LPCTSTR ptszProfileName = CmdLine_GetOption( _T("profile")); - if (ptszProfileName != NULL) - loadProfileByShortName(ptszProfileName, szProfile, cch); -} - -void getProfileDefault(TCHAR *szProfile, size_t cch) -{ - if (g_defaultProfile != NULL) { - loadProfileByShortName(g_defaultProfile, szProfile, cch); - mir_free(g_defaultProfile); - } -} - -// move profile from profile subdir -static void moveProfileDirProfiles(TCHAR *profiledir, BOOL isRootDir = TRUE) -{ - TCHAR pfd[MAX_PATH]; - if (isRootDir) - _tcsncpy_s(pfd, VARST(_T("%miranda_path%\\*.dat")), _TRUNCATE); - else - mir_sntprintf(pfd, SIZEOF(pfd), _T("%s\\*.dat"), profiledir); - - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile(pfd, &ffd); - if (hFind != INVALID_HANDLE_VALUE) { - TCHAR *c = _tcsrchr(pfd, '\\'); if (c) *c = 0; - do { - TCHAR path[MAX_PATH], path2[MAX_PATH]; - TCHAR* profile = mir_tstrdup(ffd.cFileName); - TCHAR *c = _tcsrchr(profile, '.'); if (c) *c = 0; - mir_sntprintf(path, SIZEOF(path), _T("%s\\%s"), pfd, ffd.cFileName); - mir_sntprintf(path2, SIZEOF(path2), _T("%s\\%s"), profiledir, profile); - CreateDirectoryTreeT(path2); - mir_sntprintf(path2, SIZEOF(path2), _T("%s\\%s\\%s"), profiledir, profile, ffd.cFileName); - if (_taccess(path2, 0) == 0) { - TCHAR buf[512]; - mir_sntprintf(buf, - TranslateT("Miranda is trying to upgrade your profile structure.\nIt cannot move profile %s to the new location %s\nBecause profile with this name already exists. Please resolve the issue manually."), - path, path2); - MessageBox(NULL, buf, _T("Miranda NG"), MB_ICONERROR | MB_OK); - } - else if (MoveFile(path, path2) == 0) { - TCHAR buf[512]; - mir_sntprintf(buf, - TranslateT("Miranda is trying to upgrade your profile structure.\nIt cannot move profile %s to the new location %s automatically\nMost likely this is due to insufficient privileges. Please move profile manually."), - path, path2); - MessageBox(NULL, buf, _T("Miranda NG"), MB_ICONERROR | MB_OK); - mir_free(profile); - break; - } - mir_free(profile); - } - while (FindNextFile(hFind, &ffd)); - } - FindClose(hFind); -} - -// returns 1 if a single profile (full path) is found within the profile dir -static int getProfile1(TCHAR *szProfile, size_t cch, TCHAR *profiledir, BOOL * noProfiles) -{ - int found = 0; - - if (IsInsideRootDir(profiledir, false)) - moveProfileDirProfiles(profiledir); - moveProfileDirProfiles(profiledir, FALSE); - - bool bNoDefaultProfile = (*szProfile == 0); - bool reqfd = !bNoDefaultProfile && (_taccess(szProfile, 0) == 0 || shouldAutoCreate(szProfile)); - bool bShowProfileManager = showProfileManager(); - - if (reqfd) - found++; - - if (bShowProfileManager || !reqfd) { - TCHAR searchspec[MAX_PATH]; - mir_sntprintf(searchspec, SIZEOF(searchspec), _T("%s\\*.*"), profiledir); - - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile(searchspec, &ffd); - if (hFind != INVALID_HANDLE_VALUE) { - do { - // make sure the first hit is actually a *.dat file - if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || !mir_tstrcmp(ffd.cFileName, _T(".")) || !mir_tstrcmp(ffd.cFileName, _T(".."))) - continue; - - TCHAR newProfile[MAX_PATH]; - mir_sntprintf(newProfile, SIZEOF(newProfile), _T("%s\\%s\\%s.dat"), profiledir, ffd.cFileName, ffd.cFileName); - if (_taccess(newProfile, 0) != 0) - continue; - - switch (touchDatabase(newProfile, NULL)) { - case 0: - case EGROKPRF_OBSOLETE: - if (++found == 1 && bNoDefaultProfile) - _tcsncpy_s(szProfile, cch, newProfile, _TRUNCATE); - break; - } - } - while (FindNextFile(hFind, &ffd)); - - FindClose(hFind); - } - reqfd = (!bShowProfileManager && found == 1 && bNoDefaultProfile); - } - - if (noProfiles) - *noProfiles = (found == 0); - - if (bNoDefaultProfile && !reqfd) - szProfile[0] = 0; - - return reqfd; -} - -// returns 1 if a default profile should be selected instead of showing the manager. -static int getProfileAutoRun(TCHAR *szProfile) -{ - if (*szProfile == 0) - return false; - - TCHAR Mgr[32]; - GetPrivateProfileString(_T("Database"), _T("ShowProfileMgr"), _T(""), Mgr, SIZEOF(Mgr), mirandabootini); - if (mir_tstrcmpi(Mgr, _T("never"))) - return 0; - - return fileExist(szProfile) || shouldAutoCreate(szProfile); -} - -// returns 1 if a profile was selected -static int getProfile(TCHAR *szProfile, size_t cch) -{ - getProfilePath(g_profileDir, SIZEOF(g_profileDir)); - if (IsInsideRootDir(g_profileDir, true)) - if (WritePrivateProfileString(_T("Database"), _T("ProfileDir"), _T(""), mirandabootini)) - getProfilePath(g_profileDir, SIZEOF(g_profileDir)); - - getDefaultProfile(szProfile, cch); - getProfileCmdLine(szProfile, cch); - getProfileDefault(szProfile, cch); - - if (IsInsideRootDir(g_profileDir, true)) { - MessageBox(NULL, - TranslateT("Profile cannot be placed into Miranda root folder.\nPlease move Miranda profile to some other location."), - LPGENT("Miranda NG"), MB_ICONERROR | MB_OK); - return 0; - } - - PROFILEMANAGERDATA pd = { 0 }; - if (CmdLine_GetOption(_T("ForceShowPM"))) { -LBL_Show: - pd.ptszProfile = szProfile; - pd.ptszProfileDir = g_profileDir; - if (!getProfileManager(&pd)) - return 0; - - if (!pd.bRun) - return CallService(MS_DB_CHECKPROFILE, WPARAM(szProfile), TRUE); - - return 1; - } - - if (getProfileAutoRun(szProfile)) - return 1; - - if (getProfile1(szProfile, cch, g_profileDir, &pd.noProfiles)) - return 1; - - goto LBL_Show; -} - -// carefully converts a file name from TCHAR* to char* -char* makeFileName(const TCHAR* tszOriginalName) -{ - char *szResult = NULL; - char *szFileName = mir_t2a(tszOriginalName); - TCHAR *tszFileName = mir_a2t(szFileName); - if (mir_tstrcmp(tszOriginalName, tszFileName)) { - TCHAR tszProfile[MAX_PATH]; - if (GetShortPathName(tszOriginalName, tszProfile, MAX_PATH) != 0) - szResult = mir_t2a(tszProfile); - } - - if (!szResult) - szResult = szFileName; - else - mir_free(szFileName); - mir_free(tszFileName); - - return szResult; -} - -int touchDatabase(const TCHAR *tszProfile, DATABASELINK **dblink) -{ - for (int i = arDbPlugins.getCount() - 1; i >= 0; i--) { - DATABASELINK *p = arDbPlugins[i]; - int iErrorCode = p->grokHeader(tszProfile); - if (iErrorCode == 0) { - if (dblink) - *dblink = p; - return 0; - } - if (iErrorCode == EGROKPRF_OBSOLETE) { - if (dblink) - *dblink = p; - return EGROKPRF_OBSOLETE; - } - } - - if (dblink) - *dblink = NULL; - return EGROKPRF_CANTREAD; -} - -// enumerate all plugins that had valid DatabasePluginInfo() -int tryOpenDatabase(const TCHAR *tszProfile) -{ - bool bWasOpened = false; - - for (int i = arDbPlugins.getCount() - 1; i >= 0; i--) { - DATABASELINK *p = arDbPlugins[i]; - - // liked the profile? - int err = p->grokHeader(tszProfile); - if (err != ERROR_SUCCESS) { // smth went wrong - switch (err) { - case EGROKPRF_CANTREAD: - case EGROKPRF_UNKHEADER: - // just not supported. - continue; - - case EGROKPRF_OBSOLETE: - EnsureCheckerLoaded(true); - CallService(MS_DB_CHECKPROFILE, (WPARAM)tszProfile, 2); - break; - - default: - return err; - } - } - - bWasOpened = true; - - // try to load database - MIDatabase *pDb = p->Load(tszProfile, FALSE); - if (pDb) { - fillProfileName(tszProfile); - currDblink = p; - db_setCurrent(currDb = pDb); - return 0; - } - } - - return (bWasOpened) ? -1 : EGROKPRF_CANTREAD; -} - -// enumerate all plugins that had valid DatabasePluginInfo() -static int tryCreateDatabase(const TCHAR *ptszProfile) -{ - TCHAR *tszProfile = NEWTSTR_ALLOCA(ptszProfile); - CreatePathToFileT(tszProfile); - - for (int i = 0; i < arDbPlugins.getCount(); i++) { - DATABASELINK* p = arDbPlugins[i]; - - int err = p->makeDatabase(tszProfile); - if (err == ERROR_SUCCESS) { - g_bDbCreated = true; - MIDatabase *pDb = p->Load(tszProfile, FALSE); - if (pDb != NULL) { - fillProfileName(tszProfile); - currDblink = p; - db_setCurrent(currDb = pDb); - return 0; - } - return 1; - } - } - return 1; -} - -typedef struct { - TCHAR *profile; - UINT msg; - ATOM aPath; - int found; -} ENUMMIRANDAWINDOW; - -static BOOL CALLBACK EnumMirandaWindows(HWND hwnd, LPARAM lParam) -{ - TCHAR classname[256]; - ENUMMIRANDAWINDOW *x = (ENUMMIRANDAWINDOW *)lParam; - DWORD_PTR res = 0; - if (GetClassName(hwnd, classname, SIZEOF(classname)) && mir_tstrcmp(_T("Miranda"), classname) == 0) { - if (SendMessageTimeout(hwnd, x->msg, (WPARAM)x->aPath, 0, SMTO_ABORTIFHUNG, 100, &res) && res) { - x->found++; - return FALSE; - } - } - return TRUE; -} - -static int FindMirandaForProfile(TCHAR *szProfile) -{ - ENUMMIRANDAWINDOW x = { 0 }; - x.profile = szProfile; - x.msg = RegisterWindowMessage(_T("Miranda::ProcessProfile")); - x.aPath = GlobalAddAtom(szProfile); - EnumWindows(EnumMirandaWindows, (LPARAM)&x); - GlobalDeleteAtom(x.aPath); - return x.found; -} - -int LoadDatabaseModule(void) -{ - TCHAR szProfile[MAX_PATH]; - PathToAbsoluteT(_T("."), szProfile); - _tchdir(szProfile); - szProfile[0] = 0; - - LoadDatabaseServices(); - - // find out which profile to load - if (!getProfile(szProfile, SIZEOF(szProfile))) - return 1; - - if (arDbPlugins.getCount() == 0) { - TCHAR buf[256]; - TCHAR *p = _tcsrchr(szProfile, '\\'); - mir_sntprintf(buf, TranslateT("Miranda is unable to open '%s' because you do not have any profile plugins installed.\nYou need to install dbx_mmap.dll"), p ? ++p : szProfile); - MessageBox(0, buf, TranslateT("No profile support installed!"), MB_OK | MB_ICONERROR); - } - - // find a driver to support the given profile - bool retry; - int rc; - do { - retry = false; - if (_taccess(szProfile, 0) && shouldAutoCreate(szProfile)) - rc = tryCreateDatabase(szProfile); - else - rc = tryOpenDatabase(szProfile); - - if (rc > 0) { - // if there were drivers but they all failed cos the file is locked, try and find the miranda which locked it - if (fileExist(szProfile)) { - // file isn't locked, just no driver could open it. - TCHAR buf[256]; - TCHAR *p = _tcsrchr(szProfile, '\\'); - mir_sntprintf(buf, TranslateT("Miranda was unable to open '%s', it's in an unknown format.\nThis profile might also be damaged, please run DbChecker which should be installed."), p ? ++p : szProfile); - MessageBox(0, buf, TranslateT("Miranda can't understand that profile"), MB_OK | MB_ICONERROR); - } - else if (!FindMirandaForProfile(szProfile)) { - TCHAR buf[256]; - TCHAR *p = _tcsrchr(szProfile, '\\'); - mir_sntprintf(buf, TranslateT("Miranda was unable to open '%s'\nIt's inaccessible or used by other application or Miranda instance"), p ? ++p : szProfile); - retry = MessageBox(0, buf, TranslateT("Miranda can't open that profile"), MB_RETRYCANCEL | MB_ICONERROR) == IDRETRY; - } - } - } - while (retry); - - EnsureCheckerLoaded(false); // unload dbchecker - - if (rc == ERROR_SUCCESS) { - InitIni(); - return 0; - } - - return rc; -} diff --git a/src/modules/database/database.h b/src/modules/database/database.h deleted file mode 100644 index c0acab5c48..0000000000 --- a/src/modules/database/database.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright 2012-15 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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. -*/ - -class MDatabaseCache : public MIDatabaseCache -{ - HANDLE m_hCacheHeap; - char* m_lastSetting; - size_t m_contactSize; - DBCachedContact *m_lastVL; - mir_cs m_cs; - - LIST m_lContacts; - LIST m_lGlobalSettings; - LIST m_lSettings; - - void FreeCachedVariant(DBVARIANT* V); - -public: - MDatabaseCache(size_t); - ~MDatabaseCache(); - -protected: - STDMETHODIMP_(DBCachedContact*) AddContactToCache(MCONTACT contactID); - STDMETHODIMP_(DBCachedContact*) GetCachedContact(MCONTACT contactID); - STDMETHODIMP_(DBCachedContact*) GetFirstContact(void); - STDMETHODIMP_(DBCachedContact*) GetNextContact(MCONTACT contactID); - STDMETHODIMP_(void) FreeCachedContact(MCONTACT contactID); - - STDMETHODIMP_(char*) InsertCachedSetting(const char *szName, int); - STDMETHODIMP_(char*) GetCachedSetting(const char *szModuleName, const char *szSettingName, int, int); - STDMETHODIMP_(void) SetCachedVariant(DBVARIANT *s, DBVARIANT *d); - STDMETHODIMP_(DBVARIANT*) GetCachedValuePtr(MCONTACT contactID, char *szSetting, int bAllocate); -}; diff --git a/src/modules/database/dbini.cpp b/src/modules/database/dbini.cpp deleted file mode 100644 index d972d8cfd2..0000000000 --- a/src/modules/database/dbini.cpp +++ /dev/null @@ -1,520 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "profilemanager.h" - -static bool bModuleInitialized = false; -static HANDLE hIniChangeNotification; - -static INT_PTR CALLBACK InstallIniDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - SetDlgItemText(hwndDlg, IDC_ININAME, (TCHAR*)lParam); - { - TCHAR szSecurity[11]; - const TCHAR *pszSecurityInfo; - - GetPrivateProfileString(_T("AutoExec"), _T("Warn"), _T("notsafe"), szSecurity, SIZEOF(szSecurity), mirandabootini); - if (!mir_tstrcmpi(szSecurity, _T("all"))) - pszSecurityInfo = LPGENT("Security systems to prevent malicious changes are in place and you will be warned before every change that is made."); - else if (!mir_tstrcmpi(szSecurity, _T("onlyunsafe"))) - pszSecurityInfo = LPGENT("Security systems to prevent malicious changes are in place and you will be warned before changes that are known to be unsafe."); - else if (!mir_tstrcmpi(szSecurity, _T("none"))) - pszSecurityInfo = LPGENT("Security systems to prevent malicious changes have been disabled. You will receive no further warnings."); - else pszSecurityInfo = NULL; - if (pszSecurityInfo) SetDlgItemText(hwndDlg, IDC_SECURITYINFO, TranslateTS(pszSecurityInfo)); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_VIEWINI: - { - TCHAR szPath[MAX_PATH]; - GetDlgItemText(hwndDlg, IDC_ININAME, szPath, SIZEOF(szPath)); - ShellExecute(hwndDlg, _T("open"), szPath, NULL, NULL, SW_SHOW); - } - break; - - case IDOK: - case IDCANCEL: - case IDC_NOTOALL: - EndDialog(hwndDlg, LOWORD(wParam)); - break; - } - break; - } - return FALSE; -} - -static bool IsInSpaceSeparatedList(const char *szWord, const char *szList) -{ - const char *szItem, *szEnd; - size_t wordLen = mir_strlen(szWord); - - for (szItem = szList;;) { - szEnd = strchr(szItem, ' '); - if (szEnd == NULL) - return !mir_strcmp(szItem, szWord); - - if (szEnd - szItem == wordLen) - if (!strncmp(szItem, szWord, wordLen)) - return true; - - szItem = szEnd + 1; - } -} - -struct warnSettingChangeInfo_t { - TCHAR *szIniPath; - char *szSection; - char *szSafeSections; - char *szUnsafeSections; - char *szName; - char *szValue; - int warnNoMore, cancel; -}; - -static INT_PTR CALLBACK WarnIniChangeDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - static warnSettingChangeInfo_t *warnInfo; - - switch(message) { - case WM_INITDIALOG: - { - char szSettingName[256]; - const TCHAR *pszSecurityInfo; - warnInfo = (warnSettingChangeInfo_t*)lParam; - TranslateDialogDefault(hwndDlg); - SetDlgItemText(hwndDlg, IDC_ININAME, warnInfo->szIniPath); - mir_strcpy(szSettingName, warnInfo->szSection); - mir_strcat(szSettingName, " / "); - mir_strcat(szSettingName, warnInfo->szName); - SetDlgItemTextA(hwndDlg, IDC_SETTINGNAME, szSettingName); - SetDlgItemTextA(hwndDlg, IDC_NEWVALUE, warnInfo->szValue); - if (IsInSpaceSeparatedList(warnInfo->szSection, warnInfo->szSafeSections)) - pszSecurityInfo = LPGENT("This change is known to be safe."); - else if (IsInSpaceSeparatedList(warnInfo->szSection, warnInfo->szUnsafeSections)) - pszSecurityInfo = LPGENT("This change is known to be potentially hazardous."); - else - pszSecurityInfo = LPGENT("This change is not known to be safe."); - SetDlgItemText(hwndDlg, IDC_SECURITYINFO, TranslateTS(pszSecurityInfo)); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDCANCEL: - warnInfo->cancel = 1; - // fall through - case IDYES: - case IDNO: - warnInfo->warnNoMore = IsDlgButtonChecked(hwndDlg, IDC_WARNNOMORE); - EndDialog(hwndDlg, LOWORD(wParam)); - break; - } - break; - } - return FALSE; -} - -static INT_PTR CALLBACK IniImportDoneDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - TCHAR szIniPath[MAX_PATH]; - - switch (message) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - SetDlgItemText(hwndDlg, IDC_ININAME, (TCHAR*)lParam); - SetDlgItemText(hwndDlg, IDC_NEWNAME, (TCHAR*)lParam); - return TRUE; - - case WM_COMMAND: - GetDlgItemText(hwndDlg, IDC_ININAME, szIniPath, SIZEOF(szIniPath)); - switch (LOWORD(wParam)) { - case IDC_DELETE: - DeleteFile(szIniPath); - case IDC_LEAVE: - EndDialog(hwndDlg, LOWORD(wParam)); - break; - case IDC_RECYCLE: - { - SHFILEOPSTRUCT shfo = { 0 }; - shfo.wFunc = FO_DELETE; - shfo.pFrom = szIniPath; - szIniPath[mir_tstrlen(szIniPath) + 1] = '\0'; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOF_ALLOWUNDO; - SHFileOperation(&shfo); - } - EndDialog(hwndDlg, LOWORD(wParam)); - break; - case IDC_MOVE: - TCHAR szNewPath[MAX_PATH]; - GetDlgItemText(hwndDlg, IDC_NEWNAME, szNewPath, SIZEOF(szNewPath)); - MoveFile(szIniPath, szNewPath); - EndDialog(hwndDlg, LOWORD(wParam)); - break; - } - break; - } - return FALSE; -} - -// settings: -struct SettingsList -{ - char *name; - SettingsList *next; -} *setting_items = NULL; - -int SettingsEnumProc(const char *szSetting, LPARAM lParam) -{ - SettingsList *newItem = (SettingsList *)mir_alloc(sizeof(SettingsList)); - newItem->name = mir_strdup(szSetting); - newItem->next = setting_items; - setting_items = newItem; - return 0; -} - -static void ConvertBackslashes(char *str, UINT fileCp) -{ - char *pstr; - for (pstr = str; *pstr; pstr = CharNextExA(fileCp, pstr, 0)) { - if (*pstr == '\\') { - switch (pstr[1]) { - case 'n': *pstr = '\n'; break; - case 't': *pstr = '\t'; break; - case 'r': *pstr = '\r'; break; - default: *pstr = pstr[1]; break; - } - memmove(pstr + 1, pstr + 2, mir_strlen(pstr + 2) + 1); - } - } -} - -static void ProcessIniFile(TCHAR* szIniPath, char *szSafeSections, char *szUnsafeSections, int secur, bool secFN) -{ - FILE *fp = _tfopen(szIniPath, _T("rt")); - if (fp == NULL) - return; - - bool warnThisSection = false; - char szSection[128]; szSection[0] = 0; - - while (!feof(fp)) { - char szLine[2048]; - if (fgets(szLine, sizeof(szLine), fp) == NULL) - break; -LBL_NewLine: - size_t lineLength = mir_strlen(szLine); - while (lineLength && (BYTE)(szLine[lineLength - 1]) <= ' ') - szLine[--lineLength] = '\0'; - - if (szLine[0] == ';' || szLine[0] <= ' ') - continue; - - if (szLine[0] == '[') { - char *szEnd = strchr(szLine + 1, ']'); - if (szEnd == NULL) - continue; - - if (szLine[1] == '!') - szSection[0] = '\0'; - else { - mir_strncpy(szSection, szLine + 1, min(sizeof(szSection), (int)(szEnd - szLine))); - switch (secur) { - case 0: - warnThisSection = false; - break; - - case 1: - warnThisSection = !IsInSpaceSeparatedList(szSection, szSafeSections); - break; - - case 2: - warnThisSection = IsInSpaceSeparatedList(szSection, szUnsafeSections); - break; - - default: - warnThisSection = true; - break; - } - if (secFN) warnThisSection = 0; - } - if (szLine[1] == '?') { - DBCONTACTENUMSETTINGS dbces; - dbces.pfnEnumProc = SettingsEnumProc; - mir_strncpy(szSection, szLine+2, min(sizeof(szSection), (int)(szEnd-szLine-1))); - dbces.szModule = szSection; - dbces.ofsSettings = 0; - CallService(MS_DB_CONTACT_ENUMSETTINGS, 0, (LPARAM)&dbces); - while (setting_items) { - SettingsList *next = setting_items->next; - - db_unset(NULL, szSection, setting_items->name); - - mir_free(setting_items->name); - mir_free(setting_items); - setting_items = next; - } - } - continue; - } - - if (szSection[0] == '\0') - continue; - - char *szValue = strchr(szLine, '='); - if (szValue == NULL) - continue; - - char szName[128]; - mir_strncpy(szName, szLine, min(sizeof(szName), (int)(szValue-szLine+1))); - szValue++; - { - warnSettingChangeInfo_t warnInfo; - warnInfo.szIniPath = szIniPath; - warnInfo.szName = szName; - warnInfo.szSafeSections = szSafeSections; - warnInfo.szSection = szSection; - warnInfo.szUnsafeSections = szUnsafeSections; - warnInfo.szValue = szValue; - warnInfo.warnNoMore = 0; - warnInfo.cancel = 0; - if (warnThisSection && IDNO == DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_WARNINICHANGE), NULL, WarnIniChangeDlgProc, (LPARAM)&warnInfo)) - continue; - if (warnInfo.cancel) - break; - if (warnInfo.warnNoMore) - warnThisSection = 0; - } - - switch (szValue[0]) { - case 'b': - case 'B': - db_set_b(NULL, szSection, szName, (BYTE)strtol(szValue+1, NULL, 0)); - break; - case 'w': - case 'W': - db_set_w(NULL, szSection, szName, (WORD)strtol(szValue+1, NULL, 0)); - break; - case 'd': - case 'D': - db_set_dw(NULL, szSection, szName, (DWORD)strtoul(szValue+1, NULL, 0)); - break; - case 'l': - case 'L': - case '-': - db_unset(NULL, szSection, szName); - break; - case 'e': - case 'E': - ConvertBackslashes(szValue+1, Langpack_GetDefaultCodePage()); - case 's': - case 'S': - db_set_s(NULL, szSection, szName, szValue+1); - break; - case 'g': - case 'G': - for (char *pstr = szValue + 1; *pstr; pstr++) { - if (*pstr == '\\') { - switch (pstr[1]) { - case 'n': *pstr = '\n'; break; - case 't': *pstr = '\t'; break; - case 'r': *pstr = '\r'; break; - default: *pstr = pstr[1]; break; - } - memmove(pstr + 1, pstr + 2, mir_strlen(pstr + 2) + 1); - } - } - case 'u': - case 'U': - db_set_utf(NULL, szSection, szName, szValue + 1); - break; - case 'm': - case 'M': - { - CMStringA memo(szValue + 1); - memo.Append("\r\n"); - while (fgets(szLine, sizeof(szLine), fp) != NULL) { - switch (szLine[0]) { - case 0: case '\r': case '\n': case ' ': case '\t': - break; - default: - db_set_utf(NULL, szSection, szName, memo); - goto LBL_NewLine; - } - - memo.Append(rtrim(szLine + 1)); - memo.Append("\r\n"); - } - db_set_utf(NULL, szSection, szName, memo); - } - break; - case 'n': - case 'h': - case 'N': - case 'H': - { - int len; - char *pszValue, *pszEnd; - - PBYTE buf = (PBYTE)mir_alloc(mir_strlen(szValue + 1)); - for (len = 0, pszValue = szValue + 1;; len++) { - buf[len] = (BYTE)strtol(pszValue, &pszEnd, 0x10); - if (pszValue == pszEnd) - break; - pszValue = pszEnd; - } - db_set_blob(NULL, szSection, szName, buf, len); - mir_free(buf); - } - break; - default: - TCHAR buf[250]; - mir_sntprintf(buf, TranslateT("Invalid setting type for '%s'. The first character of every value must be b, w, d, l, s, e, u, g, h or n."), _A2T(szName)); - MessageBox(NULL, buf, TranslateT("Install database settings"), MB_ICONWARNING | MB_OK); - break; - } - } - fclose(fp); -} - -static void DoAutoExec(void) -{ - TCHAR szUse[7], szIniPath[MAX_PATH], szFindPath[MAX_PATH]; - TCHAR buf[2048], szSecurity[11], szOverrideSecurityFilename[MAX_PATH], szOnCreateFilename[MAX_PATH]; - int secur; - - GetPrivateProfileString(_T("AutoExec"), _T("Use"), _T("prompt"), szUse, SIZEOF(szUse), mirandabootini); - if (!mir_tstrcmpi(szUse, _T("no"))) return; - GetPrivateProfileString(_T("AutoExec"), _T("Safe"), _T("CLC Icons CLUI CList SkinSounds"), buf, SIZEOF(buf), mirandabootini); - ptrA szSafeSections(mir_t2a(buf)); - GetPrivateProfileString(_T("AutoExec"), _T("Unsafe"), _T("AIM Facebook GG ICQ IRC JABBER MRA MSN SKYPE Tlen TWITTER VKontakte XFire"), buf, SIZEOF(buf), mirandabootini); - ptrA szUnsafeSections(mir_t2a(buf)); - GetPrivateProfileString(_T("AutoExec"), _T("Warn"), _T("notsafe"), szSecurity, SIZEOF(szSecurity), mirandabootini); - if (!mir_tstrcmpi(szSecurity, _T("none"))) secur = 0; - else if (!mir_tstrcmpi(szSecurity, _T("notsafe"))) secur = 1; - else if (!mir_tstrcmpi(szSecurity, _T("onlyunsafe"))) secur = 2; - - GetPrivateProfileString(_T("AutoExec"), _T("OverrideSecurityFilename"), _T(""), szOverrideSecurityFilename, SIZEOF(szOverrideSecurityFilename), mirandabootini); - GetPrivateProfileString(_T("AutoExec"), _T("OnCreateFilename"), _T(""), szOnCreateFilename, SIZEOF(szOnCreateFilename), mirandabootini); - GetPrivateProfileString(_T("AutoExec"), _T("Glob"), _T("autoexec_*.ini"), szFindPath, SIZEOF(szFindPath), mirandabootini); - - if (g_bDbCreated && szOnCreateFilename[0]) { - PathToAbsoluteT(VARST(szOnCreateFilename), szIniPath); - ProcessIniFile(szIniPath, szSafeSections, szUnsafeSections, 0, 1); - } - - PathToAbsoluteT(VARST(szFindPath), szFindPath); - - WIN32_FIND_DATA fd; - HANDLE hFind = FindFirstFile(szFindPath, &fd); - if (hFind == INVALID_HANDLE_VALUE) - return; - - TCHAR *str2 = _tcsrchr(szFindPath, '\\'); - if (str2 == NULL) - szFindPath[0] = 0; - else - str2[1] = 0; - - do { - bool secFN = mir_tstrcmpi(fd.cFileName, szOverrideSecurityFilename) == 0; - - mir_sntprintf(szIniPath, SIZEOF(szIniPath), _T("%s%s"), szFindPath, fd.cFileName); - if (!mir_tstrcmpi(szUse, _T("prompt")) && !secFN) { - int result = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_INSTALLINI), NULL, InstallIniDlgProc, (LPARAM)szIniPath); - if (result == IDC_NOTOALL) break; - if (result == IDCANCEL) continue; - } - - ProcessIniFile(szIniPath, szSafeSections, szUnsafeSections, secur, secFN); - - if (secFN) - DeleteFile(szIniPath); - else { - TCHAR szOnCompletion[8]; - GetPrivateProfileString(_T("AutoExec"), _T("OnCompletion"), _T("recycle"), szOnCompletion, SIZEOF(szOnCompletion), mirandabootini); - if (!mir_tstrcmpi(szOnCompletion, _T("delete"))) - DeleteFile(szIniPath); - else if (!mir_tstrcmpi(szOnCompletion, _T("recycle"))) { - SHFILEOPSTRUCT shfo = { 0 }; - shfo.wFunc = FO_DELETE; - shfo.pFrom = szIniPath; - szIniPath[mir_tstrlen(szIniPath) + 1] = 0; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOF_ALLOWUNDO; - SHFileOperation(&shfo); - } - else if (!mir_tstrcmpi(szOnCompletion, _T("rename"))) { - TCHAR szRenamePrefix[MAX_PATH], szNewPath[MAX_PATH]; - GetPrivateProfileString(_T("AutoExec"), _T("RenamePrefix"), _T("done_"), szRenamePrefix, SIZEOF(szRenamePrefix), mirandabootini); - mir_tstrcpy(szNewPath, szFindPath); - mir_tstrcat(szNewPath, szRenamePrefix); - mir_tstrcat(szNewPath, fd.cFileName); - MoveFile(szIniPath, szNewPath); - } - else if (!mir_tstrcmpi(szOnCompletion, _T("ask"))) - DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_INIIMPORTDONE), NULL, IniImportDoneDlgProc, (LPARAM)szIniPath); - } - } - while (FindNextFile(hFind, &fd)); - - FindClose(hFind); -} - -static INT_PTR CheckIniImportNow(WPARAM, LPARAM) -{ - DoAutoExec(); - FindNextChangeNotification(hIniChangeNotification); - return 0; -} - -int InitIni(void) -{ - bModuleInitialized = true; - - DoAutoExec(); - - TCHAR szMirandaDir[MAX_PATH]; - PathToAbsoluteT(_T("."), szMirandaDir); - hIniChangeNotification = FindFirstChangeNotification(szMirandaDir, 0, FILE_NOTIFY_CHANGE_FILE_NAME); - if (hIniChangeNotification != INVALID_HANDLE_VALUE) { - CreateServiceFunction("DB/Ini/CheckImportNow", CheckIniImportNow); - CallService(MS_SYSTEM_WAITONHANDLE, (WPARAM)hIniChangeNotification, (LPARAM)"DB/Ini/CheckImportNow"); - } - return 0; -} - -void UninitIni(void) -{ - if (!bModuleInitialized) - return; - - CallService(MS_SYSTEM_REMOVEWAIT, (WPARAM)hIniChangeNotification, 0); - FindCloseChangeNotification(hIniChangeNotification); -} diff --git a/src/modules/database/dbintf.cpp b/src/modules/database/dbintf.cpp deleted file mode 100644 index fed80cd528..0000000000 --- a/src/modules/database/dbintf.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-15 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "database.h" - -MIDatabase *currDb = NULL; -DATABASELINK *currDblink = NULL; - -MIR_CORE_DLL(void) db_setCurrent(MIDatabase*); - -static INT_PTR srvSetSafetyMode(WPARAM wParam, LPARAM) -{ - if (!currDb) return 1; - - currDb->SetCacheSafetyMode(wParam != 0); - return 0; -} - -static INT_PTR srvGetContactCount(WPARAM, LPARAM) -{ - return (currDb) ? currDb->GetContactCount() : 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Contacts - -static INT_PTR srvDeleteContact(WPARAM wParam, LPARAM) -{ - DBVARIANT dbv = { 0 }; - if (!db_get_ts(wParam, "ContactPhoto", "File", &dbv)) { - DeleteFile(dbv.ptszVal); - db_free(&dbv); - } - return (currDb) ? currDb->DeleteContact(wParam) : 0; -} - -static INT_PTR srvAddContact(WPARAM wParam, LPARAM) -{ - MCONTACT hNew = (currDb) ? currDb->AddContact() : 0; - Netlib_Logf(NULL, "New contact created: %d", hNew); - return hNew; -} - -static INT_PTR srvIsDbContact(WPARAM wParam, LPARAM) -{ - return (currDb) ? currDb->IsDbContact(wParam) : 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Module chain - -static INT_PTR srvEnumModuleNames(WPARAM wParam, LPARAM lParam) -{ - return (currDb) ? (INT_PTR)currDb->EnumModuleNames((DBMODULEENUMPROC)lParam, (void*)wParam) : 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Settings - -static INT_PTR srvEnumContactSettings(WPARAM wParam, LPARAM lParam) -{ - return (currDb) ? (INT_PTR)currDb->EnumContactSettings(wParam, (DBCONTACTENUMSETTINGS*)lParam) : 0; -} - -static INT_PTR srvEnumResidentSettings(WPARAM wParam, LPARAM lParam) -{ - return (currDb) ? (INT_PTR)currDb->EnumResidentSettings((DBMODULEENUMPROC)wParam, (void*)lParam) : 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Database list - -LIST arDbPlugins(5); - -static INT_PTR srvRegisterPlugin(WPARAM wParam, LPARAM lParam) -{ - DATABASELINK* pPlug = (DATABASELINK*)lParam; - if (pPlug == NULL) - return 1; - - arDbPlugins.insert(pPlug); - return 0; -} - -static INT_PTR srvFindPlugin(WPARAM wParam, LPARAM lParam) -{ - for (int i = arDbPlugins.getCount() - 1; i >= 0; i--) { - int error = arDbPlugins[i]->grokHeader((TCHAR*)lParam); - if (error == ERROR_SUCCESS || error == EGROKPRF_OBSOLETE) - return (INT_PTR)arDbPlugins[i]; - } - - return NULL; -} - -static INT_PTR srvGetCurrentDb(WPARAM wParam, LPARAM lParam) -{ - return (INT_PTR)currDb; -} - -static INT_PTR srvInitInstance(WPARAM wParam, LPARAM lParam) -{ - MIDatabase* pDb = (MIDatabase*)lParam; - if (pDb != NULL) - pDb->m_cache = new MDatabaseCache(pDb->GetContactSize()); - return 0; -} - -static INT_PTR srvDestroyInstance(WPARAM wParam, LPARAM lParam) -{ - MIDatabase* pDb = (MIDatabase*)lParam; - if (pDb != NULL) { - MDatabaseCache *pCache = (MDatabaseCache*)pDb->m_cache; - pDb->m_cache = NULL; - delete pCache; - } - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// - -int LoadDbintfModule() -{ - CreateServiceFunction(MS_DB_CONTACT_GETCOUNT, srvGetContactCount); - CreateServiceFunction(MS_DB_CONTACT_DELETE, srvDeleteContact); - CreateServiceFunction(MS_DB_CONTACT_ADD, srvAddContact); - CreateServiceFunction(MS_DB_CONTACT_IS, srvIsDbContact); - - CreateServiceFunction(MS_DB_MODULES_ENUM, srvEnumModuleNames); - - CreateServiceFunction(MS_DB_CONTACT_ENUMSETTINGS, srvEnumContactSettings); - CreateServiceFunction("DB/ResidentSettings/Enum", srvEnumResidentSettings); - - CreateServiceFunction(MS_DB_REGISTER_PLUGIN, srvRegisterPlugin); - CreateServiceFunction(MS_DB_FIND_PLUGIN, srvFindPlugin); - CreateServiceFunction(MS_DB_GET_CURRENT, srvGetCurrentDb); - - CreateServiceFunction(MS_DB_INIT_INSTANCE, srvInitInstance); - CreateServiceFunction(MS_DB_DESTROY_INSTANCE, srvDestroyInstance); - return 0; -} - -void LoadDatabaseServices() -{ - CreateServiceFunction(MS_DB_SETSAFETYMODE, srvSetSafetyMode); -} diff --git a/src/modules/database/dbutils.cpp b/src/modules/database/dbutils.cpp deleted file mode 100644 index 880e8a59d8..0000000000 --- a/src/modules/database/dbutils.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "profilemanager.h" - -static int CompareEventTypes(const DBEVENTTYPEDESCR *p1, const DBEVENTTYPEDESCR *p2) -{ - int result = mir_strcmp(p1->module, p2->module); - if (result) - return result; - - return p1->eventType - p2->eventType; -} - -static LIST eventTypes(10, CompareEventTypes); - -static BOOL bModuleInitialized = FALSE; - -static INT_PTR DbEventTypeRegister(WPARAM, LPARAM lParam) -{ - DBEVENTTYPEDESCR *et = (DBEVENTTYPEDESCR*)lParam; - if (et == NULL || et->cbSize != sizeof(DBEVENTTYPEDESCR)) - return -1; - - if (eventTypes.getIndex(et) != -1) - return -1; - - DBEVENTTYPEDESCR *p = (DBEVENTTYPEDESCR*)mir_calloc(sizeof(DBEVENTTYPEDESCR)); - p->cbSize = sizeof(DBEVENTTYPEDESCR); - p->module = mir_strdup(et->module); - p->eventType = et->eventType; - p->descr = mir_strdup(et->descr); - if (et->textService) - p->textService = mir_strdup(et->textService); - if (et->iconService) - p->iconService = mir_strdup(et->iconService); - p->eventIcon = et->eventIcon; - p->flags = et->flags; - - if (!p->textService) { - char szServiceName[100]; - mir_snprintf(szServiceName, SIZEOF(szServiceName), "%s/GetEventText%d", p->module, p->eventType); - p->textService = mir_strdup(szServiceName); - } - if (!p->iconService) { - char szServiceName[100]; - mir_snprintf(szServiceName, SIZEOF(szServiceName), "%s/GetEventIcon%d", p->module, p->eventType); - p->iconService = mir_strdup(szServiceName); - } - eventTypes.insert(p); - return 0; -} - -static INT_PTR DbEventTypeGet(WPARAM wParam, LPARAM lParam) -{ - DBEVENTTYPEDESCR tmp; - tmp.module = (char*)wParam; - tmp.eventType = lParam; - return (INT_PTR)eventTypes.find(&tmp); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static TCHAR* getEventString(DBEVENTINFO *dbei, LPSTR &buf) -{ - LPSTR in = buf; - buf += mir_strlen(buf) + 1; - return (dbei->flags & DBEF_UTF) ? Utf8DecodeT(in) : mir_a2t(in); -} - -static INT_PTR DbEventGetText(WPARAM wParam, LPARAM lParam) -{ - DBEVENTGETTEXT* egt = (DBEVENTGETTEXT*)lParam; - if (egt == NULL) - return 0; - - DBEVENTINFO *dbei = egt->dbei; - if (dbei == NULL || dbei->szModule == NULL || dbei->cbSize != sizeof(DBEVENTINFO)) - return 0; - - DBEVENTTYPEDESCR *et = (DBEVENTTYPEDESCR*)DbEventTypeGet((WPARAM)dbei->szModule, (LPARAM)dbei->eventType); - if (et && ServiceExists(et->textService)) - return CallService(et->textService, wParam, lParam); - - if (!dbei->pBlob) - return 0; - - if (dbei->eventType == EVENTTYPE_AUTHREQUEST || dbei->eventType == EVENTTYPE_ADDED) { - // EVENTTYPE_AUTHREQUEST: uin(DWORD), hContact(DWORD), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ) - // EVENTTYPE_ADDED: uin(DWORD), hContact(HANDLE), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ) - DWORD uin = *(DWORD*)dbei->pBlob; - MCONTACT hContact = (MCONTACT)*(DWORD*)(dbei->pBlob + sizeof(DWORD)); - char *buf = LPSTR(dbei->pBlob) + sizeof(DWORD)*2; - ptrT tszNick(getEventString(dbei, buf)); - ptrT tszFirst(getEventString(dbei, buf)); - ptrT tszLast(getEventString(dbei, buf)); - ptrT tszEmail(getEventString(dbei, buf)); - - CMString nick, text; - if (tszFirst || tszLast) { - nick.AppendFormat(_T("%s %s"), tszFirst, tszLast); - nick.Trim(); - } - if (tszEmail) { - if (!nick.IsEmpty()) - nick.Append(_T(", ")); - nick.Append(tszEmail); - } - if (uin != 0) { - if (!nick.IsEmpty()) - nick.Append(_T(", ")); - nick.AppendFormat(_T("%d"), uin); - } - if (!nick.IsEmpty()) - nick = _T("(") + nick + _T(")"); - - if (dbei->eventType == EVENTTYPE_AUTHREQUEST) { - ptrT tszReason(getEventString(dbei, buf)); - text.Format(TranslateT("Authorization request from %s%s: %s"), - (tszNick == NULL) ? cli.pfnGetContactDisplayName(hContact, 0) : tszNick, nick, tszReason); - } - else text.Format(TranslateT("You were added by %s%s"), - (tszNick == NULL) ? cli.pfnGetContactDisplayName(hContact, 0) : tszNick, nick); - return (egt->datatype == DBVT_WCHAR) ? (INT_PTR)mir_tstrdup(text) : (INT_PTR)mir_t2a(text); - } - - if (dbei->eventType == EVENTTYPE_CONTACTS) { - CMString text(TranslateT("Contacts: ")); - // blob is: [uin(ASCIIZ), nick(ASCIIZ)]* - char *buf = LPSTR(dbei->pBlob), *limit = LPSTR(dbei->pBlob) + dbei->cbBlob; - while (buf < limit) { - ptrT tszUin(getEventString(dbei, buf)); - ptrT tszNick(getEventString(dbei, buf)); - if (tszNick && *tszNick) - text.AppendFormat(_T("\"%s\" "), tszNick); - if (tszUin && *tszUin) - text.AppendFormat(_T("<%s>; "), tszUin); - } - return (egt->datatype == DBVT_WCHAR) ? (INT_PTR)mir_tstrdup(text) : (INT_PTR)mir_t2a(text); - } - - if (dbei->eventType == EVENTTYPE_FILE) { - char *buf = LPSTR(dbei->pBlob) + sizeof(DWORD); - ptrT tszFileName(getEventString(dbei, buf)); - ptrT tszDescription(getEventString(dbei, buf)); - ptrT &ptszText = (mir_tstrlen(tszDescription) == 0) ? tszFileName : tszDescription; - switch (egt->datatype) { - case DBVT_WCHAR: - return (INT_PTR)ptszText.detach(); - case DBVT_ASCIIZ: - return (INT_PTR)mir_t2a(ptszText); - } - return 0; - } - - // by default treat an event's blob as a string - if (egt->datatype == DBVT_WCHAR) { - char *str = (char*)alloca(dbei->cbBlob + 1); - memcpy(str, dbei->pBlob, dbei->cbBlob); - str[dbei->cbBlob] = 0; - - if (dbei->flags & DBEF_UTF) { - WCHAR *msg = NULL; - Utf8DecodeCP(str, egt->codepage, &msg); - if (msg) - return (INT_PTR)msg; - } - - return (INT_PTR)mir_a2t_cp(str, egt->codepage); - } - - if (egt->datatype == DBVT_ASCIIZ) { - char *msg = mir_strdup((char*)dbei->pBlob); - if (dbei->flags & DBEF_UTF) - Utf8DecodeCP(msg, egt->codepage, NULL); - - return (INT_PTR)msg; - } - return 0; -} - -static INT_PTR DbEventGetIcon(WPARAM wParam, LPARAM lParam) -{ - DBEVENTINFO* dbei = (DBEVENTINFO*)lParam; - HICON icon = NULL; - DBEVENTTYPEDESCR* et = (DBEVENTTYPEDESCR*)DbEventTypeGet((WPARAM)dbei->szModule, (LPARAM)dbei->eventType); - - if (et && ServiceExists(et->iconService)) { - icon = (HICON)CallService(et->iconService, wParam, lParam); - if (icon) - return (INT_PTR)icon; - } - if (et && et->eventIcon) - icon = Skin_GetIconByHandle(et->eventIcon); - if (!icon) { - char szName[100]; - mir_snprintf(szName, SIZEOF(szName), "eventicon_%s%d", dbei->szModule, dbei->eventType); - icon = Skin_GetIcon(szName); - } - - if (!icon) { - switch(dbei->eventType) { - case EVENTTYPE_URL: - icon = LoadSkinIcon(SKINICON_EVENT_URL); - break; - - case EVENTTYPE_FILE: - icon = LoadSkinIcon(SKINICON_EVENT_FILE); - break; - - default: // EVENTTYPE_MESSAGE and unknown types - icon = LoadSkinIcon(SKINICON_EVENT_MESSAGE); - break; - } - } - - return (INT_PTR)((wParam & LR_SHARED) ? icon : CopyIcon(icon)); -} - -static INT_PTR DbEventGetStringT(WPARAM wParam, LPARAM lParam) -{ - DBEVENTINFO* dbei = (DBEVENTINFO*)wParam; - char *string = (char*)lParam; - - if (dbei->flags & DBEF_UTF) - return (INT_PTR)Utf8DecodeW(string); - - return (INT_PTR)mir_a2t(string); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static int sttEnumVars(const char *szVarName, LPARAM lParam) -{ - LIST* vars = (LIST*)lParam; - vars->insert(mir_strdup(szVarName)); - return 0; -} - -static INT_PTR DbDeleteModule(WPARAM hContact, LPARAM lParam) -{ - LIST vars(20); - - DBCONTACTENUMSETTINGS dbces = { 0 }; - dbces.pfnEnumProc = sttEnumVars; - dbces.lParam = (LPARAM)&vars; - dbces.szModule = (char*)lParam; - CallService(MS_DB_CONTACT_ENUMSETTINGS, hContact, (LPARAM)&dbces); - - for (int i = vars.getCount()-1; i >= 0; i--) { - db_unset(hContact, (char*)lParam, vars[i]); - mir_free(vars[i]); - } - return 0; -} - -static INT_PTR GetProfilePath(WPARAM wParam, LPARAM lParam) -{ - if (!wParam || !lParam) - return 1; - - char *dst = (char*)lParam; - strncpy(dst, _T2A(g_profileDir), wParam); - dst[wParam-1] = 0; - return 0; -} - -static INT_PTR GetProfileName(WPARAM wParam, LPARAM lParam) -{ - if (!wParam || !lParam) - return 1; - - char *dst = (char*)lParam; - - char *tmp = makeFileName(g_profileName); - strncpy(dst, tmp, wParam); - mir_free(tmp); - - dst[wParam-1] = 0; - return 0; -} - -static INT_PTR GetProfilePathW(WPARAM wParam, LPARAM lParam) -{ - if (!wParam || !lParam) - return 1; - - wchar_t *dst = (wchar_t*)lParam; - wcsncpy(dst, g_profileDir, wParam); - dst[wParam-1] = 0; - return 0; -} - -static INT_PTR GetProfileNameW(WPARAM wParam, LPARAM lParam) -{ - wchar_t *dst = (wchar_t*)lParam; - wcsncpy(dst, g_profileName, wParam); - dst[wParam-1] = 0; - return 0; -} - -static INT_PTR SetDefaultProfile(WPARAM wParam, LPARAM lParam) -{ - extern TCHAR* g_defaultProfile; - replaceStrT(g_defaultProfile, (TCHAR*)wParam); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -int LoadEventsModule() -{ - bModuleInitialized = TRUE; - - CreateServiceFunction(MS_DB_EVENT_REGISTERTYPE, DbEventTypeRegister); - CreateServiceFunction(MS_DB_EVENT_GETTYPE, DbEventTypeGet); - CreateServiceFunction(MS_DB_EVENT_GETTEXT, DbEventGetText); - CreateServiceFunction(MS_DB_EVENT_GETICON, DbEventGetIcon); - CreateServiceFunction(MS_DB_EVENT_GETSTRINGT, DbEventGetStringT); - - CreateServiceFunction(MS_DB_MODULE_DELETE, DbDeleteModule); - - CreateServiceFunction(MS_DB_GETPROFILEPATH, GetProfilePath); - CreateServiceFunction(MS_DB_GETPROFILENAME, GetProfileName); - CreateServiceFunction(MS_DB_GETPROFILEPATHW, GetProfilePathW); - CreateServiceFunction(MS_DB_GETPROFILENAMEW, GetProfileNameW); - - CreateServiceFunction(MS_DB_SETDEFAULTPROFILE, SetDefaultProfile); - return 0; -} - -void UnloadEventsModule() -{ - if (!bModuleInitialized) - return; - - for (int i=0; i < eventTypes.getCount(); i++) { - DBEVENTTYPEDESCR *p = eventTypes[i]; - mir_free(p->module); - mir_free(p->descr); - mir_free(p->textService); - mir_free(p->iconService); - mir_free(p); - } -} diff --git a/src/modules/database/mdatabasecache.cpp b/src/modules/database/mdatabasecache.cpp deleted file mode 100644 index ffc9631d77..0000000000 --- a/src/modules/database/mdatabasecache.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-15 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "database.h" - -static int stringCompare(const char *p1, const char *p2) -{ - return mir_strcmp(p1, p2); -} - -static int compareGlobals(const DBCachedGlobalValue *p1, const DBCachedGlobalValue *p2) -{ - return mir_strcmp(p1->name, p2->name); -} - -MDatabaseCache::MDatabaseCache(size_t _size) : - m_contactSize(_size), - m_lSettings(100, stringCompare), - m_lContacts(50, NumericKeySortT), - m_lGlobalSettings(50, compareGlobals), - m_lastSetting(NULL), - m_lastVL(NULL) -{ - m_hCacheHeap = HeapCreate(0, 0, 0); -} - -MDatabaseCache::~MDatabaseCache() -{ - for (int i = 0; i < m_lContacts.getCount(); i++) - mir_free(m_lContacts[i]->pSubs); - - HeapDestroy(m_hCacheHeap); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -DBCachedContact* MDatabaseCache::AddContactToCache(MCONTACT contactID) -{ - mir_cslock lck(m_cs); - - int index = m_lContacts.getIndex((DBCachedContact*)&contactID); - if (index != -1) - return m_lContacts[index]; - - DBCachedContact *cc = (DBCachedContact*)HeapAlloc(m_hCacheHeap, HEAP_ZERO_MEMORY, m_contactSize); - cc->contactID = contactID; - cc->nSubs = -1; - m_lContacts.insert(cc); - return cc; -} - -DBCachedContact* MDatabaseCache::GetCachedContact(MCONTACT contactID) -{ - mir_cslock lck(m_cs); - - int index = m_lContacts.getIndex((DBCachedContact*)&contactID); - return (index == -1) ? NULL : m_lContacts[index]; -} - -DBCachedContact* MDatabaseCache::GetFirstContact() -{ - mir_cslock lck(m_cs); - return m_lContacts[0]; -} - -DBCachedContact* MDatabaseCache::GetNextContact(MCONTACT contactID) -{ - mir_cslock lck(m_cs); - - int index = m_lContacts.getIndex((DBCachedContact*)&contactID); - return (index == -1) ? NULL : m_lContacts[index+1]; -} - -void MDatabaseCache::FreeCachedContact(MCONTACT contactID) -{ - mir_cslock lck(m_cs); - - int index = m_lContacts.getIndex((DBCachedContact*)&contactID); - if (index == -1) - return; - - DBCachedContact *cc = m_lContacts[index]; - DBCachedContactValue* V = cc->first; - while (V != NULL) { - DBCachedContactValue* V1 = V->next; - FreeCachedVariant(&V->value); - HeapFree(m_hCacheHeap, 0, V); - V = V1; - } - - mir_free(cc->pSubs); - HeapFree(m_hCacheHeap, 0, cc); - - m_lContacts.remove(index); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -char* MDatabaseCache::InsertCachedSetting(const char* szName, int cbLen) -{ - char* newValue = (char*)HeapAlloc(m_hCacheHeap, 0, cbLen); - *newValue++ = 0; - mir_strcpy(newValue, szName); - m_lSettings.insert(newValue); - return newValue; -} - -char* MDatabaseCache::GetCachedSetting(const char *szModuleName, const char *szSettingName, int moduleNameLen, int settingNameLen) -{ - char szFullName[512]; - const char *szKey; - if (szModuleName != NULL) { - mir_strcpy(szFullName, szModuleName); - szFullName[moduleNameLen] = '/'; - mir_strcpy(szFullName + moduleNameLen + 1, szSettingName); - szKey = szFullName; - } - else szKey = szSettingName; - - if (m_lastSetting && !mir_strcmp(szKey, m_lastSetting)) - return m_lastSetting; - - int index = m_lSettings.getIndex((char*)szKey); - if (index != -1) - m_lastSetting = m_lSettings[index]; - else - m_lastSetting = InsertCachedSetting(szKey, settingNameLen + moduleNameLen + 3); - - return m_lastSetting; -} - -void MDatabaseCache::SetCachedVariant(DBVARIANT* s /* new */, DBVARIANT* d /* cached */) -{ - char* szSave = (d->type == DBVT_UTF8 || d->type == DBVT_ASCIIZ) ? d->pszVal : NULL; - - memcpy(d, s, sizeof(DBVARIANT)); - if ((s->type == DBVT_UTF8 || s->type == DBVT_ASCIIZ) && s->pszVal != NULL) { - if (szSave != NULL) - d->pszVal = (char*)HeapReAlloc(m_hCacheHeap, 0, szSave, mir_strlen(s->pszVal) + 1); - else - d->pszVal = (char*)HeapAlloc(m_hCacheHeap, 0, mir_strlen(s->pszVal) + 1); - mir_strcpy(d->pszVal, s->pszVal); - } - else if (szSave != NULL) - HeapFree(m_hCacheHeap, 0, szSave); -} - -void MDatabaseCache::FreeCachedVariant(DBVARIANT* V) -{ - if ((V->type == DBVT_ASCIIZ || V->type == DBVT_UTF8) && V->pszVal != NULL) - HeapFree(m_hCacheHeap, 0, V->pszVal); -} - -STDMETHODIMP_(DBVARIANT*) MDatabaseCache::GetCachedValuePtr(MCONTACT contactID, char *szSetting, int bAllocate) -{ - // a global setting - if (contactID == 0) { - DBCachedGlobalValue Vtemp, *V; - Vtemp.name = szSetting; - int index = m_lGlobalSettings.getIndex(&Vtemp); - if (index != -1) { - V = m_lGlobalSettings[index]; - if (bAllocate == -1) { - FreeCachedVariant(&V->value); - m_lGlobalSettings.remove(index); - HeapFree(m_hCacheHeap, 0, V); - return NULL; - } - } - else { - if (bAllocate != 1) - return NULL; - - V = (DBCachedGlobalValue*)HeapAlloc(m_hCacheHeap, HEAP_ZERO_MEMORY, sizeof(DBCachedGlobalValue)); - V->name = szSetting; - m_lGlobalSettings.insert(V); - } - - return &V->value; - } - - // a contact setting - DBCachedContactValue *V, *V1; - DBCachedContact ccTemp, *cc; - - ccTemp.contactID = contactID; - - int index = m_lContacts.getIndex(&ccTemp); - if (index == -1) - return NULL; - - m_lastVL = cc = m_lContacts[index]; - - for (V = cc->first; V != NULL; V = V->next) - if (V->name == szSetting) - break; - - if (V == NULL) { - if (bAllocate != 1) - return NULL; - - V = (DBCachedContactValue *)HeapAlloc(m_hCacheHeap, HEAP_ZERO_MEMORY, sizeof(DBCachedContactValue)); - if (cc->last) - cc->last->next = V; - else - cc->first = V; - cc->last = V; - V->name = szSetting; - } - else if (bAllocate == -1) { - m_lastVL = NULL; - FreeCachedVariant(&V->value); - if (cc->first == V) { - cc->first = V->next; - if (cc->last == V) - cc->last = V->next; // NULL - } - else - for (V1 = cc->first; V1 != NULL; V1 = V1->next) - if (V1->next == V) { - V1->next = V->next; - if (cc->last == V) - cc->last = V1; - break; - } - HeapFree(m_hCacheHeap, 0, V); - return NULL; - } - - return &V->value; -} diff --git a/src/modules/database/profilemanager.cpp b/src/modules/database/profilemanager.cpp deleted file mode 100644 index 0dc3c75304..0000000000 --- a/src/modules/database/profilemanager.cpp +++ /dev/null @@ -1,649 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "..\plugins\plugins.h" -#include "..\langpack\langpack.h" -#include "profilemanager.h" -#include - -void EnsureCheckerLoaded(bool); - -#define WM_INPUTCHANGED (WM_USER + 0x3000) -#define WM_FOCUSTEXTBOX (WM_USER + 0x3001) - -typedef BOOL (__cdecl *ENUMPROFILECALLBACK) (TCHAR *tszFullPath, TCHAR *profile, LPARAM lParam); - -void SetServiceModePlugin(pluginEntry *p); - -///////////////////////////////////////////////////////////////////////////////////////// -// Profile creator - -static int findProfiles(TCHAR *szProfileDir, ENUMPROFILECALLBACK callback, LPARAM lParam) -{ - // find in Miranda NG profile subfolders - TCHAR searchspec[MAX_PATH]; - mir_sntprintf(searchspec, SIZEOF(searchspec), _T("%s\\*.*"), szProfileDir); - - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile(searchspec, &ffd); - if (hFind == INVALID_HANDLE_VALUE) - return 0; - - do { - // find all subfolders except "." and ".." - if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && mir_tstrcmp(ffd.cFileName, _T(".")) && mir_tstrcmp(ffd.cFileName, _T(".."))) { - TCHAR buf[MAX_PATH], profile[MAX_PATH]; - mir_sntprintf(buf, _T("%s\\%s\\%s.dat"), szProfileDir, ffd.cFileName, ffd.cFileName); - if (_taccess(buf, 0) == 0) { - mir_sntprintf(profile, SIZEOF(profile), _T("%s.dat"), ffd.cFileName); - if (!callback(buf, profile, lParam)) - break; - } - } - } - while (FindNextFile(hFind, &ffd)); - - FindClose(hFind); - return 1; -} - -static LRESULT CALLBACK ProfileNameValidate(HWND edit, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (msg == WM_CHAR) { - if (_tcschr(_T(".?/\\#' "), (TCHAR)wParam) != 0) - return 0; - PostMessage(GetParent(edit), WM_INPUTCHANGED, 0, 0); - } - return mir_callNextSubclass(edit, ProfileNameValidate, msg, wParam, lParam); -} - -class CCreateProfileDlg : public CDlgBase -{ - CCtrlButton &m_btnOk; - PROFILEMANAGERDATA *m_pd; - - int CreateProfile(TCHAR *profile, DATABASELINK *link) - { - TCHAR buf[256]; - int err = 0; - // check if the file already exists - TCHAR *file = _tcsrchr(profile, '\\'); - if (file) file++; - if (_taccess(profile, 0) == 0) { - // file already exists! - mir_sntprintf(buf, - TranslateT("The profile '%s' already exists. Do you want to move it to the Recycle Bin?\n\nWARNING: The profile will be deleted if Recycle Bin is disabled.\nWARNING: A profile may contain confidential information and should be properly deleted."), - file); - if (MessageBox(m_hwnd, buf, TranslateT("The profile already exists"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) != IDYES) - return 0; - - // move the file - SHFILEOPSTRUCT sf = { 0 }; - sf.wFunc = FO_DELETE; - sf.pFrom = buf; - sf.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOF_ALLOWUNDO; - mir_sntprintf(buf, _T("%s\0"), profile); - if (SHFileOperation(&sf) != 0) { - mir_sntprintf(buf, TranslateT("Couldn't move '%s' to the Recycle Bin. Please select another profile name."), file); - MessageBox(m_hwnd, buf, TranslateT("Problem moving profile"), MB_ICONINFORMATION | MB_OK); - return 0; - } - // now the file should be gone! - } - // ask the database to create the profile - CreatePathToFileT(profile); - if ((err = link->makeDatabase(profile)) != ERROR_SUCCESS) { - mir_sntprintf(buf, TranslateT("Unable to create the profile '%s', the error was %x"), file, err); - MessageBox(m_hwnd, buf, TranslateT("Problem creating profile"), MB_ICONERROR | MB_OK); - return 0; - } - - // the profile has been created! - g_bDbCreated = true; - return 1; - } - - CCtrlCombo m_driverList; - CCtrlEdit m_profileName; - CCtrlBase m_warning; - -public: - CCreateProfileDlg(CCtrlButton &_btn, PROFILEMANAGERDATA *_pd) : - CDlgBase(hInst, IDD_PROFILE_NEW), - m_btnOk(_btn), - m_pd(_pd), - m_driverList(this, IDC_PROFILEDRIVERS), - m_profileName(this, IDC_PROFILENAME), - m_warning(this, IDC_NODBDRIVERS) - {} - - virtual void OnInitDialog() - { - // what, no plugins?! - if (arDbPlugins.getCount() == 0) { - m_driverList.Enable(false); - m_profileName.Enable(false); - ShowWindow(m_warning.GetHwnd(), TRUE); - } - else { - for (int i = 0; i < arDbPlugins.getCount(); i++) { - DATABASELINK *p = arDbPlugins[i]; - m_driverList.AddString(TranslateTS(p->szFullName), (LPARAM)p); - } - } - - // default item - m_driverList.SetCurSel(0); - - // subclass the profile name box - mir_subclassWindow(m_profileName.GetHwnd(), ProfileNameValidate); - - // decide if there is a default profile name given in the INI and if it should be used - if (m_pd->noProfiles || (shouldAutoCreate(m_pd->ptszProfile) && _taccess(m_pd->ptszProfile, 0))) { - TCHAR *profile = _tcsrchr(m_pd->ptszProfile, '\\'); - if (profile) ++profile; - else profile = m_pd->ptszProfile; - - TCHAR *p = _tcsrchr(profile, '.'); - TCHAR c = 0; - if (p) { c = *p; *p = 0; } - - m_profileName.SetText(profile); - if (c) *p = c; - } - - // focus on the textbox - PostMessage(m_hwnd, WM_FOCUSTEXTBOX, 0, 0); - } - - virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) - { - switch (msg) { - case WM_FOCUSTEXTBOX: - SetFocus(m_profileName.GetHwnd()); - break; - - case WM_INPUTCHANGED: // when input in the edit box changes - NotifyChange(); - m_btnOk.Enable(GetWindowTextLength(m_profileName.GetHwnd()) > 0); - break; - - case WM_SHOWWINDOW: - if (wParam) { - m_btnOk.SetText(TranslateT("&Create")); - SendMessage(m_hwnd, WM_INPUTCHANGED, 0, 0); - } - break; - } - return CDlgBase::DlgProc(msg, wParam, lParam); - } - - virtual void OnApply() - { - LRESULT curSel = m_driverList.GetCurSel(); - if (curSel == -1) - return; // should never happen - - ptrT szName(m_profileName.GetText()); - if (szName == 0) - return; - - // profile placed in "profile_name" subfolder - mir_sntprintf(m_pd->ptszProfile, MAX_PATH, _T("%s\\%s\\%s.dat"), m_pd->ptszProfileDir, szName, szName); - m_pd->newProfile = 1; - m_pd->dblink = (DATABASELINK *)m_driverList.GetItemData(curSel); - - if (CreateProfile(m_pd->ptszProfile, m_pd->dblink) == 0) - SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - else - m_pd->bRun = true; - } -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Profile selector - -class CChooseProfileDlg : public CDlgBase -{ - CCtrlButton &m_btnOk; - PROFILEMANAGERDATA *m_pd; - HANDLE m_hFileNotify; - - struct ProfileEnumData - { - CCtrlListView &list; - TCHAR* szProfile; - }; - - static BOOL EnumProfilesForList(TCHAR *tszFullPath, TCHAR *profile, LPARAM lParam) - { - ProfileEnumData *ped = (ProfileEnumData*)lParam; - CCtrlListView &list = ped->list; - - TCHAR sizeBuf[64]; - bool bFileLocked = true; - - TCHAR *p = _tcsrchr(profile, '.'); - mir_tstrcpy(sizeBuf, _T("0 KB")); - if (p != NULL) *p = 0; - - LVITEM item = { 0 }; - item.mask = LVIF_TEXT | LVIF_IMAGE; - item.pszText = profile; - item.iItem = 0; - - struct _stat statbuf; - if (_tstat(tszFullPath, &statbuf) == 0) { - if (statbuf.st_size > 1000000) { - mir_sntprintf(sizeBuf, SIZEOF(sizeBuf), _T("%.3lf"), (double)statbuf.st_size / 1048576.0); - mir_tstrcpy(sizeBuf + 5, _T(" MB")); - } - else { - mir_sntprintf(sizeBuf, SIZEOF(sizeBuf), _T("%.3lf"), (double)statbuf.st_size / 1024.0); - mir_tstrcpy(sizeBuf + 5, _T(" KB")); - } - bFileLocked = !fileExist(tszFullPath); - } - - DATABASELINK *dblink; - switch (touchDatabase(tszFullPath, &dblink)) { - case ERROR_SUCCESS: - item.iImage = bFileLocked; - break; - - case EGROKPRF_OBSOLETE: - item.iImage = 2; - break; - - default: - item.iImage = 3; - } - - int iItem = list.InsertItem(&item); - if (mir_tstrcmpi(ped->szProfile, tszFullPath) == 0) - list.SetItemState(iItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); - - list.SetItemText(iItem, 2, sizeBuf); - - if (dblink != NULL) { - if (bFileLocked) // file locked - list.SetItemText(iItem, 1, TranslateT("")); - else - list.SetItemText(iItem, 1, TranslateTS(dblink->szFullName)); - } - else list.SetItemText(iItem, 1, TranslateT("")); - - return TRUE; - } - - void CheckProfile(int iItem) - { - if (iItem < 0) - return; - - TCHAR profile[MAX_PATH], fullName[MAX_PATH]; - LVITEM item = { 0 }; - item.mask = LVIF_TEXT | LVIF_IMAGE; - item.iItem = iItem; - item.pszText = profile; - item.cchTextMax = SIZEOF(profile); - if (!m_profileList.GetItem(&item)) - return; - - mir_sntprintf(fullName, SIZEOF(fullName), _T("%s\\%s\\%s.dat"), m_pd->ptszProfileDir, profile, profile); - CallService(MS_DB_CHECKPROFILE, (WPARAM)fullName, item.iImage == 2); - } - - void DeleteProfile(int iItem) - { - if (iItem < 0) - return; - - TCHAR profile[MAX_PATH], profilef[MAX_PATH * 2]; - - LVITEM item = { 0 }; - item.mask = LVIF_TEXT; - item.iItem = iItem; - item.pszText = profile; - item.cchTextMax = SIZEOF(profile); - if (!m_profileList.GetItem(&item)) - return; - - mir_sntprintf(profilef, SIZEOF(profilef), TranslateT("Are you sure you want to remove profile \"%s\"?"), profile); - if (IDYES != MessageBox(NULL, profilef, _T("Miranda NG"), MB_YESNO | MB_TASKMODAL | MB_ICONWARNING)) - return; - - mir_sntprintf(profilef, SIZEOF(profilef), _T("%s\\%s%c"), m_pd->ptszProfileDir, profile, 0); - - SHFILEOPSTRUCT sf = { 0 }; - sf.wFunc = FO_DELETE; - sf.pFrom = profilef; - sf.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_ALLOWUNDO; - SHFileOperation(&sf); - m_profileList.DeleteItem(item.iItem); - } - - void CheckRun() - { - m_btnOk.Enable(m_profileList.GetSelectedCount() == 1); - - TCHAR profile[MAX_PATH]; - LVITEM item = { 0 }; - item.mask = LVIF_TEXT | LVIF_IMAGE; - item.iItem = m_profileList.GetNextItem(-1, LVNI_SELECTED | LVNI_ALL); - item.pszText = profile; - item.cchTextMax = SIZEOF(profile); - if (!m_profileList.GetItem(&item)) - return; - - switch(item.iImage) { - case 3: - m_btnOk.Enable(false); - return; - - case 2: - m_btnOk.SetText(TranslateT("&Convert")); - m_pd->bRun = false; - break; - - default: - m_btnOk.SetText(TranslateT("&Run")); - m_pd->bRun = true; - } - - // profile is placed in "profile_name" subfolder - - TCHAR tmpPath[MAX_PATH]; - mir_sntprintf(tmpPath, SIZEOF(tmpPath), _T("%s\\%s.dat"), m_pd->ptszProfileDir, profile); - if (_taccess(tmpPath, 2)) - mir_sntprintf(m_pd->ptszProfile, MAX_PATH, _T("%s\\%s\\%s.dat"), m_pd->ptszProfileDir, profile, profile); - else - _tcsncpy_s(m_pd->ptszProfile, MAX_PATH, tmpPath, _TRUNCATE); - } - - void ExecuteMenu(LPARAM lParam) - { - LVHITTESTINFO lvht = { 0 }; - lvht.pt.x = GET_X_LPARAM(lParam); - lvht.pt.y = GET_Y_LPARAM(lParam); - ScreenToClient(m_profileList.GetHwnd(), &lvht.pt); - - if (m_profileList.HitTest(&lvht) == -1) - return; - - if (lvht.iItem == -1) - return; - - LVITEM tvi = { 0 }; - tvi.mask = LVIF_IMAGE; - tvi.iItem = lvht.iItem; - if (!m_profileList.GetItem(&tvi)) - return; - - bool bConvert = (tvi.iImage == 2); - - lvht.pt.x = GET_X_LPARAM(lParam); - lvht.pt.y = GET_Y_LPARAM(lParam); - - HMENU hMenu = CreatePopupMenu(); - if (tvi.iImage < 2) { - AppendMenu(hMenu, MF_STRING, 1, TranslateT("Run")); - AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); - } - if (tvi.iImage != 3 && ServiceExists(MS_DB_CHECKPROFILE)) { - if (bConvert) - AppendMenu(hMenu, MF_STRING, 2, TranslateT("Convert database")); - else - AppendMenu(hMenu, MF_STRING, 2, TranslateT("Check database")); - AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); - } - AppendMenu(hMenu, MF_STRING, 3, TranslateT("Delete")); - int index = TrackPopupMenu(hMenu, TPM_RETURNCMD, lvht.pt.x, lvht.pt.y, 0, m_hwnd, NULL); - switch (index) { - case 1: - SendMessage(GetParent(m_hwndParent), WM_COMMAND, IDOK, 0); - break; - - case 2: - CheckProfile(lvht.iItem); - break; - - case 3: - DeleteProfile(lvht.iItem); - break; - } - DestroyMenu(hMenu); - } - - CCtrlListView m_profileList; - -public: - CChooseProfileDlg(CCtrlButton &_btn, PROFILEMANAGERDATA *_pd) : - CDlgBase(hInst, IDD_PROFILE_SELECTION), - m_btnOk(_btn), - m_pd(_pd), - m_profileList(this, IDC_PROFILELIST) - { - m_profileList.OnItemChanged = Callback(this, &CChooseProfileDlg::list_OnItemChanged); - m_profileList.OnKeyDown = Callback(this, &CChooseProfileDlg::list_OnKeyDown); - m_profileList.OnGetInfoTip = Callback(this, &CChooseProfileDlg::list_OnGetTip); - m_profileList.OnDoubleClick = Callback(this, &CChooseProfileDlg::list_OnDblClick); - } - - virtual void OnInitDialog() - { - // set columns - LVCOLUMN col; - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.pszText = TranslateT("Profile"); - col.cx = 100; - m_profileList.InsertColumn(0, &col); - - col.pszText = TranslateT("Driver"); - col.cx = 150 - GetSystemMetrics(SM_CXVSCROLL); - m_profileList.InsertColumn(1, &col); - - col.pszText = TranslateT("Size"); - col.cx = 60; - m_profileList.InsertColumn(2, &col); - - // icons - HIMAGELIST hImgList = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 2, 1); - ImageList_AddIcon_NotShared(hImgList, MAKEINTRESOURCE(IDI_USERDETAILS)); - ImageList_AddIcon_NotShared(hImgList, MAKEINTRESOURCE(IDI_DELETE)); - ImageList_AddIcon_NotShared(hImgList, MAKEINTRESOURCE(IDI_MWARNING)); - ImageList_AddIcon_NotShared(hImgList, MAKEINTRESOURCE(IDI_MFATAL)); - - // LV will destroy the image list - m_profileList.SetImageList(hImgList, LVSIL_SMALL); - m_profileList.SetExtendedListViewStyle(m_profileList.GetExtendedListViewStyle() | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT); - - // find all the profiles - ProfileEnumData ped = { m_profileList, m_pd->ptszProfile }; - findProfiles(m_pd->ptszProfileDir, EnumProfilesForList, (LPARAM)&ped); - PostMessage(m_hwnd, WM_FOCUSTEXTBOX, 0, 0); - - m_hFileNotify = FindFirstChangeNotification(m_pd->ptszProfileDir, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE); - if (m_hFileNotify != INVALID_HANDLE_VALUE) - SetTimer(m_hwnd, 0, 1200, NULL); - } - - virtual void OnDestroy() - { - KillTimer(m_hwnd, 0); - FindCloseChangeNotification(m_hFileNotify); - } - - void list_OnItemChanged(CCtrlListView::TEventInfo*) - { - CheckRun(); - } - - void list_OnKeyDown(CCtrlListView::TEventInfo *evt) - { - if (evt->nmlvkey->wVKey == VK_DELETE) - DeleteProfile(m_profileList.GetNextItem(-1, LVNI_SELECTED | LVNI_ALL)); - } - - void list_OnGetTip(CCtrlListView::TEventInfo *evt) - { - if (auto pTip = evt->nmlvit) { - TCHAR profilename[MAX_PATH], tszFullPath[MAX_PATH]; - struct _stat statbuf; - m_profileList.GetItemText(pTip->iItem, 0, profilename, SIZEOF(profilename)); - mir_sntprintf(tszFullPath, SIZEOF(tszFullPath), _T("%s\\%s\\%s.dat"), m_pd->ptszProfileDir, profilename, profilename); - _tstat(tszFullPath, &statbuf); - mir_sntprintf(pTip->pszText, pTip->cchTextMax, _T("%s\n%s: %s\n%s: %s"), tszFullPath, TranslateT("Created"), rtrimt(NEWTSTR_ALLOCA(_tctime(&statbuf.st_ctime))), TranslateT("Modified"), rtrimt(NEWTSTR_ALLOCA(_tctime(&statbuf.st_mtime)))); - } - } - - void list_OnDblClick(CCtrlListView::TEventInfo *evt) - { - CheckRun(); - EndDialog(GetParent(m_hwndParent), 1); - } - - virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) - { - switch (msg) { - case WM_TIMER: - if (WaitForSingleObject(m_hFileNotify, 0) == WAIT_OBJECT_0) { - m_profileList.DeleteAllItems(); - ProfileEnumData ped = { m_profileList, m_pd->ptszProfile }; - findProfiles(m_pd->ptszProfileDir, EnumProfilesForList, (LPARAM)&ped); - FindNextChangeNotification(m_hFileNotify); - } - break; - - case WM_FOCUSTEXTBOX: - SetFocus(m_profileList.GetHwnd()); - if (m_pd->ptszProfile[0] == 0 || m_profileList.GetSelectedCount() == 0) - m_profileList.SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); - break; - - case WM_SHOWWINDOW: - if (wParam) - CheckRun(); - break; - - case WM_CONTEXTMENU: - ExecuteMenu(lParam); - break; - } - - return CDlgBase::DlgProc(msg, wParam, lParam); - } -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Tab manager + its envelope - -class CProfileManager : public CDlgBase -{ - PROFILEMANAGERDATA *m_pd; - - CCtrlPages m_tab; - CCtrlButton m_btnOk; - CCtrlCombo m_servicePlugs; - CCtrlBase m_warning; - -public: - CProfileManager(PROFILEMANAGERDATA *_pd) : - CDlgBase(hInst, IDD_PROFILEMANAGER), - m_btnOk(this, IDOK), - m_pd(_pd), - m_tab(this, IDC_TABS), - m_servicePlugs(this, IDC_SM_COMBO), - m_warning(this, IDC_SM_LABEL) - { - m_btnOk.OnClick = Callback(this, &CProfileManager::onOk); - - m_tab.AddPage(LPGENT("My profiles"), NULL, new CChooseProfileDlg(m_btnOk, m_pd)); - m_tab.AddPage(LPGENT("New profile"), NULL, new CCreateProfileDlg(m_btnOk, m_pd)); - } - - virtual void OnInitDialog() - { - SendMessage(m_hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadImage(hInst, MAKEINTRESOURCE(IDI_DETAILSLOGO), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0)); - SendMessage(m_hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadImage(hInst, MAKEINTRESOURCE(IDI_DETAILSLOGO), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0)); - - if (m_pd->noProfiles || shouldAutoCreate(m_pd->ptszProfile)) - m_tab.ActivatePage(1); - - // service mode combobox - if (servicePlugins.getCount() == 0) { - ShowWindow(m_warning.GetHwnd(), FALSE); - ShowWindow(m_servicePlugs.GetHwnd(), FALSE); - } - else { - m_servicePlugs.AddStringA("", -1); - m_servicePlugs.SetCurSel(0); - - for (int i = 0; i < servicePlugins.getCount(); i++) { - pluginEntry *p = servicePlugins[i]; - m_servicePlugs.AddString(TranslateTS(p->pluginname), i); - } - } - } - - virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) - { - switch (msg) { - case WM_CTLCOLORSTATIC: - switch (GetDlgCtrlID((HWND)lParam)) { - case IDC_WHITERECT: - SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); - return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); - } - break; - } - return CDlgBase::DlgProc(msg, wParam, lParam); - } - - virtual void OnDestroy() - { - LRESULT curSel = m_servicePlugs.GetCurSel(); - if (curSel != -1) { - int idx = m_servicePlugs.GetItemData(curSel); - if (idx != -1) - SetServiceModePlugin(servicePlugins[idx]); - } - - DestroyIcon((HICON)SendMessage(m_hwnd, WM_SETICON, ICON_SMALL, 0)); - DestroyIcon((HICON)SendMessage(m_hwnd, WM_SETICON, ICON_BIG, 0)); - } - - void onOk(CCtrlButton*) - { - EndDialog(m_hwnd, 1); - } -}; - -int getProfileManager(PROFILEMANAGERDATA *pd) -{ - EnsureCheckerLoaded(true); - - return CProfileManager(pd).DoModal(); -} diff --git a/src/modules/database/profilemanager.h b/src/modules/database/profilemanager.h deleted file mode 100644 index 21650375a2..0000000000 --- a/src/modules/database/profilemanager.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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. -*/ - -struct PROFILEMANAGERDATA -{ - TCHAR *ptszProfile; // in/out - TCHAR *ptszProfileDir; // in/out - BOOL noProfiles; // in - - BOOL bRun; // out - BOOL newProfile; // out - DATABASELINK *dblink; // out -}; - -char* makeFileName(const TCHAR *tszOriginalName); -int touchDatabase(const TCHAR *tszProfile, DATABASELINK **pDblink); -int getProfileManager(PROFILEMANAGERDATA *pd); -int getProfilePath(TCHAR *buf, size_t cch); -int isValidProfileName(const TCHAR *name); -bool fileExist(const TCHAR *fname); -bool shouldAutoCreate(TCHAR *szProfile); - -extern TCHAR g_profileDir[MAX_PATH], g_profileName[MAX_PATH], g_shortProfileName[MAX_PATH]; -extern bool g_bDbCreated; diff --git a/src/modules/extraicons/BaseExtraIcon.cpp b/src/modules/extraicons/BaseExtraIcon.cpp deleted file mode 100644 index eb56429bbf..0000000000 --- a/src/modules/extraicons/BaseExtraIcon.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - -Copyright (C) 2009 Ricardo Pescuma Domenecci -Copyright (C) 2012-15 Miranda NG project - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "extraicons.h" - -BaseExtraIcon::BaseExtraIcon(int id, const char *name, const TCHAR *description, const char *descIcon, MIRANDAHOOKPARAM OnClick, LPARAM param) : - ExtraIcon(name), id(id), OnClick(OnClick), onClickParam(param), - tszDescription(mir_tstrdup(description)), - szDescIcon(mir_strdup(descIcon)) -{ -} - -BaseExtraIcon::~BaseExtraIcon() -{ -} - -void BaseExtraIcon::setOnClick(MIRANDAHOOKPARAM pFunc, LPARAM pParam) -{ - OnClick = pFunc; - onClickParam = pParam; -} - -int BaseExtraIcon::getID() const -{ - return id; -} - -const TCHAR* BaseExtraIcon::getDescription() const -{ - return tszDescription; -} - -void BaseExtraIcon::setDescription(const TCHAR *desc) -{ - tszDescription = mir_tstrdup(desc); -} - -const char* BaseExtraIcon::getDescIcon() const -{ - return szDescIcon; -} - -void BaseExtraIcon::setDescIcon(const char *icon) -{ - szDescIcon = mir_strdup(icon); -} - -void BaseExtraIcon::onClick(MCONTACT hContact) -{ - if (OnClick != NULL) - OnClick(hContact, (LPARAM)ConvertToClistSlot(slot), onClickParam); -} - -int BaseExtraIcon::ClistSetExtraIcon(MCONTACT hContact, HANDLE hImage) -{ - ExtraIcon *tmp = extraIconsByHandle[id - 1]; - if (tmp != this) - return tmp->ClistSetExtraIcon(hContact, hImage); - return Clist_SetExtraIcon(hContact, slot, hImage); -} diff --git a/src/modules/extraicons/CallbackExtraIcon.cpp b/src/modules/extraicons/CallbackExtraIcon.cpp deleted file mode 100644 index 712e8e3b86..0000000000 --- a/src/modules/extraicons/CallbackExtraIcon.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - -Copyright (C) 2009 Ricardo Pescuma Domenecci -Copyright (C) 2012-15 Miranda NG project - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "extraicons.h" - -CallbackExtraIcon::CallbackExtraIcon(int _id, const char *_name, const TCHAR *_description, const char *_descIcon, - MIRANDAHOOK _RebuildIcons, MIRANDAHOOK _ApplyIcon, MIRANDAHOOKPARAM _OnClick, LPARAM _param) : - BaseExtraIcon(_id, _name, _description, _descIcon, _OnClick, _param), - RebuildIcons(_RebuildIcons), ApplyIcon(_ApplyIcon), needToRebuild(true) -{ -} - -CallbackExtraIcon::~CallbackExtraIcon() -{ -} - -int CallbackExtraIcon::getType() const -{ - return EXTRAICON_TYPE_CALLBACK; -} - -void CallbackExtraIcon::rebuildIcons() -{ - if (!isEnabled()) { - needToRebuild = true; - return; - } - - needToRebuild = false; - RebuildIcons(0, 0); -} - -void CallbackExtraIcon::applyIcon(MCONTACT hContact) -{ - if (!isEnabled() || hContact == NULL) - return; - - if (needToRebuild) - rebuildIcons(); - - ApplyIcon(hContact, 0); -} - -int CallbackExtraIcon::setIcon(int id, MCONTACT hContact, HANDLE icon) -{ - if (!isEnabled() || hContact == NULL || id != this->id) - return -1; - - return ClistSetExtraIcon(hContact, icon); -} - -int CallbackExtraIcon::setIconByName(int id, MCONTACT hContact, const char *icon) -{ - return -1; -} diff --git a/src/modules/extraicons/DefaultExtraIcons.cpp b/src/modules/extraicons/DefaultExtraIcons.cpp deleted file mode 100644 index dc1833d00f..0000000000 --- a/src/modules/extraicons/DefaultExtraIcons.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* - -Copyright (C) 2009 Ricardo Pescuma Domenecci -Copyright (C) 2012-15 Miranda NG project - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "m_cluiframes.h" - -#include "ExtraIcon.h" -#include "extraicons.h" - -ExtraIcon* GetExtraIcon(HANDLE id); - -//////////////////////////////////////////////////////////////////////////////////////// -// DB extra icons - -HANDLE hExtraVisibility, hExtraChat, hExtraGender, hExtraProto; - -static void SetVisibility(MCONTACT hContact, int apparentMode, bool clear) -{ - if (hContact == NULL) - return; - - char *proto = GetContactProto(hContact); - if (IsEmpty(proto)) - return; - - if (apparentMode <= 0) - apparentMode = db_get_w(hContact, proto, "ApparentMode", 0); - - HANDLE hExtraIcon, hIcolib = NULL; - - if (db_get_b(hContact, proto, "ChatRoom", 0)) { - // Is chat - hExtraIcon = hExtraChat; - if (apparentMode == ID_STATUS_OFFLINE) - hIcolib = Skin_GetIconHandle("ChatActivity"); - } - else { - // Not chat - hExtraIcon = hExtraVisibility; - if (apparentMode == ID_STATUS_OFFLINE) - hIcolib = LoadSkinnedIconHandle(SKINICON_OTHER_INVISIBLE_ALL); - else if (apparentMode == ID_STATUS_ONLINE) - hIcolib = LoadSkinnedIconHandle(SKINICON_OTHER_VISIBLE_ALL); - } - - if (hIcolib != NULL || clear) { - ExtraIcon *extra = GetExtraIcon(hExtraIcon); - if (extra) - extra->setIcon((int)hExtraIcon, hContact, hIcolib); - } -} - -static void SetGender(MCONTACT hContact, int gender, bool clear) -{ - if (hContact == NULL) - return; - - char *proto = GetContactProto(hContact); - if (IsEmpty(proto)) - return; - - if (gender <= 0) - gender = db_get_b(hContact, proto, "Gender", 0); - if (gender <= 0) - gender = db_get_b(hContact, "UserInfo", "Gender", 0); - - const char *ico; - if (gender == 'M') - ico = "gender_male"; - else if (gender == 'F') - ico = "gender_female"; - else - ico = NULL; - - if (ico != NULL || clear) { - ExtraIcon *extra = GetExtraIcon(hExtraGender); - if (extra) - extra->setIconByName((int)hExtraGender, hContact, ico); - } -} - -struct Info -{ - const char *name; - const char *desc; - int iSkinIcon; - const char *db[8]; - void(*OnClick)(Info *info, const char *text); - - HANDLE hIcolib, hExtraIcon; -}; - -static void EmailOnClick(Info *info, const char *text) -{ - char cmd[1024]; - mir_snprintf(cmd, SIZEOF(cmd), "mailto:%s", text); - ShellExecuteA(NULL, "open", cmd, NULL, NULL, SW_SHOW); -} - -static void HomepageOnClick(Info *info, const char *text) -{ - ShellExecuteA(NULL, "open", text, NULL, NULL, SW_SHOW); -} - -static Info infos[] = -{ - { "homepage", "Homepage", SKINICON_OTHER_MIRANDAWEB, - { NULL, "Homepage", "UserInfo", "Homepage" }, - &HomepageOnClick }, - { "sms", "Phone/SMS", SKINICON_OTHER_SMS, - { NULL, "Cellular", "UserInfo", "Cellular", "UserInfo", "Phone", "UserInfo", "MyPhone0" }, - NULL }, - { "email", "E-mail", SKINICON_OTHER_SENDEMAIL, - { NULL, "e-mail", "UserInfo", "e-mail", "UserInfo", "Mye-mail0" }, - &EmailOnClick }, -}; - -static void SetExtraIcons(MCONTACT hContact) -{ - if (hContact == NULL) - return; - - char *proto = GetContactProto(hContact); - if ( IsEmpty(proto)) - return; - - for (unsigned int i = 0; i < SIZEOF(infos); i++) { - Info &p = infos[i]; - - for (unsigned int j = 0; j < SIZEOF(p.db); j += 2) { - if (p.db[j + 1] == NULL) - break; - - ptrA szValue(db_get_sa(hContact, p.db[j] == NULL ? proto : p.db[j], p.db[j + 1])); - if (!IsEmpty(szValue)) { - ExtraIcon_SetIcon(p.hExtraIcon, hContact, p.hIcolib); - break; - } - } - } -} - -static int SettingChanged(WPARAM hContact, LPARAM lParam) -{ - if (hContact == NULL) - return 0; - - char *proto = GetContactProto(hContact); - if (IsEmpty(proto)) - return 0; - - DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam; - bool isProto = (mir_strcmp(cws->szModule, proto) == 0); - if (isProto && mir_strcmp(cws->szSetting, "ApparentMode") == 0) { - SetVisibility(hContact, cws->value.type == DBVT_DELETED ? 0 : cws->value.wVal, true); - return 0; - } - - if (mir_strcmp(cws->szSetting, "Gender") == 0 && (isProto || mir_strcmp(cws->szModule, "UserInfo") == 0)) { - SetGender(hContact, cws->value.type == DBVT_DELETED ? 0 : cws->value.bVal, true); - return 0; - } - - for (int i = 0; i < SIZEOF(infos); i++) { - Info &p = infos[i]; - - for (int j = 0; j < SIZEOF(p.db); j += 2) { - if (p.db[j + 1] == NULL) - break; - if (p.db[j] == NULL && !isProto) - continue; - if (p.db[j] != NULL && mir_strcmp(cws->szModule, p.db[j])) - continue; - if (mir_strcmp(cws->szSetting, p.db[j + 1])) - continue; - - bool show = (cws->value.type != DBVT_DELETED && !IsEmpty(cws->value.pszVal)); - ExtraIcon_SetIcon(p.hExtraIcon, hContact, show ? p.hIcolib : NULL); - break; - } - } - - return 0; -} - -static int DefaultOnClick(WPARAM hContact, LPARAM lParam, LPARAM param) -{ - Info *p = (Info*)param; - if (p == NULL) - return 0; - - if (hContact == NULL) - return 0; - - char *proto = GetContactProto(hContact); - if (IsEmpty(proto)) - return 0; - - bool found = false; - for (int j = 0; !found && j < SIZEOF(p->db); j += 2) { - if (p->db[j + 1] == NULL) - break; - - ptrA szValue(db_get_sa(hContact, p->db[j] == NULL ? proto : p->db[j], p->db[j + 1])); - if (!IsEmpty(szValue)) { - p->OnClick(p, szValue); - found = true; - } - } - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Protocol icon - -struct ProtoInfo -{ - ProtoInfo(LPCSTR _proto, HANDLE _image) : - proto(mir_strdup(_proto)), - hImage(_image) - {} - - ptrA proto; - HANDLE hImage; -}; - -static int CompareProtos(const ProtoInfo *p1, const ProtoInfo *p2) -{ return mir_strcmp(p1->proto, p2->proto); -} - -OBJLIST arProtos(10, CompareProtos); - -static int ProtocolRebuildIcons(WPARAM wParam, LPARAM lParam) -{ - arProtos.destroy(); - return 0; -} - -static ProtoInfo* FindProto(const char *proto) -{ - ProtoInfo *p = arProtos.find((ProtoInfo*)&proto); - if (p) - return p; - - HICON hIcon = LoadSkinnedProtoIcon(proto, ID_STATUS_ONLINE); - if (hIcon == NULL) - return NULL; - - HANDLE hImage = ExtraIcon_Add(hIcon); - if (hImage == INVALID_HANDLE_VALUE) - return NULL; - - p = new ProtoInfo(proto, hImage); - arProtos.insert(p); - return p; -} - -static int ProtocolApplyIcon(WPARAM hContact, LPARAM lParam) -{ - char *proto = GetContactProto(hContact); - if (IsEmpty(proto)) - return 0; - - HANDLE hImage = INVALID_HANDLE_VALUE; - ProtoInfo *pi = FindProto(proto); - if (pi != NULL) - hImage = pi->hImage; - - ExtraIcon_SetIcon(hExtraProto, hContact, hImage); - return 0; -} - -static int ProtocolOnClick(WPARAM wParam, LPARAM lParam, LPARAM param) -{ - if (wParam) - CallService(MS_USERINFO_SHOWDIALOG, wParam, 0); - return 0; -} - -//////////////////////////////////////////////////////////////////////////////////////// - -void DefaultExtraIcons_Load() -{ - hExtraChat = ExtraIcon_Register("chat_activity", LPGEN("Chat activity"), "ChatActivity"); - hExtraVisibility = ExtraIcon_Register("visibility", "Visibility", LoadSkinnedIconName(SKINICON_OTHER_VISIBLE_ALL)); - hExtraGender = ExtraIcon_Register("gender", "Gender", "gender_male"); - hExtraProto = ExtraIcon_Register("protocol", "Account", LoadSkinnedIconName(SKINICON_OTHER_ACCMGR), - &ProtocolRebuildIcons, &ProtocolApplyIcon, &ProtocolOnClick); - - for (int i = 0; i < SIZEOF(infos); i++) { - Info &p = infos[i]; - p.hIcolib = LoadSkinnedIconHandle(p.iSkinIcon); - if (p.OnClick) - p.hExtraIcon = ExtraIcon_Register(p.name, p.desc, LoadSkinnedIconName(p.iSkinIcon), DefaultOnClick, (LPARAM)&p); - else - p.hExtraIcon = ExtraIcon_Register(p.name, p.desc, LoadSkinnedIconName(p.iSkinIcon)); - } - - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - SetExtraIcons(hContact); - SetVisibility(hContact, -1, false); - SetGender(hContact, -1, false); - } - - HookEvent(ME_DB_CONTACT_SETTINGCHANGED, SettingChanged); -} diff --git a/src/modules/extraicons/ExtraIcon.cpp b/src/modules/extraicons/ExtraIcon.cpp deleted file mode 100644 index 4a841423f3..0000000000 --- a/src/modules/extraicons/ExtraIcon.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - -Copyright (C) 2009 Ricardo Pescuma Domenecci -Copyright (C) 2012-15 Miranda NG project - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "extraicons.h" - -ExtraIcon::ExtraIcon(const char *name) : - szName(mir_strdup(name)), slot(-1), position(1000), hLangpack(0) -{ -} - -ExtraIcon::~ExtraIcon() -{ -} - -const char *ExtraIcon::getName() const -{ - return szName; -} - -int ExtraIcon::getSlot() const -{ - return slot; -} - -void ExtraIcon::setSlot(int slot) -{ - this->slot = slot; -} - -int ExtraIcon::getPosition() const -{ - return position; -} - -void ExtraIcon::setPosition(int position) -{ - this->position = position; -} - -bool ExtraIcon::isEnabled() const -{ - return slot >= 0; -} - -void ExtraIcon::applyIcons() -{ - if (!isEnabled()) - return; - - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - // Clear to assert that it will be cleared - Clist_SetExtraIcon(hContact, slot, INVALID_HANDLE_VALUE); - applyIcon(hContact); - } -} diff --git a/src/modules/extraicons/ExtraIcon.h b/src/modules/extraicons/ExtraIcon.h deleted file mode 100644 index 3f4c34d8e0..0000000000 --- a/src/modules/extraicons/ExtraIcon.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - -Copyright (C) 2009 Ricardo Pescuma Domenecci -Copyright (C) 2012-15 Miranda NG project - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#ifndef __EXTRAICON_H__ -#define __EXTRAICON_H__ - -#define EXTRAICON_TYPE_GROUP -1 - -///////////////////////////////////////////////////////////////////////////////////////// -// ExtraIcon - base class for all extra icons - -class ExtraIcon -{ -public: - ExtraIcon(const char *name); - virtual ~ExtraIcon(); - - virtual void rebuildIcons() = 0; - virtual void applyIcons(); - virtual void applyIcon(MCONTACT hContact) =0 ; - virtual void onClick(MCONTACT hContact) = 0; - - virtual int setIcon(int id, MCONTACT hContact, HANDLE icon) = 0; - virtual int setIconByName(int id, MCONTACT hContact, const char* icon) = 0; - virtual void storeIcon(MCONTACT hContact, void *icon) {}; - - virtual const char *getName() const; - virtual const TCHAR *getDescription() const = 0; - virtual const char *getDescIcon() const = 0; - virtual int getType() const = 0; - - virtual int getSlot() const; - virtual void setSlot(int slot); - - virtual int getPosition() const; - virtual void setPosition(int position); - - virtual bool isEnabled() const; - - virtual int ClistSetExtraIcon(MCONTACT hContact, HANDLE hImage) = 0; - - int hLangpack; - -protected: - ptrA szName; - - int slot; - int position; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// BaseExtraIcon - basic class for all 'real' extra icons - -class BaseExtraIcon : public ExtraIcon -{ -public: - BaseExtraIcon(int id, const char *name, const TCHAR *description, const char *descIcon, MIRANDAHOOKPARAM OnClick, LPARAM param); - virtual ~BaseExtraIcon(); - - virtual int getID() const; - virtual const TCHAR *getDescription() const; - virtual void setDescription(const TCHAR *desc); - virtual const char *getDescIcon() const; - virtual void setDescIcon(const char *icon); - virtual int getType() const =0; - - virtual void onClick(MCONTACT hContact); - virtual void setOnClick(MIRANDAHOOKPARAM OnClick, LPARAM param); - - virtual int ClistSetExtraIcon(MCONTACT hContact, HANDLE hImage); - -protected: - int id; - ptrT tszDescription; - ptrA szDescIcon; - MIRANDAHOOKPARAM OnClick; - LPARAM onClickParam; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CallbackExtraIcon - extra icon, implemented using callback functions - -class CallbackExtraIcon : public BaseExtraIcon -{ -public: - CallbackExtraIcon(int id, const char *name, const TCHAR *description, const char *descIcon, - MIRANDAHOOK RebuildIcons, MIRANDAHOOK ApplyIcon, MIRANDAHOOKPARAM OnClick, LPARAM param); - virtual ~CallbackExtraIcon(); - - virtual int getType() const; - - virtual void rebuildIcons(); - virtual void applyIcon(MCONTACT hContact); - - virtual int setIcon(int id, MCONTACT hContact, HANDLE icon); - virtual int setIconByName(int id, MCONTACT hContact, const char* icon); - -private: - int(*RebuildIcons)(WPARAM wParam, LPARAM lParam); - int(*ApplyIcon)(WPARAM wParam, LPARAM lParam); - - bool needToRebuild; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// IcolibExtraIcon - extra icon, implemented using icolib - -class IcolibExtraIcon : public BaseExtraIcon -{ -public: - IcolibExtraIcon(int id, const char *name, const TCHAR *description, const char *descIcon, MIRANDAHOOKPARAM OnClick, LPARAM param); - virtual ~IcolibExtraIcon(); - - virtual int getType() const; - - virtual void rebuildIcons(); - virtual void applyIcon(MCONTACT hContact); - - virtual int setIcon(int id, MCONTACT hContact, HANDLE icon); - virtual int setIconByName(int id, MCONTACT hContact, const char* icon); - virtual void storeIcon(MCONTACT hContact, void *icon); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// ExtraIconGroup - joins some slots into one - -class ExtraIconGroup : public ExtraIcon -{ - int internalSetIcon(int id, MCONTACT hContact, HANDLE icon, bool bByName); -public: - ExtraIconGroup(const char *name); - virtual ~ExtraIconGroup(); - - virtual void addExtraIcon(BaseExtraIcon *extra); - - virtual void rebuildIcons(); - virtual void applyIcon(MCONTACT hContact); - virtual void onClick(MCONTACT hContact); - - virtual int setIcon(int id, MCONTACT hContact, HANDLE icon); - virtual int setIconByName(int id, MCONTACT hContact, const char *icon); - - virtual const TCHAR* getDescription() const; - virtual const char* getDescIcon() const; - virtual int getType() const; - - virtual int getPosition() const; - virtual void setSlot(int slot); - - LIST items; - - virtual int ClistSetExtraIcon(MCONTACT hContact, HANDLE hImage); - -protected: - ptrT tszDescription; - bool setValidExtraIcon; - bool insideApply; - - virtual ExtraIcon *getCurrentItem(MCONTACT hContact) const; -}; - -#endif // __EXTRAICON_H__ diff --git a/src/modules/extraicons/ExtraIconGroup.cpp b/src/modules/extraicons/ExtraIconGroup.cpp deleted file mode 100644 index 26704a0cfa..0000000000 --- a/src/modules/extraicons/ExtraIconGroup.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - -Copyright (C) 2009 Ricardo Pescuma Domenecci -Copyright (C) 2012-15 Miranda NG project - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "extraicons.h" - -ExtraIconGroup::ExtraIconGroup(const char *_name) : - ExtraIcon(_name), setValidExtraIcon(false), insideApply(false), - items(1) -{ - db_set_resident(MODULE_NAME, _name); -} - -ExtraIconGroup::~ExtraIconGroup() -{ -} - -void ExtraIconGroup::addExtraIcon(BaseExtraIcon *extra) -{ - items.insert(extra); - - CMString description; - for (int i = 0; i < items.getCount(); i++) { - if (i > 0) - description += _T(" / "); - description += items[i]->getDescription(); - } - - tszDescription = mir_tstrdup(description); -} - -void ExtraIconGroup::rebuildIcons() -{ - for (int i = 0; i < items.getCount(); i++) - items[i]->rebuildIcons(); -} - -void ExtraIconGroup::applyIcon(MCONTACT hContact) -{ - if (!isEnabled() || hContact == NULL) - return; - - setValidExtraIcon = false; - - insideApply = true; - - int i; - for (i = 0; i < items.getCount(); i++) { - items[i]->applyIcon(hContact); - if (setValidExtraIcon) - break; - } - - insideApply = false; - - db_set_dw(hContact, MODULE_NAME, szName, setValidExtraIcon ? items[i]->getID() : 0); -} - -int ExtraIconGroup::getPosition() const -{ - int pos = INT_MAX; - for (int i = 0; i < items.getCount(); i++) - pos = MIN(pos, items[i]->getPosition()); - return pos; -} - -void ExtraIconGroup::setSlot(int slot) -{ - ExtraIcon::setSlot(slot); - - for (int i = 0; i < items.getCount(); i++) - items[i]->setSlot(slot); -} - -ExtraIcon * ExtraIconGroup::getCurrentItem(MCONTACT hContact) const -{ - int id = (int)db_get_dw(hContact, MODULE_NAME, szName, 0); - if (id < 1) - return NULL; - - for (int i = 0; i < items.getCount(); i++) - if (id == items[i]->getID()) - return items[i]; - - return NULL; -} - -void ExtraIconGroup::onClick(MCONTACT hContact) -{ - ExtraIcon *extra = getCurrentItem(hContact); - if (extra != NULL) - extra->onClick(hContact); -} - -int ExtraIconGroup::setIcon(int id, MCONTACT hContact, HANDLE value) -{ - return internalSetIcon(id, hContact, (void*)value, false); -} - -int ExtraIconGroup::setIconByName(int id, MCONTACT hContact, const char *value) -{ - return internalSetIcon(id, hContact, (void*)value, true); -} - -int ExtraIconGroup::internalSetIcon(int id, MCONTACT hContact, void *value, bool bByName) -{ - if (insideApply) { - for (int i=0; i < items.getCount(); i++) - if (items[i]->getID() == id) { - if (bByName) - return items[i]->setIconByName(id, hContact, (const char*)value); - return items[i]->setIcon(id, hContact, (HANDLE)value); - } - - return -1; - } - - ExtraIcon *current = getCurrentItem(hContact); - int currentPos = items.getCount(); - int storePos = items.getCount(); - for (int i=0; i < items.getCount(); i++) { - if (items[i]->getID() == id) - storePos = i; - - if (items[i] == current) - currentPos = i; - } - - if (storePos == items.getCount()) - return -1; - - if (storePos > currentPos) { - items[storePos]->storeIcon(hContact, value); - return 0; - } - - // Ok, we have to set the icon, but we have to assert it is a valid icon - - setValidExtraIcon = false; - - int ret; - if (bByName) - ret = items[storePos]->setIconByName(id, hContact, (const char*)value); - else - ret = items[storePos]->setIcon(id, hContact, (HANDLE)value); - - if (storePos < currentPos) { - if (setValidExtraIcon) - db_set_dw(hContact, MODULE_NAME, szName, items[storePos]->getID()); - } - else if (storePos == currentPos) { - if (!setValidExtraIcon) { - db_set_dw(hContact, MODULE_NAME, szName, 0); - - insideApply = true; - - for (++storePos; storePos < items.getCount(); ++storePos) { - items[storePos]->applyIcon(hContact); - if (setValidExtraIcon) - break; - } - - insideApply = false; - - if (setValidExtraIcon && storePos < items.getCount()) - db_set_dw(hContact, MODULE_NAME, szName, items[storePos]->getID()); - } - } - - return ret; -} - -const TCHAR *ExtraIconGroup::getDescription() const -{ - return tszDescription; -} - -const char *ExtraIconGroup::getDescIcon() const -{ - for (int i = 0; i < items.getCount(); i++) - if (!IsEmpty(items[i]->getDescIcon())) - return items[i]->getDescIcon(); - - return ""; -} - -int ExtraIconGroup::getType() const -{ - return EXTRAICON_TYPE_GROUP; -} - -int ExtraIconGroup::ClistSetExtraIcon(MCONTACT hContact, HANDLE hImage) -{ - if (hImage != INVALID_HANDLE_VALUE) - setValidExtraIcon = true; - - return Clist_SetExtraIcon(hContact, slot, hImage); -} diff --git a/src/modules/extraicons/IcolibExtraIcon.cpp b/src/modules/extraicons/IcolibExtraIcon.cpp deleted file mode 100644 index 3a9521f4d4..0000000000 --- a/src/modules/extraicons/IcolibExtraIcon.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - -Copyright (C) 2009 Ricardo Pescuma Domenecci -Copyright (C) 2012-15 Miranda NG project - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "extraicons.h" -#include "usedIcons.h" - -#include "..\icolib\IcoLib.h" - -IcolibExtraIcon::IcolibExtraIcon(int _id, const char *_name, const TCHAR *_description, const char *_descIcon, - MIRANDAHOOKPARAM _OnClick, LPARAM _param) : - BaseExtraIcon(_id, _name, _description, _descIcon, _OnClick, _param) -{ - db_set_resident(MODULE_NAME, _name); -} - -IcolibExtraIcon::~IcolibExtraIcon() -{ -} - -int IcolibExtraIcon::getType() const -{ - return EXTRAICON_TYPE_ICOLIB; -} - -void IcolibExtraIcon::rebuildIcons() -{ -} - -void IcolibExtraIcon::applyIcon(MCONTACT hContact) -{ - if (!isEnabled() || hContact == NULL) - return; - - HANDLE hImage = INVALID_HANDLE_VALUE; - - ptrA szIconName(db_get_sa(hContact, MODULE_NAME, szName)); - if (!IsEmpty(szIconName)) - hImage = GetIcon(szIconName); - - ClistSetExtraIcon(hContact, hImage); -} - -int IcolibExtraIcon::setIcon(int id, MCONTACT hContact, HANDLE hIcoLib) -{ - if (hContact == NULL || id != this->id) - return -1; - - if (hIcoLib == INVALID_HANDLE_VALUE) - hIcoLib = NULL; - - if (isEnabled()) { - ptrA szIconName(db_get_sa(hContact, MODULE_NAME, szName)); - if (!IsEmpty(szIconName)) - RemoveIcon(szIconName); - } - - IcolibItem *p = (IcolibItem*)hIcoLib; - char *szName = (p) ? p->name : NULL; - storeIcon(hContact, szName); - - if (isEnabled()) - return ClistSetExtraIcon(hContact, (hIcoLib == NULL) ? INVALID_HANDLE_VALUE : AddIcon(szName)); - - return 0; -} - -int IcolibExtraIcon::setIconByName(int id, MCONTACT hContact, const char *icon) -{ - if (hContact == NULL || id != this->id) - return -1; - - if (icon == INVALID_HANDLE_VALUE) - icon = NULL; - - if (isEnabled()) { - ptrA szIconName(db_get_sa(hContact, MODULE_NAME, szName)); - if (!IsEmpty(szIconName)) - RemoveIcon(szIconName); - } - - storeIcon(hContact, (char*)icon); - - if (isEnabled()) - return ClistSetExtraIcon(hContact, (IsEmpty(icon)) ? INVALID_HANDLE_VALUE : AddIcon(icon)); - - return 0; -} - -void IcolibExtraIcon::storeIcon(MCONTACT hContact, void *icon) -{ - if (hContact == NULL) - return; - - const char *icolibName = (const char *)icon; - if (IsEmpty(icolibName)) - db_unset(hContact, MODULE_NAME, szName); - else - db_set_s(hContact, MODULE_NAME, szName, icolibName); -} diff --git a/src/modules/extraicons/extraicons.cpp b/src/modules/extraicons/extraicons.cpp deleted file mode 100644 index be02a26b87..0000000000 --- a/src/modules/extraicons/extraicons.cpp +++ /dev/null @@ -1,545 +0,0 @@ -/* - -Copyright (C) 2009 Ricardo Pescuma Domenecci -Copyright (C) 2012-15 Miranda NG project - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "m_cluiframes.h" - -#include "extraicons.h" -#include "usedIcons.h" -#include "..\clist\clc.h" - -// Prototypes /////////////////////////////////////////////////////////////////////////// - -int SortFunc(const ExtraIcon *p1, const ExtraIcon *p2) -{ - int ret = p1->getPosition() - p2->getPosition(); - if (ret != 0) - return ret; - - int id1 = (p1->getType() != EXTRAICON_TYPE_GROUP) ? ((BaseExtraIcon*) p1)->getID() : 0; - int id2 = (p2->getType() != EXTRAICON_TYPE_GROUP) ? ((BaseExtraIcon*) p2)->getID() : 0; - return id1 - id2; -} - -LIST extraIconsByHandle(10), extraIconsBySlot(10, SortFunc); -LIST registeredExtraIcons(10); - -BOOL clistRebuildAlreadyCalled = FALSE; -BOOL clistApplyAlreadyCalled = FALSE; - -int clistFirstSlot = 0; -int clistSlotCount = 0; - -// Functions //////////////////////////////////////////////////////////////////////////// - -int InitOptionsCallback(WPARAM wParam, LPARAM lParam); - -// Called when all the modules are loaded -int ModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - // add our modules to the KnownModules list - CallService("DBEditorpp/RegisterSingleModule", (WPARAM) MODULE_NAME, 0); - CallService("DBEditorpp/RegisterSingleModule", (WPARAM) MODULE_NAME "Groups", 0); - - HookEvent(ME_OPT_INITIALISE, InitOptionsCallback); - return 0; -} - -int GetNumberOfSlots() -{ - return clistSlotCount; -} - -int ConvertToClistSlot(int slot) -{ - if (slot < 0) - return slot; - - return clistFirstSlot + slot; -} - -int ExtraImage_ExtraIDToColumnNum(int extra) -{ - return (extra < 1 || extra > EXTRA_ICON_COUNT) ? -1 : extra-1; -} - -int Clist_SetExtraIcon(MCONTACT hContact, int slot, HANDLE hImage) -{ - if (cli.hwndContactTree == 0) - return -1; - - int icol = ExtraImage_ExtraIDToColumnNum( ConvertToClistSlot(slot)); - if (icol == -1) - return -1; - - HANDLE hItem = (HANDLE)SendMessage(cli.hwndContactTree, CLM_FINDCONTACT, hContact, 0); - if (hItem == 0) - return -1; - - SendMessage(cli.hwndContactTree, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(icol,hImage)); - return 0; -} - -ExtraIcon* GetExtraIcon(HANDLE id) -{ - int i = (int)id; - if (i < 1 || i > extraIconsByHandle.getCount()) - return NULL; - - return extraIconsByHandle[i-1]; -} - -ExtraIcon* GetExtraIconBySlot(int slot) -{ - for (int i = 0; i < extraIconsBySlot.getCount(); i++) { - ExtraIcon *extra = extraIconsBySlot[i]; - if (extra->getSlot() == slot) - return extra; - } - return NULL; -} - -BaseExtraIcon* GetExtraIconByName(const char *name) -{ - for (int i=0; i < registeredExtraIcons.getCount(); i++) { - BaseExtraIcon *extra = registeredExtraIcons[i]; - if (mir_strcmp(name, extra->getName()) == 0) - return extra; - } - return NULL; -} - -static void LoadGroups(LIST &groups) -{ - int count = db_get_w(NULL, MODULE_NAME "Groups", "Count", 0); - for (int i=0; i < count; i++) { - char setting[512]; - mir_snprintf(setting, "%d_count", i); - unsigned int items = db_get_w(NULL, MODULE_NAME "Groups", setting, 0); - if (items < 1) - continue; - - mir_snprintf(setting, "__group_%d", i); - ExtraIconGroup *group = new ExtraIconGroup(setting); - - for (unsigned int j = 0; j < items; j++) { - mir_snprintf(setting, "%d_%d", i, j); - ptrA szIconName(db_get_sa(NULL, MODULE_NAME "Groups", setting)); - if (IsEmpty(szIconName)) - continue; - - BaseExtraIcon *extra = GetExtraIconByName(szIconName); - if (extra == NULL) - continue; - - group->items.insert(extra); - if (extra->getSlot() >= 0) - group->setSlot(extra->getSlot()); - } - - if (group->items.getCount() < 2) { - delete group; - continue; - } - - groups.insert(group); - } -} - -static ExtraIconGroup* IsInGroup(LIST &groups, BaseExtraIcon *extra) -{ - for (int i = 0; i < groups.getCount(); i++) { - ExtraIconGroup *group = groups[i]; - for (int j = 0; j < group->items.getCount(); j++) { - if (extra == group->items[j]) - return group; - } - } - return NULL; -} - -void RebuildListsBasedOnGroups(LIST &groups) -{ - extraIconsByHandle.destroy(); - - for (int i=0; i < registeredExtraIcons.getCount(); i++) - extraIconsByHandle.insert(registeredExtraIcons[i]); - - for (int k=0; k < extraIconsBySlot.getCount(); k++) { - ExtraIcon *extra = extraIconsBySlot[k]; - if (extra->getType() == EXTRAICON_TYPE_GROUP) - delete extra; - } - extraIconsBySlot.destroy(); - - for (int i=0; i < groups.getCount(); i++) { - ExtraIconGroup *group = groups[i]; - - for (int j = 0; j < group->items.getCount(); j++) - extraIconsByHandle.put(group->items[j]->getID()-1, group); - - extraIconsBySlot.insert(group); - } - - for (int k=0; k < extraIconsByHandle.getCount(); k++) { - ExtraIcon *extra = extraIconsByHandle[k]; - if (extra->getType() != EXTRAICON_TYPE_GROUP) - extraIconsBySlot.insert(extra); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -void KillModuleExtraIcons(int hLangpack) -{ - LIST arDeleted(1); - - for (int i=registeredExtraIcons.getCount()-1; i >= 0; i--) { - BaseExtraIcon *p = registeredExtraIcons[i]; - if (p->hLangpack == hLangpack) { - registeredExtraIcons.remove(i); - arDeleted.insert(p); - } - } - - if (arDeleted.getCount() == 0) - return; - - LIST groups(1); - LoadGroups(groups); - RebuildListsBasedOnGroups(groups); - - for (int k=0; k < arDeleted.getCount(); k++) - delete arDeleted[k]; -} - -/////////////////////////////////////////////////////////////////////////////// - -int ClistExtraListRebuild(WPARAM, LPARAM) -{ - clistRebuildAlreadyCalled = TRUE; - - ResetIcons(); - - for (int i=0; i < extraIconsBySlot.getCount(); i++) - extraIconsBySlot[i]->rebuildIcons(); - - return 0; -} - -int ClistExtraImageApply(WPARAM hContact, LPARAM) -{ - if (hContact == NULL) - return 0; - - clistApplyAlreadyCalled = TRUE; - - for (int i=0; i < extraIconsBySlot.getCount(); i++) - extraIconsBySlot[i]->applyIcon(hContact); - - return 0; -} - -int ClistExtraClick(WPARAM hContact, LPARAM lParam) -{ - if (hContact == NULL) - return 0; - - int clistSlot = (int)lParam; - - for (int i=0; i < extraIconsBySlot.getCount(); i++) { - ExtraIcon *extra = extraIconsBySlot[i]; - if (ConvertToClistSlot(extra->getSlot()) == clistSlot) { - extra->onClick(hContact); - break; - } - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Extra image list functions - -HANDLE hEventExtraImageListRebuilding, hEventExtraImageApplying, hEventExtraClick; - -static bool bImageCreated = false; -static int g_mutex_bSetAllExtraIconsCycle = 0; -static HIMAGELIST hExtraImageList; - -HANDLE ExtraIcon_Add(HICON hIcon) -{ - if (hExtraImageList == 0 || hIcon == 0) - return INVALID_HANDLE_VALUE; - - int res = ImageList_AddIcon(hExtraImageList, hIcon); - return (res > 0xFFFE) ? INVALID_HANDLE_VALUE : (HANDLE)res; -} - -void fnReloadExtraIcons() -{ - SendMessage(cli.hwndContactTree, CLM_SETEXTRASPACE, db_get_b(NULL,"CLUI","ExtraColumnSpace",18), 0); - SendMessage(cli.hwndContactTree, CLM_SETEXTRAIMAGELIST, 0, 0); - - if (hExtraImageList) - ImageList_Destroy(hExtraImageList); - - hExtraImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLOR32|ILC_MASK,1,256); - - SendMessage(cli.hwndContactTree, CLM_SETEXTRAIMAGELIST, 0, (LPARAM)hExtraImageList); - SendMessage(cli.hwndContactTree, CLM_SETEXTRACOLUMNS, EXTRA_ICON_COUNT, 0); - NotifyEventHooks(hEventExtraImageListRebuilding,0,0); - bImageCreated = true; -} - -void fnSetAllExtraIcons(MCONTACT hContact) -{ - if (cli.hwndContactTree == 0) - return; - - g_mutex_bSetAllExtraIconsCycle = 1; - bool hcontgiven = (hContact != 0); - - if (!bImageCreated) - cli.pfnReloadExtraIcons(); - - SendMessage(cli.hwndContactTree, CLM_SETEXTRACOLUMNS, EXTRA_ICON_COUNT, 0); - - if (hContact == NULL) - hContact = db_find_first(); - - for (; hContact; hContact = db_find_next(hContact)) { - ClcCacheEntry* pdnce = (ClcCacheEntry*)cli.pfnGetCacheEntry(hContact); - if (pdnce == NULL) - continue; - - NotifyEventHooks(hEventExtraImageApplying, hContact, 0); - if (hcontgiven) break; - Sleep(0); - } - - g_mutex_bSetAllExtraIconsCycle = 0; - cli.pfnInvalidateRect(cli.hwndContactTree, NULL, FALSE); - Sleep(0); -} - -/////////////////////////////////////////////////////////////////////////////// -// Services - -INT_PTR ExtraIcon_Register(WPARAM wParam, LPARAM lParam) -{ - if (wParam == 0) - return 0; - - EXTRAICON_INFO *ei = (EXTRAICON_INFO *)wParam; - if (ei->cbSize < sizeof(EXTRAICON_INFO)) - return 0; - if (ei->type != EXTRAICON_TYPE_CALLBACK && ei->type != EXTRAICON_TYPE_ICOLIB) - return 0; - if (IsEmpty(ei->name) || IsEmpty(ei->description)) - return 0; - if (ei->type == EXTRAICON_TYPE_CALLBACK && (ei->ApplyIcon == NULL || ei->RebuildIcons == NULL)) - return 0; - - ptrT tszDesc(mir_a2t(ei->description)); - TCHAR *desc = TranslateTH(lParam, tszDesc); - - BaseExtraIcon *extra = GetExtraIconByName(ei->name); - if (extra != NULL) { - if (ei->type != extra->getType() || ei->type != EXTRAICON_TYPE_ICOLIB) - return 0; - - // Found one, now merge it - if (mir_tstrcmpi(extra->getDescription(), desc)) { - CMString newDesc = extra->getDescription(); - newDesc += _T(" / "); - newDesc += desc; - extra->setDescription(newDesc.c_str()); - } - - if (!IsEmpty(ei->descIcon)) - extra->setDescIcon(ei->descIcon); - - if (ei->OnClick != NULL) - extra->setOnClick(ei->OnClick, ei->onClickParam); - - if (extra->getSlot() > 0) { - if (clistRebuildAlreadyCalled) - extra->rebuildIcons(); - if (clistApplyAlreadyCalled) - extraIconsByHandle[extra->getID() - 1]->applyIcons(); - } - - return extra->getID(); - } - - int id = registeredExtraIcons.getCount() + 1; - - switch (ei->type) { - case EXTRAICON_TYPE_CALLBACK: - extra = new CallbackExtraIcon(id, ei->name, desc, ei->descIcon == NULL ? "" : ei->descIcon, - ei->RebuildIcons, ei->ApplyIcon, ei->OnClick, ei->onClickParam); - break; - case EXTRAICON_TYPE_ICOLIB: - extra = new IcolibExtraIcon(id, ei->name, desc, ei->descIcon == NULL ? "" : ei->descIcon, ei->OnClick, - ei->onClickParam); - break; - default: - return 0; - } - - char setting[512]; - mir_snprintf(setting, "Position_%s", ei->name); - extra->setPosition(db_get_w(NULL, MODULE_NAME, setting, 1000)); - - mir_snprintf(setting, "Slot_%s", ei->name); - int slot = db_get_w(NULL, MODULE_NAME, setting, 1); - if (slot == (WORD)-1) - slot = -1; - extra->setSlot(slot); - - extra->hLangpack = (int)lParam; - - registeredExtraIcons.insert(extra); - extraIconsByHandle.insert(extra); - - LIST groups(1); - LoadGroups(groups); - - ExtraIconGroup *group = IsInGroup(groups, extra); - if (group != NULL) - RebuildListsBasedOnGroups(groups); - else { - for (int i = 0; i < groups.getCount(); i++) - delete groups[i]; - - extraIconsBySlot.insert(extra); - } - - if (slot >= 0 || group != NULL) { - if (clistRebuildAlreadyCalled) - extra->rebuildIcons(); - - slot = 0; - for (int i = 0; i < extraIconsBySlot.getCount(); i++) { - ExtraIcon *ex = extraIconsBySlot[i]; - if (ex->getSlot() < 0) - continue; - - int oldSlot = ex->getSlot(); - ex->setSlot(slot++); - - if (clistApplyAlreadyCalled && (ex == group || ex == extra || oldSlot != slot)) - extra->applyIcons(); - } - } - - return id; -} - -INT_PTR ExtraIcon_SetIcon(WPARAM wParam, LPARAM) -{ - if (wParam == 0) - return -1; - - EXTRAICON *ei = (EXTRAICON*)wParam; - if (ei->cbSize < sizeof(EXTRAICON) || ei->hExtraIcon == NULL || ei->hContact == NULL) - return -1; - - ExtraIcon *extra = GetExtraIcon(ei->hExtraIcon); - if (extra == NULL) - return -1; - - return extra->setIcon((int)ei->hExtraIcon, ei->hContact, ei->hImage); -} - -INT_PTR ExtraIcon_SetIconByName(WPARAM wParam, LPARAM) -{ - if (wParam == 0) - return -1; - - EXTRAICON *ei = (EXTRAICON*)wParam; - if (ei->cbSize < sizeof(EXTRAICON) || ei->hExtraIcon == NULL || ei->hContact == NULL) - return -1; - - ExtraIcon *extra = GetExtraIcon(ei->hExtraIcon); - if (extra == NULL) - return -1; - - return extra->setIconByName((int)ei->hExtraIcon, ei->hContact, ei->icoName); -} - -static INT_PTR svcExtraIcon_Add(WPARAM wParam, LPARAM) -{ - return (INT_PTR)ExtraIcon_Add((HICON)wParam); -} - -/////////////////////////////////////////////////////////////////////////////// - -static IconItem iconList[] = -{ - { LPGEN("Chat activity"), "ChatActivity", IDI_CHAT }, - { LPGEN("Male"), "gender_male", IDI_MALE }, - { LPGEN("Female"), "gender_female", IDI_FEMALE } -}; - -void LoadExtraIconsModule() -{ - DWORD ret = CallService(MS_CLUI_GETCAPS, CLUICAPS_FLAGS2, 0); - clistFirstSlot = HIWORD(ret); - clistSlotCount = LOWORD(ret); - - // Services - CreateServiceFunction(MS_EXTRAICON_REGISTER, ExtraIcon_Register); - CreateServiceFunction(MS_EXTRAICON_SET_ICON, ExtraIcon_SetIcon); - CreateServiceFunction(MS_EXTRAICON_SET_ICON_BY_NAME, &ExtraIcon_SetIconByName); - - CreateServiceFunction(MS_CLIST_EXTRA_ADD_ICON, svcExtraIcon_Add); - - hEventExtraClick = CreateHookableEvent(ME_CLIST_EXTRA_CLICK); - hEventExtraImageApplying = CreateHookableEvent(ME_CLIST_EXTRA_IMAGE_APPLY); - hEventExtraImageListRebuilding = CreateHookableEvent(ME_CLIST_EXTRA_LIST_REBUILD); - - // Icons - Icon_Register(NULL, LPGEN("Contact list"), iconList, SIZEOF(iconList)); - - // Hooks - HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); - - HookEvent(ME_CLIST_EXTRA_LIST_REBUILD, ClistExtraListRebuild); - HookEvent(ME_CLIST_EXTRA_IMAGE_APPLY, ClistExtraImageApply); - HookEvent(ME_CLIST_EXTRA_CLICK, ClistExtraClick); - - DefaultExtraIcons_Load(); -} - -void UnloadExtraIconsModule(void) -{ - for (int k = 0; k < extraIconsBySlot.getCount(); k++) { - ExtraIcon *extra = extraIconsBySlot[k]; - if (extra->getType() == EXTRAICON_TYPE_GROUP) - delete extra; - } - - for (int i = 0; i < registeredExtraIcons.getCount(); i++) - delete registeredExtraIcons[i]; -} diff --git a/src/modules/extraicons/extraicons.h b/src/modules/extraicons/extraicons.h deleted file mode 100644 index 9214dec2cf..0000000000 --- a/src/modules/extraicons/extraicons.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - -Copyright (C) 2009 Ricardo Pescuma Domenecci -Copyright (C) 2012-15 Miranda NG project - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#ifndef __COMMONS_H__ -# define __COMMONS_H__ - -#define MODULE_NAME "ExtraIcons" - -// Global Variables -extern HINSTANCE hInst; - -#define FREE(_m_) if (_m_ != NULL) { free(_m_); _m_ = NULL; } - -#define ICON_SIZE 16 - -#include "Extraicon.h" - -extern LIST registeredExtraIcons; -extern LIST extraIconsByHandle, extraIconsBySlot; -void RebuildListsBasedOnGroups(LIST &groups); -ExtraIcon * GetExtraIconBySlot(int slot); - -int GetNumberOfSlots(); -int ConvertToClistSlot(int slot); - -int Clist_SetExtraIcon(MCONTACT hContact, int slot, HANDLE hImage); - -void DefaultExtraIcons_Load(); - -HANDLE ExtraIcon_Add(HICON hIcon); - -void fnReloadExtraIcons(); -void fnSetAllExtraIcons(MCONTACT hContact); - -static inline BOOL IsEmpty(const char *str) -{ - return str == NULL || str[0] == 0; -} - -static inline int MIN(int a, int b) -{ - if (a <= b) - return a; - return b; -} - -static inline int MAX(int a, int b) -{ - if (a >= b) - return a; - return b; -} - -#endif // __COMMONS_H__ diff --git a/src/modules/extraicons/options_ei.cpp b/src/modules/extraicons/options_ei.cpp deleted file mode 100644 index 28d0bf553d..0000000000 --- a/src/modules/extraicons/options_ei.cpp +++ /dev/null @@ -1,472 +0,0 @@ -/* - -Copyright (C) 2009 Ricardo Pescuma Domenecci -Copyright (C) 2012-15 Miranda NG project - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "extraicons.h" - -#define ICON_SIZE 16 - -int SortFunc(const ExtraIcon *p1, const ExtraIcon *p2); - -struct intlist -{ - intlist() : count(0), data(0) {} - ~intlist() { mir_free(data); } - - void add(int val) - { - data = (int*)mir_realloc(data, sizeof(int)*(count + 1)); - data[count++] = val; - } - - int count; - int *data; -}; - -static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) -{ - intlist *a = (intlist*)lParam1; - intlist *b = (intlist*)lParam2; - return SortFunc(registeredExtraIcons[a->data[0] - 1], registeredExtraIcons[b->data[0] - 1]); -} - -// Functions ////////////////////////////////////////////////////////////////////////////////////// - -BOOL ScreenToClient(HWND hWnd, LPRECT lpRect) -{ - POINT pt; - pt.x = lpRect->left; - pt.y = lpRect->top; - - BOOL ret = ScreenToClient(hWnd, &pt); - if (!ret) - return ret; - - lpRect->left = pt.x; - lpRect->top = pt.y; - - pt.x = lpRect->right; - pt.y = lpRect->bottom; - - ret = ScreenToClient(hWnd, &pt); - - lpRect->right = pt.x; - lpRect->bottom = pt.y; - - return ret; -} - -static void RemoveExtraIcons(int slot) -{ - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) - Clist_SetExtraIcon(hContact, slot, INVALID_HANDLE_VALUE); -} - -class CExtraIconOptsDlg : public CDlgBase -{ - intlist* Tree_GetIDs(HTREEITEM hItem) - { - TVITEMEX tvi; - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - tvi.hItem = hItem; - m_tree.GetItem(&tvi); - return (intlist*)tvi.lParam; - } - - HTREEITEM Tree_AddExtraIcon(BaseExtraIcon *extra, bool selected, HTREEITEM hAfter = TVI_LAST) - { - intlist *ids = new intlist(); - ids->add(extra->getID()); - - TVINSERTSTRUCT tvis = { 0 }; - tvis.hInsertAfter = hAfter; - tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; - tvis.item.stateMask = TVIS_STATEIMAGEMASK; - tvis.item.iSelectedImage = tvis.item.iImage = extra->getID(); - tvis.item.lParam = (LPARAM)ids; - tvis.item.pszText = (LPTSTR)extra->getDescription(); - tvis.item.state = INDEXTOSTATEIMAGEMASK(selected ? 2 : 1); - return m_tree.InsertItem(&tvis); - } - - HTREEITEM Tree_AddExtraIconGroup(intlist &group, bool selected, HTREEITEM hAfter = TVI_LAST) - { - intlist *ids = new intlist(); - CMString desc; - int img = 0; - for (int i = 0; i < group.count; i++) { - BaseExtraIcon *extra = registeredExtraIcons[group.data[i] - 1]; - ids->add(extra->getID()); - - if (img == 0 && !IsEmpty(extra->getDescIcon())) - img = extra->getID(); - - if (i > 0) - desc += _T(" / "); - desc += extra->getDescription(); - } - - TVINSERTSTRUCT tvis = { 0 }; - tvis.hInsertAfter = hAfter; - tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; - tvis.item.stateMask = TVIS_STATEIMAGEMASK; - tvis.item.iSelectedImage = tvis.item.iImage = img; - tvis.item.lParam = (LPARAM)ids; - tvis.item.pszText = (TCHAR*)desc.c_str(); - tvis.item.state = INDEXTOSTATEIMAGEMASK(selected ? 2 : 1); - return m_tree.InsertItem(&tvis); - } - - void GroupSelectedItems() - { - LIST<_TREEITEM> toRemove(1); - intlist ids; - bool selected = false; - HTREEITEM hPlace = NULL; - - // Find items - HTREEITEM hItem = m_tree.GetRoot(); - TVITEMEX tvi = { 0 }; - tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT | TVIF_STATE; - while (hItem) { - if (m_tree.IsSelected(hItem)) { - if (hPlace == NULL) - hPlace = hItem; - - tvi.hItem = hItem; - m_tree.GetItem(&tvi); - - intlist *iids = (intlist*)tvi.lParam; - for (int i = 0; i < iids->count; i++) - ids.add(iids->data[i]); - - if ((tvi.state & INDEXTOSTATEIMAGEMASK(3)) == INDEXTOSTATEIMAGEMASK(2)) - selected = true; - - toRemove.insert(hItem); - } - - hItem = m_tree.GetNextSibling(hItem); - } - - if (hPlace != NULL) { - // Add new - HTREEITEM hNew = Tree_AddExtraIconGroup(ids, selected, hPlace); - - // Remove old - for (int i = 0; i < toRemove.getCount(); i++) { - delete Tree_GetIDs(toRemove[i]); - m_tree.DeleteItem(toRemove[i]); - } - - // Select - m_tree.UnselectAll(); - m_tree.SelectItem(hNew); - } - } - - void UngroupSelectedItems() - { - HTREEITEM hItem = m_tree.GetSelection(); - if (hItem == NULL) - return; - - intlist *ids = Tree_GetIDs(hItem); - if (ids->count < 2) - return; - - bool selected = m_tree.IsSelected(hItem); - - for (int i = ids->count - 1; i >= 0; i--) { - BaseExtraIcon *extra = registeredExtraIcons[ids->data[i] - 1]; - Tree_AddExtraIcon(extra, selected, hItem); - } - - delete ids; - m_tree.DeleteItem(hItem); - - m_tree.UnselectAll(); - } - - int ShowPopup(int popup) - { - // Fix selection - HTREEITEM hSelected = m_tree.GetDropHilight(); - HTREEITEM hItem = m_tree.GetRoot(); - while (hItem) { - if (hItem != hSelected && m_tree.IsSelected(hItem)) - m_tree.DropHilite(hItem); - - hItem = m_tree.GetNextSibling(hItem); - } - - HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_OPT_POPUP)); - HMENU submenu = GetSubMenu(menu, popup); - TranslateMenu(submenu); - - DWORD pos = GetMessagePos(); - int ret = TrackPopupMenu(submenu, TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_LEFTALIGN, LOWORD(pos), HIWORD(pos), 0, m_hwnd, NULL); - - DestroyMenu(menu); - - // Revert selection - hItem = m_tree.GetRoot(); - while (hItem) { - if (hItem != hSelected && m_tree.IsSelected(hItem)) - m_tree.DropUnhilite(hItem); - hItem = m_tree.GetNextSibling(hItem); - } - - return ret; - } - - CCtrlTreeView m_tree; - -public: - CExtraIconOptsDlg() : - CDlgBase(hInst, IDD_EI_OPTIONS), - m_tree(this, IDC_EXTRAORDER) - { - m_tree.SetFlags(MTREE_DND | MTREE_MULTISELECT); - } - - virtual void OnInitDialog() - { - int numSlots = GetNumberOfSlots(); - if (numSlots < (int)registeredExtraIcons.getCount()) { - HWND label = GetDlgItem(m_hwnd, IDC_MAX_ICONS_L); - SetWindowText(label, CMString(FORMAT, TranslateT("*only the first %d icons will be shown"), numSlots)); - ShowWindow(label, SW_SHOW); - } - - int cx = GetSystemMetrics(SM_CXSMICON); - HIMAGELIST hImageList = ImageList_Create(cx, cx, ILC_COLOR32 | ILC_MASK, 2, 2); - - HICON hBlankIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_BLANK), IMAGE_ICON, cx, cx, 0); - ImageList_AddIcon(hImageList, hBlankIcon); - - for (int i = 0; i < registeredExtraIcons.getCount(); i++) { - ExtraIcon *extra = registeredExtraIcons[i]; - - HICON hIcon = Skin_GetIcon(extra->getDescIcon()); - if (hIcon == NULL) - ImageList_AddIcon(hImageList, hBlankIcon); - else { - ImageList_AddIcon(hImageList, hIcon); - Skin_ReleaseIcon(hIcon); - } - } - m_tree.SetImageList(hImageList, TVSIL_NORMAL); - DestroyIcon(hBlankIcon); - - for (int k = 0; k < extraIconsBySlot.getCount(); k++) { - ExtraIcon *extra = extraIconsBySlot[k]; - - if (extra->getType() == EXTRAICON_TYPE_GROUP) { - ExtraIconGroup *group = (ExtraIconGroup *)extra; - intlist ids; - for (int j = 0; j < group->items.getCount(); j++) - ids.add(group->items[j]->getID()); - Tree_AddExtraIconGroup(ids, extra->isEnabled()); - } - else Tree_AddExtraIcon((BaseExtraIcon *)extra, extra->isEnabled()); - } - - TVSORTCB sort = { 0 }; - sort.hParent = NULL; - sort.lParam = 0; - sort.lpfnCompare = CompareFunc; - m_tree.SortChildrenCB(&sort, 0); - } - - virtual void OnApply() - { - // Store old slots - int *oldSlots = new int[registeredExtraIcons.getCount()]; - int lastUsedSlot = -1; - for (int i = 0; i < registeredExtraIcons.getCount(); i++) { - if (extraIconsByHandle[i] == registeredExtraIcons[i]) - oldSlots[i] = registeredExtraIcons[i]->getSlot(); - else - // Remove old slot for groups to re-set images - oldSlots[i] = -1; - lastUsedSlot = MAX(lastUsedSlot, registeredExtraIcons[i]->getSlot()); - } - lastUsedSlot = MIN(lastUsedSlot, GetNumberOfSlots()); - - // Get user data and create new groups - LIST groups(1); - - BYTE pos = 0; - int firstEmptySlot = 0; - HTREEITEM ht = m_tree.GetRoot(); - TVITEMEX tvi; - tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE; - tvi.stateMask = TVIS_STATEIMAGEMASK; - while (ht) { - tvi.hItem = ht; - m_tree.GetItem(&tvi); - - intlist*ids = (intlist*)tvi.lParam; - if (ids == NULL || ids->count < 1) - continue; // ??? - - bool enabled = ((tvi.state & INDEXTOSTATEIMAGEMASK(3)) == INDEXTOSTATEIMAGEMASK(2)); - int slot = (enabled ? firstEmptySlot++ : -1); - if (slot >= GetNumberOfSlots()) - slot = -1; - - if (ids->count == 1) { - BaseExtraIcon *extra = registeredExtraIcons[ids->data[0] - 1]; - extra->setPosition(pos++); - extra->setSlot(slot); - } - else { - char name[128]; - mir_snprintf(name, "__group_%d", groups.getCount()); - - ExtraIconGroup *group = new ExtraIconGroup(name); - - for (int i = 0; i < ids->count; i++) { - BaseExtraIcon *extra = registeredExtraIcons[ids->data[i] - 1]; - extra->setPosition(pos++); - - group->addExtraIcon(extra); - } - - group->setSlot(slot); - groups.insert(group); - } - - ht = m_tree.GetNextSibling(ht); - } - - // Store data - for (int i = 0; i < registeredExtraIcons.getCount(); i++) { - BaseExtraIcon *extra = registeredExtraIcons[i]; - - char setting[512]; - mir_snprintf(setting, "Position_%s", extra->getName()); - db_set_w(NULL, MODULE_NAME, setting, extra->getPosition()); - - mir_snprintf(setting, "Slot_%s", extra->getName()); - db_set_w(NULL, MODULE_NAME, setting, extra->getSlot()); - } - - CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)MODULE_NAME "Groups"); - db_set_w(NULL, MODULE_NAME "Groups", "Count", groups.getCount()); - for (int k = 0; k < groups.getCount(); k++) { - ExtraIconGroup *group = groups[k]; - - char setting[512]; - mir_snprintf(setting, "%d_count", k); - db_set_w(NULL, MODULE_NAME "Groups", setting, (WORD)group->items.getCount()); - - for (int j = 0; j < group->items.getCount(); j++) { - BaseExtraIcon *extra = group->items[j]; - - mir_snprintf(setting, "%d_%d", k, j); - db_set_s(NULL, MODULE_NAME "Groups", setting, extra->getName()); - } - } - - // Clean removed slots - for (int j = firstEmptySlot; j <= lastUsedSlot; j++) - RemoveExtraIcons(j); - - // Apply icons to new slots - RebuildListsBasedOnGroups(groups); - for (int n = 0; n < extraIconsBySlot.getCount(); n++) { - ExtraIcon *extra = extraIconsBySlot[n]; - if (extra->getType() != EXTRAICON_TYPE_GROUP) - if (oldSlots[((BaseExtraIcon *)extra)->getID() - 1] == extra->getSlot()) - continue; - - if (extra->isEnabled()) - extra->applyIcons(); - } - - delete[] oldSlots; - } - - virtual void OnDestroy() - { - HTREEITEM hItem = m_tree.GetRoot(); - while (hItem) { - delete Tree_GetIDs(hItem); - hItem = m_tree.GetNextSibling(hItem); - } - - ImageList_Destroy(m_tree.GetImageList(TVSIL_NORMAL)); - } - - virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) - { - if (msg == WM_NOTIFY) { - LPNMHDR lpnmhdr = (LPNMHDR)lParam; - if (lpnmhdr->idFrom == IDC_EXTRAORDER && lpnmhdr->code == NM_RCLICK) { - HTREEITEM hSelected = m_tree.GetDropHilight(); - if (hSelected != NULL && !m_tree.IsSelected(hSelected)) { - m_tree.UnselectAll(); - m_tree.SelectItem(hSelected); - } - - int sels = m_tree.GetNumSelected(); - if (sels > 1) { - if (ShowPopup(0) == ID_GROUP) { - GroupSelectedItems(); - NotifyChange(); - } - } - else if (sels == 1) { - HTREEITEM hItem = m_tree.GetSelection(); - intlist *ids = Tree_GetIDs(hItem); - if (ids->count > 1) { - if (ShowPopup(1) == ID_UNGROUP) { - UngroupSelectedItems(); - NotifyChange(); - } - } - } - } - } - - return CDlgBase::DlgProc(msg, wParam, lParam); - } -}; - -///////////////////////////////////////////////////////////////////////////////////////// - -int InitOptionsCallback(WPARAM wParam, LPARAM lParam) -{ - if (GetNumberOfSlots() < 1) - return 0; - - OPTIONSDIALOGPAGE odp = { 0 }; - odp.pszGroup = LPGEN("Contact list"); - odp.pszTitle = LPGEN("Extra icons"); - odp.pszTab = LPGEN("General"); - odp.flags = ODPF_BOLDGROUPS; - odp.pDialog = new CExtraIconOptsDlg(); - Options_AddPage(wParam, &odp); - return 0; -} diff --git a/src/modules/extraicons/usedIcons.cpp b/src/modules/extraicons/usedIcons.cpp deleted file mode 100644 index db967687dd..0000000000 --- a/src/modules/extraicons/usedIcons.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - -Copyright (C) 2009 Ricardo Pescuma Domenecci -Copyright (C) 2012-15 Miranda NG project - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "extraicons.h" - -struct Icon -{ - char *name; - int refCount; - HANDLE hImage; - - Icon(const char *icolibName) : - name( mir_strdup(icolibName)), refCount(0), hImage(INVALID_HANDLE_VALUE) - { - } - - ~Icon() - { mir_free(name); - } -}; - -static int SortFunc(const Icon *p1, const Icon *p2) -{ - return mir_strcmp(p1->name, p2->name); -} - -static OBJLIST usedIcons(50, SortFunc); - -static Icon* FindIcon(const char *icolibName) -{ - Icon *icon = usedIcons.find((Icon*)&icolibName); - if (icon == NULL) - usedIcons.insert(icon = new Icon(icolibName)); - - if (icon->hImage == INVALID_HANDLE_VALUE) { - HICON hIcon = Skin_GetIcon(icon->name); - if (hIcon != NULL) { - icon->hImage = ExtraIcon_Add(hIcon); - Skin_ReleaseIcon(hIcon); - } - } - - return icon; -} - -HANDLE GetIcon(const char *icolibName) -{ - return FindIcon(icolibName)->hImage; -} - -HANDLE AddIcon(const char *icolibName) -{ - Icon *icon = FindIcon(icolibName); - icon->refCount++; - return icon->hImage; -} - -void RemoveIcon(const char *icolibName) -{ - Icon *icon = usedIcons.find((Icon*)&icolibName); - if (icon != NULL) - icon->refCount--; -} - -void ResetIcons() -{ - for (int i = usedIcons.getCount()-1; i >= 0; i--) { - Icon &p = usedIcons[i]; - if (p.refCount <= 0) - usedIcons.remove(i); - else - p.hImage = INVALID_HANDLE_VALUE; - } -} diff --git a/src/modules/extraicons/usedIcons.h b/src/modules/extraicons/usedIcons.h deleted file mode 100644 index b15da88108..0000000000 --- a/src/modules/extraicons/usedIcons.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - -Copyright (C) 2009 Ricardo Pescuma Domenecci -Copyright (C) 2012-15 Miranda NG project - -This is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this file; see the file license.txt. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. -*/ - -#ifndef __USEDICONS_H__ -#define __USEDICONS_H__ - -HANDLE GetIcon(LPCSTR icolibName); - -HANDLE AddIcon(LPCSTR icolibName); -HANDLE AddIcon(HANDLE hIcolib); - -void RemoveIcon(LPCSTR icolibName); -void ResetIcons(); - - -#endif // __USEDICONS_H__ diff --git a/src/modules/findadd/findadd.cpp b/src/modules/findadd/findadd.cpp deleted file mode 100644 index f19f3760bf..0000000000 --- a/src/modules/findadd/findadd.cpp +++ /dev/null @@ -1,1061 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "findadd.h" - -#define TIMERID_THROBBER 111 - -#define HM_SEARCHACK (WM_USER+10) -#define M_SETGROUPVISIBILITIES (WM_USER+11) - -static HWND hwndFindAdd = NULL; -static HANDLE hHookModulesLoaded = 0; -static HGENMENU hMainMenuItem = NULL; -static int OnSystemModulesLoaded(WPARAM wParam, LPARAM lParam); - -static int FindAddDlgResizer(HWND, LPARAM lParam, UTILRESIZECONTROL *urc) -{ - static int y, nextY, oldTop; - FindAddDlgData *dat = (FindAddDlgData*)lParam; - - switch (urc->wId) { - case IDC_RESULTS: - return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; - - case IDOK: - dat->minDlgHeight = nextY + urc->rcItem.bottom - urc->rcItem.top; - return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; - - case IDC_ADD: - case IDC_MOREOPTIONS: - return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM; - - case IDC_STATUSBAR: - return RD_ANCHORX_WIDTH | RD_ANCHORY_BOTTOM; - - case IDC_PROTOIDGROUP: //the resize is always processed in template order - nextY = y = urc->rcItem.top; - if (dat->showProtoId) nextY = y + urc->rcItem.bottom - urc->rcItem.top + 7; - break; - - case IDC_EMAILGROUP: - oldTop = urc->rcItem.top; - y = nextY; - if (dat->showEmail) nextY = y + urc->rcItem.bottom - urc->rcItem.top + 7; - OffsetRect(&urc->rcItem, 0, y - oldTop); - return RD_ANCHORX_LEFT | RD_ANCHORY_CUSTOM; - - case IDC_NAMEGROUP: - oldTop = urc->rcItem.top; - y = nextY; - if (dat->showName) nextY = y + urc->rcItem.bottom - urc->rcItem.top + 7; - OffsetRect(&urc->rcItem, 0, y - oldTop); - return RD_ANCHORX_LEFT | RD_ANCHORY_CUSTOM; - - case IDC_ADVANCEDGROUP: - oldTop = urc->rcItem.top; - y = nextY; - if (dat->showAdvanced) nextY = y + urc->rcItem.bottom - urc->rcItem.top + 7; - OffsetRect(&urc->rcItem, 0, y - oldTop); - return RD_ANCHORX_LEFT | RD_ANCHORY_CUSTOM; - - case IDC_TINYEXTENDEDGROUP: - oldTop = urc->rcItem.top; - y = nextY; - if (dat->showTiny) { - int height = urc->dlgNewSize.cy - y - (urc->dlgOriginalSize.cy - urc->rcItem.bottom); - nextY = y + 200; //min height for custom dialog - urc->rcItem.top = urc->rcItem.bottom - height; - } - return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; - - case IDC_BYEMAIL: - case IDC_EMAIL: - case IDC_BYNAME: - case IDC_STNAMENICK: - case IDC_STNAMEFIRST: - case IDC_STNAMELAST: - case IDC_NAMENICK: - case IDC_NAMEFIRST: - case IDC_NAMELAST: - case IDC_BYADVANCED: - case IDC_BYCUSTOM: - case IDC_ADVANCED: - OffsetRect(&urc->rcItem, 0, y - oldTop); - return RD_ANCHORX_LEFT | RD_ANCHORY_CUSTOM; - - case IDC_HEADERBAR: - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH; - } - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; -} - -static void RenderThrobber(HDC hdc, RECT *rcItem, int *throbbing, int *pivot) -{ - InflateRect(rcItem, -1, 0); - int width = rcItem->right - rcItem->left; - int height = rcItem->bottom - rcItem->top; - int height2 = height / 2; - - if (*throbbing) { - /* create memdc */ - HDC hMemDC = CreateCompatibleDC(0); - HBITMAP hBitmap = (HBITMAP)SelectObject(hMemDC, CreateCompatibleBitmap(hdc, width, height)); - /* flush it */ - RECT rc; - rc.left = rc.top = 0; - rc.right = width; - rc.bottom = height; - HBRUSH hBr = GetSysColorBrush(COLOR_BTNFACE); - FillRect(hMemDC, &rc, hBr); - DeleteObject(hBr); - /* set up the pen */ - HPEN hPen = (HPEN)SelectObject(hMemDC, CreatePen(PS_SOLID, 4, GetSysColor(COLOR_BTNSHADOW))); - /* draw everything before the pivot */ - int x = *pivot; - while (x > (-height)) { - MoveToEx(hMemDC, x + height2, 0, NULL); - LineTo(hMemDC, x - height2, height); - x -= 12; - } - - /* draw everything after the pivot */ - x = *pivot; - while (x < width + height) { - MoveToEx(hMemDC, x + height2, 0, NULL); - LineTo(hMemDC, x - height2, height); - x += 12; - } - - /* move the pivot */ - *pivot += 2; - /* reset the pivot point if it gets past the rect */ - if (*pivot > width) *pivot = 0; - /* put back the old pen and delete the new one */ - DeleteObject(SelectObject(hMemDC, hPen)); - /* cap the top and bottom */ - hPen = (HPEN)SelectObject(hMemDC, CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNFACE))); - MoveToEx(hMemDC, 0, 0, NULL); - LineTo(hMemDC, width, 0); - MoveToEx(hMemDC, 0, height - 1, NULL); - LineTo(hMemDC, width, height - 1); - /* select in the old pen and delete the new pen */ - DeleteObject(SelectObject(hMemDC, hPen)); - /* paint to screen */ - BitBlt(hdc, rcItem->left, rcItem->top, width, height, hMemDC, 0, 0, SRCCOPY); - /* select back in the old bitmap and delete the created one, as well as freeing the mem dc. */ - hBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); - DeleteObject(hBitmap); - DeleteDC(hMemDC); - } - else { - /* just flush the DC */ - HBRUSH hBr = GetSysColorBrush(COLOR_BTNFACE); - FillRect(hdc, rcItem, hBr); - DeleteObject(hBr); - } -} - -static void StartThrobber(HWND hwndDlg, FindAddDlgData *dat) -{ - dat->throbbing = 1; - SetTimer(hwndDlg, TIMERID_THROBBER, 25, NULL); -} - -static void StopThrobber(HWND hwndDlg, FindAddDlgData *dat) -{ - KillTimer(hwndDlg, TIMERID_THROBBER); - dat->throbbing = 0; - dat->pivot = 0; - InvalidateRect(GetDlgItem(hwndDlg, IDC_STATUSBAR), NULL, FALSE); -} - -static LRESULT CALLBACK AdvancedSearchDlgSubclassProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (msg == WM_COMMAND) { - HWND parentHwnd = GetParent(hwndDlg); - switch (LOWORD(wParam)) { - case IDOK: - SendMessage(parentHwnd, WM_COMMAND, MAKEWPARAM(IDOK, BN_CLICKED), (LPARAM)GetDlgItem(parentHwnd, IDOK)); - SetFocus(GetDlgItem(parentHwnd, IDC_ADVANCED)); - break; - - case IDCANCEL: - CheckDlgButton(parentHwnd, IDC_ADVANCED, BST_UNCHECKED); - SendMessage(parentHwnd, WM_COMMAND, MAKEWPARAM(IDC_ADVANCED, BN_CLICKED), (LPARAM)GetDlgItem(parentHwnd, IDC_ADVANCED)); - SetFocus(GetDlgItem(parentHwnd, IDC_ADVANCED)); - break; - } - } - return mir_callNextSubclass(hwndDlg, AdvancedSearchDlgSubclassProc, msg, wParam, lParam); -} - -static void ShowAdvancedSearchDlg(HWND hwndDlg, FindAddDlgData *dat) -{ - char *szProto = (char*)SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETCURSEL, 0, 0), 0); - if (szProto == NULL) - return; - - if (dat->hwndAdvSearch == NULL) { - RECT rc; - dat->hwndAdvSearch = (HWND)CallProtoServiceInt(NULL, szProto, PS_CREATEADVSEARCHUI, 0, (LPARAM)hwndDlg); - if (dat->hwndAdvSearch != NULL) - mir_subclassWindow(dat->hwndAdvSearch, AdvancedSearchDlgSubclassProc); - GetWindowRect(GetDlgItem(hwndDlg, IDC_RESULTS), &rc); - SetWindowPos(dat->hwndAdvSearch, 0, rc.left, rc.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); - } - - AnimateWindow(dat->hwndAdvSearch, 150, AW_ACTIVATE | AW_SLIDE | AW_HOR_POSITIVE); - RedrawWindow(dat->hwndAdvSearch, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); - - CheckDlgButton(hwndDlg, IDC_ADVANCED, BST_CHECKED); -} - -static void ReposTinySearchDlg(HWND hwndDlg, FindAddDlgData *dat) -{ - if (dat->hwndTinySearch == NULL) - return; - - RECT rc; - RECT clientRect; - POINT pt = { 0, 0 }; - GetWindowRect(GetDlgItem(hwndDlg, IDC_TINYEXTENDEDGROUP), &rc); - GetWindowRect(dat->hwndTinySearch, &clientRect); - pt.x = rc.left; - pt.y = rc.top; - ScreenToClient(hwndDlg, &pt); - SetWindowPos(dat->hwndTinySearch, 0, pt.x + 5, pt.y + 15, rc.right - rc.left - 10, rc.bottom - rc.top - 30, SWP_NOZORDER); -} - -static void ShowTinySearchDlg(HWND hwndDlg, FindAddDlgData *dat) -{ - char *szProto = (char*)SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETCURSEL, 0, 0), 0); - if (szProto == NULL) - return; - - if (dat->hwndTinySearch == NULL) { - dat->hwndTinySearch = (HWND)CallProtoServiceInt(NULL, szProto, PS_CREATEADVSEARCHUI, 0, (LPARAM)/*GetDlgItem(*/hwndDlg/*, IDC_TINYEXTENDEDGROUP)*/); - if (dat->hwndTinySearch) - ReposTinySearchDlg(hwndDlg, dat); - else - dat->showTiny = false; - } - ShowWindow(dat->hwndTinySearch, SW_SHOW); -} - -static void HideAdvancedSearchDlg(HWND hwndDlg, FindAddDlgData *dat) -{ - if (dat->hwndAdvSearch == NULL) - return; - - AnimateWindow(dat->hwndAdvSearch, 150, AW_HIDE | AW_BLEND); - CheckDlgButton(hwndDlg, IDC_ADVANCED, BST_UNCHECKED); -} - -void EnableResultButtons(HWND hwndDlg, int enable) -{ - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), enable); - EnableWindow(GetDlgItem(hwndDlg, IDC_MOREOPTIONS), enable); -} - -static const int controls[] = { IDC_BYPROTOID, IDC_BYEMAIL, IDC_BYNAME, IDC_BYADVANCED, IDC_BYCUSTOM }; - -static void CheckSearchTypeRadioButton(HWND hwndDlg, int idControl) -{ - for (int i = 0; i < SIZEOF(controls); i++) - CheckDlgButton(hwndDlg, controls[i], idControl == controls[i] ? BST_CHECKED : BST_UNCHECKED); -} - -#define sttErrMsg TranslateT("You haven't filled in the search field. Please enter a search term and try again.") -#define sttErrTitle TranslateT("Search") - -static void SetListItemText(HWND hwndList, int idx, int col, TCHAR *szText) -{ - if (szText == NULL || *szText == 0) - szText = TranslateT(""); - - ListView_SetItemText(hwndList, idx, col, szText); -} - -static TCHAR* sttDecodeString(DWORD dwFlags, MAllStrings &src) -{ - if (dwFlags & PSR_UNICODE) - return mir_u2t(src.w); - - if (dwFlags & PSR_UTF8) - return mir_utf8decodeT(src.a); - - return mir_a2t(src.a); -} - -static INT_PTR CALLBACK DlgProcFindAdd(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - FindAddDlgData *dat = (FindAddDlgData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - HWND hwndList = GetDlgItem(hwndDlg, IDC_RESULTS); - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - Window_SetIcon_IcoLib(hwndDlg, SKINICON_OTHER_FINDUSER); - dat = (FindAddDlgData*)mir_calloc(sizeof(FindAddDlgData)); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); - dat->notSearchedYet = 1; - dat->iLastColumnSortIndex = 1; - dat->bSortAscending = 1; - SendDlgItemMessage(hwndDlg, IDC_MOREOPTIONS, BUTTONSETARROW, 1, 0); - SendDlgItemMessage(hwndDlg, IDOK, BUTTONADDTOOLTIP, (WPARAM)LPGENT("Ctrl+Search add contact"), BATF_TCHAR); - - ListView_SetExtendedListViewStyle(hwndList, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP); - { - RECT rc; - GetClientRect(hwndList, &rc); - - LVCOLUMN lvc; - lvc.mask = LVCF_TEXT | LVCF_WIDTH; - lvc.pszText = TranslateT("Results"); - lvc.cx = rc.right - 1; - ListView_InsertColumn(hwndList, 0, &lvc); - - LVITEM lvi; - lvi.mask = LVIF_TEXT; - lvi.iItem = 0; - lvi.iSubItem = 0; - lvi.pszText = TranslateT("There are no results to display."); - ListView_InsertItem(hwndList, &lvi); - - // Allocate a reasonable amount of space in the status bar - HDC hdc = GetDC(GetDlgItem(hwndDlg, IDC_STATUSBAR)); - SelectObject(hdc, (HFONT)SendDlgItemMessage(hwndDlg, IDC_STATUSBAR, WM_GETFONT, 0, 0)); - - SIZE textSize; - GetTextExtentPoint32(hdc, TranslateT("Searching"), (int)mir_tstrlen(TranslateT("Searching")), &textSize); - - int partWidth[3]; - partWidth[0] = textSize.cx; - GetTextExtentPoint32(hdc, _T("01234567890123456789"), 20, &textSize); - partWidth[0] += textSize.cx; - ReleaseDC(GetDlgItem(hwndDlg, IDC_STATUSBAR), hdc); - partWidth[1] = partWidth[0] + 150; - partWidth[2] = -1; - SendDlgItemMessage(hwndDlg, IDC_STATUSBAR, SB_SETPARTS, SIZEOF(partWidth), (LPARAM)partWidth); - SendDlgItemMessage(hwndDlg, IDC_STATUSBAR, SB_SETTEXT, 1 | SBT_OWNERDRAW, 0); - SetStatusBarSearchInfo(GetDlgItem(hwndDlg, IDC_STATUSBAR), dat); - - TCHAR *szProto = NULL; - DBVARIANT dbv; - if (!db_get_ts(NULL, "FindAdd", "LastSearched", &dbv)) { - szProto = NEWTSTR_ALLOCA(dbv.ptszVal); - db_free(&dbv); /* free string szProto was fetched with */ - } - - int i, index = 0, cbwidth = 0, netProtoCount = 0; - for (i = 0; i < accounts.getCount(); i++) { - if (!Proto_IsAccountEnabled(accounts[i])) - continue; - - DWORD caps = (DWORD)CallProtoServiceInt(NULL, accounts[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0); - if (caps & PF1_ANYSEARCH) - netProtoCount++; - } - dat->himlComboIcons = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, netProtoCount + 1, netProtoCount + 1); - SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CBEM_SETIMAGELIST, 0, (LPARAM)dat->himlComboIcons); - - COMBOBOXEXITEM cbei; - cbei.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT | CBEIF_LPARAM; - cbei.iItem = 0; - hdc = GetDC(hwndDlg); - SelectObject(hdc, (HFONT)SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, WM_GETFONT, 0, 0)); - if (netProtoCount > 1) { - cbei.pszText = TranslateT("All networks"); - GetTextExtentPoint32(hdc, cbei.pszText, (int)mir_tstrlen(cbei.pszText), &textSize); - if (textSize.cx > cbwidth) - cbwidth = textSize.cx; - cbei.iImage = cbei.iSelectedImage = ImageList_AddIcon_IconLibLoaded(dat->himlComboIcons, SKINICON_OTHER_SEARCHALL); - cbei.lParam = 0; - SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CBEM_INSERTITEM, 0, (LPARAM)&cbei); - cbei.iItem++; - } - - for (i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (!Proto_IsAccountEnabled(pa)) - continue; - - DWORD caps = (DWORD)CallProtoServiceInt(NULL, pa->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0); - if (!(caps & PF1_ANYSEARCH)) - continue; - - cbei.pszText = pa->tszAccountName; - GetTextExtentPoint32(hdc, cbei.pszText, (int)mir_tstrlen(cbei.pszText), &textSize); - if (textSize.cx > cbwidth) - cbwidth = textSize.cx; - - HICON hIcon = (HICON)CallProtoServiceInt(NULL, pa->szModuleName, PS_LOADICON, PLI_PROTOCOL | PLIF_SMALL, 0); - cbei.iImage = cbei.iSelectedImage = ImageList_AddIcon(dat->himlComboIcons, hIcon); - DestroyIcon(hIcon); - cbei.lParam = (LPARAM)pa->szModuleName; - SendDlgItemMessageA(hwndDlg, IDC_PROTOLIST, CBEM_INSERTITEM, 0, (LPARAM)&cbei); - if (szProto && cbei.pszText && !mir_tstrcmp(szProto, pa->tszAccountName)) - index = cbei.iItem; - cbei.iItem++; - } - cbwidth += 32; - - RECT rect; - SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rect); - if ((rect.right - rect.left) < cbwidth) - SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_SETDROPPEDWIDTH, cbwidth, 0); - SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_SETCURSEL, index, 0); - - SendMessage(hwndDlg, M_SETGROUPVISIBILITIES, 0, 0); - Utils_RestoreWindowPosition(hwndDlg, NULL, "FindAdd", ""); - } - return TRUE; - - case WM_SIZE: - { - UTILRESIZEDIALOG urd = { 0 }; - urd.cbSize = sizeof(urd); - urd.hwndDlg = hwndDlg; - urd.hInstance = hInst; - urd.lpTemplate = MAKEINTRESOURCEA(IDD_FINDADD); - urd.lParam = (LPARAM)dat; - urd.pfnResizer = FindAddDlgResizer; - CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); - ReposTinySearchDlg(hwndDlg, dat); - SendDlgItemMessage(hwndDlg, IDC_STATUSBAR, WM_SIZE, 0, 0); - if (dat->notSearchedYet) { - RECT rc; - GetClientRect(hwndList, &rc); - ListView_SetColumnWidth(hwndList, 0, rc.right); - } - } - //fall through - case WM_MOVE: - if (dat && dat->hwndAdvSearch) { - RECT rc; - GetWindowRect(hwndList, &rc); - SetWindowPos(dat->hwndAdvSearch, 0, rc.left, rc.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); - } - break; - - case WM_GETMINMAXINFO: - RECT rc, rc2; - GetWindowRect(hwndList, &rc); - GetWindowRect(hwndDlg, &rc2); - { - MINMAXINFO *mmi = (MINMAXINFO*)lParam; - mmi->ptMinTrackSize.x = rc.left - rc2.left + 10 + GetSystemMetrics(SM_CXFRAME); - GetClientRect(GetDlgItem(hwndDlg, IDC_MOREOPTIONS), &rc); - mmi->ptMinTrackSize.x += rc.right + 5; - GetClientRect(GetDlgItem(hwndDlg, IDC_ADD), &rc); - mmi->ptMinTrackSize.x += rc.right + 5; - GetClientRect(GetDlgItem(hwndDlg, IDC_STATUSBAR), &rc); - mmi->ptMinTrackSize.y = dat->minDlgHeight + 20 + GetSystemMetrics(SM_CYCAPTION) + 2 * GetSystemMetrics(SM_CYFRAME); - GetClientRect(GetDlgItem(hwndDlg, IDC_STATUSBAR), &rc); - mmi->ptMinTrackSize.y += rc.bottom; - } - return 0; - - case M_SETGROUPVISIBILITIES: - dat->showAdvanced = dat->showEmail = dat->showName = dat->showProtoId = dat->showTiny = 0; - { - char *szProto = (char*)SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETCURSEL, 0, 0), 0); - if (szProto == (char *)CB_ERR) - break; - if (szProto == NULL) { - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (Proto_IsAccountEnabled(pa)) { - DWORD protoCaps = (DWORD)CallProtoServiceInt(NULL, pa->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0); - if (protoCaps & PF1_SEARCHBYEMAIL) dat->showEmail = 1; - if (protoCaps & PF1_SEARCHBYNAME) dat->showName = 1; - } - } - } - else { - DWORD protoCaps = (DWORD)CallProtoServiceInt(NULL, szProto, PS_GETCAPS, PFLAGNUM_1, 0); - if (protoCaps & PF1_BASICSEARCH) dat->showProtoId = 1; - if (protoCaps & PF1_SEARCHBYEMAIL) dat->showEmail = 1; - if (protoCaps & PF1_SEARCHBYNAME) dat->showName = 1; - - if (protoCaps & PF1_EXTSEARCHUI) dat->showAdvanced = 1; - else if (protoCaps & PF1_EXTSEARCH) dat->showTiny = 1; - - if (protoCaps & PF1_USERIDISEMAIL && dat->showProtoId) { dat->showProtoId = 0; dat->showEmail = 1; } - if (dat->showProtoId) { - char *szUniqueId = (char*)CallProtoServiceInt(NULL, szProto, PS_GETCAPS, PFLAG_UNIQUEIDTEXT, 0); - if (szUniqueId) - SetDlgItemTextA(hwndDlg, IDC_BYPROTOID, szUniqueId); - else - SetDlgItemText(hwndDlg, IDC_BYPROTOID, TranslateT("Handle")); - - if (protoCaps & PF1_NUMERICUSERID) - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_PROTOID), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_PROTOID), GWL_STYLE) | ES_NUMBER); - else - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_PROTOID), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_PROTOID), GWL_STYLE)&~ES_NUMBER); - } - } - - if (dat->showTiny) - ShowTinySearchDlg(hwndDlg, dat); - else if (dat->hwndTinySearch) { - DestroyWindow(dat->hwndTinySearch); - dat->hwndTinySearch = NULL; - } - -#define en(id, t) ShowWindow( GetDlgItem(hwndDlg, IDC_##id), dat->show##t?SW_SHOW:SW_HIDE) - en(PROTOIDGROUP, ProtoId); en(BYPROTOID, ProtoId); en(PROTOID, ProtoId); - en(EMAILGROUP, Email); en(BYEMAIL, Email); en(EMAIL, Email); - en(NAMEGROUP, Name); en(BYNAME, Name); - en(STNAMENICK, Name); en(NAMENICK, Name); - en(STNAMEFIRST, Name); en(NAMEFIRST, Name); - en(STNAMELAST, Name); en(NAMELAST, Name); - en(ADVANCEDGROUP, Advanced); en(BYADVANCED, Advanced); en(ADVANCED, Advanced); - en(BYCUSTOM, Tiny); en(TINYEXTENDEDGROUP, Tiny); -#undef en - int checkmarkVisible = (dat->showAdvanced && IsDlgButtonChecked(hwndDlg, IDC_BYADVANCED)) || - (dat->showEmail && IsDlgButtonChecked(hwndDlg, IDC_BYEMAIL)) || - (dat->showTiny && IsDlgButtonChecked(hwndDlg, IDC_BYCUSTOM)) || - (dat->showName && IsDlgButtonChecked(hwndDlg, IDC_BYNAME)) || - (dat->showProtoId && IsDlgButtonChecked(hwndDlg, IDC_BYPROTOID)); - if (!checkmarkVisible) { - if (dat->showProtoId) CheckSearchTypeRadioButton(hwndDlg, IDC_BYPROTOID); - else if (dat->showEmail) CheckSearchTypeRadioButton(hwndDlg, IDC_BYEMAIL); - else if (dat->showName) CheckSearchTypeRadioButton(hwndDlg, IDC_BYNAME); - else if (dat->showAdvanced) CheckSearchTypeRadioButton(hwndDlg, IDC_BYADVANCED); - else if (dat->showTiny) CheckSearchTypeRadioButton(hwndDlg, IDC_BYCUSTOM); - } - - SendMessage(hwndDlg, WM_SIZE, 0, 0); - - MINMAXINFO mmi; - SendMessage(hwndDlg, WM_GETMINMAXINFO, 0, (LPARAM)&mmi); - - RECT rc; - GetWindowRect(hwndDlg, &rc); - if (rc.bottom - rc.top < mmi.ptMinTrackSize.y) - SetWindowPos(hwndDlg, 0, 0, 0, rc.right - rc.left, mmi.ptMinTrackSize.y, SWP_NOZORDER | SWP_NOMOVE); - } - break; - - case WM_TIMER: - if (wParam == TIMERID_THROBBER) { - int borders[3]; - SendDlgItemMessage(hwndDlg, IDC_STATUSBAR, SB_GETBORDERS, 0, (LPARAM)borders); - - RECT rc; - SendDlgItemMessage(hwndDlg, IDC_STATUSBAR, SB_GETRECT, 1, (LPARAM)&rc); - InflateRect(&rc, -borders[2] / 2, -borders[1] / 2); - HDC hdc = GetDC(GetDlgItem(hwndDlg, IDC_STATUSBAR)); - RenderThrobber(hdc, &rc, &dat->throbbing, &dat->pivot); - ReleaseDC(GetDlgItem(hwndDlg, IDC_STATUSBAR), hdc); - } - break; - - case WM_DRAWITEM: - { - DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)lParam; - if (dis->CtlID == IDC_STATUSBAR && dis->itemID == 1) { - RenderThrobber(dis->hDC, &dis->rcItem, &dat->throbbing, &dat->pivot); - return TRUE; - } - } - break; - - case WM_NOTIFY: - if (wParam == IDC_RESULTS) { - switch (((LPNMHDR)lParam)->code) { - case LVN_ITEMCHANGED: - { - int count = ListView_GetSelectedCount(hwndList); - if (dat->notSearchedYet) - count = 0; - EnableResultButtons(hwndDlg, count); - } - break; - - case LVN_COLUMNCLICK: - HDITEM hdi; - hdi.mask = HDI_FORMAT; - hdi.fmt = HDF_LEFT | HDF_STRING; - Header_SetItem(ListView_GetHeader(hwndList), dat->iLastColumnSortIndex, &hdi); - - LPNMLISTVIEW nmlv = (LPNMLISTVIEW)lParam; - if (nmlv->iSubItem != dat->iLastColumnSortIndex) { - dat->bSortAscending = TRUE; - dat->iLastColumnSortIndex = nmlv->iSubItem; - } - else dat->bSortAscending = !dat->bSortAscending; - - hdi.fmt = HDF_LEFT | HDF_STRING | (dat->bSortAscending ? HDF_SORTDOWN : HDF_SORTUP); - Header_SetItem(ListView_GetHeader(hwndList), dat->iLastColumnSortIndex, &hdi); - - ListView_SortItemsEx(hwndList, SearchResultsCompareFunc, (LPARAM)hwndDlg); - } - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_PROTOLIST: - if (HIWORD(wParam) == CBN_SELCHANGE) { - HideAdvancedSearchDlg(hwndDlg, dat); - if (dat->hwndAdvSearch) { - DestroyWindow(dat->hwndAdvSearch); - dat->hwndAdvSearch = NULL; - } - if (dat->hwndTinySearch) { - DestroyWindow(dat->hwndTinySearch); - dat->hwndTinySearch = NULL; - } - SendMessage(hwndDlg, M_SETGROUPVISIBILITIES, 0, 0); - } - break; - - case IDC_BYPROTOID: - case IDC_BYEMAIL: - case IDC_BYNAME: - { - int count = ListView_GetSelectedCount(hwndList); - if (dat->notSearchedYet) - count = 0; - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), count); - HideAdvancedSearchDlg(hwndDlg, dat); - } - break; - - case IDC_PROTOID: - if (HIWORD(wParam) == EN_CHANGE) { - HideAdvancedSearchDlg(hwndDlg, dat); - CheckSearchTypeRadioButton(hwndDlg, IDC_BYPROTOID); - } - break; - - case IDC_EMAIL: - if (HIWORD(wParam) == EN_CHANGE) { - HideAdvancedSearchDlg(hwndDlg, dat); - CheckSearchTypeRadioButton(hwndDlg, IDC_BYEMAIL); - } - break; - - case IDC_NAMENICK: - case IDC_NAMEFIRST: - case IDC_NAMELAST: - if (HIWORD(wParam) == EN_CHANGE) { - HideAdvancedSearchDlg(hwndDlg, dat); - CheckSearchTypeRadioButton(hwndDlg, IDC_BYNAME); - } - break; - - case IDC_ADVANCED: - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), ListView_GetSelectedCount(hwndList) > 0); - if (IsDlgButtonChecked(hwndDlg, IDC_ADVANCED)) - ShowAdvancedSearchDlg(hwndDlg, dat); - else - HideAdvancedSearchDlg(hwndDlg, dat); - CheckSearchTypeRadioButton(hwndDlg, IDC_BYADVANCED); - break; - - case IDCANCEL: - DestroyWindow(hwndDlg); - break; - - case IDOK: - HideAdvancedSearchDlg(hwndDlg, dat); - if (dat->searchCount) { //cancel search - SetDlgItemText(hwndDlg, IDOK, TranslateT("&Search")); - if (dat->hResultHook) { UnhookEvent(dat->hResultHook); dat->hResultHook = NULL; } - if (dat->search) { mir_free(dat->search); dat->search = NULL; } - dat->searchCount = 0; - StopThrobber(hwndDlg, dat); - SetStatusBarSearchInfo(GetDlgItem(hwndDlg, IDC_STATUSBAR), dat); - } - else { - char *szProto = (char*)SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETCURSEL, 0, 0), 0); - if (dat->search) - mir_free(dat->search), dat->search = NULL; - dat->searchCount = 0; - dat->hResultHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_SEARCHACK); - if (IsDlgButtonChecked(hwndDlg, IDC_BYCUSTOM)) - BeginSearch(hwndDlg, dat, szProto, PS_SEARCHBYADVANCED, PF1_EXTSEARCHUI, dat->hwndTinySearch); - else if (IsDlgButtonChecked(hwndDlg, IDC_BYPROTOID)) { - TCHAR str[256]; - GetDlgItemText(hwndDlg, IDC_PROTOID, str, SIZEOF(str)); - rtrimt(str); - if (str[0] == 0) - MessageBox(hwndDlg, sttErrMsg, sttErrTitle, MB_ICONERROR | MB_OK); - else - BeginSearch(hwndDlg, dat, szProto, PS_BASICSEARCH, PF1_BASICSEARCH, str); - } - else if (IsDlgButtonChecked(hwndDlg, IDC_BYEMAIL)) { - TCHAR str[256]; - GetDlgItemText(hwndDlg, IDC_EMAIL, str, SIZEOF(str)); - rtrimt(str); - if (str[0] == 0) - MessageBox(hwndDlg, sttErrMsg, sttErrTitle, MB_ICONERROR | MB_OK); - else - BeginSearch(hwndDlg, dat, szProto, PS_SEARCHBYEMAIL, PF1_SEARCHBYEMAIL, str); - } - else if (IsDlgButtonChecked(hwndDlg, IDC_BYNAME)) { - TCHAR nick[256], first[256], last[256]; - PROTOSEARCHBYNAME psbn; - GetDlgItemText(hwndDlg, IDC_NAMENICK, nick, SIZEOF(nick)); - GetDlgItemText(hwndDlg, IDC_NAMEFIRST, first, SIZEOF(first)); - GetDlgItemText(hwndDlg, IDC_NAMELAST, last, SIZEOF(last)); - psbn.pszFirstName = first; - psbn.pszLastName = last; - psbn.pszNick = nick; - if (nick[0] == 0 && first[0] == 0 && last[0] == 0) - MessageBox(hwndDlg, sttErrMsg, sttErrTitle, MB_ICONERROR | MB_OK); - else - BeginSearch(hwndDlg, dat, szProto, PS_SEARCHBYNAME, PF1_SEARCHBYNAME, &psbn); - } - else if (IsDlgButtonChecked(hwndDlg, IDC_BYADVANCED)) { - if (dat->hwndAdvSearch == NULL) - MessageBox(hwndDlg, sttErrMsg, sttErrTitle, MB_ICONERROR | MB_OK); - else - BeginSearch(hwndDlg, dat, szProto, PS_SEARCHBYADVANCED, PF1_EXTSEARCHUI, dat->hwndAdvSearch); - } - - if (dat->searchCount == 0) { - if (dat->hResultHook) { - UnhookEvent(dat->hResultHook); - dat->hResultHook = NULL; - } - break; - } - - dat->notSearchedYet = 0; - FreeSearchResults(hwndList); - - CreateResultsColumns(hwndList, dat, szProto); - SetStatusBarSearchInfo(GetDlgItem(hwndDlg, IDC_STATUSBAR), dat); - SetStatusBarResultInfo(hwndDlg); - StartThrobber(hwndDlg, dat); - SetDlgItemText(hwndDlg, IDOK, TranslateT("Cancel")); - } - break; - - case IDC_ADD: - { - ADDCONTACTSTRUCT acs = { 0 }; - - if (ListView_GetSelectedCount(hwndList) == 1) { - LVITEM lvi; - lvi.mask = LVIF_PARAM; - lvi.iItem = ListView_GetNextItem(hwndList, -1, LVNI_ALL | LVNI_SELECTED); - ListView_GetItem(hwndList, &lvi); - ListSearchResult *lsr = (ListSearchResult*)lvi.lParam; - acs.szProto = lsr->szProto; - acs.psr = &lsr->psr; - } - else { - TCHAR str[256]; - GetDlgItemText(hwndDlg, IDC_PROTOID, str, SIZEOF(str)); - if (*rtrimt(str) == 0) - break; - - PROTOSEARCHRESULT psr = { 0 }; - psr.cbSize = sizeof(psr); - psr.flags = PSR_TCHAR; - psr.id.t = str; - - acs.psr = &psr; - acs.szProto = (char*)SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETITEMDATA, - SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETCURSEL, 0, 0), 0); - } - - acs.handleType = HANDLE_SEARCHRESULT; - CallService(MS_ADDCONTACT_SHOW, (WPARAM)hwndDlg, (LPARAM)&acs); - } - break; - - case IDC_MOREOPTIONS: - RECT rc; - GetWindowRect(GetDlgItem(hwndDlg, IDC_MOREOPTIONS), &rc); - ShowMoreOptionsMenu(hwndDlg, rc.left, rc.bottom); - break; - } - - if (lParam && dat->hwndTinySearch == (HWND)lParam && - HIWORD(wParam) == EN_SETFOCUS && LOWORD(wParam) == 0 && - BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_BYCUSTOM)) { - CheckSearchTypeRadioButton(hwndDlg, IDC_BYCUSTOM); - } - break; - - case WM_CONTEXTMENU: - { - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - - LVHITTESTINFO lvhti; - lvhti.pt = pt; - ScreenToClient(hwndDlg, &pt); - switch (GetDlgCtrlID(ChildWindowFromPoint(hwndDlg, pt))) { - case IDC_RESULTS: - if (dat->notSearchedYet) - return TRUE; - ScreenToClient(hwndList, &lvhti.pt); - if (ListView_HitTest(hwndList, &lvhti) == -1) - break; - ShowMoreOptionsMenu(hwndDlg, (short)LOWORD(lParam), (short)HIWORD(lParam)); - return TRUE; - } - } - break; - - case HM_SEARCHACK: - { - ACKDATA *ack = (ACKDATA*)lParam; - if (ack->type != ACKTYPE_SEARCH) - break; - - int i; - for (i = 0; i < dat->searchCount; i++) - if (dat->search[i].hProcess == ack->hProcess && dat->search[i].hProcess != NULL && !mir_strcmp(dat->search[i].szProto, ack->szModule)) break; - if (i == dat->searchCount) - break; - - if (ack->result == ACKRESULT_SUCCESS || ack->result == ACKRESULT_FAILED) { - dat->searchCount--; - memmove(dat->search + i, dat->search + i + 1, sizeof(struct ProtoSearchInfo)*(dat->searchCount - i)); - if (dat->searchCount == 0) { - mir_free(dat->search); - dat->search = NULL; - UnhookEvent(dat->hResultHook); - dat->hResultHook = NULL; - SetDlgItemText(hwndDlg, IDOK, TranslateT("&Search")); - StopThrobber(hwndDlg, dat); - } - ListView_SortItemsEx(hwndList, SearchResultsCompareFunc, (LPARAM)hwndDlg); - SetStatusBarSearchInfo(GetDlgItem(hwndDlg, IDC_STATUSBAR), dat); - } - else if (ack->result == ACKRESULT_SEARCHRESULT && ack->lParam) { - CUSTOMSEARCHRESULTS *csr = (CUSTOMSEARCHRESULTS*)ack->lParam; - dat->bFlexSearchResult = TRUE; - PROTOSEARCHRESULT *psr = &csr->psr; - // check if this is column names data (psr->cbSize == 0) - if (psr->cbSize == 0) { // blob contain info about columns - // first remove all exist items - FreeSearchResults(hwndList); - ListView_DeleteAllItems(hwndList); //not sure if previous delete list items too - - //second remove all columns - while (ListView_DeleteColumn(hwndList, 1)); //will delete fist column till it possible - - // now will add columns and captions; - LVCOLUMN lvc = { 0 }; - lvc.mask = LVCF_TEXT; - for (int iColumn = 0; iColumn < csr->nFieldCount; iColumn++) { - lvc.pszText = TranslateTS(csr->pszFields[iColumn]); - ListView_InsertColumn(hwndList, iColumn + 1, &lvc); - } - } - else { // blob contain info about found contacts - ListSearchResult *lsr = (ListSearchResult*)mir_alloc(offsetof(struct ListSearchResult, psr) + psr->cbSize); - lsr->szProto = ack->szModule; - memcpy(&lsr->psr, psr, psr->cbSize); - - /* Next block is not needed but behavior will be kept */ - lsr->psr.id.t = sttDecodeString(psr->flags, psr->id); - lsr->psr.nick.t = sttDecodeString(psr->flags, psr->nick); - lsr->psr.firstName.t = sttDecodeString(psr->flags, psr->firstName); - lsr->psr.lastName.t = sttDecodeString(psr->flags, psr->lastName); - lsr->psr.email.t = sttDecodeString(psr->flags, psr->email); - lsr->psr.flags = psr->flags & ~PSR_UNICODE | PSR_TCHAR; - - LVITEM lvi = { 0 }; - lvi.mask = LVIF_PARAM | LVIF_IMAGE; - lvi.lParam = (LPARAM)lsr; - for (int i = SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETCOUNT, 0, 0); i--;) { - char *szComboProto = (char*)SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETITEMDATA, i, 0); - if (szComboProto == NULL) continue; - if (!mir_strcmp(szComboProto, ack->szModule)) { - COMBOBOXEXITEM cbei = { 0 }; - cbei.mask = CBEIF_IMAGE; - cbei.iItem = i; - SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CBEM_GETITEM, 0, (LPARAM)&cbei); - lvi.iImage = cbei.iImage; - } - } - int iItem = ListView_InsertItem(hwndList, &lvi); - for (int col = 0; col < csr->nFieldCount; col++) - SetListItemText(hwndList, iItem, col + 1, csr->pszFields[col]); - - ListView_SortItemsEx(hwndList, SearchResultsCompareFunc, (LPARAM)hwndDlg); - iItem = 0; - while (ListView_SetColumnWidth(hwndList, iItem++, LVSCW_AUTOSIZE_USEHEADER)); - SetStatusBarResultInfo(hwndDlg); - } - break; - } - else if (ack->result == ACKRESULT_DATA) { - PROTOSEARCHRESULT *psr = (PROTOSEARCHRESULT*)ack->lParam; - ListSearchResult *lsr = (ListSearchResult*)mir_alloc(offsetof(struct ListSearchResult, psr) + psr->cbSize); - lsr->szProto = ack->szModule; - - dat->bFlexSearchResult = FALSE; - - memcpy(&lsr->psr, psr, psr->cbSize); - lsr->psr.nick.t = sttDecodeString(psr->flags, psr->nick); - lsr->psr.firstName.t = sttDecodeString(psr->flags, psr->firstName); - lsr->psr.lastName.t = sttDecodeString(psr->flags, psr->lastName); - lsr->psr.email.t = sttDecodeString(psr->flags, psr->email); - lsr->psr.id.t = sttDecodeString(psr->flags, psr->id); - lsr->psr.flags = psr->flags & ~PSR_UNICODE | PSR_TCHAR; - - LVITEM lvi = { 0 }; - lvi.mask = LVIF_PARAM | LVIF_IMAGE; - lvi.lParam = (LPARAM)lsr; - for (int i = SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETCOUNT, 0, 0); i--;) { - char *szComboProto = (char*)SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETITEMDATA, i, 0); - if (szComboProto == NULL) continue; - if (!mir_strcmp(szComboProto, ack->szModule)) { - COMBOBOXEXITEM cbei = { 0 }; - cbei.mask = CBEIF_IMAGE; - cbei.iItem = i; - SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CBEM_GETITEM, 0, (LPARAM)&cbei); - lvi.iImage = cbei.iImage; - break; - } - } - - int iItem = ListView_InsertItem(hwndList, &lvi); - SetListItemText(hwndList, iItem, 1, lsr->psr.id.t); - SetListItemText(hwndList, iItem, 2, lsr->psr.nick.t); - SetListItemText(hwndList, iItem, 3, lsr->psr.firstName.t); - SetListItemText(hwndList, iItem, 4, lsr->psr.lastName.t); - SetListItemText(hwndList, iItem, 5, lsr->psr.email.t); - SetStatusBarResultInfo(hwndDlg); - } - } - break; - - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - - case WM_DESTROY: - int len = SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETLBTEXTLEN, SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETCURSEL, 0, 0), 0); - TCHAR *szProto = (TCHAR*)alloca(sizeof(TCHAR)*(len + 1)); - if (szProto != NULL) { - *szProto = '\0'; - SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETLBTEXT, SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_GETCURSEL, 0, 0), (LPARAM)szProto); - db_set_ts(NULL, "FindAdd", "LastSearched", szProto); - } - - SaveColumnSizes(hwndList); - if (dat->hResultHook != NULL) - UnhookEvent(dat->hResultHook); - FreeSearchResults(hwndList); - ImageList_Destroy(dat->himlComboIcons); - mir_free(dat->search); - if (dat->hwndAdvSearch) { - DestroyWindow(dat->hwndAdvSearch); - dat->hwndAdvSearch = NULL; - } - if (dat->hwndTinySearch) { - DestroyWindow(dat->hwndTinySearch); - dat->hwndTinySearch = NULL; - } - mir_free(dat); - Window_FreeIcon_IcoLib(hwndDlg); - Utils_SaveWindowPosition(hwndDlg, NULL, "FindAdd", ""); - break; - } - return FALSE; -} - -static INT_PTR FindAddCommand(WPARAM, LPARAM) -{ - if (IsWindow(hwndFindAdd)) { - ShowWindow(hwndFindAdd, SW_SHOWNORMAL); - SetForegroundWindow(hwndFindAdd); - SetFocus(hwndFindAdd); - } - else { - int netProtoCount = 0; - - // Make sure we have some networks to search on. This is not ideal since - // this check will be repeated every time the dialog is requested, but it - // must be done since this service can be called from other places than the menu. - // One alternative would be to only create the service if we have network - // protocols loaded but that would delay the creation until MODULE_LOADED and - // that is not good either... - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (!Proto_IsAccountEnabled(pa)) - continue; - - int protoCaps = CallProtoServiceInt(NULL, pa->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0); - if (protoCaps & PF1_ANYSEARCH) - netProtoCount++; - } - if (netProtoCount > 0) - hwndFindAdd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_FINDADD), NULL, DlgProcFindAdd); - } - return 0; -} - -int FindAddPreShutdown(WPARAM, LPARAM) -{ - if (IsWindow(hwndFindAdd)) - DestroyWindow(hwndFindAdd); - hwndFindAdd = NULL; - return 0; -} - -int LoadFindAddModule(void) -{ - CreateServiceFunction(MS_FINDADD_FINDADD, FindAddCommand); - HookEvent(ME_SYSTEM_MODULESLOADED, OnSystemModulesLoaded); - HookEvent(ME_PROTO_ACCLISTCHANGED, OnSystemModulesLoaded); - HookEvent(ME_SYSTEM_PRESHUTDOWN, FindAddPreShutdown); - - CLISTMENUITEM mi = { sizeof(mi) }; - mi.position = 500020000; - mi.icolibItem = GetSkinIconHandle(SKINICON_OTHER_FINDUSER); - mi.pszName = LPGEN("&Find/add contacts..."); - mi.pszService = MS_FINDADD_FINDADD; - hMainMenuItem = Menu_AddMainMenuItem(&mi); - return 0; -} - -static int OnSystemModulesLoaded(WPARAM, LPARAM) -{ - int netProtoCount = 0; - - // Make sure we have some networks to search on. - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - int protoCaps = CallProtoServiceInt(NULL, pa->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0); - if (protoCaps & PF1_ANYSEARCH) - netProtoCount++; - } - - Menu_ShowItem(hMainMenuItem, netProtoCount != 0); - return 0; -} diff --git a/src/modules/findadd/findadd.h b/src/modules/findadd/findadd.h deleted file mode 100644 index 4d7ecd27c2..0000000000 --- a/src/modules/findadd/findadd.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 PF1_ANYSEARCH (PF1_BASICSEARCH | PF1_EXTSEARCHUI | PF1_SEARCHBYEMAIL | PF1_SEARCHBYNAME | PF1_EXTSEARCH) - -struct ListSearchResult -{ - const char *szProto; - PROTOSEARCHRESULT psr; -}; - -struct ProtoSearchInfo -{ - const char *szProto; - HANDLE hProcess; -}; - -struct FindAddDlgData -{ - HANDLE hResultHook; - int bSortAscending; - int iLastColumnSortIndex; - HIMAGELIST himlComboIcons; - int showProtoId, showEmail, showName, showAdvanced, showTiny; - int minDlgHeight; - int notSearchedYet; - struct ProtoSearchInfo *search; - int searchCount; - int throbbing; - int pivot; - HWND hwndAdvSearch; - HWND hwndTinySearch; - BOOL bFlexSearchResult; -}; - -int CALLBACK SearchResultsCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); -void FreeSearchResults(HWND hwndResults); -int BeginSearch(HWND hwndDlg, struct FindAddDlgData *dat, const char *szProto, const char *szSearchService, DWORD requiredCapability, void *pvSearchParams); -void SetStatusBarSearchInfo(HWND hwndStatus, struct FindAddDlgData *dat); -void SetStatusBarResultInfo(HWND hwndDlg); -void CreateResultsColumns(HWND hwndResults, struct FindAddDlgData *dat, char *szProto); -void EnableResultButtons(HWND hwndDlg, int enable); -void ShowMoreOptionsMenu(HWND hwndDlg, int x, int y); -void SaveColumnSizes(HWND hwndResults); diff --git a/src/modules/findadd/searchresults.cpp b/src/modules/findadd/searchresults.cpp deleted file mode 100644 index 9b8db18ff0..0000000000 --- a/src/modules/findadd/searchresults.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "findadd.h" - -enum { - COLUMNID_PROTO, - COLUMNID_HANDLE, - COLUMNID_NICK, - COLUMNID_FIRST, - COLUMNID_LAST, - COLUMNID_EMAIL, - NUM_COLUMNID -}; - -void SaveColumnSizes(HWND hwndResults) -{ - int columnOrder[NUM_COLUMNID]; - - struct FindAddDlgData *dat = (struct FindAddDlgData*)GetWindowLongPtr(GetParent(hwndResults), GWLP_USERDATA); - int columnCount = Header_GetItemCount(ListView_GetHeader(hwndResults)); - if (columnCount != NUM_COLUMNID) return; - ListView_GetColumnOrderArray(hwndResults, columnCount, columnOrder); - for (int i = 0; i < NUM_COLUMNID; i++) { - char szSetting[32]; - mir_snprintf(szSetting, "ColOrder%d", i); - db_set_b(NULL, "FindAdd", szSetting, (BYTE)columnOrder[i]); - mir_snprintf(szSetting, "ColWidth%d", i); - db_set_w(NULL, "FindAdd", szSetting, (WORD)ListView_GetColumnWidth(hwndResults, i)); - } - db_set_b(NULL, "FindAdd", "SortColumn", (BYTE)dat->iLastColumnSortIndex); - db_set_b(NULL, "FindAdd", "SortAscending", (BYTE)dat->bSortAscending); -} - -static const TCHAR *szColumnNames[] = { NULL, NULL, _T("Nick"), _T("First Name"), _T("Last Name"), _T("E-mail") }; -static int defaultColumnSizes[] = { 0, 90, 100, 100, 100, 2000 }; -void LoadColumnSizes(HWND hwndResults, const char *szProto) -{ - HDITEM hdi; - int columnOrder[NUM_COLUMNID]; - int columnCount; - char szSetting[32]; - bool colOrdersValid; - - defaultColumnSizes[COLUMNID_PROTO] = GetSystemMetrics(SM_CXSMICON) + 4; - FindAddDlgData *dat = (FindAddDlgData*)GetWindowLongPtr(GetParent(hwndResults), GWLP_USERDATA); - - columnCount = NUM_COLUMNID; - colOrdersValid = true; - for (int i = 0; i < NUM_COLUMNID; i++) { - LVCOLUMN lvc; - if (i < columnCount) { - int bNeedsFree = FALSE; - lvc.mask = LVCF_TEXT | LVCF_WIDTH; - if (szColumnNames[i] != NULL) - lvc.pszText = TranslateTS(szColumnNames[i]); - else if (i == COLUMNID_HANDLE) { - if (szProto) { - bNeedsFree = TRUE; - lvc.pszText = mir_a2t((char*)CallProtoServiceInt(NULL, szProto, PS_GETCAPS, PFLAG_UNIQUEIDTEXT, 0)); - } - else lvc.pszText = _T("ID"); - } - else lvc.mask &= ~LVCF_TEXT; - mir_snprintf(szSetting, "ColWidth%d", i); - lvc.cx = db_get_w(NULL, "FindAdd", szSetting, defaultColumnSizes[i]); - ListView_InsertColumn(hwndResults, i, (LPARAM)&lvc); - - if (bNeedsFree) - mir_free(lvc.pszText); - } - mir_snprintf(szSetting, "ColOrder%d", i); - columnOrder[i] = db_get_b(NULL, "FindAdd", szSetting, -1); - if (columnOrder[i] == -1 || columnOrder[i] >= NUM_COLUMNID) - colOrdersValid = false; - } - - if (colOrdersValid) - ListView_SetColumnOrderArray(hwndResults, columnCount, columnOrder); - - dat->iLastColumnSortIndex = db_get_b(NULL, "FindAdd", "SortColumn", COLUMNID_NICK); - if (dat->iLastColumnSortIndex >= columnCount) dat->iLastColumnSortIndex = COLUMNID_NICK; - dat->bSortAscending = db_get_b(NULL, "FindAdd", "SortAscending", TRUE); - - hdi.mask = HDI_FORMAT; - hdi.fmt = HDF_LEFT | HDF_STRING | (dat->bSortAscending ? HDF_SORTDOWN : HDF_SORTUP); - Header_SetItem(ListView_GetHeader(hwndResults), dat->iLastColumnSortIndex, &hdi); -} - -static LPARAM ListView_GetItemLParam(HWND hwndList, int idx) -{ - LVITEM lv; - lv.iItem = idx; - lv.mask = LVIF_PARAM; - ListView_GetItem(hwndList, &lv); - return lv.lParam; -} - -int CALLBACK SearchResultsCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) -{ - struct FindAddDlgData *dat = (struct FindAddDlgData*)GetWindowLongPtr((HWND)lParamSort, GWLP_USERDATA); - struct ListSearchResult *lsr1, *lsr2; - HWND hList = GetDlgItem((HWND)lParamSort, IDC_RESULTS); - - int sortMultiplier = dat->bSortAscending ? 1 : -1; - int sortCol = dat->iLastColumnSortIndex; - if (!dat->bFlexSearchResult) { - lsr1 = (struct ListSearchResult*)ListView_GetItemLParam(hList, (int)lParam1); - lsr2 = (struct ListSearchResult*)ListView_GetItemLParam(hList, (int)lParam2); - if (lsr1 == NULL || lsr2 == NULL) - return 0; - - switch (sortCol) { - case COLUMNID_PROTO: - return mir_strcmp(lsr1->szProto, lsr2->szProto)*sortMultiplier; - case COLUMNID_HANDLE: - return mir_tstrcmpi(lsr1->psr.id.t, lsr2->psr.id.t)*sortMultiplier; - case COLUMNID_NICK: - return mir_tstrcmpi(lsr1->psr.nick.t, lsr2->psr.nick.t)*sortMultiplier; - case COLUMNID_FIRST: - return mir_tstrcmpi(lsr1->psr.firstName.t, lsr2->psr.firstName.t)*sortMultiplier; - case COLUMNID_LAST: - return mir_tstrcmpi(lsr1->psr.lastName.t, lsr2->psr.lastName.t)*sortMultiplier; - case COLUMNID_EMAIL: - return mir_tstrcmpi(lsr1->psr.email.t, lsr2->psr.email.t)*sortMultiplier; - } - } - else { - TCHAR szText1[100]; - TCHAR szText2[100]; - ListView_GetItemText(hList, (int)lParam1, sortCol, szText1, SIZEOF(szText1)); - ListView_GetItemText(hList, (int)lParam2, sortCol, szText2, SIZEOF(szText2)); - return mir_tstrcmpi(szText1, szText2)*sortMultiplier; - } - return 0; -} - -void FreeSearchResults(HWND hwndResults) -{ - LV_ITEM lvi; - for (lvi.iItem = ListView_GetItemCount(hwndResults) - 1; lvi.iItem >= 0; lvi.iItem--) { - lvi.mask = LVIF_PARAM; - ListView_GetItem(hwndResults, &lvi); - struct ListSearchResult *lsr = (struct ListSearchResult*)lvi.lParam; - if (lsr == NULL) continue; - mir_free(lsr->psr.id.t); - mir_free(lsr->psr.email.t); - mir_free(lsr->psr.nick.t); - mir_free(lsr->psr.firstName.t); - mir_free(lsr->psr.lastName.t); - mir_free(lsr); - } - ListView_DeleteAllItems(hwndResults); - EnableResultButtons(GetParent(hwndResults), 0); -} - -// on its own thread -static void BeginSearchFailed(void * arg) -{ - TCHAR buf[128]; - if (arg != NULL) { - const TCHAR* protoName = (TCHAR*)arg; - mir_sntprintf(buf, - TranslateT("Could not start a search on '%s', there was a problem - is %s connected?"), - protoName, protoName); - mir_free((char*)arg); - } - else mir_tstrncpy(buf, TranslateT("Could not search on any of the protocols, are you online?"), SIZEOF(buf)); - MessageBox(0, buf, TranslateT("Problem with search"), MB_OK | MB_ICONERROR); -} - -int BeginSearch(HWND, struct FindAddDlgData *dat, const char *szProto, const char *szSearchService, DWORD requiredCapability, void *pvSearchParams) -{ - if (szProto == NULL) { - int failures = 0; - dat->searchCount = 0; - dat->search = (struct ProtoSearchInfo*)mir_calloc(sizeof(struct ProtoSearchInfo) * accounts.getCount()); - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (!Proto_IsAccountEnabled(pa)) continue; - DWORD caps = (DWORD)CallProtoServiceInt(NULL, pa->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0); - if (!(caps&requiredCapability)) continue; - dat->search[dat->searchCount].hProcess = (HANDLE)CallProtoServiceInt(NULL, pa->szModuleName, szSearchService, 0, (LPARAM)pvSearchParams); - dat->search[dat->searchCount].szProto = pa->szModuleName; - if (dat->search[dat->searchCount].hProcess == NULL) failures++; - else dat->searchCount++; - } - if (failures) { - //infuriatingly vague error message. fixme. - if (dat->searchCount == 0) { - forkthread(BeginSearchFailed, 0, NULL); - mir_free(dat->search); - dat->search = NULL; - return 1; - } - } - } - else { - dat->search = (struct ProtoSearchInfo*)mir_alloc(sizeof(struct ProtoSearchInfo)); - dat->searchCount = 1; - dat->search[0].hProcess = (HANDLE)CallProtoServiceInt(NULL, szProto, szSearchService, 0, (LPARAM)pvSearchParams); - dat->search[0].szProto = szProto; - if (dat->search[0].hProcess == NULL) { - //infuriatingly vague error message. fixme. - PROTOACCOUNT *pa = Proto_GetAccount(szProto); - forkthread(BeginSearchFailed, 0, mir_tstrdup(pa->tszAccountName)); - mir_free(dat->search); - dat->search = NULL; - dat->searchCount = 0; - return 1; - } - } - return 0; -} - -void SetStatusBarSearchInfo(HWND hwndStatus, struct FindAddDlgData *dat) -{ - CMString str; - - if (dat->searchCount != 0) { - str = TranslateT("Searching"); - for (int i = 0; i < dat->searchCount; i++) { - PROTOACCOUNT *pa = Proto_GetAccount(dat->search[i].szProto); - if (!pa) - continue; - - str.Append(i ? _T(", ") : _T(" ")); - str.Append(pa->tszAccountName); - } - } - else str = TranslateT("Idle"); - - SendMessage(hwndStatus, SB_SETTEXT, 0, (LPARAM)str.c_str()); -} - -struct ProtoResultsSummary { - const char *szProto; - int count; -}; - -void SetStatusBarResultInfo(HWND hwndDlg) -{ - HWND hwndResults = GetDlgItem(hwndDlg, IDC_RESULTS); - CMString str; - - int total = ListView_GetItemCount(hwndResults); - if (total != 0) { - LV_ITEM lvi; - struct ProtoResultsSummary *subtotal = NULL; - int subtotalCount = 0; - for (lvi.iItem = total - 1; lvi.iItem >= 0; lvi.iItem--) { - lvi.mask = LVIF_PARAM; - ListView_GetItem(hwndResults, &lvi); - struct ListSearchResult *lsr = (struct ListSearchResult*)lvi.lParam; - if (lsr == NULL) - continue; - - int i = 0; - while (i < subtotalCount) { - if (subtotal[i].szProto == lsr->szProto) { - subtotal[i].count++; - break; - } - i++; - } - if (i == subtotalCount) { - subtotal = (struct ProtoResultsSummary*)mir_realloc(subtotal, sizeof(struct ProtoResultsSummary)*(subtotalCount + 1)); - subtotal[subtotalCount].szProto = lsr->szProto; - subtotal[subtotalCount++].count = 1; - } - } - if (subtotalCount == 1) { - PROTOACCOUNT *pa = Proto_GetAccount(subtotal[0].szProto); - if (pa == NULL) { - mir_free(subtotal); - return; - } - else if (total == 1) - str.AppendFormat(TranslateT("1 %s user found"), pa->tszAccountName); - else - str.AppendFormat(TranslateT("%d %s users found"), total, pa->tszAccountName); - } - else { - str.AppendFormat(TranslateT("%d users found ("), total); - for (int i = 0; i < subtotalCount; i++) { - PROTOACCOUNT *pa = Proto_GetAccount(subtotal[i].szProto); - if (pa == NULL) - continue; - - if (i) - str.Append(_T(", ")); - - str.AppendFormat(_T("%d %s"), subtotal[i].count, pa->tszAccountName); - } - str.AppendChar(')'); - } - mir_free(subtotal); - } - else str = TranslateT("No users found"); - - SendDlgItemMessage(hwndDlg, IDC_STATUSBAR, SB_SETTEXT, 2, (LPARAM)str.c_str()); -} - -void CreateResultsColumns(HWND hwndResults, struct FindAddDlgData *dat, char *szProto) -{ - SaveColumnSizes(hwndResults); - while (ListView_DeleteColumn(hwndResults, 0)); - ListView_SetImageList(hwndResults, dat->himlComboIcons, LVSIL_SMALL); - LoadColumnSizes(hwndResults, szProto); -} - -void ShowMoreOptionsMenu(HWND hwndDlg, int x, int y) -{ - struct FindAddDlgData *dat = (struct FindAddDlgData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - LVITEM lvi; - if (ListView_GetSelectedCount(GetDlgItem(hwndDlg, IDC_RESULTS)) != 1) return; - lvi.mask = LVIF_PARAM; - lvi.iItem = ListView_GetNextItem(GetDlgItem(hwndDlg, IDC_RESULTS), -1, LVNI_ALL | LVNI_SELECTED); - ListView_GetItem(GetDlgItem(hwndDlg, IDC_RESULTS), &lvi); - struct ListSearchResult *lsr = (struct ListSearchResult*)lvi.lParam; - - HMENU hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXT)); - HMENU hPopupMenu = GetSubMenu(hMenu, 4); - TranslateMenu(hPopupMenu); - int commandId = TrackPopupMenu(hPopupMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, x, y, 0, hwndDlg, NULL); - switch (commandId) { - case IDC_ADD: - { - ADDCONTACTSTRUCT acs = { 0 }; - acs.handleType = HANDLE_SEARCHRESULT; - acs.szProto = lsr->szProto; - acs.psr = &lsr->psr; - CallService(MS_ADDCONTACT_SHOW, (WPARAM)hwndDlg, (LPARAM)&acs); - } - break; - case IDC_DETAILS: - { - MCONTACT hContact = (MCONTACT)CallProtoServiceInt(NULL, lsr->szProto, PS_ADDTOLIST, PALF_TEMPORARY, (LPARAM)&lsr->psr); - CallService(MS_USERINFO_SHOWDIALOG, hContact, 0); - } - break; - case IDC_SENDMESSAGE: - { - MCONTACT hContact = (MCONTACT)CallProtoServiceInt(NULL, lsr->szProto, PS_ADDTOLIST, PALF_TEMPORARY, (LPARAM)&lsr->psr); - CallService(MS_MSG_SENDMESSAGE, hContact, 0); - } - break; - } - DestroyMenu(hPopupMenu); - DestroyMenu(hMenu); -} diff --git a/src/modules/fonts/FontOptions.cpp b/src/modules/fonts/FontOptions.cpp deleted file mode 100644 index a028f0d9cc..0000000000 --- a/src/modules/fonts/FontOptions.cpp +++ /dev/null @@ -1,1390 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "FontService.h" - -// *_w2 is working copy of list -// *_w3 is stores initial configuration - -static int sttCompareFont(const FontInternal* p1, const FontInternal* p2) -{ - int result = mir_tstrcmp(p1->group, p2->group); - if (result != 0) - return result; - - result = p1->order - p2->order; - if (result != 0) - return result; - - return mir_tstrcmp(p1->getName(), p2->getName()); -} - -OBJLIST font_id_list(20, sttCompareFont), font_id_list_w2(20, sttCompareFont), font_id_list_w3(20, sttCompareFont); - -static int sttCompareColour(const ColourInternal* p1, const ColourInternal* p2) -{ - int result = mir_tstrcmp(p1->group, p2->group); - if (result != 0) - return result; - - result = p1->order - p2->order; - if (result != 0) - return result; - - return mir_tstrcmp(p1->getName(), p2->getName()); -} - -OBJLIST colour_id_list(10, sttCompareColour), colour_id_list_w2(10, sttCompareColour), colour_id_list_w3(10, sttCompareColour); - -static int sttCompareEffect(const EffectInternal* p1, const EffectInternal* p2) -{ - int result = mir_tstrcmp(p1->group, p2->group); - if (result != 0) - return result; - - result = p1->order - p2->order; - if (result != 0) - return result; - - return mir_tstrcmp(p1->getName(), p2->getName()); -} - -OBJLIST effect_id_list(10, sttCompareEffect), effect_id_list_w2(10, sttCompareEffect), effect_id_list_w3(10, sttCompareEffect); - -struct DrawTextWithEffectParam -{ - int cbSize; - HDC hdc; // handle to DC - LPCTSTR lpchText; // text to draw - int cchText; // length of text to draw - LPRECT lprc; // rectangle coordinates - UINT dwDTFormat; // formatting options - FONTEFFECT * pEffect; // effect to be drawn on -}; - -#define MS_DRAW_TEXT_WITH_EFFECTA "Modern/SkinEngine/DrawTextWithEffectA" -#define MS_DRAW_TEXT_WITH_EFFECTW "Modern/SkinEngine/DrawTextWithEffectW" - -#define MS_DRAW_TEXT_WITH_EFFECT MS_DRAW_TEXT_WITH_EFFECTW - -// Helper -int __inline DrawTextWithEffect(HDC hdc, LPCTSTR lpchText, int cchText, RECT * lprc, UINT dwDTFormat, FONTEFFECT * pEffect) -{ - DrawTextWithEffectParam params; - static BYTE bIfServiceExists = ServiceExists(MS_DRAW_TEXT_WITH_EFFECT) ? 1 : 0; - - if (pEffect == NULL || pEffect->effectIndex == 0) - return DrawText(hdc, lpchText, cchText, lprc, dwDTFormat); // If no effect specified draw by GDI it just more careful with ClearType - - if (bIfServiceExists == 0) - return DrawText(hdc, lpchText, cchText, lprc, dwDTFormat); - - // else - params.cbSize = sizeof(DrawTextWithEffectParam); - params.hdc = hdc; - params.lpchText = lpchText; - params.cchText = cchText; - params.lprc = lprc; - params.dwDTFormat = dwDTFormat; - params.pEffect = pEffect; - return CallService(MS_DRAW_TEXT_WITH_EFFECT, (WPARAM)¶ms, 0); -} - -#define UM_SETFONTGROUP (WM_USER + 101) -#define TIMER_ID 11015 - -#define FSUI_COLORBOXWIDTH 50 -#define FSUI_COLORBOXLEFT 5 -#define FSUI_FONTFRAMEHORZ 5 -#define FSUI_FONTFRAMEVERT 4 -#define FSUI_FONTLEFT (FSUI_COLORBOXLEFT+FSUI_COLORBOXWIDTH+5) - -void UpdateFontSettings(FontIDW *font_id, FontSettingsT *fontsettings); -void UpdateColourSettings(ColourIDW *colour_id, COLORREF *colour); -void UpdateEffectSettings(EffectIDW *effect_id, FONTEFFECT* effectsettings); - -static void WriteLine(FILE *out, const char pszText[]) -{ - fputs(pszText, out); - fputc('\n', out); -} - -static BOOL ExportSettings(HWND hwndDlg, const TCHAR *filename, OBJLIST& flist, OBJLIST& clist, OBJLIST& elist) -{ - FILE *out = _tfopen(filename, _T("w")); - if (out == NULL) { - MessageBox(hwndDlg, filename, TranslateT("Failed to create file"), MB_ICONWARNING | MB_OK); - return FALSE; - } - - char header[512], buff[1024]; - header[0] = 0; - - fputs("SETTINGS:\n\n", out); - - for (int i = 0; i < flist.getCount(); i++) { - FontInternal& F = flist[i]; - - mir_snprintf(buff, "\n[%s]", F.dbSettingsGroup); - if (mir_strcmp(buff, header) != 0) { - strncpy(header, buff, SIZEOF(header)); - WriteLine(out, buff); - } - - fprintf(out, (F.flags & FIDF_APPENDNAME) ? "%sName=s%S\n" : "%s=s%S\n", F.prefix, F.value.szFace); - - int iFontSize; - if (F.flags & FIDF_SAVEACTUALHEIGHT) { - SIZE size; - LOGFONT lf; - CreateFromFontSettings(&F.value, &lf); - HFONT hFont = CreateFontIndirect(&lf); - - HDC hdc = GetDC(hwndDlg); - HFONT hOldFont = (HFONT)SelectObject(hdc, hFont); - GetTextExtentPoint32(hdc, _T("_W"), 2, &size); - ReleaseDC(hwndDlg, hdc); - SelectObject(hdc, hOldFont); - DeleteObject(hFont); - - iFontSize = size.cy; - } - else if (F.flags & FIDF_SAVEPOINTSIZE) { - HDC hdc = GetDC(hwndDlg); - iFontSize = (BYTE)-MulDiv(F.value.size, 72, GetDeviceCaps(hdc, LOGPIXELSY)); - ReleaseDC(hwndDlg, hdc); - } - else iFontSize = F.value.size; - fprintf(out, "%sSize=b%d\n", F.prefix, iFontSize); - - fprintf(out, "%sSty=b%d\n", F.prefix, F.value.style); - fprintf(out, "%sSet=b%d\n", F.prefix, F.value.charset); - fprintf(out, "%sCol=d%d\n", F.prefix, F.value.colour); - - if (F.flags & FIDF_NOAS) - fprintf(out, "%sAs=w%d\n", F.prefix, 0x00FF); - - fprintf(out, "%sFlags=w%d\n", F.prefix, F.flags); - } - - header[0] = 0; - for (int i = 0; i < clist.getCount(); i++) { - ColourInternal& C = clist[i]; - - mir_snprintf(buff, "\n[%s]", C.dbSettingsGroup); - if (mir_strcmp(buff, header) != 0) { - strncpy_s(header, buff, _TRUNCATE); - WriteLine(out, buff); - } - fprintf(out, "%s=d%d\n", C.setting, (DWORD)C.value); - } - - header[0] = 0; - for (int i = 0; i < elist.getCount(); i++) { - EffectInternal& E = elist[i]; - - mir_snprintf(buff, "\n[%s]", E.dbSettingsGroup); - if (mir_strcmp(buff, header) != 0) { - strncpy_s(header, buff, _TRUNCATE); - WriteLine(out, buff); - } - fprintf(out, "%sEffect=b%d\n", E.setting, E.value.effectIndex); - fprintf(out, "%sEffectCol1=d%d\n", E.setting, E.value.baseColour); - fprintf(out, "%sEffectCol2=d%d\n", E.setting, E.value.secondaryColour); - } - - fclose(out); - return TRUE; -} - -void OptionsChanged() -{ - NotifyEventHooks(hFontReloadEvent, 0, 0); - NotifyEventHooks(hColourReloadEvent, 0, 0); -} - -TOOLINFO ti; -int x, y; - -UINT_PTR CALLBACK CFHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) -{ - if (uiMsg == WM_INITDIALOG) { - CHOOSEFONT* cf = (CHOOSEFONT *)lParam; - if (cf != NULL) { - if (cf->lCustData & FIDF_DISABLESTYLES) { - EnableWindow(GetDlgItem(hdlg, 1137), FALSE); - ShowWindow(GetDlgItem(hdlg, 1137), SW_HIDE); - ShowWindow(GetDlgItem(hdlg, 1095), SW_SHOW); - } - else if (cf->lCustData & FIDF_ALLOWEFFECTS) { - EnableWindow(GetDlgItem(hdlg, 1139), FALSE); - ShowWindow(GetDlgItem(hdlg, 1139), SW_HIDE); - ShowWindow(GetDlgItem(hdlg, 1091), SW_HIDE); - } - } - } - - return 0; -} - -struct FSUIListItemData -{ - int font_id; - int colour_id; - int effect_id; -}; - -static BOOL sttFsuiBindColourIdToFonts(HWND hwndList, const TCHAR *name, const TCHAR *backgroundGroup, const TCHAR *backgroundName, int colourId) -{ - BOOL res = FALSE; - for (int i = SendMessage(hwndList, LB_GETCOUNT, 0, 0); i--;) { - FSUIListItemData *itemData = (FSUIListItemData *)SendMessage(hwndList, LB_GETITEMDATA, i, 0); - if (itemData && itemData->font_id >= 0) { - FontInternal& F = font_id_list_w2[itemData->font_id]; - - if (name && !mir_tstrcmp(F.name, name)) { - itemData->colour_id = colourId; - res = TRUE; - } - - if (backgroundGroup && backgroundName && !mir_tstrcmp(F.backgroundGroup, backgroundGroup) && !mir_tstrcmp(F.backgroundName, backgroundName)) { - itemData->colour_id = colourId; - res = TRUE; - } - } - } - - return res; -} - -static bool sttFsuiBindEffectIdToFonts(HWND hwndList, const TCHAR *name, int effectId) -{ - for (int i = SendMessage(hwndList, LB_GETCOUNT, 0, 0); i--;) { - FSUIListItemData *itemData = (FSUIListItemData *)SendMessage(hwndList, LB_GETITEMDATA, i, 0); - if (itemData && itemData->font_id >= 0) { - FontInternal& F = font_id_list_w2[itemData->font_id]; - - if (name && !mir_tstrcmp(F.name, name)) { - itemData->effect_id = effectId; - return true; - } - } - } - - return false; -} - -static HTREEITEM sttFindNamedTreeItemAt(HWND hwndTree, HTREEITEM hItem, const TCHAR *name) -{ - TVITEM tvi = { 0 }; - TCHAR str[MAX_PATH]; - - if (hItem) - tvi.hItem = TreeView_GetChild(hwndTree, hItem); - else - tvi.hItem = TreeView_GetRoot(hwndTree); - - if (!name) - return tvi.hItem; - - tvi.mask = TVIF_TEXT; - tvi.pszText = str; - tvi.cchTextMax = SIZEOF(str); - - while (tvi.hItem) { - TreeView_GetItem(hwndTree, &tvi); - - if (!mir_tstrcmp(tvi.pszText, name)) - return tvi.hItem; - - tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); - } - return NULL; -} - -static void sttFsuiCreateSettingsTreeNode(HWND hwndTree, const TCHAR *groupName, int hLangpack) -{ - TCHAR itemName[1024]; - TCHAR* sectionName; - int sectionLevel = 0; - - HTREEITEM hSection = NULL; - mir_tstrcpy(itemName, groupName); - sectionName = itemName; - - while (sectionName) { - // allow multi-level tree - TCHAR* pItemName = sectionName; - HTREEITEM hItem; - - // one level deeper - if (sectionName = _tcschr(sectionName, '/')) - *sectionName = 0; - - pItemName = TranslateTH(hLangpack, pItemName); - - hItem = sttFindNamedTreeItemAt(hwndTree, hSection, pItemName); - if (!sectionName || !hItem) { - if (!hItem) { - TVINSERTSTRUCT tvis = { 0 }; - TreeItem *treeItem = (TreeItem *)mir_alloc(sizeof(TreeItem)); - treeItem->groupName = sectionName ? NULL : mir_tstrdup(groupName); - treeItem->paramName = mir_t2a(itemName); - - tvis.hParent = hSection; - tvis.hInsertAfter = TVI_SORT;//TVI_LAST; - tvis.item.mask = TVIF_TEXT | TVIF_PARAM; - tvis.item.pszText = pItemName; - tvis.item.lParam = (LPARAM)treeItem; - - hItem = TreeView_InsertItem(hwndTree, &tvis); - - memset(&tvis.item, 0, sizeof(tvis.item)); - tvis.item.hItem = hItem; - tvis.item.mask = TVIF_HANDLE | TVIF_STATE; - tvis.item.state = tvis.item.stateMask = db_get_b(NULL, "FontServiceUI", treeItem->paramName, TVIS_EXPANDED); - TreeView_SetItem(hwndTree, &tvis.item); - } - } - - if (sectionName) { - *sectionName = '/'; - sectionName++; - } - - sectionLevel++; - - hSection = hItem; - } -} - -static void sttSaveCollapseState(HWND hwndTree) -{ - HTREEITEM hti; - TVITEM tvi; - - hti = TreeView_GetRoot(hwndTree); - while (hti != NULL) { - HTREEITEM ht; - TreeItem *treeItem; - - tvi.mask = TVIF_STATE | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM; - tvi.hItem = hti; - tvi.stateMask = (DWORD)-1; - TreeView_GetItem(hwndTree, &tvi); - - if (tvi.cChildren > 0) { - treeItem = (TreeItem *)tvi.lParam; - if (tvi.state & TVIS_EXPANDED) - db_set_b(NULL, "FontServiceUI", treeItem->paramName, TVIS_EXPANDED); - else - db_set_b(NULL, "FontServiceUI", treeItem->paramName, 0); - } - - ht = TreeView_GetChild(hwndTree, hti); - if (ht == NULL) { - ht = TreeView_GetNextSibling(hwndTree, hti); - while (ht == NULL) { - hti = TreeView_GetParent(hwndTree, hti); - if (hti == NULL) break; - ht = TreeView_GetNextSibling(hwndTree, hti); - } - } - - hti = ht; - } -} - -static void sttFreeListItems(HWND hList) -{ - int count = SendMessage(hList, LB_GETCOUNT, 0, 0); - if (count > 0) { - for (int idx = 0; idx < count; idx++) { - LRESULT res = SendMessage(hList, LB_GETITEMDATA, idx, 0); - FSUIListItemData *itemData = (FSUIListItemData *)res; - if (itemData && res != LB_ERR) - mir_free(itemData); - } - } -} - -static void ShowEffectButton(HWND hwndDlg, BOOL bShow) -{ - ShowWindow(GetDlgItem(hwndDlg, IDC_BKGCOLOUR), bShow ? SW_HIDE : SW_SHOW); - ShowWindow(GetDlgItem(hwndDlg, IDC_BKGCOLOUR_STATIC), bShow ? SW_HIDE : SW_SHOW); - - ShowWindow(GetDlgItem(hwndDlg, IDC_EFFECT), bShow ? SW_SHOW : SW_HIDE); - ShowWindow(GetDlgItem(hwndDlg, IDC_EFFECT_STATIC), bShow ? SW_SHOW : SW_HIDE); -} - -TCHAR* ModernEffectNames[] = { LPGENT(""), LPGENT("Shadow at left"), LPGENT("Shadow at right"), LPGENT("Outline"), LPGENT("Outline smooth"), LPGENT("Smooth bump"), LPGENT("Contour thin"), LPGENT("Contour heavy") }; - -static INT_PTR CALLBACK ChooseEffectDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - static FONTEFFECT * pEffect = NULL; - - switch (uMsg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - pEffect = (FONTEFFECT*)lParam; - { - for (int i = 0; i < SIZEOF(ModernEffectNames); i++) { - int itemid = SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_ADDSTRING, 0, (LPARAM)TranslateTS(ModernEffectNames[i])); - SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_SETITEMDATA, itemid, i); - SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_SETCURSEL, 0, 0); - } - - int cnt = SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_GETCOUNT, 0, 0); - for (int i = 0; i < cnt; i++) { - if (SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_GETITEMDATA, i, 0) == pEffect->effectIndex) { - SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_SETCURSEL, i, 0); - break; - } - } - } - - SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR1, CPM_SETCOLOUR, 0, pEffect->baseColour & 0x00FFFFFF); - SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR2, CPM_SETCOLOUR, 0, pEffect->secondaryColour & 0x00FFFFFF); - - SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR_SPIN1, UDM_SETRANGE, 0, MAKELONG(255, 0)); - SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR_SPIN2, UDM_SETRANGE, 0, MAKELONG(255, 0)); - SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR_SPIN1, UDM_SETPOS, 0, MAKELONG((BYTE)~((BYTE)((pEffect->baseColour & 0xFF000000) >> 24)), 0)); - SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR_SPIN2, UDM_SETPOS, 0, MAKELONG((BYTE)~((BYTE)((pEffect->secondaryColour & 0xFF000000) >> 24)), 0)); - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - { - int i = SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_GETCURSEL, 0, 0); - pEffect->effectIndex = (BYTE)SendDlgItemMessage(hwndDlg, IDC_EFFECT_COMBO, CB_GETITEMDATA, i, 0); - pEffect->baseColour = SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR1, CPM_GETCOLOUR, 0, 0) | ((~(BYTE)SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR_SPIN1, UDM_GETPOS, 0, 0)) << 24); - pEffect->secondaryColour = SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR2, CPM_GETCOLOUR, 0, 0) | ((~(BYTE)SendDlgItemMessage(hwndDlg, IDC_EFFECT_COLOUR_SPIN2, UDM_GETPOS, 0, 0)) << 24); - } - EndDialog(hwndDlg, IDOK); - return TRUE; - - case IDCANCEL: - EndDialog(hwndDlg, IDCANCEL); - return TRUE; - } - break; - case WM_DESTROY: - pEffect = NULL; - return TRUE; - } - return FALSE; -} - -static void sttSaveFontData(HWND hwndDlg, FontInternal &F) -{ - LOGFONT lf; - char str[128]; - - if (F.flags & FIDF_APPENDNAME) - mir_snprintf(str, "%sName", F.prefix); - else - strncpy_s(str, F.prefix, _TRUNCATE); - - if (db_set_ts(NULL, F.dbSettingsGroup, str, F.value.szFace)) { - char buff[1024]; - WideCharToMultiByte(code_page, 0, F.value.szFace, -1, buff, 1024, 0, 0); - db_set_s(NULL, F.dbSettingsGroup, str, buff); - } - - mir_snprintf(str, "%sSize", F.prefix); - if (F.flags & FIDF_SAVEACTUALHEIGHT) { - SIZE size; - CreateFromFontSettings(&F.value, &lf); - HFONT hFont = CreateFontIndirect(&lf); - HDC hdc = GetDC(hwndDlg); - HFONT hOldFont = (HFONT)SelectObject(hdc, hFont); - GetTextExtentPoint32(hdc, _T("_W"), 2, &size); - ReleaseDC(hwndDlg, hdc); - SelectObject(hdc, hOldFont); - DeleteObject(hFont); - - db_set_b(NULL, F.dbSettingsGroup, str, (char)size.cy); - } - else if (F.flags & FIDF_SAVEPOINTSIZE) { - HDC hdc = GetDC(hwndDlg); - db_set_b(NULL, F.dbSettingsGroup, str, (BYTE)-MulDiv(F.value.size, 72, GetDeviceCaps(hdc, LOGPIXELSY))); - ReleaseDC(hwndDlg, hdc); - } - else db_set_b(NULL, F.dbSettingsGroup, str, F.value.size); - - mir_snprintf(str, "%sSty", F.prefix); - db_set_b(NULL, F.dbSettingsGroup, str, F.value.style); - mir_snprintf(str, "%sSet", F.prefix); - db_set_b(NULL, F.dbSettingsGroup, str, F.value.charset); - mir_snprintf(str, "%sCol", F.prefix); - db_set_dw(NULL, F.dbSettingsGroup, str, F.value.colour); - if (F.flags & FIDF_NOAS) { - mir_snprintf(str, "%sAs", F.prefix); - db_set_w(NULL, F.dbSettingsGroup, str, (WORD)0x00FF); - } - mir_snprintf(str, "%sFlags", F.prefix); - db_set_w(NULL, F.dbSettingsGroup, str, (WORD)F.flags); -} - -static INT_PTR CALLBACK DlgProcLogOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int i, selCount; - LOGFONT lf; - - static HBRUSH hBkgColourBrush = 0; - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - font_id_list_w2 = font_id_list; - font_id_list_w3 = font_id_list; - - colour_id_list_w2 = colour_id_list; - colour_id_list_w3 = colour_id_list; - - effect_id_list_w2 = effect_id_list; - effect_id_list_w3 = effect_id_list; - - for (i = 0; i < font_id_list_w2.getCount(); i++) { - FontInternal& F = font_id_list_w2[i]; - // sync settings with database - UpdateFontSettings(&F, &F.value); - sttFsuiCreateSettingsTreeNode(GetDlgItem(hwndDlg, IDC_FONTGROUP), F.group, F.hLangpack); - } - - for (i = 0; i < colour_id_list_w2.getCount(); i++) { - ColourInternal& C = colour_id_list_w2[i]; - - // sync settings with database - UpdateColourSettings(&C, &C.value); - sttFsuiCreateSettingsTreeNode(GetDlgItem(hwndDlg, IDC_FONTGROUP), C.group, C.hLangpack); - } - - for (i = 0; i < effect_id_list_w2.getCount(); i++) { - EffectInternal& E = effect_id_list_w2[i]; - - // sync settings with database - UpdateEffectSettings(&E, &E.value); - sttFsuiCreateSettingsTreeNode(GetDlgItem(hwndDlg, IDC_FONTGROUP), E.group, E.hLangpack); - } - - SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_SETDEFAULTCOLOUR, 0, (LPARAM)GetSysColor(COLOR_WINDOW)); - return TRUE; - - case UM_SETFONTGROUP: - TreeItem *treeItem; - { - TVITEM tvi = { 0 }; - tvi.hItem = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_FONTGROUP)); - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - TreeView_GetItem(GetDlgItem(hwndDlg, IDC_FONTGROUP), &tvi); - treeItem = (TreeItem *)tvi.lParam; - TCHAR *group_buff = treeItem->groupName; - - sttFreeListItems(GetDlgItem(hwndDlg, IDC_FONTLIST)); - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_RESETCONTENT, 0, 0); - - if (group_buff) { - BOOL need_restart = FALSE; - - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, WM_SETREDRAW, FALSE, 0); - - for (int fontId = 0; fontId < font_id_list_w2.getCount(); fontId++) { - FontInternal &F = font_id_list_w2[fontId]; - if (!_tcsncmp(F.group, group_buff, 64)) { - FSUIListItemData *itemData = (FSUIListItemData*)mir_alloc(sizeof(FSUIListItemData)); - itemData->colour_id = -1; - itemData->effect_id = -1; - itemData->font_id = fontId; - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_ADDSTRING, (WPARAM)-1, (LPARAM)itemData); - need_restart |= (F.flags & FIDF_NEEDRESTART); - } - } - - if (hBkgColourBrush) { - DeleteObject(hBkgColourBrush); - hBkgColourBrush = 0; - } - - for (int colourId = 0; colourId < colour_id_list_w2.getCount(); colourId++) { - ColourInternal &C = colour_id_list_w2[colourId]; - if (!_tcsncmp(C.group, group_buff, 64)) { - if (!sttFsuiBindColourIdToFonts(GetDlgItem(hwndDlg, IDC_FONTLIST), C.name, C.group, C.name, colourId)) { - FSUIListItemData *itemData = (FSUIListItemData*)mir_alloc(sizeof(FSUIListItemData)); - itemData->colour_id = colourId; - itemData->font_id = -1; - itemData->effect_id = -1; - - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_ADDSTRING, (WPARAM)-1, (LPARAM)itemData); - } - - if (mir_tstrcmp(C.name, _T("Background")) == 0) - hBkgColourBrush = CreateSolidBrush(C.value); - } - } - - if (!hBkgColourBrush) - hBkgColourBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); - - for (int effectId = 0; effectId < effect_id_list_w2.getCount(); effectId++) { - EffectInternal& E = effect_id_list_w2[effectId]; - if (!_tcsncmp(E.group, group_buff, 64)) { - if (!sttFsuiBindEffectIdToFonts(GetDlgItem(hwndDlg, IDC_FONTLIST), E.name, effectId)) { - FSUIListItemData *itemData = (FSUIListItemData*)mir_alloc(sizeof(FSUIListItemData)); - itemData->effect_id = effectId; - itemData->font_id = -1; - itemData->colour_id = -1; - - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_ADDSTRING, (WPARAM)-1, (LPARAM)itemData); - } - } - } - - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, WM_SETREDRAW, TRUE, 0); - UpdateWindow(GetDlgItem(hwndDlg, IDC_FONTLIST)); - - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_SETSEL, TRUE, 0); - SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_FONTLIST, LBN_SELCHANGE), 0); - } - else { - EnableWindow(GetDlgItem(hwndDlg, IDC_BKGCOLOUR), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_FONTCOLOUR), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_CHOOSEFONT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_RESET), FALSE); - ShowEffectButton(hwndDlg, FALSE); - } - } - return TRUE; - - case WM_MEASUREITEM: - { - MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam; - if ((mis->CtlID != IDC_FONTLIST) || (mis->itemID == -1)) - break; - - FSUIListItemData *itemData = (FSUIListItemData *)mis->itemData; - if (!itemData) - return FALSE; - - HFONT hFont = NULL, hoFont = NULL; - BOOL bIsFont = FALSE; - TCHAR *itemName = NULL; - if (itemData->font_id >= 0) { - int iItem = itemData->font_id; - bIsFont = TRUE; - CreateFromFontSettings(&font_id_list_w2[iItem].value, &lf); - hFont = CreateFontIndirect(&lf); - itemName = font_id_list_w2[iItem].getName(); - } - - if (itemData->colour_id >= 0) { - int iItem = itemData->colour_id; - if (!itemName) - itemName = colour_id_list_w2[iItem].getName(); - } - - HDC hdc = GetDC(GetDlgItem(hwndDlg, mis->CtlID)); - if (hFont) - hoFont = (HFONT)SelectObject(hdc, hFont); - else - hoFont = (HFONT)SelectObject(hdc, (HFONT)SendDlgItemMessage(hwndDlg, mis->CtlID, WM_GETFONT, 0, 0)); - - SIZE fontSize; - GetTextExtentPoint32(hdc, itemName, (int)mir_tstrlen(itemName), &fontSize); - if (hoFont) SelectObject(hdc, hoFont); - if (hFont) DeleteObject(hFont); - ReleaseDC(GetDlgItem(hwndDlg, mis->CtlID), hdc); - mis->itemWidth = fontSize.cx + 2 * FSUI_FONTFRAMEHORZ + 4; - mis->itemHeight = fontSize.cy + 2 * FSUI_FONTFRAMEVERT + 4; - } - return TRUE; - - case WM_DRAWITEM: - FONTEFFECT Effect; - { - DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam; - HFONT hFont = NULL, hoFont = NULL; - COLORREF clBack = (COLORREF)-1; - COLORREF clText = GetSysColor(COLOR_WINDOWTEXT); - BOOL bIsFont = FALSE; - TCHAR *itemName = NULL; - - FSUIListItemData *itemData = (FSUIListItemData *)dis->itemData; - FONTEFFECT * pEffect = NULL; - - if (dis->CtlID != IDC_FONTLIST) - break; - - if (!itemData) return FALSE; - - if (itemData->font_id >= 0) { - int iItem = itemData->font_id; - bIsFont = TRUE; - CreateFromFontSettings(&font_id_list_w2[iItem].value, &lf); - hFont = CreateFontIndirect(&lf); - itemName = font_id_list_w2[iItem].getName(); - clText = font_id_list_w2[iItem].value.colour; - } - - if (itemData->colour_id >= 0) { - int iItem = itemData->colour_id; - if (bIsFont) - clBack = colour_id_list_w2[iItem].value; - else { - clText = colour_id_list_w2[iItem].value; - itemName = colour_id_list_w2[iItem].getName(); - } - } - - if (itemData->effect_id >= 0) { - int iItem = itemData->effect_id; - - Effect.effectIndex = effect_id_list_w2[iItem].value.effectIndex; - Effect.baseColour = effect_id_list_w2[iItem].value.baseColour; - Effect.secondaryColour = effect_id_list_w2[iItem].value.secondaryColour; - pEffect = &Effect; - - if (!bIsFont) - itemName = effect_id_list_w2[iItem].getName(); - } - - if (hFont) - hoFont = (HFONT)SelectObject(dis->hDC, hFont); - else - hoFont = (HFONT)SelectObject(dis->hDC, (HFONT)SendDlgItemMessage(hwndDlg, dis->CtlID, WM_GETFONT, 0, 0)); - - SetBkMode(dis->hDC, TRANSPARENT); - - if (dis->itemState & ODS_SELECTED) { - SetTextColor(dis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); - FillRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_HIGHLIGHT)); - } - else { - SetTextColor(dis->hDC, bIsFont ? clText : GetSysColor(COLOR_WINDOWTEXT)); - if (bIsFont && (clBack != (COLORREF)-1)) { - HBRUSH hbrTmp = CreateSolidBrush(clBack); - FillRect(dis->hDC, &dis->rcItem, hbrTmp); - DeleteObject(hbrTmp); - } - else FillRect(dis->hDC, &dis->rcItem, bIsFont ? hBkgColourBrush : GetSysColorBrush(COLOR_WINDOW)); - } - - if (bIsFont) { - HBRUSH hbrBack; - RECT rc; - - if (clBack != (COLORREF)-1) - hbrBack = CreateSolidBrush(clBack); - else { - LOGBRUSH lb; - GetObject(hBkgColourBrush, sizeof(lf), &lb); - hbrBack = CreateBrushIndirect(&lb); - } - - SetRect(&rc, - dis->rcItem.left + FSUI_COLORBOXLEFT, - dis->rcItem.top + FSUI_FONTFRAMEVERT, - dis->rcItem.left + FSUI_COLORBOXLEFT + FSUI_COLORBOXWIDTH, - dis->rcItem.bottom - FSUI_FONTFRAMEVERT); - - FillRect(dis->hDC, &rc, hbrBack); - DeleteObject(hbrBack); - - FrameRect(dis->hDC, &rc, GetSysColorBrush(COLOR_HIGHLIGHT)); - rc.left += 1; - rc.top += 1; - rc.right -= 1; - rc.bottom -= 1; - FrameRect(dis->hDC, &rc, GetSysColorBrush(COLOR_HIGHLIGHTTEXT)); - - SetTextColor(dis->hDC, clText); - - DrawTextWithEffect(dis->hDC, _T("abc"), 3, &rc, DT_CENTER | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS, pEffect); - - if (dis->itemState & ODS_SELECTED) { - SetTextColor(dis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); - pEffect = NULL; // Do not draw effect on selected item name text - } - rc = dis->rcItem; - rc.left += FSUI_FONTLEFT; - DrawTextWithEffect(dis->hDC, itemName, (int)mir_tstrlen(itemName), &rc, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS, pEffect); - } - else { - RECT rc; - HBRUSH hbrTmp; - SetRect(&rc, - dis->rcItem.left + FSUI_COLORBOXLEFT, - dis->rcItem.top + FSUI_FONTFRAMEVERT, - dis->rcItem.left + FSUI_COLORBOXLEFT + FSUI_COLORBOXWIDTH, - dis->rcItem.bottom - FSUI_FONTFRAMEVERT); - - hbrTmp = CreateSolidBrush(clText); - FillRect(dis->hDC, &rc, hbrTmp); - DeleteObject(hbrTmp); - - FrameRect(dis->hDC, &rc, GetSysColorBrush(COLOR_HIGHLIGHT)); - rc.left += 1; - rc.top += 1; - rc.right -= 1; - rc.bottom -= 1; - FrameRect(dis->hDC, &rc, GetSysColorBrush(COLOR_HIGHLIGHTTEXT)); - - rc = dis->rcItem; - rc.left += FSUI_FONTLEFT; - - DrawTextWithEffect(dis->hDC, itemName, (int)mir_tstrlen(itemName), &rc, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS, pEffect); - } - if (hoFont) SelectObject(dis->hDC, hoFont); - if (hFont) DeleteObject(hFont); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_FONTLIST: - if (HIWORD(wParam) == LBN_SELCHANGE) { - char bEnableFont = 1; - char bEnableClText = 1; - char bEnableClBack = 1; - char bEnableEffect = 1; - char bEnableReset = 1; - - COLORREF clBack = 0xffffffff; - COLORREF clText = 0xffffffff; - - if (selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0)) { - int *selItems = (int *)mir_alloc(font_id_list_w2.getCount() * sizeof(int)); - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, (WPARAM)selCount, (LPARAM)selItems); - for (i = 0; i < selCount; i++) { - FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0); - if (IsBadReadPtr(itemData, sizeof(FSUIListItemData))) continue; // prevent possible problems with corrupted itemData - - if (bEnableClBack && (itemData->colour_id < 0)) - bEnableClBack = 0; - if (bEnableEffect && (itemData->effect_id < 0)) - bEnableEffect = 0; - if (bEnableFont && (itemData->font_id < 0)) - bEnableFont = 0; - if (!bEnableFont || bEnableClText && (itemData->font_id < 0)) - bEnableClText = 0; - if (bEnableReset && (itemData->font_id >= 0) && !(font_id_list_w2[itemData->font_id].flags&FIDF_DEFAULTVALID)) - bEnableReset = 0; - - if (bEnableClBack && (itemData->colour_id >= 0) && (clBack == 0xffffffff)) - clBack = colour_id_list_w2[itemData->colour_id].value; - if (bEnableClText && (itemData->font_id >= 0) && (clText == 0xffffffff)) - clText = font_id_list_w2[itemData->font_id].value.colour; - } - mir_free(selItems); - } - else bEnableFont = bEnableClText = bEnableClBack = bEnableReset = bEnableEffect = 0; - - EnableWindow(GetDlgItem(hwndDlg, IDC_BKGCOLOUR), bEnableClBack); - ShowEffectButton(hwndDlg, bEnableEffect && !bEnableClBack); - - EnableWindow(GetDlgItem(hwndDlg, IDC_FONTCOLOUR), bEnableClText); - EnableWindow(GetDlgItem(hwndDlg, IDC_CHOOSEFONT), bEnableFont); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_RESET), bEnableReset); - - if (bEnableClBack) SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_SETCOLOUR, 0, clBack); - if (bEnableClText) SendDlgItemMessage(hwndDlg, IDC_FONTCOLOUR, CPM_SETCOLOUR, 0, clText); - - return TRUE; - } - - if (HIWORD(wParam) != LBN_DBLCLK) - return TRUE; - - //fall through - - case IDC_CHOOSEFONT: - if (selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0)) { - int *selItems = (int *)mir_alloc(selCount * sizeof(int)); - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, (WPARAM)selCount, (LPARAM)selItems); - - FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[0], 0); - if (itemData->font_id < 0) { - mir_free(selItems); - if (itemData->colour_id >= 0) - SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, WM_LBUTTONUP, 0, 0); - return TRUE; - } - - FontInternal& F = font_id_list_w2[itemData->font_id]; - CreateFromFontSettings(&F.value, &lf); - - CHOOSEFONT cf = { 0 }; - cf.lStructSize = sizeof(cf); - cf.hwndOwner = hwndDlg; - cf.lpLogFont = &lf; - cf.lCustData = F.flags; - cf.Flags = CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_ENABLEHOOK; - cf.lpfnHook = CFHookProc; - - if (F.flags & FIDF_ALLOWEFFECTS) // enable effects section - cf.Flags |= CF_EFFECTS; - else if (F.flags & FIDF_DISABLESTYLES) { // mutually exclusive with FIDF_ALLOWEFFECTS - cf.Flags |= CF_TTONLY | CF_NOOEMFONTS; - lf.lfWeight = FW_NORMAL; - lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = FALSE; - } - - if (ChooseFont(&cf)) { - for (i = 0; i < selCount; i++) { - FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0); - if (itemData->font_id < 0) - continue; - - FontInternal& F1 = font_id_list_w2[itemData->font_id]; - F1.value.size = (char)lf.lfHeight; - F1.value.style = (lf.lfWeight >= FW_BOLD ? DBFONTF_BOLD : 0) | (lf.lfItalic ? DBFONTF_ITALIC : 0) | (lf.lfUnderline ? DBFONTF_UNDERLINE : 0) | (lf.lfStrikeOut ? DBFONTF_STRIKEOUT : 0); - F1.value.charset = lf.lfCharSet; - _tcsncpy_s(F1.value.szFace, lf.lfFaceName, _TRUNCATE); - - MEASUREITEMSTRUCT mis = { 0 }; - mis.CtlID = IDC_FONTLIST; - mis.itemID = selItems[i]; - mis.itemData = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0); - SendMessage(hwndDlg, WM_MEASUREITEM, 0, (LPARAM)& mis); - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_SETITEMHEIGHT, selItems[i], mis.itemHeight); - } - InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), TRUE); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - - mir_free(selItems); - } - return TRUE; - - case IDC_EFFECT: - if (selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0)) { - int *selItems = (int *)mir_alloc(selCount * sizeof(int)); - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, (WPARAM)selCount, (LPARAM)selItems); - FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[0], 0); - EffectInternal& E = effect_id_list_w2[itemData->effect_id]; - - FONTEFFECT es = E.value; - if (IDOK == DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CHOOSE_FONT_EFFECT), hwndDlg, ChooseEffectDlgProc, (LPARAM)&es)) { - for (int i = 0; i < selCount; i++) { - FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0); - if (itemData->effect_id < 0) - continue; - - EffectInternal& E1 = effect_id_list_w2[itemData->effect_id]; - E1.value = es; - } - InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), TRUE); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - - mir_free(selItems); - } - return TRUE; - - case IDC_FONTCOLOUR: - if (selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0)) { - int *selItems = (int *)mir_alloc(selCount * sizeof(int)); - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, (WPARAM)selCount, (LPARAM)selItems); - for (int i = 0; i < selCount; i++) { - FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0); - if (itemData->font_id < 0) continue; - font_id_list_w2[itemData->font_id].value.colour = SendDlgItemMessage(hwndDlg, IDC_FONTCOLOUR, CPM_GETCOLOUR, 0, 0); - } - mir_free(selItems); - InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), TRUE); - } - break; - - case IDC_BKGCOLOUR: - if (selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0)) { - int *selItems = (int *)mir_alloc(selCount * sizeof(int)); - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, (WPARAM)selCount, (LPARAM)selItems); - for (i = 0; i < selCount; i++) { - FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0); - if (itemData->colour_id < 0) continue; - colour_id_list_w2[itemData->colour_id].value = SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_GETCOLOUR, 0, 0); - - if (mir_tstrcmp(colour_id_list_w2[itemData->colour_id].name, _T("Background")) == 0) { - if (hBkgColourBrush) DeleteObject(hBkgColourBrush); - hBkgColourBrush = CreateSolidBrush(colour_id_list_w2[itemData->colour_id].value); - } - } - mir_free(selItems); - InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), TRUE); - } - break; - - case IDC_BTN_RESET: - if (font_id_list_w2.getCount() && (selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0))) { - int *selItems = (int *)mir_alloc(font_id_list_w2.getCount() * sizeof(int)); - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, (WPARAM)selCount, (LPARAM)selItems); - for (i = 0; i < selCount; i++) { - FSUIListItemData *itemData = (FSUIListItemData *)SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0); - if (IsBadReadPtr(itemData, sizeof(FSUIListItemData))) continue; // prevent possible problems with corrupted itemData - - if ((itemData->font_id >= 0) && (font_id_list_w2[itemData->font_id].flags & FIDF_DEFAULTVALID)) { - font_id_list_w2[itemData->font_id].value = font_id_list_w2[itemData->font_id].deffontsettings; - - MEASUREITEMSTRUCT mis = { 0 }; - mis.CtlID = IDC_FONTLIST; - mis.itemID = selItems[i]; - mis.itemData = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[i], 0); - SendMessage(hwndDlg, WM_MEASUREITEM, 0, (LPARAM)& mis); - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_SETITEMHEIGHT, selItems[i], mis.itemHeight); - } - - if (itemData->colour_id >= 0) - colour_id_list_w2[itemData->colour_id].value = colour_id_list_w2[itemData->colour_id].defcolour; - - if (itemData->effect_id >= 0) - effect_id_list_w2[itemData->effect_id].value = effect_id_list_w2[itemData->effect_id].defeffect; - - } - mir_free(selItems); - InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, TRUE); - SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_FONTLIST, LBN_SELCHANGE), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), TRUE); - } - break; - - case IDC_BTN_EXPORT: - { - TCHAR fname_buff[MAX_PATH], filter[MAX_PATH]; - mir_sntprintf(filter, SIZEOF(filter), _T("%s (*.ini)%c*.ini%c%s (*.txt)%c*.TXT%c%s (*.*)%c*.*%c"), TranslateT("Configuration files"), 0, 0, TranslateT("Text files"), 0, 0, TranslateT("All files"), 0, 0); - - OPENFILENAME ofn = { 0 }; - ofn.lStructSize = sizeof(ofn); - ofn.lpstrFile = fname_buff; - ofn.lpstrFile[0] = '\0'; - ofn.nMaxFile = MAX_PATH; - ofn.hwndOwner = hwndDlg; - ofn.Flags = OFN_NOREADONLYRETURN | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT; - ofn.lpstrFilter = filter; - ofn.nFilterIndex = 1; - - ofn.lpstrDefExt = _T("ini"); - - if (GetSaveFileName(&ofn) == TRUE) - if (!ExportSettings(hwndDlg, ofn.lpstrFile, font_id_list, colour_id_list, effect_id_list)) - MessageBox(hwndDlg, TranslateT("Error writing file"), TranslateT("Error"), MB_ICONWARNING | MB_OK); - } - return TRUE; - - case IDC_BTN_UNDO: - font_id_list_w2 = font_id_list_w3; - colour_id_list_w2 = colour_id_list_w3; - effect_id_list_w2 = effect_id_list_w3; - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), FALSE); - - SendMessage(hwndDlg, UM_SETFONTGROUP, 0, 0); - break; - } - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->idFrom == 0 && ((LPNMHDR)lParam)->code == PSN_APPLY) { - char str[32]; - - font_id_list_w3 = font_id_list; - colour_id_list_w3 = colour_id_list; - effect_id_list_w3 = effect_id_list; - - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UNDO), TRUE); - - font_id_list = font_id_list_w2; - colour_id_list = colour_id_list_w2; - effect_id_list = effect_id_list_w2; - - for (i = 0; i < font_id_list_w2.getCount(); i++) { - FontInternal& F = font_id_list_w2[i]; - sttSaveFontData(hwndDlg, F); - } - - for (i = 0; i < colour_id_list_w2.getCount(); i++) { - ColourInternal& C = colour_id_list_w2[i]; - - strncpy_s(str, C.setting, _TRUNCATE); - db_set_dw(NULL, C.dbSettingsGroup, str, C.value); - } - - for (i = 0; i < effect_id_list_w2.getCount(); i++) { - EffectInternal& E = effect_id_list_w2[i]; - - mir_snprintf(str, "%sEffect", E.setting); - db_set_b(NULL, E.dbSettingsGroup, str, E.value.effectIndex); - - mir_snprintf(str, "%sEffectCol1", E.setting); - db_set_dw(NULL, E.dbSettingsGroup, str, E.value.baseColour); - - mir_snprintf(str, "%sEffectCol2", E.setting); - db_set_dw(NULL, E.dbSettingsGroup, str, E.value.secondaryColour); - } - - OptionsChanged(); - return TRUE; - } - - if (((LPNMHDR)lParam)->idFrom == IDC_FONTGROUP) { - switch (((NMHDR*)lParam)->code) { - case TVN_SELCHANGED: - SendMessage(hwndDlg, UM_SETFONTGROUP, 0, 0); - break; - - case TVN_DELETEITEM: - TreeItem *treeItem = (TreeItem *)(((LPNMTREEVIEW)lParam)->itemOld.lParam); - if (treeItem) { - mir_free(treeItem->groupName); - mir_free(treeItem->paramName); - mir_free(treeItem); - } - break; - } - } - break; - - case WM_DESTROY: - KillTimer(hwndDlg, TIMER_ID); - sttSaveCollapseState(GetDlgItem(hwndDlg, IDC_FONTGROUP)); - DeleteObject(hBkgColourBrush); - font_id_list_w2.destroy(); - font_id_list_w3.destroy(); - colour_id_list_w2.destroy(); - colour_id_list_w3.destroy(); - effect_id_list_w2.destroy(); - effect_id_list_w3.destroy(); - sttFreeListItems(GetDlgItem(hwndDlg, IDC_FONTLIST)); - break; - } - return FALSE; -} - -int OptInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.position = -790000000; - odp.hInstance = hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_FONTS); - odp.pszTitle = LPGEN("Fonts and colors"); - odp.pszGroup = LPGEN("Customize"); - odp.flags = ODPF_BOLDGROUPS; - odp.pfnDlgProc = DlgProcLogOptions; - Options_AddPage(wParam, &odp); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static FontInternal* sttFindFont(OBJLIST &fonts, char *module, char *prefix) -{ - for (int i = 0; i < fonts.getCount(); i++) { - FontInternal& F = fonts[i]; - if (!mir_strcmp(F.dbSettingsGroup, module) && !mir_strcmp(F.prefix, prefix)) - return &F; - } - - return 0; -} - -static FontInternal fntHeader, fntGeneral, fntSmall; - -static INT_PTR CALLBACK DlgProcModernOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int i; - LOGFONT lf; - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - fntHeader = *sttFindFont(font_id_list, "Fonts", "Header"); - UpdateFontSettings(&fntHeader, &fntHeader.value); - fntGeneral = *sttFindFont(font_id_list, "Fonts", "Generic"); - UpdateFontSettings(&fntGeneral, &fntGeneral.value); - fntSmall = *sttFindFont(font_id_list, "Fonts", "Small"); - UpdateFontSettings(&fntSmall, &fntSmall.value); - return TRUE; - - case WM_DRAWITEM: - { - FontInternal *pf = 0; - DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam; - switch (dis->CtlID) { - case IDC_PREVIEWHEADER: - pf = &fntHeader; - break; - case IDC_PREVIEWGENERAL: - pf = &fntGeneral; - break; - case IDC_PREVIEWSMALL: - pf = &fntSmall; - break; - } - - if (!pf) - break; - - HFONT hFont = NULL, hoFont = NULL; - COLORREF clText = GetSysColor(COLOR_WINDOWTEXT); - CreateFromFontSettings(&pf->value, &lf); - hFont = CreateFontIndirect(&lf); - hoFont = (HFONT)SelectObject(dis->hDC, hFont); - SetBkMode(dis->hDC, TRANSPARENT); - SetTextColor(dis->hDC, GetSysColor(COLOR_BTNTEXT)); - FillRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_BTNFACE)); - DrawText(dis->hDC, TranslateT("Sample text"), -1, &dis->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS | DT_CENTER); - if (hoFont) - SelectObject(dis->hDC, hoFont); - return TRUE; - } - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_CHOOSEFONTHEADER: - case IDC_CHOOSEFONTGENERAL: - case IDC_CHOOSEFONTSMALL: - { - FontInternal *pf = NULL; - switch (LOWORD(wParam)) { - case IDC_CHOOSEFONTHEADER: - pf = &fntHeader; - break; - case IDC_CHOOSEFONTGENERAL: - pf = &fntGeneral; - break; - case IDC_CHOOSEFONTSMALL: - pf = &fntSmall; - break; - }; - - CreateFromFontSettings(&pf->value, &lf); - - CHOOSEFONT cf = { 0 }; - cf.lStructSize = sizeof(cf); - cf.hwndOwner = hwndDlg; - cf.lpLogFont = &lf; - cf.lCustData = pf->flags; - cf.Flags = CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS; - if (pf->flags & FIDF_ALLOWEFFECTS) { - cf.Flags |= CF_EFFECTS | CF_ENABLEHOOK; - cf.lpfnHook = CFHookProc; - } - - if (ChooseFont(&cf)) { - pf->value.size = (char)lf.lfHeight; - pf->value.style = (lf.lfWeight >= FW_BOLD ? DBFONTF_BOLD : 0) | (lf.lfItalic ? DBFONTF_ITALIC : 0) | (lf.lfUnderline ? DBFONTF_UNDERLINE : 0) | (lf.lfStrikeOut ? DBFONTF_STRIKEOUT : 0); - pf->value.charset = lf.lfCharSet; - _tcsncpy_s(pf->value.szFace, lf.lfFaceName, _TRUNCATE); - - InvalidateRect(GetDlgItem(hwndDlg, IDC_PREVIEWHEADER), NULL, TRUE); - InvalidateRect(GetDlgItem(hwndDlg, IDC_PREVIEWGENERAL), NULL, TRUE); - InvalidateRect(GetDlgItem(hwndDlg, IDC_PREVIEWSMALL), NULL, TRUE); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - return TRUE; - } - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->idFrom == 0 && ((LPNMHDR)lParam)->code == PSN_APPLY) { - for (i = 0; i < font_id_list.getCount(); i++) { - FontInternal &F = font_id_list[i]; - if (F.deffontsettings.charset == SYMBOL_CHARSET) - continue; - - COLORREF cl = F.value.colour; - if (F.isHeader()) - F.value = fntHeader.value; - else if ((F.flags & FIDF_CLASSMASK) == FIDF_CLASSSMALL) - F.value = fntSmall.value; - else - F.value = fntGeneral.value; - - F.value.colour = cl; - sttSaveFontData(hwndDlg, F); - } - - OptionsChanged(); - } - break; - } - return FALSE; -} - -INT_PTR CALLBACK AccMgrDlgProc(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgPluginOpt(HWND, UINT, WPARAM, LPARAM); - -int FontsModernOptInit(WPARAM wParam, LPARAM lParam) -{ - static int iBoldControls[] = - { - IDC_TXT_TITLE1, IDC_TXT_TITLE2, IDC_TXT_TITLE3, - MODERNOPT_CTRL_LAST - }; - - MODERNOPTOBJECT obj = {0}; - obj.cbSize = sizeof(obj); - obj.dwFlags = MODEROPT_FLG_TCHAR|MODEROPT_FLG_NORESIZE; - obj.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); - obj.hInstance = hInst; - obj.iSection = MODERNOPT_PAGE_SKINS; - obj.iType = MODERNOPT_TYPE_SUBSECTIONPAGE; - obj.iBoldControls = iBoldControls; - obj.lptzSubsection = LPGENT("Fonts"); - obj.lpzClassicGroup = "Customize"; - obj.lpzClassicPage = "Fonts"; - obj.lpzHelpUrl = "http://wiki.miranda-ng.org/"; - - obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_FONTS); - obj.pfnDlgProc = DlgProcModernOptions; - CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); - - obj.iSection = MODERNOPT_PAGE_ACCOUNTS; - obj.iType = MODERNOPT_TYPE_SECTIONPAGE; - obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_ACCOUNTS); - obj.pfnDlgProc = AccMgrDlgProc; - obj.lpzClassicGroup = NULL; - obj.lpzClassicPage = "Network"; - obj.lpzHelpUrl = "http://wiki.miranda-ng.org/"; - CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); - - obj.iSection = MODERNOPT_PAGE_MODULES; - obj.iType = MODERNOPT_TYPE_SECTIONPAGE; - obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_MODULES); - obj.pfnDlgProc = DlgPluginOpt; - obj.iBoldControls = iBoldControls; - obj.lpzClassicGroup = NULL; - obj.lpzClassicPage = NULL; - obj.lpzHelpUrl = "http://wiki.miranda-ng.org/"; - CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); - return 0; -} diff --git a/src/modules/fonts/FontService.cpp b/src/modules/fonts/FontService.cpp deleted file mode 100644 index 166110f2a8..0000000000 --- a/src/modules/fonts/FontService.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "FontService.h" - -int code_page = CP_ACP; -HANDLE hFontReloadEvent, hColourReloadEvent; - -int OptInit(WPARAM, LPARAM); -int FontsModernOptInit(WPARAM wParam, LPARAM lParam); - -INT_PTR RegisterFont(WPARAM wParam, LPARAM lParam); -INT_PTR RegisterFontW(WPARAM wParam, LPARAM lParam); - -INT_PTR GetFont(WPARAM wParam, LPARAM lParam); -INT_PTR GetFontW(WPARAM wParam, LPARAM lParam); - -INT_PTR RegisterColour(WPARAM wParam, LPARAM lParam); -INT_PTR RegisterColourW(WPARAM wParam, LPARAM lParam); - -INT_PTR GetColour(WPARAM wParam, LPARAM lParam); -INT_PTR GetColourW(WPARAM wParam, LPARAM lParam); - -INT_PTR RegisterEffect(WPARAM wParam, LPARAM lParam); -INT_PTR RegisterEffectW(WPARAM wParam, LPARAM lParam); - -INT_PTR GetEffect(WPARAM wParam, LPARAM lParam); -INT_PTR GetEffectW(WPARAM wParam, LPARAM lParam); - -static int OnModulesLoaded(WPARAM, LPARAM) -{ - HookEvent(ME_OPT_INITIALISE, OptInit); - HookEvent(ME_MODERNOPT_INITIALIZE, FontsModernOptInit); - return 0; -} - -static int OnPreShutdown(WPARAM, LPARAM) -{ - DestroyHookableEvent(hFontReloadEvent); - DestroyHookableEvent(hColourReloadEvent); - - font_id_list.destroy(); - colour_id_list.destroy(); - return 0; -} - -int LoadFontserviceModule(void) -{ - code_page = Langpack_GetDefaultCodePage(); - - CreateServiceFunction("Font/Register", RegisterFont); - CreateServiceFunction("Font/RegisterW", RegisterFontW); - CreateServiceFunction(MS_FONT_GET, GetFont); - CreateServiceFunction(MS_FONT_GETW, GetFontW); - - CreateServiceFunction("Colour/Register", RegisterColour); - CreateServiceFunction("Colour/RegisterW", RegisterColourW); - CreateServiceFunction(MS_COLOUR_GET, GetColour); - CreateServiceFunction(MS_COLOUR_GETW, GetColourW); - - CreateServiceFunction("Effect/Register", RegisterEffect); - CreateServiceFunction("Effect/RegisterW", RegisterEffectW); - CreateServiceFunction(MS_EFFECT_GET, GetEffect); - CreateServiceFunction(MS_EFFECT_GETW, GetEffectW); - - hFontReloadEvent = CreateHookableEvent(ME_FONT_RELOAD); - hColourReloadEvent = CreateHookableEvent(ME_COLOUR_RELOAD); - - // create generic fonts - FontIDT fontid = { sizeof(fontid) }; - strncpy(fontid.dbSettingsGroup, "Fonts", sizeof(fontid.dbSettingsGroup)); - _tcsncpy_s(fontid.group, LPGENT("General"), _TRUNCATE); - - _tcsncpy_s(fontid.name, LPGENT("Headers"), _TRUNCATE); - fontid.flags = FIDF_APPENDNAME | FIDF_NOAS | FIDF_SAVEPOINTSIZE | FIDF_ALLOWEFFECTS | FIDF_CLASSHEADER; - strncpy(fontid.prefix, "Header", SIZEOF(fontid.prefix)); - FontRegisterT(&fontid); - - _tcsncpy_s(fontid.name, LPGENT("Generic text"), _TRUNCATE); - fontid.flags = FIDF_APPENDNAME | FIDF_NOAS | FIDF_SAVEPOINTSIZE | FIDF_ALLOWEFFECTS | FIDF_CLASSGENERAL; - strncpy(fontid.prefix, "Generic", SIZEOF(fontid.prefix)); - FontRegisterT(&fontid); - - _tcsncpy_s(fontid.name, LPGENT("Small text"), _TRUNCATE); - fontid.flags = FIDF_APPENDNAME | FIDF_NOAS | FIDF_SAVEPOINTSIZE | FIDF_ALLOWEFFECTS | FIDF_CLASSSMALL; - strncpy(fontid.prefix, "Small", SIZEOF(fontid.prefix)); - FontRegisterT(&fontid); - - // do last for silly dyna plugin - HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); - HookEvent(ME_SYSTEM_PRESHUTDOWN, OnPreShutdown); - return 0; -} diff --git a/src/modules/fonts/FontService.h b/src/modules/fonts/FontService.h deleted file mode 100644 index 970fd25090..0000000000 --- a/src/modules/fonts/FontService.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "m_fontservice.h" - -// a font identifier structure - used for registering a font, and getting one out again - -struct FontInternal : public FontIDT -{ - FontSettingsT value; - int hLangpack; - - __inline TCHAR* getName() const { return TranslateTH(hLangpack, name); } - - __inline bool isHeader() const - { - if ((flags & FIDF_CLASSMASK) == FIDF_CLASSHEADER) - return true; - - if ((flags & FIDF_CLASSMASK) == 0) - if (_tcsstr(name, _T("Incoming nick")) || _tcsstr(name, _T("Outgoing nick")) || _tcsstr(name, _T("Incoming timestamp")) || _tcsstr(name, _T("Outgoing timestamp"))) - return true; - return false; - } -}; - -struct ColourInternal : public ColourIDT -{ - __inline TCHAR* getName() const { return TranslateTH(hLangpack, name); } - - COLORREF value; - int hLangpack; -}; - -struct EffectInternal : public EffectIDT -{ - __inline TCHAR* getName() const { return TranslateTH(hLangpack, name); } - - int hLangpack; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// global data & functions - -typedef struct -{ - char *paramName; - TCHAR *groupName; -} - TreeItem; - -extern OBJLIST font_id_list; -extern OBJLIST colour_id_list; -extern OBJLIST effect_id_list; - -extern int code_page; -extern HANDLE hFontReloadEvent, hColourReloadEvent; - -int CreateFromFontSettings(FontSettingsT *fs, LOGFONT *lf); diff --git a/src/modules/fonts/services.cpp b/src/modules/fonts/services.cpp deleted file mode 100644 index 77f29e8218..0000000000 --- a/src/modules/fonts/services.cpp +++ /dev/null @@ -1,501 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "FontService.h" - -#define FontID_OLDSIZE (offsetof(FontID, backgroundGroup)) -#define FontIDW_OLDSIZE (offsetof(FontIDW, backgroundGroup)) - -void ConvertFontSettings(FontSettings *fs, FontSettingsW *fsw) -{ - fsw->colour = fs->colour; - fsw->size = fs->size; - fsw->style = fs->style; - fsw->charset = fs->charset; - - MultiByteToWideChar(code_page, 0, fs->szFace, -1, fsw->szFace, LF_FACESIZE); -} - -bool ConvertFontID(FontID *fid, FontIDW *fidw) -{ - if (fid->cbSize != sizeof(FontID) && fid->cbSize != FontID_OLDSIZE) - return false; - - memset(fidw, 0, sizeof(FontIDW)); - fidw->cbSize = sizeof(FontIDW); - strncpy_s(fidw->dbSettingsGroup, fid->dbSettingsGroup, _TRUNCATE); - strncpy_s(fidw->prefix, fid->prefix, _TRUNCATE); - fidw->flags = fid->flags; - fidw->order = fid->order; - ConvertFontSettings(&fid->deffontsettings, &fidw->deffontsettings); - - MultiByteToWideChar(code_page, 0, fid->group, -1, fidw->group, 64); - MultiByteToWideChar(code_page, 0, fid->name, -1, fidw->name, 64); - - if (fid->cbSize > FontID_OLDSIZE) { - MultiByteToWideChar(code_page, 0, fid->backgroundGroup, -1, fidw->backgroundGroup, 64); - MultiByteToWideChar(code_page, 0, fid->backgroundName, -1, fidw->backgroundName, 64); - } - return true; -} - -bool ConvertColourID(ColourID *cid, ColourIDW *cidw) -{ - if (cid->cbSize != sizeof(ColourID)) - return false; - - cidw->cbSize = sizeof(ColourIDW); - - strncpy_s(cidw->dbSettingsGroup, cid->dbSettingsGroup, _TRUNCATE); - strncpy_s(cidw->setting, cid->setting, _TRUNCATE); - cidw->flags = cid->flags; - cidw->defcolour = cid->defcolour; - cidw->order = cid->order; - - MultiByteToWideChar(code_page, 0, cid->group, -1, cidw->group, 64); - MultiByteToWideChar(code_page, 0, cid->name, -1, cidw->name, 64); - return true; -} - -bool ConvertEffectID(EffectID *eid, EffectIDW *eidw) -{ - if (eid->cbSize != sizeof(EffectID)) - return false; - - eidw->cbSize = sizeof(EffectIDW); - - strncpy_s(eidw->dbSettingsGroup, eid->dbSettingsGroup, _TRUNCATE); - strncpy_s(eidw->setting, eid->setting, _TRUNCATE); - eidw->flags = eid->flags; - eidw->defeffect.effectIndex = eid->defeffect.effectIndex; - eidw->defeffect.baseColour = eid->defeffect.baseColour; - eidw->defeffect.secondaryColour = eid->defeffect.secondaryColour; - eidw->order = eid->order; - - MultiByteToWideChar(code_page, 0, eid->group, -1, eidw->group, 64); - MultiByteToWideChar(code_page, 0, eid->name, -1, eidw->name, 64); - return true; -} - -void ConvertLOGFONT(LOGFONTW *lfw, LOGFONTA *lfa) -{ - lfa->lfHeight = lfw->lfHeight; - lfa->lfWidth = lfw->lfWidth; - lfa->lfEscapement = lfw->lfEscapement; - lfa->lfOrientation = lfw->lfOrientation; - lfa->lfWeight = lfw->lfWeight; - lfa->lfItalic = lfw->lfItalic; - lfa->lfUnderline = lfw->lfUnderline; - lfa->lfStrikeOut = lfw->lfStrikeOut; - lfa->lfCharSet = lfw->lfCharSet; - lfa->lfOutPrecision = lfw->lfOutPrecision; - lfa->lfClipPrecision = lfw->lfClipPrecision; - lfa->lfQuality = lfw->lfQuality; - lfa->lfPitchAndFamily = lfw->lfPitchAndFamily; - - WideCharToMultiByte(code_page, 0, lfw->lfFaceName, -1, lfa->lfFaceName, LF_FACESIZE, 0, 0); -} - -static void GetDefaultFontSetting(LOGFONT *lf, COLORREF* colour) -{ - SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), lf, FALSE); - if (colour) - *colour = GetSysColor(COLOR_WINDOWTEXT); - - lf->lfHeight = 10; - - HDC hdc = GetDC(0); - lf->lfHeight = -MulDiv(lf->lfHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72); - ReleaseDC(0, hdc); -} - -int GetFontSettingFromDB(char *settings_group, char *prefix, LOGFONT *lf, COLORREF *colour, DWORD flags) -{ - GetDefaultFontSetting(lf, colour); - - char idstr[256]; - if (flags & FIDF_APPENDNAME) - mir_snprintf(idstr, "%sName", prefix); - else - strncpy_s(idstr, prefix, _TRUNCATE); - - int retval = 0; - ptrT tszGroup(db_get_tsa(NULL, settings_group, idstr)); - if (tszGroup != NULL) - _tcsncpy_s(lf->lfFaceName, tszGroup, _TRUNCATE); - else - retval = 1; - - if (colour) { - mir_snprintf(idstr, "%sCol", prefix); - *colour = db_get_dw(NULL, settings_group, idstr, *colour); - } - - mir_snprintf(idstr, "%sSize", prefix); - lf->lfHeight = (char)db_get_b(NULL, settings_group, idstr, lf->lfHeight); - - mir_snprintf(idstr, "%sSty", prefix); - BYTE style = (BYTE)db_get_b(NULL, settings_group, idstr, - (lf->lfWeight == FW_NORMAL ? 0 : DBFONTF_BOLD) | (lf->lfItalic ? DBFONTF_ITALIC : 0) | (lf->lfUnderline ? DBFONTF_UNDERLINE : 0) | lf->lfStrikeOut ? DBFONTF_STRIKEOUT : 0); - - lf->lfWidth = lf->lfEscapement = lf->lfOrientation = 0; - lf->lfWeight = style & DBFONTF_BOLD ? FW_BOLD : FW_NORMAL; - lf->lfItalic = (style & DBFONTF_ITALIC) != 0; - lf->lfUnderline = (style & DBFONTF_UNDERLINE) != 0; - lf->lfStrikeOut = (style & DBFONTF_STRIKEOUT) != 0; - - mir_snprintf(idstr, "%sSet", prefix); - lf->lfCharSet = db_get_b(NULL, settings_group, idstr, lf->lfCharSet); - - lf->lfOutPrecision = OUT_DEFAULT_PRECIS; - lf->lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf->lfQuality = DEFAULT_QUALITY; - lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; - - if (lf->lfHeight > 0) { - HDC hdc = GetDC(0); - if (flags & FIDF_SAVEPOINTSIZE) - lf->lfHeight = -MulDiv(lf->lfHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72); - else { // assume SAVEACTUALHEIGHT - HFONT hFont = CreateFontIndirect(lf); - HFONT hOldFont = (HFONT)SelectObject(hdc, hFont); - - TEXTMETRIC tm; - GetTextMetrics(hdc, &tm); - lf->lfHeight = -(lf->lfHeight - tm.tmInternalLeading); - - SelectObject(hdc, hOldFont); - DeleteObject(hFont); - } - - ReleaseDC(0, hdc); - } - - return retval; -} - -int CreateFromFontSettings(FontSettingsT *fs, LOGFONT *lf) -{ - GetDefaultFontSetting(lf, 0); - - _tcsncpy_s(lf->lfFaceName, fs->szFace, _TRUNCATE); - - lf->lfWidth = lf->lfEscapement = lf->lfOrientation = 0; - lf->lfWeight = fs->style & DBFONTF_BOLD ? FW_BOLD : FW_NORMAL; - lf->lfItalic = (fs->style & DBFONTF_ITALIC) != 0; - lf->lfUnderline = (fs->style & DBFONTF_UNDERLINE) != 0; - lf->lfStrikeOut = (fs->style & DBFONTF_STRIKEOUT) != 0; - lf->lfCharSet = fs->charset; - lf->lfOutPrecision = OUT_DEFAULT_PRECIS; - lf->lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf->lfQuality = DEFAULT_QUALITY; - lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; - - lf->lfHeight = fs->size; - return 0; -} - -void UpdateFontSettings(FontIDW *font_id, FontSettingsT *fontsettings) -{ - LOGFONT lf; - COLORREF colour; - if (GetFontSettingFromDB(font_id->dbSettingsGroup, font_id->prefix, &lf, &colour, font_id->flags) && (font_id->flags & FIDF_DEFAULTVALID)) { - CreateFromFontSettings(&font_id->deffontsettings, &lf); - colour = font_id->deffontsettings.colour; - } - - fontsettings->style = - (lf.lfWeight == FW_NORMAL ? 0 : DBFONTF_BOLD) | (lf.lfItalic ? DBFONTF_ITALIC : 0) | (lf.lfUnderline ? DBFONTF_UNDERLINE : 0) | (lf.lfStrikeOut ? DBFONTF_STRIKEOUT : 0); - - fontsettings->size = (char)lf.lfHeight; - fontsettings->charset = lf.lfCharSet; - fontsettings->colour = colour; - _tcsncpy_s(fontsettings->szFace, lf.lfFaceName, _TRUNCATE); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// RegisterFont service - -static int sttRegisterFontWorker(FontIDW *font_id, int hLangpack) -{ - if (font_id->cbSize != sizeof(FontIDW) && font_id->cbSize != FontIDW_OLDSIZE) - return -1; - - for (int i = 0; i < font_id_list.getCount(); i++) { - FontInternal& F = font_id_list[i]; - if (!mir_tstrcmp(F.group, font_id->group) && !mir_tstrcmp(F.name, font_id->name) && !(F.flags & FIDF_ALLOWREREGISTER)) - return 1; - } - - char idstr[256]; - mir_snprintf(idstr, "%sFlags", font_id->prefix); - db_set_dw(0, font_id->dbSettingsGroup, idstr, font_id->flags); - - FontInternal* newItem = new FontInternal; - memset(newItem, 0, sizeof(FontInternal)); - memcpy(newItem, font_id, font_id->cbSize); - newItem->hLangpack = hLangpack; - - if (!mir_tstrcmp(newItem->deffontsettings.szFace, _T("MS Shell Dlg"))) { - LOGFONT lf; - SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, FALSE); - mir_tstrncpy(newItem->deffontsettings.szFace, lf.lfFaceName, SIZEOF(newItem->deffontsettings.szFace)); - if (!newItem->deffontsettings.size) - newItem->deffontsettings.size = lf.lfHeight; - } - - UpdateFontSettings(font_id, &newItem->value); - font_id_list.insert(newItem); - return 0; -} - -INT_PTR RegisterFontW(WPARAM wParam, LPARAM lParam) -{ - return sttRegisterFontWorker((FontIDW*)wParam, (int)lParam); -} - -INT_PTR RegisterFont(WPARAM wParam, LPARAM lParam) -{ - FontIDW temp; - if (!ConvertFontID((FontID*)wParam, &temp)) return -1; - return sttRegisterFontWorker(&temp, (int)lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// GetFont service - -static INT_PTR sttGetFontWorker(FontIDW *font_id, LOGFONT *lf) -{ - COLORREF colour; - - for (int i = 0; i < font_id_list.getCount(); i++) { - FontInternal& F = font_id_list[i]; - if (!_tcsncmp(F.name, font_id->name, SIZEOF(F.name)) && !_tcsncmp(F.group, font_id->group, SIZEOF(F.group))) { - if (GetFontSettingFromDB(F.dbSettingsGroup, F.prefix, lf, &colour, F.flags) && (F.flags & FIDF_DEFAULTVALID)) { - CreateFromFontSettings(&F.deffontsettings, lf); - colour = F.deffontsettings.colour; - } - - return colour; - } - } - - GetDefaultFontSetting(lf, &colour); - return colour; -} - -INT_PTR GetFontW(WPARAM wParam, LPARAM lParam) -{ - return sttGetFontWorker((FontIDW*)wParam, (LOGFONT*)lParam); -} - -INT_PTR GetFont(WPARAM wParam, LPARAM lParam) -{ - FontIDW temp; - if (!ConvertFontID((FontID*)wParam, &temp)) - return -1; - - LOGFONT lftemp; - int ret = sttGetFontWorker(&temp, &lftemp); - ConvertLOGFONT(&lftemp, (LOGFONTA*)lParam); - return ret; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void KillModuleFonts(int hLangpack) -{ - for (int i = font_id_list.getCount() - 1; i >= 0; i--) - if (font_id_list[i].hLangpack == hLangpack) - font_id_list.remove(i); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// RegisterColour service - -void UpdateColourSettings(ColourIDW *colour_id, COLORREF *colour) -{ - *colour = (COLORREF)db_get_dw(NULL, colour_id->dbSettingsGroup, colour_id->setting, colour_id->defcolour); -} - -static INT_PTR sttRegisterColourWorker(ColourIDW *colour_id, int hLangpack) -{ - if (colour_id->cbSize != sizeof(ColourIDW)) - return -1; - - for (int i = 0; i < colour_id_list.getCount(); i++) { - ColourInternal& C = colour_id_list[i]; - if (!mir_tstrcmp(C.group, colour_id->group) && !mir_tstrcmp(C.name, colour_id->name)) - return 1; - } - - ColourInternal* newItem = new ColourInternal; - memset(newItem, 0, sizeof(ColourInternal)); - memcpy(newItem, colour_id, sizeof(ColourIDW)); - newItem->hLangpack = hLangpack; - UpdateColourSettings(colour_id, &newItem->value); - colour_id_list.insert(newItem); - return 0; -} - -INT_PTR RegisterColourW(WPARAM wParam, LPARAM lParam) -{ - return sttRegisterColourWorker((ColourIDW*)wParam, (int)lParam); -} - -INT_PTR RegisterColour(WPARAM wParam, LPARAM lParam) -{ - ColourIDW temp; - if (!ConvertColourID((ColourID*)wParam, &temp)) return -1; - return sttRegisterColourWorker(&temp, (int)lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// GetColour service - -static INT_PTR sttGetColourWorker(ColourIDW *colour_id) -{ - for (int i = 0; i < colour_id_list.getCount(); i++) { - ColourInternal& C = colour_id_list[i]; - if (!mir_tstrcmp(C.group, colour_id->group) && !mir_tstrcmp(C.name, colour_id->name)) - return db_get_dw(NULL, C.dbSettingsGroup, C.setting, C.defcolour); - } - - return -1; -} - -INT_PTR GetColourW(WPARAM wParam, LPARAM) -{ - return sttGetColourWorker((ColourIDW*)wParam); -} - -INT_PTR GetColour(WPARAM wParam, LPARAM) -{ - ColourIDW temp; - if (!ConvertColourID((ColourID*)wParam, &temp)) return -1; - return sttGetColourWorker(&temp); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void KillModuleColours(int hLangpack) -{ - for (int i = colour_id_list.getCount() - 1; i >= 0; i--) - if (colour_id_list[i].hLangpack == hLangpack) - colour_id_list.remove(i); -} - -////////////////////////////////////////////////////////////////////////// -// Effects - -void UpdateEffectSettings(EffectIDW *effect_id, FONTEFFECT *effectsettings) -{ - char str[256]; - mir_snprintf(str, "%sEffect", effect_id->setting); - effectsettings->effectIndex = db_get_b(NULL, effect_id->dbSettingsGroup, str, effect_id->defeffect.effectIndex); - - mir_snprintf(str, "%sEffectCol1", effect_id->setting); - effectsettings->baseColour = db_get_dw(NULL, effect_id->dbSettingsGroup, str, effect_id->defeffect.baseColour); - - mir_snprintf(str, "%sEffectCol2", effect_id->setting); - effectsettings->secondaryColour = db_get_dw(NULL, effect_id->dbSettingsGroup, str, effect_id->defeffect.secondaryColour); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// RegisterEffect service - -static INT_PTR sttRegisterEffectWorker(EffectIDW *effect_id, int hLangpack) -{ - if (effect_id->cbSize != sizeof(EffectIDW)) - return -1; - - for (int i = 0; i < effect_id_list.getCount(); i++) { - EffectInternal& E = effect_id_list[i]; - if (!mir_tstrcmp(E.group, effect_id->group) && !mir_tstrcmp(E.name, effect_id->name)) - return 1; - } - - EffectInternal* newItem = new EffectInternal; - memset(newItem, 0, sizeof(EffectInternal)); - memcpy(newItem, effect_id, sizeof(EffectIDW)); - newItem->hLangpack = hLangpack; - UpdateEffectSettings(effect_id, &newItem->value); - effect_id_list.insert(newItem); - return 0; -} - -INT_PTR RegisterEffectW(WPARAM wParam, LPARAM lParam) -{ - return sttRegisterEffectWorker((EffectIDW*)wParam, (int)lParam); -} - -INT_PTR RegisterEffect(WPARAM wParam, LPARAM lParam) -{ - EffectIDW temp; - if (!ConvertEffectID((EffectID*)wParam, &temp)) return -1; - return sttRegisterEffectWorker(&temp, (int)lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// GetEffect service - -static INT_PTR sttGetEffectWorker(EffectIDW *effect_id, FONTEFFECT *effect) -{ - for (int i = 0; i < effect_id_list.getCount(); i++) { - EffectInternal& E = effect_id_list[i]; - if (!_tcsncmp(E.name, effect_id->name, SIZEOF(E.name)) && !_tcsncmp(E.group, effect_id->group, SIZEOF(E.group))) { - FONTEFFECT temp; - UpdateEffectSettings(effect_id, &temp); - - effect->effectIndex = temp.effectIndex; - effect->baseColour = temp.baseColour; - effect->secondaryColour = temp.secondaryColour; - return TRUE; - } - } - - return FALSE; -} - -INT_PTR GetEffectW(WPARAM wParam, LPARAM lParam) -{ - return sttGetEffectWorker((EffectIDW*)wParam, (FONTEFFECT*)lParam); -} - -INT_PTR GetEffect(WPARAM wParam, LPARAM lParam) -{ - EffectIDW temp; - if (!ConvertEffectID((EffectID*)wParam, &temp)) return -1; - return sttGetEffectWorker(&temp, (FONTEFFECT*)lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void KillModuleEffects(int hLangpack) -{ - for (int i = effect_id_list.getCount() - 1; i >= 0; i--) - if (effect_id_list[i].hLangpack == hLangpack) - effect_id_list.remove(i); -} diff --git a/src/modules/icolib/IcoLib.h b/src/modules/icolib/IcoLib.h deleted file mode 100644 index e8bd131b1d..0000000000 --- a/src/modules/icolib/IcoLib.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 SECTIONPARAM_MAKE(index, level, flags) MAKELONG((index)&0xFFFF, MAKEWORD(level, flags)) -#define SECTIONPARAM_INDEX(lparam) LOWORD(lparam) -#define SECTIONPARAM_LEVEL(lparam) LOBYTE(HIWORD(lparam)) -#define SECTIONPARAM_FLAGS(lparam) HIBYTE(HIWORD(lparam)) -#define SECTIONPARAM_HAVEPAGE 0x0001 - -struct SectionItem -{ - TCHAR* name; - int flags; - int maxOrder; - int ref_count; -}; - -struct IconSourceFile -{ - TCHAR* file; - int ref_count; -}; - -struct IconSourceItem -{ - IconSourceFile* file; - int indx; - int cx, cy; - - int ref_count; - - HICON icon; - int icon_ref_count; - - BYTE* icon_data; - int icon_size; -}; - -struct IcolibItem -{ - char* name; - SectionItem* section; - int orderID; - TCHAR* description; - TCHAR* default_file; - int default_indx; - int cx, cy; - int hLangpack; - - IconSourceItem* source_small; - IconSourceItem* source_big; - IconSourceItem* default_icon; - - TCHAR* temp_file; - HICON temp_icon; - BOOL temp_reset; - - __inline TCHAR* getDescr() const { return TranslateTH(hLangpack, description); } -}; - -// extracticon.c - -UINT _ExtractIconEx(LPCTSTR lpszFile, int iconIndex, int cxIcon, int cyIcon, HICON *phicon, UINT flags); - -void __fastcall SAFE_FREE(void** p); -void __fastcall SafeDestroyIcon(HICON* icon); - -int IconSourceItem_Release(IconSourceItem** pitem); -int IconSourceItem_ReleaseIcon(IconSourceItem* item); -HICON IconSourceItem_GetIcon(IconSourceItem* item); -IconSourceItem* GetIconSourceItem(const TCHAR* file, int indx, int cxIcon, int cyIcon); - -IcolibItem* IcoLib_FindHIcon(HICON hIcon, bool &big); -IcolibItem* IcoLib_FindIcon(const char* pszIconName); - -HICON IconItem_GetIcon(IcolibItem* item, bool big); - -int SkinOptionsInit(WPARAM, LPARAM); - -extern mir_cs csIconList; -extern LIST iconList; -extern LIST sectionList; - -extern BOOL bNeedRebuild; -extern int iconEventActive; -extern HICON hIconBlank; -extern HANDLE hIcons2ChangedEvent, hIconsChangedEvent; diff --git a/src/modules/icolib/extracticon.cpp b/src/modules/icolib/extracticon.cpp deleted file mode 100644 index d3bafc6bde..0000000000 --- a/src/modules/icolib/extracticon.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#ifdef _ASSERT -#undef _ASSERT -#endif -#define _ASSERT(n) -// http://msdn.microsoft.com/library/default.asp?url = /library/en-us/winui/winui/windowsuserinterface/resources/introductiontoresources/resourcereference/resourcestructures/newheader.asp -typedef struct -{ - WORD Reserved; - WORD ResType; - WORD ResCount; -} - NEWHEADER; - -#define MAGIC_ICON 0 -#define MAGIC_ICO1 1 -#define MAGIC_CUR 2 -#define MAGIC_BMP ((WORD)'B'+((WORD)'M'<<8)) - -#define MAGIC_ANI1 ((WORD)'R'+((WORD)'I'<<8)) -#define MAGIC_ANI2 ((WORD)'F'+((WORD)'F'<<8)) -#define MAGIC_ANI3 ((WORD)'A'+((WORD)'C'<<8)) -#define MAGIC_ANI4 ((WORD)'O'+((WORD)'N'<<8)) - -#define VER30 0x00030000 - -void* _RelativeVirtualAddresstoPtr(IMAGE_DOS_HEADER* pDosHeader, DWORD rva) -{ - IMAGE_NT_HEADERS* pPE = (IMAGE_NT_HEADERS*)((BYTE*)pDosHeader + pDosHeader->e_lfanew); - IMAGE_SECTION_HEADER* pSection = IMAGE_FIRST_SECTION(pPE); - int i; - - for (i=0; i < pPE->FileHeader.NumberOfSections; i++) { - IMAGE_SECTION_HEADER* cSection = &pSection[i]; - DWORD size = cSection->Misc.VirtualSize ? cSection->Misc.VirtualSize : cSection->SizeOfRawData; - - if (rva >= cSection->VirtualAddress && rva < cSection->VirtualAddress + size) - return (LPBYTE)pDosHeader + cSection->PointerToRawData + (rva - cSection->VirtualAddress); - } - - return NULL; -} - -void* _GetResourceTable(IMAGE_DOS_HEADER* pDosHeader) -{ - IMAGE_NT_HEADERS* pPE = (IMAGE_NT_HEADERS*)((BYTE*)pDosHeader + pDosHeader->e_lfanew); - - if (pPE->Signature != IMAGE_NT_SIGNATURE) - return NULL; - if (pPE->FileHeader.SizeOfOptionalHeader < 2) - return NULL; - - // The DataDirectory is an array of 16 structures. - // Each array entry has a predefined meaning for what it refers to. - - switch (pPE->OptionalHeader.Magic) - { - case IMAGE_NT_OPTIONAL_HDR32_MAGIC: - if (pPE->FileHeader.SizeOfOptionalHeader >= sizeof(IMAGE_OPTIONAL_HEADER32)) - return _RelativeVirtualAddresstoPtr(pDosHeader, ((PIMAGE_NT_HEADERS32)pPE)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress); - break; - - case IMAGE_NT_OPTIONAL_HDR64_MAGIC: - if (pPE->FileHeader.SizeOfOptionalHeader >= sizeof(IMAGE_OPTIONAL_HEADER64)) - return _RelativeVirtualAddresstoPtr(pDosHeader, ((PIMAGE_NT_HEADERS64)pPE)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress); - break; - } - - return NULL; -} - -IMAGE_RESOURCE_DIRECTORY_ENTRY* _FindResourceBase(void* prt, int resType, int* pCount) -{ - IMAGE_RESOURCE_DIRECTORY* pDir = (IMAGE_RESOURCE_DIRECTORY*)prt; - IMAGE_RESOURCE_DIRECTORY_ENTRY* pRes; - int i, count; - - *pCount = 0; - - count = pDir->NumberOfIdEntries + pDir->NumberOfNamedEntries; - pRes = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(pDir+1); - - for (i=0; i < count; i++) - if (pRes[i].Name == (DWORD)resType) break; - - if (i == count) return NULL; - - pDir = (IMAGE_RESOURCE_DIRECTORY*)((LPBYTE)prt + - (pRes[i].OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)); - - count = pDir->NumberOfIdEntries + pDir->NumberOfNamedEntries; - *pCount = count; - pRes = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(pDir+1); - - return pRes; -} - -int _FindResourceCount(void* prt, int resType) -{ - int count; - - _FindResourceBase(prt, resType, &count); - return count; -} - -void* _FindResource(IMAGE_DOS_HEADER* pDosHeader, void* prt, int resIndex, int resType, DWORD* pcbSize) -{ - int count, index = 0; - IMAGE_RESOURCE_DIRECTORY_ENTRY* pRes; - IMAGE_RESOURCE_DATA_ENTRY* pEntry; - - pRes = _FindResourceBase(prt, resType, &count); - if (resIndex < 0) { - for (index = 0; index < count; index++) - if (pRes[index].Name == (DWORD)(-resIndex)) - break; - } - else index = resIndex; - - if (index >= count) - return NULL; - - if (pRes[index].OffsetToData & IMAGE_RESOURCE_DATA_IS_DIRECTORY) { - IMAGE_RESOURCE_DIRECTORY* pDir; - pDir = (IMAGE_RESOURCE_DIRECTORY*)((LPBYTE)prt + (pRes[index].OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)); - pRes = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(pDir+1); - index = 0; - } - - if (pRes[index].OffsetToData & IMAGE_RESOURCE_DATA_IS_DIRECTORY) - return NULL; - - pEntry = (IMAGE_RESOURCE_DATA_ENTRY*)((LPBYTE)prt + pRes[index].OffsetToData); - *pcbSize = pEntry->Size; - return _RelativeVirtualAddresstoPtr(pDosHeader, pEntry->OffsetToData); -} - -UINT _ExtractFromExe(HANDLE hFile, int iconIndex, int cxIconSize, int cyIconSize, HICON *phicon, UINT flags) -{ - int retval = 0; - DWORD fileLen = GetFileSize(hFile, NULL); - HANDLE hFileMap = INVALID_HANDLE_VALUE, pFile = NULL; - IMAGE_DOS_HEADER* pDosHeader; - void* pRes; - DWORD cbSize = 0; - NEWHEADER* pIconDir; - int idIcon; - LPBITMAPINFOHEADER pIcon; - // UINT res = 0; - - hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); - if (hFileMap == NULL) goto cleanup; - - pFile = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0); - if (pFile == NULL) goto cleanup; - - pDosHeader = (IMAGE_DOS_HEADER*)(void*)pFile; - if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) goto cleanup; - if (pDosHeader->e_lfanew <= 0) goto cleanup; - if ((DWORD)(pDosHeader->e_lfanew) >= fileLen) goto cleanup; - - pRes = _GetResourceTable(pDosHeader); - if (!pRes) goto cleanup; - if (!phicon) { - retval = _FindResourceCount(pRes, (int)RT_GROUP_ICON); - goto cleanup; - } - - pIconDir = (NEWHEADER*)_FindResource(pDosHeader, pRes, iconIndex, (int)RT_GROUP_ICON, &cbSize); - if (!pIconDir) goto cleanup; - if (pIconDir->Reserved || pIconDir->ResType != RES_ICON) goto cleanup; - - idIcon = LookupIconIdFromDirectoryEx((LPBYTE)pIconDir, TRUE, cxIconSize, cyIconSize, flags); - pIcon = (LPBITMAPINFOHEADER)_FindResource(pDosHeader, pRes, -idIcon, (int)RT_ICON, &cbSize); - if (!pIcon) goto cleanup; - - if (pIcon->biSize != sizeof(BITMAPINFOHEADER) && pIcon->biSize != sizeof(BITMAPCOREHEADER)) { - _ASSERT(0); - goto cleanup; - } - - *phicon = CreateIconFromResourceEx((LPBYTE)pIcon, cbSize, TRUE, VER30, cxIconSize, cyIconSize, flags); - retval = 1; - -cleanup: - if (pFile) UnmapViewOfFile(pFile); - if (hFileMap != INVALID_HANDLE_VALUE) CloseHandle(hFileMap); - - return retval; -} - -UINT _ExtractFromICO(LPCTSTR pFileName, int iconIndex, int cxIcon, int cyIcon, HICON* phicon, UINT flags) -{ - HICON hicon; - - if (iconIndex >= 1) - return 0; - - // do we just want a count? - if (!phicon) - return 1; - - flags |= LR_LOADFROMFILE; - hicon = (HICON)LoadImage(NULL, pFileName, IMAGE_ICON, cxIcon, cyIcon, flags); - if (!hicon) - return 0; - - *phicon = hicon; - return 1; -} - -UINT _ExtractIconEx(LPCTSTR lpszFile, int iconIndex, int cxIcon, int cyIcon, HICON *phicon, UINT flags) -{ - HANDLE hFile; - WORD magic[6]; - DWORD read = 0; - UINT res = 0; - - if (cxIcon == GetSystemMetrics(SM_CXICON) && cyIcon == GetSystemMetrics(SM_CYICON)) - res = ExtractIconEx(lpszFile, iconIndex, phicon, NULL, 1); - else if (cxIcon == GetSystemMetrics(SM_CXSMICON) && cyIcon == GetSystemMetrics(SM_CYSMICON)) - res = ExtractIconEx(lpszFile, iconIndex, NULL, phicon, 1); - else if (cxIcon == 0 || cyIcon == 0) - res = ExtractIconEx(lpszFile, iconIndex, NULL, phicon, 1); - // check if the api succeded, if not try our method too - if (res) return res; - - hFile = CreateFile(lpszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if (hFile == INVALID_HANDLE_VALUE) - return 0; - - // failed to read file signature - if (!ReadFile(hFile, &magic, sizeof(magic), &read, NULL) || (read != sizeof(magic))) { - CloseHandle(hFile); - return 0; - } - - switch (magic[0]) { - case IMAGE_DOS_SIGNATURE: - res = _ExtractFromExe(hFile, iconIndex, cxIcon, cyIcon, phicon, flags); - break; - - case MAGIC_ANI1: // ani cursors are RIFF file of type 'ACON' - if (magic[1] == MAGIC_ANI2 && magic[4] == MAGIC_ANI3 && magic[5] == MAGIC_ANI4) - res = _ExtractFromICO(lpszFile, iconIndex, cxIcon, cyIcon, phicon, flags); - break; - - case MAGIC_ICON: - if ((magic[1] == MAGIC_ICO1 || magic[1] == MAGIC_CUR) && magic[2] >= 1) - res = _ExtractFromICO(lpszFile, iconIndex, cxIcon, cyIcon, phicon, flags); - - break; - } - - CloseHandle(hFile); - return res; -} diff --git a/src/modules/icolib/skin2icons.cpp b/src/modules/icolib/skin2icons.cpp deleted file mode 100644 index 5b41b14e36..0000000000 --- a/src/modules/icolib/skin2icons.cpp +++ /dev/null @@ -1,902 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#include "IcoLib.h" - -static BOOL bModuleInitialized = FALSE; -HANDLE hIcons2ChangedEvent, hIconsChangedEvent; - -HICON hIconBlank = NULL; - -static HANDLE - hIcoLib_AddNewIcon, hIcoLib_RemoveIcon, hIcoLib_GetIcon, hIcoLib_GetIcon2, - hIcoLib_GetIconHandle, hIcoLib_IsManaged, hIcoLib_AddRef, hIcoLib_ReleaseIcon; - -int iconEventActive = 0; - -BOOL bNeedRebuild = FALSE; - -mir_cs csIconList; - -static int sttCompareSections(const SectionItem* p1, const SectionItem* p2) -{ - return mir_tstrcmp(p1->name, p2->name); -} - -LIST sectionList(20, sttCompareSections); - -static int sttCompareIconSourceFiles(const IconSourceFile* p1, const IconSourceFile* p2) -{ - return mir_tstrcmpi(p1->file, p2->file); -} - -static LIST iconSourceFileList(10, sttCompareIconSourceFiles); - -static int sttCompareIconSourceItems(const IconSourceItem* p1, const IconSourceItem* p2) -{ - if (p1->indx < p2->indx) - return -1; - - if (p1->indx > p2->indx) - return 1; - - if (p1->cx < p2->cx) - return -1; - - if (p1->cx > p2->cx) - return 1; - - if (p1->cy < p2->cy) - return -1; - - if (p1->cy > p2->cy) - return 1; - - if (p1->file == p2->file) - return 0; - - return (p1->file > p2->file) ? 1 : -1; -} - -static LIST iconSourceList(20, sttCompareIconSourceItems); - -static int sttCompareIcons(const IcolibItem* p1, const IcolibItem* p2) -{ - return mir_strcmp(p1->name, p2->name); -} - -LIST iconList(20, sttCompareIcons); - -///////////////////////////////////////////////////////////////////////////////////////// -// Utility functions - -void __fastcall SAFE_FREE(void** p) -{ - if (*p) { - mir_free(*p); - *p = NULL; - } -} - -void __fastcall SafeDestroyIcon(HICON* icon) -{ - if (*icon) { - DestroyIcon(*icon); - *icon = NULL; - } -} - -// Helper functions to manage Icon resources - -IconSourceFile* IconSourceFile_Get(const TCHAR* file, bool isPath) -{ - TCHAR fileFull[ MAX_PATH ]; - - if (!file) - return NULL; - - if (isPath) - PathToAbsoluteT(file, fileFull); /// TODO: convert path to long - eliminate duplicate items - else - _tcsncpy_s(fileFull, file, _TRUNCATE); - - IconSourceFile key = { fileFull }; - int ix; - if ((ix = iconSourceFileList.getIndex(&key)) != -1) { - iconSourceFileList[ ix ]->ref_count++; - return iconSourceFileList[ ix ]; - } - - IconSourceFile* newItem = (IconSourceFile*)mir_calloc(sizeof(IconSourceFile)); - newItem->file = mir_tstrdup(fileFull); - newItem->ref_count = 1; - iconSourceFileList.insert(newItem); - - return newItem; -} - -int IconSourceFile_Release(IconSourceFile** pitem) -{ - if (pitem && *pitem && (*pitem)->ref_count) { - IconSourceFile* item = *pitem; - if (--item->ref_count <= 0) { - int indx; - if ((indx = iconSourceFileList.getIndex(item)) != -1) { - SAFE_FREE((void**)&item->file); - iconSourceFileList.remove(indx); - SAFE_FREE((void**)&item); - } - } - *pitem = NULL; - return 0; - } - return 1; -} - -static int BytesPerScanLine(int PixelsPerScanline, int BitsPerPixel, int Alignment) -{ - Alignment--; - int bytes = ((PixelsPerScanline * BitsPerPixel) + Alignment) & ~Alignment; - return bytes / 8; -} - -static int InitializeBitmapInfoHeader(HBITMAP bitmap, BITMAPINFOHEADER* bi) -{ - DIBSECTION DS; - int bytes; - - DS.dsBmih.biSize = 0; - bytes = GetObject(bitmap, sizeof(DS), &DS); - if (bytes == 0) return 1; // Failure - else if ((bytes >= (sizeof(DS.dsBm) + sizeof(DS.dsBmih))) && - (DS.dsBmih.biSize >= DWORD(sizeof(DS.dsBmih)))) - *bi = DS.dsBmih; - else { - memset(bi, 0, sizeof(BITMAPINFOHEADER)); - bi->biSize = sizeof(BITMAPINFOHEADER); - bi->biWidth = DS.dsBm.bmWidth; - bi->biHeight = DS.dsBm.bmHeight; - } - bi->biBitCount = DS.dsBm.bmBitsPixel * DS.dsBm.bmPlanes; - bi->biPlanes = 1; - if (bi->biClrImportant > bi->biClrUsed) - bi->biClrImportant = bi->biClrUsed; - if (!bi->biSizeImage) - bi->biSizeImage = BytesPerScanLine(bi->biWidth, bi->biBitCount, 32) * abs(bi->biHeight); - return 0; // Success -} - -static int InternalGetDIBSizes(HBITMAP bitmap, int* InfoHeaderSize, int* ImageSize) -{ - BITMAPINFOHEADER bi; - - if (InitializeBitmapInfoHeader(bitmap, &bi)) return 1; // Failure - if (bi.biBitCount > 8) { - *InfoHeaderSize = sizeof(BITMAPINFOHEADER); - if ((bi.biCompression & BI_BITFIELDS) != 0) - *InfoHeaderSize += 12; - } - else { - if (bi.biClrUsed == 0) - *InfoHeaderSize = sizeof(BITMAPINFOHEADER) + - sizeof(RGBQUAD) * (int)(1 << bi.biBitCount); - else - *InfoHeaderSize = sizeof(BITMAPINFOHEADER) + - sizeof(RGBQUAD) * bi.biClrUsed; - } - *ImageSize = bi.biSizeImage; - return 0; // Success -} - -static int InternalGetDIB(HBITMAP bitmap, HPALETTE palette, void* bitmapInfo, void* Bits) -{ - HPALETTE oldPal = 0; - - if (InitializeBitmapInfoHeader(bitmap, (BITMAPINFOHEADER*)bitmapInfo)) return 1; // Failure - - HDC DC = CreateCompatibleDC(0); - if (palette) { - oldPal = SelectPalette(DC, palette, FALSE); - RealizePalette(DC); - } - int result = GetDIBits(DC, bitmap, 0, ((BITMAPINFOHEADER*)bitmapInfo)->biHeight, Bits, (BITMAPINFO*)bitmapInfo, DIB_RGB_COLORS) == 0; - - if (oldPal) SelectPalette(DC, oldPal, FALSE); - DeleteDC(DC); - return result; -} - -static int GetIconData(HICON icon, BYTE** data, int* size) -{ - ICONINFO iconInfo; - int MonoInfoSize, ColorInfoSize; - int MonoBitsSize, ColorBitsSize; - - if (!data || !size) return 1; // Failure - - if (!GetIconInfo(icon, &iconInfo)) return 1; // Failure - - if (InternalGetDIBSizes(iconInfo.hbmMask, &MonoInfoSize, &MonoBitsSize) || - InternalGetDIBSizes(iconInfo.hbmColor, &ColorInfoSize, &ColorBitsSize)) { - DeleteObject(iconInfo.hbmColor); - DeleteObject(iconInfo.hbmMask); - return 1; // Failure - } - void* MonoInfo = mir_alloc(MonoInfoSize); - void* MonoBits = mir_alloc(MonoBitsSize); - void* ColorInfo = mir_alloc(ColorInfoSize); - void* ColorBits = mir_alloc(ColorBitsSize); - - if (InternalGetDIB(iconInfo.hbmMask, 0, MonoInfo, MonoBits) || - InternalGetDIB(iconInfo.hbmColor, 0, ColorInfo, ColorBits)) { - SAFE_FREE(&MonoInfo); - SAFE_FREE(&MonoBits); - SAFE_FREE(&ColorInfo); - SAFE_FREE(&ColorBits); - DeleteObject(iconInfo.hbmColor); - DeleteObject(iconInfo.hbmMask); - return 1; // Failure - } - - *size = ColorInfoSize + ColorBitsSize + MonoBitsSize; - *data = (BYTE*)mir_alloc(*size); - - BYTE* buf = *data; - ((BITMAPINFOHEADER*)ColorInfo)->biHeight *= 2; // color height includes mono bits - memcpy(buf, ColorInfo, ColorInfoSize); - buf += ColorInfoSize; - memcpy(buf, ColorBits, ColorBitsSize); - buf += ColorBitsSize; - memcpy(buf, MonoBits, MonoBitsSize); - - SAFE_FREE(&MonoInfo); - SAFE_FREE(&MonoBits); - SAFE_FREE(&ColorInfo); - SAFE_FREE(&ColorBits); - DeleteObject(iconInfo.hbmColor); - DeleteObject(iconInfo.hbmMask); - return 0; // Success -} - -#define VER30 0x00030000 - -HICON IconSourceItem_GetIcon(IconSourceItem* item) -{ - if (item->icon) { - item->icon_ref_count++; - return item->icon; - } - - if (item->icon_size) { - item->icon = CreateIconFromResourceEx(item->icon_data, item->icon_size, TRUE, VER30, item->cx, item->cy, LR_COLOR); - if (item->icon) { - item->icon_ref_count++; - return item->icon; - } - } - //SHOULD BE REPLACED WITH GOOD ENOUGH FUNCTION - _ExtractIconEx(item->file->file, item->indx, item->cx, item->cy, &item->icon, LR_COLOR); - - if (item->icon) - item->icon_ref_count++; - - return item->icon; -} - -int IconSourceItem_ReleaseIcon(IconSourceItem* item) -{ - if (item && item->icon_ref_count) { - item->icon_ref_count--; - if (!item->icon_ref_count) { - if (!item->icon_size) - if (GetIconData(item->icon, &item->icon_data, &item->icon_size)) - item->icon_size = 0; // Failure - SafeDestroyIcon(&item->icon); - } - return 0; // Success - } - return 1; // Failure -} - -IconSourceItem* GetIconSourceItem(const TCHAR* file, int indx, int cxIcon, int cyIcon) -{ - if (!file) - return NULL; - - IconSourceFile* r_file = IconSourceFile_Get(file, true); - IconSourceItem key = { r_file, indx, cxIcon, cyIcon }; - int ix; - if ((ix = iconSourceList.getIndex(&key)) != -1) { - IconSourceFile_Release(&r_file); - iconSourceList[ ix ]->ref_count++; - return iconSourceList[ ix ]; - } - - IconSourceItem* newItem = (IconSourceItem*)mir_calloc(sizeof(IconSourceItem)); - newItem->file = r_file; - newItem->indx = indx; - newItem->ref_count = 1; - newItem->cx = cxIcon; - newItem->cy = cyIcon; - iconSourceList.insert(newItem); - - return newItem; -} - -IconSourceItem* GetIconSourceItemFromPath(const TCHAR* path, int cxIcon, int cyIcon) -{ - if (!path) - return NULL; - - TCHAR file[ MAX_PATH ]; - mir_tstrncpy(file, path, SIZEOF(file)); - TCHAR *comma = _tcsrchr(file, ','); - - int n; - if (!comma) - n = 0; - else { - n = _ttoi(comma+1); - *comma = 0; - } - return GetIconSourceItem(file, n, cxIcon, cyIcon); -} - -IconSourceItem* CreateStaticIconSourceItem(int cxIcon, int cyIcon) -{ - TCHAR sourceName[ MAX_PATH ]; - IconSourceFile key = { sourceName }; - - int i=0; - do { // find new unique name - mir_sntprintf(sourceName, SIZEOF(sourceName), _T("*StaticIcon_%d"), i++); - } - while (iconSourceFileList.getIndex(&key) != -1); - - IconSourceItem* newItem = (IconSourceItem*)mir_calloc(sizeof(IconSourceItem)); - newItem->file = IconSourceFile_Get(sourceName, false); - newItem->indx = 0; - newItem->ref_count = 1; - newItem->cx = cxIcon; - newItem->cy = cyIcon; - iconSourceList.insert(newItem); - - return newItem; -} - -int IconSourceItem_Release(IconSourceItem** pitem) -{ - if (pitem && *pitem && (*pitem)->ref_count) { - IconSourceItem* item = *pitem; - item->ref_count--; - if (!item->ref_count) { - int indx; - if ((indx = iconSourceList.getIndex(item)) != -1) { - IconSourceFile_Release(&item->file); - SafeDestroyIcon(&item->icon); - SAFE_FREE((void**)&item->icon_data); - iconSourceList.remove(indx); - SAFE_FREE((void**)&item); - } - } - *pitem = NULL; - return 0; - } - return 1; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Service functions - -static SectionItem* IcoLib_AddSection(TCHAR *sectionName, BOOL create_new) -{ - if (!sectionName) - return NULL; - - int indx; - SectionItem key = { sectionName, 0 }; - if ((indx = sectionList.getIndex(&key)) != -1) - return sectionList[ indx ]; - - if (create_new) { - SectionItem* newItem = (SectionItem*)mir_calloc(sizeof(SectionItem)); - newItem->name = mir_tstrdup(sectionName); - newItem->flags = 0; - sectionList.insert(newItem); - bNeedRebuild = TRUE; - return newItem; - } - - return NULL; -} - -static void IcoLib_RemoveSection(SectionItem* section) -{ - if (!section) - return; - - int indx; - if ((indx = sectionList.getIndex(section)) != -1) { - sectionList.remove(indx); - SAFE_FREE((void**)§ion->name); - SAFE_FREE((void**)§ion); - bNeedRebuild = TRUE; - } -} - -IcolibItem* IcoLib_FindIcon(const char* pszIconName) -{ - int indx = iconList.getIndex((IcolibItem*)&pszIconName); - return (indx != -1) ? iconList[ indx ] : 0; -} - -IcolibItem* IcoLib_FindHIcon(HICON hIcon, bool &big) -{ - if (hIcon == NULL) - return NULL; - - for (int i = 0; i < iconList.getCount(); i++) { - IcolibItem *p = iconList[i]; - if ((void*)p == hIcon) { - big = (p->source_small == NULL); - return p; - } - if (p->source_small && p->source_small->icon == hIcon) { - big = false; - return p; - } - if (p->source_big && p->source_big->icon == hIcon) { - big = true; - return p; - } - } - - return NULL; -} - -static void IcoLib_FreeIcon(IcolibItem* icon) -{ - if (!icon) return; - - SAFE_FREE((void**)&icon->name); - SAFE_FREE((void**)&icon->description); - SAFE_FREE((void**)&icon->default_file); - SAFE_FREE((void**)&icon->temp_file); - if (icon->section) { - if (!--icon->section->ref_count) - IcoLib_RemoveSection(icon->section); - icon->section = NULL; - } - IconSourceItem_Release(&icon->source_small); - IconSourceItem_Release(&icon->source_big); - IconSourceItem_Release(&icon->default_icon); - SafeDestroyIcon(&icon->temp_icon); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib_AddNewIcon - -HANDLE IcoLib_AddNewIcon(int hLangpack, SKINICONDESC *sid) -{ - bool utf = (sid->flags & SIDF_UNICODE) != 0; - bool utf_path = (sid->flags & SIDF_PATH_UNICODE) != 0; - - mir_cslock lck(csIconList); - - IcolibItem *item = IcoLib_FindIcon(sid->pszName); - if (!item) { - item = (IcolibItem*)mir_calloc(sizeof(IcolibItem)); - item->name = sid->pszName; - iconList.insert(item); - } - else IcoLib_FreeIcon(item); - - item->name = mir_strdup(sid->pszName); - if (utf) { - item->description = mir_u2t(sid->description.w); - item->section = IcoLib_AddSection(sid->section.w, TRUE); - } - else { - item->description = mir_a2t(sid->description.a); - WCHAR *pwszSection = sid->section.a ? mir_a2u(sid->section.a) : NULL; - item->section = IcoLib_AddSection(pwszSection, TRUE); - SAFE_FREE((void**)&pwszSection); - } - - if (item->section) { - item->section->ref_count++; - item->orderID = ++item->section->maxOrder; - } - else item->orderID = 0; - - if (sid->defaultFile.a) { - WCHAR fileFull[ MAX_PATH ]; - if (utf_path) - PathToAbsoluteT(sid->defaultFile.w, fileFull); - else - PathToAbsoluteT(_A2T(sid->defaultFile.a), fileFull); - item->default_file = mir_wstrdup(fileFull); - } - item->default_indx = sid->iDefaultIndex; - - item->cx = sid->cx; - item->cy = sid->cy; - item->hLangpack = hLangpack; - - if (sid->hDefaultIcon) { - bool big; - IcolibItem* def_item = IcoLib_FindHIcon(sid->hDefaultIcon, big); - if (def_item) { - item->default_icon = big ? def_item->source_big : def_item->source_small; - item->default_icon->ref_count++; - } - else { - int cx = item->cx ? item->cx : GetSystemMetrics(SM_CXSMICON); - int cy = item->cy ? item->cy : GetSystemMetrics(SM_CYSMICON); - item->default_icon = CreateStaticIconSourceItem(cx, cy); - if (GetIconData(sid->hDefaultIcon, &item->default_icon->icon_data, &item->default_icon->icon_size)) - IconSourceItem_Release(&item->default_icon); - } - } - - if (item->section) - item->section->flags = sid->flags & SIDF_SORTED; - - return item; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib_RemoveIcon - -static int IcoLib_RemoveIcon_Internal(int i) -{ - IcolibItem *item = iconList[ i ]; - IcoLib_FreeIcon(item); - iconList.remove(i); - SAFE_FREE((void**)&item); - return 0; -} - -static INT_PTR IcoLib_RemoveIcon(WPARAM wParam, LPARAM lParam) -{ - if (wParam) { - mir_cslock lck(csIconList); - - int i = iconList.indexOf((IcolibItem*)wParam); - if (i != -1) - return IcoLib_RemoveIcon_Internal(i); - } - - if (lParam) { - mir_cslock lck(csIconList); - - int i = iconList.getIndex((IcolibItem*)&lParam); - if (i != -1) - return IcoLib_RemoveIcon_Internal(i); - } - return 1; // Failed -} - -void KillModuleIcons(int hLangpack) -{ - if (!bModuleInitialized) - return; - - mir_cslock lck(csIconList); - for (int i = iconList.getCount()-1; i >= 0; i--) { - IcolibItem *item = iconList[i]; - if ( item->hLangpack == hLangpack) { - IcoLib_FreeIcon(item); - iconList.remove(i); - SAFE_FREE((void**)&item); - } - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IconItem_GetDefaultIcon - -HICON IconItem_GetDefaultIcon(IcolibItem* item, bool big) -{ - HICON hIcon = NULL; - - if (item->default_icon && !big) { - IconSourceItem_Release(&item->source_small); - item->source_small = item->default_icon; - item->source_small->ref_count++; - hIcon = IconSourceItem_GetIcon(item->source_small); - } - - if (!hIcon && item->default_file) { - int cx = item->cx ? item->cx : GetSystemMetrics(big ? SM_CXICON : SM_CXSMICON); - int cy = item->cy ? item->cy : GetSystemMetrics(big ? SM_CYICON : SM_CYSMICON); - IconSourceItem* def_icon = GetIconSourceItem(item->default_file, item->default_indx, cx, cy); - if (big) { - if (def_icon != item->source_big) { - IconSourceItem_Release(&item->source_big); - item->source_big = def_icon; - if (def_icon) { - def_icon->ref_count++; - hIcon = IconSourceItem_GetIcon(def_icon); - } - } - else - IconSourceItem_Release(&def_icon); - } - else { - if (def_icon != item->default_icon) { - IconSourceItem_Release(&item->default_icon); - item->default_icon = def_icon; - if (def_icon) { - IconSourceItem_Release(&item->source_small); - item->source_small = def_icon; - def_icon->ref_count++; - hIcon = IconSourceItem_GetIcon(def_icon); - } - } - else - IconSourceItem_Release(&def_icon); - } - } - return hIcon; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IconItem_GetIcon - -HICON IconItem_GetIcon(IcolibItem* item, bool big) -{ - DBVARIANT dbv = {0}; - HICON hIcon = NULL; - - big = big && !item->cx; - IconSourceItem* &source = big ? item->source_big : item->source_small; - - if (!source && !db_get_ts(NULL, "SkinIcons", item->name, &dbv)) { - TCHAR tszFullPath[MAX_PATH]; - PathToAbsoluteT(dbv.ptszVal, tszFullPath); - int cx = item->cx ? item->cx : GetSystemMetrics(big ? SM_CXICON : SM_CXSMICON); - int cy = item->cy ? item->cy : GetSystemMetrics(big ? SM_CYICON : SM_CYSMICON); - source = GetIconSourceItemFromPath(tszFullPath, cx, cy); - db_free(&dbv); - } - - if (source) - hIcon = IconSourceItem_GetIcon(source); - - if (!hIcon) - hIcon = IconItem_GetDefaultIcon(item, big); - - if (!hIcon) - return hIconBlank; - - return hIcon; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib_GetIcon -// lParam: pszIconName -// wParam: PLOADIMAGEPARAM or NULL. -// if wParam == NULL, default is used: -// uType = IMAGE_ICON -// cx/cyDesired = GetSystemMetrics(SM_CX/CYSMICON) -// fuLoad = 0 - -HICON IcoLib_GetIcon(const char* pszIconName, bool big) -{ - if (!pszIconName) - return hIconBlank; - - mir_cslock lck(csIconList); - IcolibItem* item = IcoLib_FindIcon(pszIconName); - return (item) ? IconItem_GetIcon(item, big) : NULL; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib_GetIconHandle -// lParam: pszIconName - -HANDLE IcoLib_GetIconHandle(const char* pszIconName) -{ - if (!pszIconName) - return NULL; - - mir_cslock lck(csIconList); - return IcoLib_FindIcon(pszIconName); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib_GetIconByHandle -// lParam: icolib item handle -// wParam: 0 - -HICON IcoLib_GetIconByHandle(HANDLE hItem, bool big) -{ - if (hItem == NULL) - return NULL; - - mir_cslock lck(csIconList); - IcolibItem* pi = (IcolibItem*)hItem; - if ( iconList.getIndex(pi) != -1) - return IconItem_GetIcon(pi, big); - - return hIconBlank; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib_IsManaged -// lParam: NULL -// wParam: HICON - -HANDLE IcoLib_IsManaged(HICON hIcon) -{ - mir_cslock lck(csIconList); - - bool big; - return IcoLib_FindHIcon(hIcon, big); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib_AddRef -// lParam: NULL -// wParam: HICON - -static INT_PTR IcoLib_AddRef(WPARAM wParam, LPARAM) -{ - mir_cslock lck(csIconList); - - bool big; - IcolibItem *item = IcoLib_FindHIcon((HICON)wParam, big); - - INT_PTR res = 1; - if (item) { - IconSourceItem* source = big && !item->cx ? item->source_big : item->source_small; - if (source->icon_ref_count) { - source->icon_ref_count++; - res = 0; - } - } - - return res; -} - -static int SkinSystemModulesLoaded(WPARAM, LPARAM) -{ - HookEvent(ME_OPT_INITIALISE, SkinOptionsInit); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Module initialization and finalization procedure - -static INT_PTR sttIcoLib_AddNewIcon(WPARAM wParam, LPARAM lParam) -{ - return (INT_PTR)IcoLib_AddNewIcon((int)wParam, (SKINICONDESC*)lParam); -} - -static INT_PTR sttIcoLib_GetIcon(WPARAM wParam, LPARAM lParam) -{ - return (INT_PTR)IcoLib_GetIcon((const char*)lParam, wParam != 0); -} - -static INT_PTR sttIcoLib_GetIconHandle(WPARAM, LPARAM lParam) -{ - return (INT_PTR)IcoLib_GetIconHandle((const char*)lParam); -} - -static INT_PTR sttIcoLib_GetIconByHandle(WPARAM wParam, LPARAM lParam) -{ - return (INT_PTR)IcoLib_GetIconByHandle((HANDLE)lParam, wParam != 0); -} - -static INT_PTR sttIcoLib_ReleaseIcon(WPARAM wParam, LPARAM lParam) -{ - return (INT_PTR)IcoLib_ReleaseIcon((HICON)wParam, (char*)lParam, false); -} - -static INT_PTR sttIcoLib_ReleaseIconBig(WPARAM wParam, LPARAM lParam) -{ - return (INT_PTR)IcoLib_ReleaseIcon((HICON)wParam, (char*)lParam, true); -} - -static INT_PTR sttIcoLib_IsManaged(WPARAM wParam, LPARAM) -{ - return (INT_PTR)IcoLib_IsManaged((HICON)wParam); -} - -int LoadIcoLibModule(void) -{ - bModuleInitialized = TRUE; - - hIconBlank = LoadIconEx(NULL, MAKEINTRESOURCE(IDI_BLANK), 0); - - hIcoLib_AddNewIcon = CreateServiceFunction("Skin2/Icons/AddIcon", sttIcoLib_AddNewIcon); - hIcoLib_RemoveIcon = CreateServiceFunction(MS_SKIN2_REMOVEICON, IcoLib_RemoveIcon); - hIcoLib_GetIcon = CreateServiceFunction(MS_SKIN2_GETICON, sttIcoLib_GetIcon); - hIcoLib_GetIconHandle = CreateServiceFunction(MS_SKIN2_GETICONHANDLE, sttIcoLib_GetIconHandle); - hIcoLib_GetIcon2 = CreateServiceFunction(MS_SKIN2_GETICONBYHANDLE, sttIcoLib_GetIconByHandle); - hIcoLib_IsManaged = CreateServiceFunction(MS_SKIN2_ISMANAGEDICON, sttIcoLib_IsManaged); - hIcoLib_AddRef = CreateServiceFunction(MS_SKIN2_ADDREFICON, IcoLib_AddRef); - hIcoLib_ReleaseIcon = CreateServiceFunction(MS_SKIN2_RELEASEICON, sttIcoLib_ReleaseIcon); - hIcoLib_ReleaseIcon = CreateServiceFunction(MS_SKIN2_RELEASEICONBIG, sttIcoLib_ReleaseIconBig); - - hIcons2ChangedEvent = CreateHookableEvent(ME_SKIN2_ICONSCHANGED); - hIconsChangedEvent = CreateHookableEvent(ME_SKIN_ICONSCHANGED); - - HookEvent(ME_SYSTEM_MODULESLOADED, SkinSystemModulesLoaded); - - return 0; -} - -void UnloadIcoLibModule(void) -{ - int i; - - if (!bModuleInitialized) return; - - DestroyHookableEvent(hIconsChangedEvent); - DestroyHookableEvent(hIcons2ChangedEvent); - - DestroyServiceFunction(hIcoLib_AddNewIcon); - DestroyServiceFunction(hIcoLib_RemoveIcon); - DestroyServiceFunction(hIcoLib_GetIcon); - DestroyServiceFunction(hIcoLib_GetIconHandle); - DestroyServiceFunction(hIcoLib_GetIcon2); - DestroyServiceFunction(hIcoLib_IsManaged); - DestroyServiceFunction(hIcoLib_AddRef); - DestroyServiceFunction(hIcoLib_ReleaseIcon); - - for (i = iconList.getCount()-1; i >= 0; i--) { - IcolibItem* p = iconList[i]; - iconList.remove(i); - IcoLib_FreeIcon(p); - mir_free(p); - } - - for (i = iconSourceList.getCount()-1; i >= 0; i--) { - IconSourceItem* p = iconSourceList[i]; - iconSourceList.remove(i); - IconSourceFile_Release(&p->file); - SafeDestroyIcon(&p->icon); - SAFE_FREE((void**)&p->icon_data); - SAFE_FREE((void**)&p); - } - - for (i = iconSourceFileList.getCount()-1; i >= 0; i--) { - IconSourceFile* p = iconSourceFileList[i]; - iconSourceFileList.remove(i); - SAFE_FREE((void**)&p->file); - SAFE_FREE((void**)&p); - } - - for (i = 0; i < sectionList.getCount(); i++) { - SAFE_FREE((void**)§ionList[i]->name); - mir_free(sectionList[i]); - } - - SafeDestroyIcon(&hIconBlank); - bModuleInitialized = false; -} diff --git a/src/modules/icolib/skin2opts.cpp b/src/modules/icolib/skin2opts.cpp deleted file mode 100644 index c856cd8b30..0000000000 --- a/src/modules/icolib/skin2opts.cpp +++ /dev/null @@ -1,1047 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#include "IcoLib.h" - -struct TreeItem -{ - char *paramName; - DWORD value; -}; - -struct IcoLibOptsData -{ - HWND hwndIndex; -}; - -///////////////////////////////////////////////////////////////////////////////////////// - -static HICON ExtractIconFromPath(const TCHAR *path, int cxIcon, int cyIcon) -{ - TCHAR *comma; - TCHAR file[MAX_PATH], fileFull[MAX_PATH]; - int n; - HICON hIcon; - - if (!path) - return (HICON)NULL; - - mir_tstrncpy(file, path, SIZEOF(file)); - comma = _tcsrchr(file, ','); - if (!comma) - n = 0; - else { - n = _ttoi(comma + 1); - *comma = 0; - } - PathToAbsoluteT(file, fileFull); - hIcon = NULL; - - //SHOULD BE REPLACED WITH GOOD ENOUGH FUNCTION - _ExtractIconEx(fileFull, n, cxIcon, cyIcon, &hIcon, LR_COLOR); - return hIcon; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib_ReleaseIcon -// lParam: pszIconName or NULL -// wParam: HICON or NULL - -int IcoLib_ReleaseIcon(HICON hIcon, char* szIconName, bool big) -{ - mir_cslock lck(csIconList); - - IcolibItem *item = NULL; - if (szIconName) - item = IcoLib_FindIcon(szIconName); - - if (!item && hIcon) // find by HICON - item = IcoLib_FindHIcon(hIcon, big); - - int res = 1; - if (item) { - IconSourceItem* source = big && !item->cx ? item->source_big : item->source_small; - if (source && source->icon_ref_count) { - if (iconEventActive) - source->icon_ref_count--; - else - IconSourceItem_ReleaseIcon(source); - res = 0; - } - } - - return res; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IconItem_GetIcon_Preview - -HICON IconItem_GetIcon_Preview(IcolibItem* item) -{ - HICON hIcon = NULL; - - if (!item->temp_reset) { - HICON hRefIcon = IconItem_GetIcon(item, false); - hIcon = CopyIcon(hRefIcon); - if (item->source_small && item->source_small->icon == hRefIcon) - IconSourceItem_ReleaseIcon(item->source_small); - } - else { - if (item->default_icon) { - HICON hRefIcon = IconSourceItem_GetIcon(item->default_icon); - if (hRefIcon) { - hIcon = CopyIcon(hRefIcon); - if (item->default_icon->icon == hRefIcon) - IconSourceItem_ReleaseIcon(item->default_icon); - } - } - - if (!hIcon && item->default_file) { - IconSourceItem_Release(&item->default_icon); - item->default_icon = GetIconSourceItem(item->default_file, item->default_indx, item->cx, item->cy); - if (item->default_icon) { - HICON hRefIcon = IconSourceItem_GetIcon(item->default_icon); - if (hRefIcon) { - hIcon = CopyIcon(hRefIcon); - if (item->default_icon->icon == hRefIcon) - IconSourceItem_ReleaseIcon(item->default_icon); - } - } - } - - if (!hIcon) - return CopyIcon(hIconBlank); - } - return hIcon; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib GUI service routines - -static void __fastcall MySetCursor(TCHAR* nCursor) -{ - SetCursor(LoadCursor(NULL, nCursor)); -} - -static void LoadSectionIcons(TCHAR *filename, SectionItem* sectionActive) -{ - TCHAR path[MAX_PATH]; - mir_sntprintf(path, SIZEOF(path), _T("%s,"), filename); - size_t suffIndx = mir_tstrlen(path); - - mir_cslock lck(csIconList); - - for (int indx = 0; indx < iconList.getCount(); indx++) { - IcolibItem *item = iconList[indx]; - - if (item->default_file && item->section == sectionActive) { - _itot(item->default_indx, path + suffIndx, 10); - HICON hIcon = ExtractIconFromPath(path, item->cx, item->cy); - if (!hIcon) - continue; - - SAFE_FREE((void**)&item->temp_file); - SafeDestroyIcon(&item->temp_icon); - - item->temp_file = mir_tstrdup(path); - item->temp_icon = hIcon; - item->temp_reset = FALSE; - } - } -} - -void LoadSubIcons(HWND htv, TCHAR *filename, HTREEITEM hItem) -{ - TVITEM tvi; - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - tvi.hItem = hItem; - TreeView_GetItem(htv, &tvi); - - TreeItem *treeItem = (TreeItem *)tvi.lParam; - SectionItem* sectionActive = sectionList[SECTIONPARAM_INDEX(treeItem->value)]; - - tvi.hItem = TreeView_GetChild(htv, tvi.hItem); - while (tvi.hItem) { - LoadSubIcons(htv, filename, tvi.hItem); - tvi.hItem = TreeView_GetNextSibling(htv, tvi.hItem); - } - - if (SECTIONPARAM_FLAGS(treeItem->value) & SECTIONPARAM_HAVEPAGE) - LoadSectionIcons(filename, sectionActive); -} - -static void UndoChanges(int iconIndx, int cmd) -{ - IcolibItem *item = iconList[iconIndx]; - - if (!item->temp_file && !item->temp_icon && item->temp_reset && cmd == ID_CANCELCHANGE) - item->temp_reset = FALSE; - else { - SAFE_FREE((void**)&item->temp_file); - SafeDestroyIcon(&item->temp_icon); - } - - if (cmd == ID_RESET) - item->temp_reset = TRUE; -} - -void UndoSubItemChanges(HWND htv, HTREEITEM hItem, int cmd) -{ - TVITEM tvi = { 0 }; - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - tvi.hItem = hItem; - TreeView_GetItem(htv, &tvi); - - TreeItem *treeItem = (TreeItem *)tvi.lParam; - if (SECTIONPARAM_FLAGS(treeItem->value) & SECTIONPARAM_HAVEPAGE) { - mir_cslock lck(csIconList); - - for (int indx = 0; indx < iconList.getCount(); indx++) - if (iconList[indx]->section == sectionList[SECTIONPARAM_INDEX(treeItem->value)]) - UndoChanges(indx, cmd); - } - - tvi.hItem = TreeView_GetChild(htv, tvi.hItem); - while (tvi.hItem) { - UndoSubItemChanges(htv, tvi.hItem, cmd); - tvi.hItem = TreeView_GetNextSibling(htv, tvi.hItem); - } -} - -static void OpenIconsPage() -{ - CallService(MS_UTILS_OPENURL, OUF_NEWWINDOW, (LPARAM)"http://miranda-ng.org/"); -} - -static int OpenPopupMenu(HWND hwndDlg) -{ - HMENU hMenu, hPopup; - POINT pt; - int cmd; - - GetCursorPos(&pt); - hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_ICOLIB_CONTEXT)); - hPopup = GetSubMenu(hMenu, 0); - TranslateMenu(hPopup); - cmd = TrackPopupMenu(hPopup, TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL); - DestroyMenu(hMenu); - return cmd; -} - -static TCHAR* OpenFileDlg(HWND hParent, const TCHAR* szFile, BOOL bAll) -{ - OPENFILENAME ofn = { 0 }; - TCHAR filter[512], *pfilter, file[MAX_PATH * 2]; - - ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; - ofn.hwndOwner = hParent; - - mir_tstrcpy(filter, TranslateT("Icon sets")); - if (bAll) - mir_tstrcat(filter, _T(" (*.dll;*.icl;*.exe;*.ico)")); - else - mir_tstrcat(filter, _T(" (*.dll)")); - - pfilter = filter + mir_tstrlen(filter) + 1; - if (bAll) - mir_tstrcpy(pfilter, _T("*.DLL;*.ICL;*.EXE;*.ICO")); - else - mir_tstrcpy(pfilter, _T("*.DLL")); - - pfilter += mir_tstrlen(pfilter) + 1; - mir_tstrcpy(pfilter, TranslateT("All files")); - mir_tstrcat(pfilter, _T(" (*)")); - pfilter += mir_tstrlen(pfilter) + 1; - mir_tstrcpy(pfilter, _T("*")); - pfilter += mir_tstrlen(pfilter) + 1; - *pfilter = '\0'; - - ofn.lpstrFilter = filter; - ofn.lpstrDefExt = _T("dll"); - mir_tstrncpy(file, szFile, SIZEOF(file)); - ofn.lpstrFile = file; - ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_DONTADDTORECENT; - ofn.nMaxFile = MAX_PATH * 2; - - if (!GetOpenFileName(&ofn)) - return NULL; - - return mir_tstrdup(file); -} - -// -// User interface -// - -#define DM_REBUILDICONSPREVIEW (WM_USER+10) -#define DM_CHANGEICON (WM_USER+11) -#define DM_CHANGESPECIFICICON (WM_USER+12) -#define DM_UPDATEICONSPREVIEW (WM_USER+13) -#define DM_REBUILD_CTREE (WM_USER+14) - -INT_PTR CALLBACK DlgProcIconImport(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -void DoOptionsChanged(HWND hwndDlg) -{ - SendMessage(hwndDlg, DM_UPDATEICONSPREVIEW, 0, 0); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); -} - -void DoIconsChanged(HWND hwndDlg) -{ - SendMessage(hwndDlg, DM_UPDATEICONSPREVIEW, 0, 0); - - iconEventActive = 1; // Disable icon destroying - performance boost - NotifyEventHooks(hIconsChangedEvent, 0, 0); - NotifyEventHooks(hIcons2ChangedEvent, 0, 0); - iconEventActive = 0; - - mir_cslock lck(csIconList); // Destroy unused icons - for (int indx = 0; indx < iconList.getCount(); indx++) { - IcolibItem *item = iconList[indx]; - if (item->source_small && !item->source_small->icon_ref_count) { - item->source_small->icon_ref_count++; - IconSourceItem_ReleaseIcon(item->source_small); - } - if (item->source_big && !item->source_big->icon_ref_count) { - item->source_big->icon_ref_count++; - IconSourceItem_ReleaseIcon(item->source_big); - } - } -} - -static HTREEITEM FindNamedTreeItemAt(HWND hwndTree, HTREEITEM hItem, const TCHAR *name) -{ - TVITEM tvi = { 0 }; - TCHAR str[MAX_PATH]; - - if (hItem) - tvi.hItem = TreeView_GetChild(hwndTree, hItem); - else - tvi.hItem = TreeView_GetRoot(hwndTree); - - if (!name) - return tvi.hItem; - - tvi.mask = TVIF_TEXT; - tvi.pszText = str; - tvi.cchTextMax = SIZEOF(str); - - while (tvi.hItem) { - TreeView_GetItem(hwndTree, &tvi); - - if (!mir_tstrcmp(tvi.pszText, name)) - return tvi.hItem; - - tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); - } - return NULL; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// icon import dialog's window procedure - -static int IconDlg_Resize(HWND, LPARAM, UTILRESIZECONTROL *urc) -{ - switch (urc->wId) { - case IDC_ICONSET: - return RD_ANCHORX_WIDTH | RD_ANCHORY_TOP; - - case IDC_BROWSE: - return RD_ANCHORX_RIGHT | RD_ANCHORY_TOP; - - case IDC_PREVIEW: - return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; - - case IDC_GETMORE: - return RD_ANCHORX_CENTRE | RD_ANCHORY_BOTTOM; - } - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; // default -} - -INT_PTR CALLBACK DlgProcIconImport(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static HWND hwndParent, hwndDragOver; - static int dragging; - static int dragItem, dropHiLite; - static HWND hPreview = NULL; - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - hwndParent = (HWND)lParam; - hPreview = GetDlgItem(hwndDlg, IDC_PREVIEW); - dragging = dragItem = 0; - ListView_SetImageList(hPreview, ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 0, 100), LVSIL_NORMAL); - ListView_SetIconSpacing(hPreview, 56, 67); - { - RECT rcThis, rcParent; - int cxScreen = GetSystemMetrics(SM_CXSCREEN); - - GetWindowRect(hwndDlg, &rcThis); - GetWindowRect(hwndParent, &rcParent); - OffsetRect(&rcThis, rcParent.right - rcThis.left, 0); - OffsetRect(&rcThis, 0, rcParent.top - rcThis.top); - GetWindowRect(GetParent(hwndParent), &rcParent); - if (rcThis.right > cxScreen) { - OffsetRect(&rcParent, cxScreen - rcThis.right, 0); - OffsetRect(&rcThis, cxScreen - rcThis.right, 0); - MoveWindow(GetParent(hwndParent), rcParent.left, rcParent.top, rcParent.right - rcParent.left, rcParent.bottom - rcParent.top, TRUE); - } - MoveWindow(hwndDlg, rcThis.left, rcThis.top, rcThis.right - rcThis.left, rcThis.bottom - rcThis.top, FALSE); - GetClientRect(hwndDlg, &rcThis); - SendMessage(hwndDlg, WM_SIZE, 0, MAKELPARAM(rcThis.right - rcThis.left, rcThis.bottom - rcThis.top)); - } - - SHAutoComplete(GetDlgItem(hwndDlg, IDC_ICONSET), 1); - - SetDlgItemText(hwndDlg, IDC_ICONSET, _T("icons.dll")); - return TRUE; - - case DM_REBUILDICONSPREVIEW: - { - MySetCursor(IDC_WAIT); - ListView_DeleteAllItems(hPreview); - HIMAGELIST hIml = ListView_GetImageList(hPreview, LVSIL_NORMAL); - ImageList_RemoveAll(hIml); - - TCHAR filename[MAX_PATH], caption[64]; - GetDlgItemText(hwndDlg, IDC_ICONSET, filename, SIZEOF(filename)); - { - RECT rcPreview, rcGroup; - - GetWindowRect(hPreview, &rcPreview); - GetWindowRect(GetDlgItem(hwndDlg, IDC_IMPORTMULTI), &rcGroup); - //SetWindowPos(hPreview, 0, 0, 0, rcPreview.right-rcPreview.left, rcGroup.bottom-rcPreview.top, SWP_NOZORDER|SWP_NOMOVE); - } - - if (_taccess(filename, 0) != 0) { - MySetCursor(IDC_ARROW); - break; - } - - LVITEM lvi; - lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; - lvi.iSubItem = 0; - lvi.iItem = 0; - int count = (int)_ExtractIconEx(filename, -1, 16, 16, NULL, LR_DEFAULTCOLOR); - for (int i = 0; i < count; lvi.iItem++, i++) { - mir_sntprintf(caption, SIZEOF(caption), _T("%d"), i + 1); - lvi.pszText = caption; - - HICON hIcon; - _ExtractIconEx(filename, i, 16, 16, &hIcon, LR_DEFAULTCOLOR); - lvi.iImage = ImageList_AddIcon(hIml, hIcon); - DestroyIcon(hIcon); - lvi.lParam = i; - ListView_InsertItem(hPreview, &lvi); - } - MySetCursor(IDC_ARROW); - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_BROWSE: - { - TCHAR str[MAX_PATH], *file; - GetDlgItemText(hwndDlg, IDC_ICONSET, str, SIZEOF(str)); - if (!(file = OpenFileDlg(GetParent(hwndDlg), str, TRUE))) - break; - SetDlgItemText(hwndDlg, IDC_ICONSET, file); - SAFE_FREE((void**)&file); - } - break; - - case IDC_GETMORE: - OpenIconsPage(); - break; - - case IDC_ICONSET: - if (HIWORD(wParam) == EN_CHANGE) - SendMessage(hwndDlg, DM_REBUILDICONSPREVIEW, 0, 0); - break; - } - break; - - case WM_MOUSEMOVE: - if (dragging) { - LVHITTESTINFO lvhti; - int onItem = 0; - HWND hwndOver; - RECT rc; - POINT ptDrag; - HWND hPPreview = GetDlgItem(hwndParent, IDC_PREVIEW); - - lvhti.pt.x = (short)LOWORD(lParam); lvhti.pt.y = (short)HIWORD(lParam); - ClientToScreen(hwndDlg, &lvhti.pt); - hwndOver = WindowFromPoint(lvhti.pt); - GetWindowRect(hwndOver, &rc); - ptDrag.x = lvhti.pt.x - rc.left; ptDrag.y = lvhti.pt.y - rc.top; - if (hwndOver != hwndDragOver) { - ImageList_DragLeave(hwndDragOver); - hwndDragOver = hwndOver; - ImageList_DragEnter(hwndDragOver, ptDrag.x, ptDrag.y); - } - - ImageList_DragMove(ptDrag.x, ptDrag.y); - if (hwndOver == hPPreview) { - ScreenToClient(hPPreview, &lvhti.pt); - - if (ListView_HitTest(hPPreview, &lvhti) != -1) { - if (lvhti.iItem != dropHiLite) { - ImageList_DragLeave(hwndDragOver); - if (dropHiLite != -1) - ListView_SetItemState(hPPreview, dropHiLite, 0, LVIS_DROPHILITED); - dropHiLite = lvhti.iItem; - ListView_SetItemState(hPPreview, dropHiLite, LVIS_DROPHILITED, LVIS_DROPHILITED); - UpdateWindow(hPPreview); - ImageList_DragEnter(hwndDragOver, ptDrag.x, ptDrag.y); - } - onItem = 1; - } - } - - if (!onItem && dropHiLite != -1) { - ImageList_DragLeave(hwndDragOver); - ListView_SetItemState(hPPreview, dropHiLite, 0, LVIS_DROPHILITED); - UpdateWindow(hPPreview); - ImageList_DragEnter(hwndDragOver, ptDrag.x, ptDrag.y); - dropHiLite = -1; - } - MySetCursor(onItem ? IDC_ARROW : IDC_NO); - } - break; - - case WM_LBUTTONUP: - if (dragging) { - ReleaseCapture(); - ImageList_EndDrag(); - dragging = 0; - if (dropHiLite != -1) { - TCHAR path[MAX_PATH], fullPath[MAX_PATH], filename[MAX_PATH]; - LVITEM lvi; - - GetDlgItemText(hwndDlg, IDC_ICONSET, fullPath, SIZEOF(fullPath)); - PathToRelativeT(fullPath, filename); - lvi.mask = LVIF_PARAM; - lvi.iItem = dragItem; lvi.iSubItem = 0; - ListView_GetItem(hPreview, &lvi); - mir_sntprintf(path, SIZEOF(path), _T("%s,%d"), filename, (int)lvi.lParam); - SendMessage(hwndParent, DM_CHANGEICON, dropHiLite, (LPARAM)path); - ListView_SetItemState(GetDlgItem(hwndParent, IDC_PREVIEW), dropHiLite, 0, LVIS_DROPHILITED); - } - } - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->idFrom) { - case IDC_PREVIEW: - switch (((LPNMHDR)lParam)->code) { - case LVN_BEGINDRAG: - SetCapture(hwndDlg); - dragging = 1; - dragItem = ((LPNMLISTVIEW)lParam)->iItem; - dropHiLite = -1; - ImageList_BeginDrag(ListView_GetImageList(hPreview, LVSIL_NORMAL), dragItem, GetSystemMetrics(SM_CXICON) / 2, GetSystemMetrics(SM_CYICON) / 2); - { - POINT pt; - RECT rc; - - GetCursorPos(&pt); - GetWindowRect(hwndDlg, &rc); - ImageList_DragEnter(hwndDlg, pt.x - rc.left, pt.y - rc.top); - hwndDragOver = hwndDlg; - } - break; - } - break; - } - break; - - case WM_SIZE: // make the dlg resizeable - if (!IsIconic(hwndDlg)) { - UTILRESIZEDIALOG urd = { 0 }; - urd.cbSize = sizeof(urd); - urd.hInstance = hInst; - urd.hwndDlg = hwndDlg; - urd.lParam = 0; // user-defined - urd.lpTemplate = MAKEINTRESOURCEA(IDD_ICOLIB_IMPORT); - urd.pfnResizer = IconDlg_Resize; - CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); - } - break; - - case WM_CLOSE: - DestroyWindow(hwndDlg); - EnableWindow(GetDlgItem(hwndParent, IDC_IMPORT), TRUE); - break; - - } - - return FALSE; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib options window procedure - -static int CALLBACK DoSortIconsFunc(LPARAM lParam1, LPARAM lParam2, LPARAM) -{ - return mir_tstrcmpi(iconList[lParam1]->getDescr(), iconList[lParam2]->getDescr()); -} - -static int CALLBACK DoSortIconsFuncByOrder(LPARAM lParam1, LPARAM lParam2, LPARAM) -{ - return iconList[lParam1]->orderID - iconList[lParam2]->orderID; -} - -static void SaveCollapseState(HWND hwndTree) -{ - HTREEITEM hti = TreeView_GetRoot(hwndTree); - while (hti != NULL) { - TVITEM tvi; - tvi.mask = TVIF_STATE | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM; - tvi.hItem = hti; - tvi.stateMask = (DWORD)-1; - TreeView_GetItem(hwndTree, &tvi); - - if (tvi.cChildren > 0) { - TreeItem *treeItem = (TreeItem *)tvi.lParam; - if (tvi.state & TVIS_EXPANDED) - db_set_b(NULL, "SkinIconsUI", treeItem->paramName, TVIS_EXPANDED); - else - db_set_b(NULL, "SkinIconsUI", treeItem->paramName, 0); - } - - HTREEITEM ht = TreeView_GetChild(hwndTree, hti); - if (ht == NULL) { - ht = TreeView_GetNextSibling(hwndTree, hti); - while (ht == NULL) { - hti = TreeView_GetParent(hwndTree, hti); - if (hti == NULL) break; - ht = TreeView_GetNextSibling(hwndTree, hti); - } - } - - hti = ht; - } -} - -INT_PTR CALLBACK DlgProcIcoLibOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - struct IcoLibOptsData *dat; - static HTREEITEM prevItem = 0; - static HWND hPreview = NULL; - - dat = (struct IcoLibOptsData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - hPreview = GetDlgItem(hwndDlg, IDC_PREVIEW); - dat = (struct IcoLibOptsData*)mir_alloc(sizeof(struct IcoLibOptsData)); - dat->hwndIndex = NULL; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); - // - // Reset temporary data & upload sections list - // - { - mir_cslock lck(csIconList); - - for (int indx = 0; indx < iconList.getCount(); indx++) { - iconList[indx]->temp_file = NULL; - iconList[indx]->temp_icon = NULL; - iconList[indx]->temp_reset = FALSE; - } - bNeedRebuild = FALSE; - } - - // - // Setup preview listview - // - ListView_SetUnicodeFormat(hPreview, TRUE); - ListView_SetExtendedListViewStyleEx(hPreview, LVS_EX_INFOTIP, LVS_EX_INFOTIP); - ListView_SetImageList(hPreview, ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 0, 30), LVSIL_NORMAL); - ListView_SetIconSpacing(hPreview, 56, 67); - - SendMessage(hwndDlg, DM_REBUILD_CTREE, 0, 0); - return TRUE; - - case DM_REBUILD_CTREE: - { - HWND hwndTree = GetDlgItem(hwndDlg, IDC_CATEGORYLIST); - int indx; - TCHAR itemName[1024]; - HTREEITEM hSection; - - if (!hwndTree) break; - - TreeView_SelectItem(hwndTree, NULL); - TreeView_DeleteAllItems(hwndTree); - - for (indx = 0; indx < sectionList.getCount(); indx++) { - TCHAR* sectionName; - int sectionLevel = 0; - - hSection = NULL; - mir_tstrcpy(itemName, sectionList[indx]->name); - sectionName = itemName; - - while (sectionName) { - // allow multi-level tree - TCHAR* pItemName = sectionName; - HTREEITEM hItem; - - if (sectionName = _tcschr(sectionName, '/')) { - // one level deeper - *sectionName = 0; - } - - pItemName = TranslateTS(pItemName); - hItem = FindNamedTreeItemAt(hwndTree, hSection, pItemName); - if (!sectionName || !hItem) { - if (!hItem) { - TVINSERTSTRUCT tvis = { 0 }; - TreeItem *treeItem = (TreeItem *)mir_alloc(sizeof(TreeItem)); - treeItem->value = SECTIONPARAM_MAKE(indx, sectionLevel, sectionName ? 0 : SECTIONPARAM_HAVEPAGE); - treeItem->paramName = mir_t2a(itemName); - - tvis.hParent = hSection; - tvis.hInsertAfter = TVI_SORT; - tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_STATE; - tvis.item.pszText = pItemName; - tvis.item.lParam = (LPARAM)treeItem; - - tvis.item.state = tvis.item.stateMask = db_get_b(NULL, "SkinIconsUI", treeItem->paramName, TVIS_EXPANDED); - hItem = TreeView_InsertItem(hwndTree, &tvis); - } - else { - TVITEM tvi = { 0 }; - tvi.hItem = hItem; - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - TreeView_GetItem(hwndTree, &tvi); - TreeItem *treeItem = (TreeItem *)tvi.lParam; - treeItem->value = SECTIONPARAM_MAKE(indx, sectionLevel, SECTIONPARAM_HAVEPAGE); - } - } - - if (sectionName) { - *sectionName = '/'; - sectionName++; - } - sectionLevel++; - - hSection = hItem; - } - } - - ShowWindow(hwndTree, SW_SHOW); - - TreeView_SelectItem(hwndTree, FindNamedTreeItemAt(hwndTree, 0, NULL)); - } - break; - - // Rebuild preview to new section - case DM_REBUILDICONSPREVIEW: - { - SectionItem* sectionActive = (SectionItem*)lParam; - EnableWindow(hPreview, sectionActive != NULL); - - ListView_DeleteAllItems(hPreview); - HIMAGELIST hIml = ListView_GetImageList(hPreview, LVSIL_NORMAL); - ImageList_RemoveAll(hIml); - - if (sectionActive == NULL) - break; - - LVITEM lvi = { 0 }; - lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; - { - mir_cslock lck(csIconList); - - for (int indx = 0; indx < iconList.getCount(); indx++) { - IcolibItem *item = iconList[indx]; - if (item->section == sectionActive) { - lvi.pszText = item->getDescr(); - HICON hIcon = item->temp_icon; - if (!hIcon) - hIcon = IconItem_GetIcon_Preview(item); - lvi.iImage = ImageList_AddIcon(hIml, hIcon); - lvi.lParam = indx; - ListView_InsertItem(hPreview, &lvi); - if (hIcon != item->temp_icon) - SafeDestroyIcon(&hIcon); - } - } - } - - if (sectionActive->flags & SIDF_SORTED) - ListView_SortItems(hPreview, DoSortIconsFunc, 0); - else - ListView_SortItems(hPreview, DoSortIconsFuncByOrder, 0); - } - break; - - // Refresh preview to new section - case DM_UPDATEICONSPREVIEW: - { - LVITEM lvi = { 0 }; - HICON hIcon; - int indx, count; - HIMAGELIST hIml = ListView_GetImageList(hPreview, LVSIL_NORMAL); - - lvi.mask = LVIF_IMAGE | LVIF_PARAM; - count = ListView_GetItemCount(hPreview); - - for (indx = 0; indx < count; indx++) { - lvi.iItem = indx; - ListView_GetItem(hPreview, &lvi); - { - mir_cslock lck(csIconList); - hIcon = iconList[lvi.lParam]->temp_icon; - if (!hIcon) - hIcon = IconItem_GetIcon_Preview(iconList[lvi.lParam]); - } - - if (hIcon) - ImageList_ReplaceIcon(hIml, lvi.iImage, hIcon); - if (hIcon != iconList[lvi.lParam]->temp_icon) SafeDestroyIcon(&hIcon); - } - ListView_RedrawItems(hPreview, 0, count); - } - break; - - // Temporary change icon - only inside options dialog - case DM_CHANGEICON: - { - LVITEM lvi = { 0 }; - lvi.mask = LVIF_PARAM; - lvi.iItem = wParam; - ListView_GetItem(hPreview, &lvi); - { - mir_cslock lck(csIconList); - IcolibItem *item = iconList[lvi.lParam]; - - SAFE_FREE((void**)&item->temp_file); - SafeDestroyIcon(&item->temp_icon); - - TCHAR *path = (TCHAR*)lParam; - item->temp_file = mir_tstrdup(path); - item->temp_icon = (HICON)ExtractIconFromPath(path, item->cx, item->cy); - item->temp_reset = FALSE; - } - DoOptionsChanged(hwndDlg); - } - break; - - case WM_COMMAND: - if (LOWORD(wParam) == IDC_IMPORT) { - dat->hwndIndex = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ICOLIB_IMPORT), GetParent(hwndDlg), DlgProcIconImport, (LPARAM)hwndDlg); - EnableWindow((HWND)lParam, FALSE); - } - else if (LOWORD(wParam) == IDC_GETMORE) { - OpenIconsPage(); - break; - } - else if (LOWORD(wParam) == IDC_LOADICONS) { - TCHAR filetmp[1] = { 0 }; - TCHAR *file; - - if (file = OpenFileDlg(hwndDlg, filetmp, FALSE)) { - HWND htv = GetDlgItem(hwndDlg, IDC_CATEGORYLIST); - TCHAR filename[MAX_PATH]; - - PathToRelativeT(file, filename); - SAFE_FREE((void**)&file); - - MySetCursor(IDC_WAIT); - LoadSubIcons(htv, filename, TreeView_GetSelection(htv)); - MySetCursor(IDC_ARROW); - - DoOptionsChanged(hwndDlg); - } - } - break; - - case WM_CONTEXTMENU: - if ((HWND)wParam == hPreview) { - UINT count = ListView_GetSelectedCount(hPreview); - - if (count > 0) { - int cmd = OpenPopupMenu(hwndDlg); - switch (cmd) { - case ID_CANCELCHANGE: - case ID_RESET: - { - LVITEM lvi = { 0 }; - int itemIndx = -1; - - while ((itemIndx = ListView_GetNextItem(hPreview, itemIndx, LVNI_SELECTED)) != -1) { - lvi.mask = LVIF_PARAM; - lvi.iItem = itemIndx; //lvhti.iItem; - ListView_GetItem(hPreview, &lvi); - - UndoChanges(lvi.lParam, cmd); - } - - DoOptionsChanged(hwndDlg); - break; - } - } - } - } - else { - HWND htv = GetDlgItem(hwndDlg, IDC_CATEGORYLIST); - if ((HWND)wParam == htv) { - int cmd = OpenPopupMenu(hwndDlg); - - switch (cmd) { - case ID_CANCELCHANGE: - case ID_RESET: - UndoSubItemChanges(htv, TreeView_GetSelection(htv), cmd); - DoOptionsChanged(hwndDlg); - break; - } - } - } - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - { - mir_cslock lck(csIconList); - - for (int indx = 0; indx < iconList.getCount(); indx++) { - IcolibItem *item = iconList[indx]; - if (item->temp_reset) { - db_unset(NULL, "SkinIcons", item->name); - if (item->source_small != item->default_icon) { - IconSourceItem_Release(&item->source_small); - } - } - else if (item->temp_file) { - db_set_ts(NULL, "SkinIcons", item->name, item->temp_file); - IconSourceItem_Release(&item->source_small); - SafeDestroyIcon(&item->temp_icon); - } - } - } - - DoIconsChanged(hwndDlg); - return TRUE; - } - break; - - case IDC_PREVIEW: - if (((LPNMHDR)lParam)->code == LVN_GETINFOTIP) { - IcolibItem *item; - NMLVGETINFOTIP *pInfoTip = (NMLVGETINFOTIP *)lParam; - LVITEM lvi; - lvi.mask = LVIF_PARAM; - lvi.iItem = pInfoTip->iItem; - ListView_GetItem(pInfoTip->hdr.hwndFrom, &lvi); - - if (lvi.lParam < iconList.getCount()) { - item = iconList[lvi.lParam]; - if (item->temp_file) - _tcsncpy_s(pInfoTip->pszText, pInfoTip->cchTextMax, item->temp_file, _TRUNCATE); - else if (item->default_file) - mir_sntprintf(pInfoTip->pszText, pInfoTip->cchTextMax, _T("%s, %d"), item->default_file, item->default_indx); - } - } - if (bNeedRebuild) { - bNeedRebuild = FALSE; - SendMessage(hwndDlg, DM_REBUILD_CTREE, 0, 0); - } - break; - - case IDC_CATEGORYLIST: - switch (((NMHDR*)lParam)->code) { - case TVN_SELCHANGED: - { - NMTREEVIEW *pnmtv = (NMTREEVIEW*)lParam; - TVITEM tvi = pnmtv->itemNew; - TreeItem *treeItem = (TreeItem *)tvi.lParam; - if (treeItem) - SendMessage(hwndDlg, DM_REBUILDICONSPREVIEW, 0, (LPARAM)( - (SECTIONPARAM_FLAGS(treeItem->value)&SECTIONPARAM_HAVEPAGE) ? - sectionList[SECTIONPARAM_INDEX(treeItem->value)] : NULL)); - } - break; - - case TVN_DELETEITEM: - TreeItem *treeItem = (TreeItem *)(((LPNMTREEVIEW)lParam)->itemOld.lParam); - if (treeItem) { - mir_free(treeItem->paramName); - mir_free(treeItem); - } - break; - } - - if (bNeedRebuild) { - { - mir_cslock lck(csIconList); - bNeedRebuild = FALSE; - } - SendMessage(hwndDlg, DM_REBUILD_CTREE, 0, 0); - } - } - break; - - case WM_DESTROY: - SaveCollapseState(GetDlgItem(hwndDlg, IDC_CATEGORYLIST)); - DestroyWindow(dat->hwndIndex); - { - mir_cslock lck(csIconList); - for (int indx = 0; indx < iconList.getCount(); indx++) { - IcolibItem *item = iconList[indx]; - - SAFE_FREE((void**)&item->temp_file); - SafeDestroyIcon(&item->temp_icon); - } - } - - SAFE_FREE((void**)&dat); - break; - } - - return FALSE; -} - -int SkinOptionsInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.hInstance = hInst; - odp.flags = ODPF_BOLDGROUPS; - odp.position = -180000000; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICOLIB); - odp.pszTitle = LPGEN("Icons"); - odp.pfnDlgProc = DlgProcIcoLibOpts; - Options_AddPage(wParam, &odp); - return 0; -} diff --git a/src/modules/ignore/ignore.cpp b/src/modules/ignore/ignore.cpp deleted file mode 100644 index 9d984a5a5c..0000000000 --- a/src/modules/ignore/ignore.cpp +++ /dev/null @@ -1,441 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#define IGNOREEVENT_MAX 7 - -static const DWORD ignoreIdToPf1[IGNOREEVENT_MAX] = {PF1_IMRECV, PF1_URLRECV, PF1_FILERECV, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; -static const DWORD ignoreIdToPf4[IGNOREEVENT_MAX] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, PF4_SUPPORTTYPING}; - -static DWORD GetMask(MCONTACT hContact) -{ - DWORD mask = db_get_dw(hContact, "Ignore", "Mask1", (DWORD)(-1)); - if (mask == (DWORD)(-1)) { - if (hContact == NULL) mask = 0; - else { - if (db_get_b(hContact, "CList", "Hidden", 0) || db_get_b(hContact, "CList", "NotOnList", 0)) - mask = db_get_dw(NULL, "Ignore", "Mask1", 0); - else - mask = db_get_dw(NULL, "Ignore", "Default1", 0); - } - } - return mask; -} - -static void SetListGroupIcons(HWND hwndList, HANDLE hFirstItem, HANDLE hParentItem, int *groupChildCount) -{ - int iconOn[IGNOREEVENT_MAX] = {1, 1, 1, 1, 1, 1, 1}; - int childCount[IGNOREEVENT_MAX] = {0, 0, 0, 0, 0, 0, 0}, i; - int iImage; - HANDLE hItem, hChildItem; - - int typeOfFirst = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hFirstItem, 0); - //check groups - if (typeOfFirst == CLCIT_GROUP) hItem = hFirstItem; - else hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hFirstItem); - while (hItem) { - hChildItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); - if (hChildItem) SetListGroupIcons(hwndList, hChildItem, hItem, childCount); - for (i=0; i < SIZEOF(iconOn); i++) - if (iconOn[i] && SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, i) == 0) iconOn[i] = 0; - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hItem); - } - //check contacts - if (typeOfFirst == CLCIT_CONTACT) hItem = hFirstItem; - else hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hFirstItem); - while (hItem) { - for (i=0; i < SIZEOF(iconOn); i++) { - iImage = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, i); - if (iconOn[i] && iImage == 0) iconOn[i] = 0; - if (iImage != EMPTY_EXTRA_ICON) - childCount[i]++; - } - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hItem); - } - //set icons - for (i=0; i < SIZEOF(iconOn); i++) { - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hParentItem, MAKELPARAM(i, childCount[i]?(iconOn[i]?i+3:0) : EMPTY_EXTRA_ICON)); - if (groupChildCount) groupChildCount[i]+=childCount[i]; - } - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hParentItem, MAKELPARAM(IGNOREEVENT_MAX, 1)); - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hParentItem, MAKELPARAM(IGNOREEVENT_MAX+1, 2)); -} - -static void SetAllChildIcons(HWND hwndList, HANDLE hFirstItem, int iColumn, int iImage) -{ - HANDLE hItem; - - int typeOfFirst = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hFirstItem, 0); - //check groups - if (typeOfFirst == CLCIT_GROUP) hItem = hFirstItem; - else hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hFirstItem); - while (hItem) { - HANDLE hChildItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); - if (hChildItem) - SetAllChildIcons(hwndList, hChildItem, iColumn, iImage); - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hItem); - } - //check contacts - if (typeOfFirst == CLCIT_CONTACT) hItem = hFirstItem; - else hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hFirstItem); - while (hItem) { - int iOldIcon = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, iColumn); - if (iOldIcon != EMPTY_EXTRA_ICON && iOldIcon != iImage) - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hItem); - } -} - -static void ResetListOptions(HWND hwndList) -{ - SendMessage(hwndList, CLM_SETHIDEEMPTYGROUPS, 1, 0); -} - -static void SetIconsForColumn(HWND hwndList, HANDLE hItem, HANDLE hItemAll, int iColumn, int iImage) -{ - switch ( SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hItem, 0)) { - case CLCIT_CONTACT: - { - int oldiImage = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, iColumn); - if (oldiImage != EMPTY_EXTRA_ICON && oldiImage != iImage) - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); - } - break; - case CLCIT_INFO: - if (hItem == hItemAll) - SetAllChildIcons(hwndList, hItem, iColumn, iImage); - else - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); //hItemUnknown - break; - - case CLCIT_GROUP: - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); - if (hItem) - SetAllChildIcons(hwndList, hItem, iColumn, iImage); - } -} - -static void InitialiseItem(HWND hwndList, MCONTACT hContact, HANDLE hItem, DWORD proto1Caps, DWORD proto4Caps) -{ - DWORD mask = GetMask(hContact); - for (int i=0; i < IGNOREEVENT_MAX; i++) - if ((ignoreIdToPf1[i] == 0xFFFFFFFF && ignoreIdToPf4[i] == 0xFFFFFFFF) || (proto1Caps&ignoreIdToPf1[i] || proto4Caps&ignoreIdToPf4[i])) - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(i, mask&(1<idFrom) { - case IDC_LIST: - switch (((LPNMHDR)lParam)->code) { - case CLN_NEWCONTACT: - case CLN_LISTREBUILT: - SetAllContactIcons( GetDlgItem(hwndDlg, IDC_LIST)); - //fall through - case CLN_CONTACTMOVED: - SetListGroupIcons( GetDlgItem(hwndDlg, IDC_LIST), (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll, NULL); - break; - case CLN_OPTIONSCHANGED: - ResetListOptions(GetDlgItem(hwndDlg, IDC_LIST)); - break; - case CLN_CHECKCHANGED: - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case NM_CLICK: - { - NMCLISTCONTROL *nm = (NMCLISTCONTROL*)lParam; - if (nm->iColumn == -1) - break; - - DWORD hitFlags; - HANDLE hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_HITTEST, (WPARAM)&hitFlags, MAKELPARAM(nm->pt.x, nm->pt.y)); - if (hItem == NULL || !(hitFlags & CLCHT_ONITEMEXTRA)) - break; - - if (nm->iColumn == IGNOREEVENT_MAX) { // ignore all - for (int iImage = 0;iImageiColumn == IGNOREEVENT_MAX+1) { // ignore none - for (int iImage = 0;iImageiColumn, 0)); - if (iImage == 0) - iImage = nm->iColumn+3; - else if (iImage != EMPTY_EXTRA_ICON) - iImage = 0; - SetIconsForColumn( GetDlgItem(hwndDlg, IDC_LIST), hItem, hItemAll, nm->iColumn, iImage); - } - SetListGroupIcons( GetDlgItem(hwndDlg, IDC_LIST), (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll, NULL); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - break; - - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - HANDLE hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_FINDCONTACT, hContact, 0); - if (hItem) SaveItemMask( GetDlgItem(hwndDlg, IDC_LIST), hContact, hItem, "Mask1"); - if (SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) - db_unset(hContact, "CList", "Hidden"); - else - db_set_b(hContact, "CList", "Hidden", 1); - } - - SaveItemMask( GetDlgItem(hwndDlg, IDC_LIST), NULL, hItemAll, "Default1"); - SaveItemMask( GetDlgItem(hwndDlg, IDC_LIST), NULL, hItemUnknown, "Mask1"); - return TRUE; - } - } - break; - - case WM_DESTROY: - for (int i=0; i < SIZEOF(hIcons); i++) - DestroyIcon(hIcons[i]); - HIMAGELIST hIml = (HIMAGELIST)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETEXTRAIMAGELIST, 0, 0); - ImageList_Destroy(hIml); - break; - } - return FALSE; -} - -static int IgnoreOptInitialise(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.position = 900000000; - odp.hInstance = hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_IGNORE); - odp.pszTitle = LPGEN("Ignore"); - odp.pszGroup = LPGEN("Contacts"); - odp.pfnDlgProc = DlgProcIgnoreOpts; - odp.flags = ODPF_BOLDGROUPS; - Options_AddPage(wParam, &odp); - return 0; -} - -static INT_PTR IsIgnored(WPARAM wParam, LPARAM lParam) -{ - DWORD mask = GetMask(wParam); - if (lParam < 1 || lParam > IGNOREEVENT_MAX) - return 1; - return (mask >> (lParam-1))&1; -} - -static INT_PTR Ignore(WPARAM wParam, LPARAM lParam) -{ - DWORD mask = GetMask(wParam); - if ((lParam < 1 || lParam > IGNOREEVENT_MAX) && lParam != IGNOREEVENT_ALL) - return 1; - if (lParam == IGNOREEVENT_ALL) - mask = (1 << IGNOREEVENT_MAX)-1; - else - mask |= 1 << (lParam-1); - db_set_dw(wParam, "Ignore", "Mask1", mask); - return 0; -} - -static INT_PTR Unignore(WPARAM wParam, LPARAM lParam) -{ - DWORD mask = GetMask(wParam); - if ((lParam < 1 || lParam > IGNOREEVENT_MAX) && lParam != IGNOREEVENT_ALL) - return 1; - - if (lParam == IGNOREEVENT_ALL) - mask = 0; - else - mask &= ~(1 << (lParam-1)); - db_set_dw(wParam, "Ignore", "Mask1", mask); - return 0; -} - -static INT_PTR IgnoreRecvMessage(WPARAM wParam, LPARAM lParam) -{ - if (IsIgnored((WPARAM)((CCSDATA*)lParam)->hContact, IGNOREEVENT_MESSAGE)) - return 1; - return CallService(MS_PROTO_CHAINRECV, wParam, lParam); -} - -static INT_PTR IgnoreRecvUrl(WPARAM wParam, LPARAM lParam) -{ - if ( IsIgnored((WPARAM)((CCSDATA*)lParam)->hContact, IGNOREEVENT_URL)) - return 1; - return CallService(MS_PROTO_CHAINRECV, wParam, lParam); -} - -static INT_PTR IgnoreRecvFile(WPARAM wParam, LPARAM lParam) -{ - if ( IsIgnored((WPARAM)((CCSDATA*)lParam)->hContact, IGNOREEVENT_FILE)) - return 1; - return CallService(MS_PROTO_CHAINRECV, wParam, lParam); -} - -static INT_PTR IgnoreRecvAuth(WPARAM wParam, LPARAM lParam) -{ - if ( IsIgnored((WPARAM)((CCSDATA*)lParam)->hContact, IGNOREEVENT_AUTHORIZATION)) - return 1; - return CallService(MS_PROTO_CHAINRECV, wParam, lParam); -} - -static int IgnoreAddedNotify(WPARAM, LPARAM lParam) -{ - DBEVENTINFO *dbei = (DBEVENTINFO*)lParam; - if (dbei && dbei->eventType == EVENTTYPE_ADDED && dbei->pBlob != NULL) { - MCONTACT hContact = DbGetAuthEventContact(dbei); - if (CallService(MS_DB_CONTACT_IS, hContact, 0) && IsIgnored(hContact, IGNOREEVENT_YOUWEREADDED)) - return 1; - } - return 0; -} - -static int iBoldControls[] = { IDC_TXT_TITLE1, IDC_TXT_TITLE2, IDC_TXT_TITLE3, MODERNOPT_CTRL_LAST }; - -static int IgnoreModernOptInit(WPARAM wParam, LPARAM) -{ - MODERNOPTOBJECT obj = { sizeof(obj) }; - obj.hInstance = hInst; - obj.dwFlags = MODEROPT_FLG_TCHAR; - obj.iSection = MODERNOPT_PAGE_IGNORE; - obj.iType = MODERNOPT_TYPE_SECTIONPAGE; - obj.iBoldControls = iBoldControls; - obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_IGNORE); - obj.pfnDlgProc = DlgProcIgnoreOpts; - CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); - return 0; -} - -int LoadIgnoreModule(void) -{ - PROTOCOLDESCRIPTOR pd = { sizeof(pd) }; - pd.szName = "Ignore"; - pd.type = PROTOTYPE_IGNORE; - CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); - - CreateProtoServiceFunction("Ignore", PSR_MESSAGE, IgnoreRecvMessage); - CreateProtoServiceFunction("Ignore", PSR_URL, IgnoreRecvUrl); - CreateProtoServiceFunction("Ignore", PSR_FILE, IgnoreRecvFile); - CreateProtoServiceFunction("Ignore", PSR_AUTH, IgnoreRecvAuth); - - CreateServiceFunction(MS_IGNORE_ISIGNORED, IsIgnored); - CreateServiceFunction(MS_IGNORE_IGNORE, Ignore); - CreateServiceFunction(MS_IGNORE_UNIGNORE, Unignore); - - HookEvent(ME_DB_EVENT_FILTER_ADD, IgnoreAddedNotify); - HookEvent(ME_MODERNOPT_INITIALIZE, IgnoreModernOptInit); - HookEvent(ME_OPT_INITIALISE, IgnoreOptInitialise); - return 0; -} diff --git a/src/modules/langpack/langpack.cpp b/src/modules/langpack/langpack.cpp deleted file mode 100644 index 4904e26fcc..0000000000 --- a/src/modules/langpack/langpack.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "langpack.h" - -MIR_CORE_DLL(int) LoadLangPackDescr(const TCHAR *szLangPack, LANGPACK_INFO *lpInfo); - -BOOL EnumLangpacks(ENUM_PACKS_CALLBACK callback, WPARAM wParam, LPARAM lParam) -{ - if (callback == NULL) return FALSE; - - BOOL res = FALSE; - - /* language folder */ - ptrT langpack(db_get_tsa(NULL, "Langpack", "Current")); - - TCHAR tszFullPath[MAX_PATH]; - PathToAbsoluteT(_T("\\Languages\\langpack_*.txt"), tszFullPath); - - BOOL fPackFound = FALSE; - WIN32_FIND_DATA wfd; - HANDLE hFind = FindFirstFile(tszFullPath, &wfd); - if (hFind != INVALID_HANDLE_VALUE) { - do { - if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; - /* get data */ - PathToAbsoluteT(_T("\\Languages\\"), tszFullPath); - mir_tstrcat(tszFullPath, wfd.cFileName); - - LANGPACK_INFO pack; - if (!LoadLangPackDescr(tszFullPath, &pack)) { - pack.ftFileDate = wfd.ftLastWriteTime; - /* enabled? */ - if (langpack && !mir_tstrcmpi(langpack, wfd.cFileName)) { - if (!fPackFound) pack.flags |= LPF_ENABLED; - fPackFound = TRUE; - } - /* callback */ - res = callback(&pack, wParam, lParam); - if (!res) { FindClose(hFind); return FALSE; } - } - } while (FindNextFile(hFind, &wfd)); - FindClose(hFind); - } - - /* default langpack: English */ - if (callback != NULL) { - LANGPACK_INFO pack; - pack.Locale = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); - mir_tstrcpy(pack.tszLanguage, _T("English")); - pack.szAuthors = "Miranda NG Development Team"; - pack.szAuthorEmail = "project-info@miranda-ng.org"; - DWORD v = CallService(MS_SYSTEM_GETVERSION, 0, 0); - pack.szLastModifiedUsing.Format("%d.%d.%d", ((v >> 24) & 0xFF), ((v >> 16) & 0xFF), ((v >> 8) & 0xFF)); - /* file date */ - if (GetModuleFileName(NULL, pack.tszFullPath, SIZEOF(pack.tszFullPath))) { - mir_tstrcpy(pack.tszFileName, _T("default")); - HANDLE hFile = CreateFile(pack.tszFileName, 0, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); - if (hFile != INVALID_HANDLE_VALUE) { - GetFileTime(hFile, NULL, NULL, &pack.ftFileDate); - CloseHandle(hFile); - } - } - pack.flags = LPF_DEFAULT; - - if (!fPackFound) pack.flags |= LPF_ENABLED; - /* callback */ - if (!callback(&pack, wParam, lParam)) return FALSE; - } - - return fPackFound; -} diff --git a/src/modules/langpack/langpack.h b/src/modules/langpack/langpack.h deleted file mode 100644 index 900f853f69..0000000000 --- a/src/modules/langpack/langpack.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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. -*/ - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR srvTranslateString(WPARAM wParam, LPARAM lParam); -static INT_PTR srvTranslateMenu(WPARAM wParam, LPARAM lParam); -static INT_PTR srvRegisterLP(WPARAM wParam, LPARAM lParam); -static INT_PTR srvGetDefaultCodePage(WPARAM, LPARAM); -static INT_PTR srvGetDefaultLocale(WPARAM, LPARAM); -static INT_PTR srvPcharToTchar(WPARAM wParam, LPARAM lParam); -static INT_PTR srvReloadLangpack(WPARAM wParam, LPARAM lParam); -static INT_PTR srvGetPluginLangpack(WPARAM wParam, LPARAM lParam); - -///////////////////////////////////////////////////////////////////////////////////////// - -#define LPF_ENABLED (1<<0) // pack is enabled -#define LPF_NOLOCALE (1<<1) // pack has no valid locale -#define LPF_DEFAULT (1<<2) // pack is the english default (no langpack) - -/* Langpack Info */ -struct LANGPACK_INFO -{ - TCHAR tszLanguage[64]; - LCID Locale; - WORD codepage; - CMStringA szAuthors, szAuthorEmail, szLastModifiedUsing; - FILETIME ftFileDate; - TCHAR tszFileName[MAX_PATH]; /* just the file name itself */ - TCHAR tszFullPath[MAX_PATH]; /* full path to the langpack */ - BYTE flags; /* see LPIF_* flags */ -}; - -typedef BOOL(*ENUM_PACKS_CALLBACK) (LANGPACK_INFO *pack, WPARAM wParam, LPARAM lParam); -BOOL EnumLangpacks(ENUM_PACKS_CALLBACK callback, WPARAM wParam, LPARAM lParam); - -int LangpackOptionsInit(WPARAM wParam, LPARAM); diff --git a/src/modules/langpack/lpopts.cpp b/src/modules/langpack/lpopts.cpp deleted file mode 100644 index 4adb56ec11..0000000000 --- a/src/modules/langpack/lpopts.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "langpack.h" - -static void SetDlgItemText_CP(HWND hwndDlg, int ctrlID, LPCSTR str) -{ - SetDlgItemText(hwndDlg, ctrlID, ptrT(mir_utf8decodeT(str))); -} - -static void DisplayPackInfo(HWND hwndDlg, const LANGPACK_INFO *pack) -{ - /* locale string */ - if (!(pack->flags & LPF_NOLOCALE)) { - TCHAR szLocaleName[256], szLanguageName[128], szContryName[128]; - - if (!GetLocaleInfo(pack->Locale, WINVER >= _WIN32_WINNT_WIN7 ? LOCALE_SENGLISHLANGUAGENAME : LOCALE_SENGLANGUAGE, szLanguageName, SIZEOF(szLanguageName))) - szLanguageName[0] = _T('\0'); - if (!GetLocaleInfo(pack->Locale, WINVER >= _WIN32_WINNT_WIN7 ? LOCALE_SENGLISHCOUNTRYNAME : LOCALE_SENGCOUNTRY, szContryName, SIZEOF(szContryName))) - szContryName[0] = _T('\0'); - - /* add some note if its incompatible */ - if (szLanguageName[0] && szContryName[0]) { - mir_sntprintf(szLocaleName, SIZEOF(szLocaleName), _T("%s (%s)"), TranslateTS(szLanguageName), TranslateTS(szContryName)); - if (!IsValidLocale(pack->Locale, LCID_INSTALLED)) { - TCHAR *pszIncompat; - pszIncompat = TranslateT("(incompatible)"); - szLocaleName[SIZEOF(szLocaleName) - mir_tstrlen(pszIncompat) - 1] = 0; - mir_tstrcat(mir_tstrcat(szLocaleName, _T(" ")), pszIncompat); - } - SetDlgItemText(hwndDlg, IDC_LANGLOCALE, szLocaleName); - } - else SetDlgItemText(hwndDlg, IDC_LANGLOCALE, TranslateT("Unknown")); - } - else SetDlgItemText(hwndDlg, IDC_LANGLOCALE, TranslateT("Unknown")); - - /* file date */ - SYSTEMTIME stFileDate; - TCHAR szDate[128]; szDate[0] = 0; - if (FileTimeToSystemTime(&pack->ftFileDate, &stFileDate)) - GetDateFormat((LCID)CallService(MS_LANGPACK_GETLOCALE, 0, 0), DATE_SHORTDATE, &stFileDate, NULL, szDate, SIZEOF(szDate)); - SetDlgItemText(hwndDlg, IDC_LANGDATE, szDate); - - /* general */ - SetDlgItemText_CP(hwndDlg, IDC_LANGMODUSING, pack->szLastModifiedUsing); - SetDlgItemText_CP(hwndDlg, IDC_LANGAUTHORS, pack->szAuthors); - SetDlgItemText_CP(hwndDlg, IDC_LANGEMAIL, pack->szAuthorEmail); - SetDlgItemText(hwndDlg, IDC_LANGINFOFRAME, TranslateTS(pack->tszLanguage)); -} - -static BOOL InsertPackItemEnumProc(LANGPACK_INFO *pack, WPARAM wParam, LPARAM lParam) -{ - LANGPACK_INFO *pack2 = new LANGPACK_INFO(); - *pack2 = *pack; - - /* insert */ - TCHAR tszName[512]; - mir_sntprintf(tszName, SIZEOF(tszName), _T("%s [%s]"), - TranslateTS(pack->tszLanguage), - pack->flags & LPF_DEFAULT ? TranslateT("built-in") : pack->tszFileName); - UINT message = pack->flags & LPF_DEFAULT ? CB_INSERTSTRING : CB_ADDSTRING; - int idx = SendMessage((HWND)wParam, message, 0, (LPARAM)tszName); - SendMessage((HWND)wParam, CB_SETITEMDATA, idx, (LPARAM)pack2); - if (pack->flags & LPF_ENABLED) { - SendMessage((HWND)wParam, CB_SETCURSEL, idx, 0); - DisplayPackInfo(GetParent((HWND)wParam), pack); - EnableWindow(GetDlgItem(GetParent((HWND)wParam), IDC_RELOAD), !(pack->flags & LPF_DEFAULT)); - } - - return TRUE; -} - -static void CALLBACK OpenOptions(void*) -{ - OPENOPTIONSDIALOG ood = { sizeof(ood) }; - ood.pszGroup = "Customize"; - ood.pszPage = "Languages"; - Options_Open(&ood); -} - -static void ReloadOptions(void *hWnd) -{ - while (IsWindow((HWND)hWnd)) - Sleep(50); - - CallFunctionAsync(OpenOptions, 0); -} - -INT_PTR CALLBACK DlgLangpackOpt(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HWND hwndList = GetDlgItem(hwndDlg, IDC_LANGUAGES); - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - ComboBox_ResetContent(hwndList); - EnumLangpacks(InsertPackItemEnumProc, (WPARAM)hwndList, (LPARAM)0); - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_LANGEMAIL: - { - char buf[512]; - mir_strcpy(buf, "mailto:"); - if (GetDlgItemTextA(hwndDlg, LOWORD(wParam), &buf[7], SIZEOF(buf) - 7)) - CallService(MS_UTILS_OPENURL, 0, (LPARAM)buf); - } - break; - - case IDC_MORELANG: - CallService(MS_UTILS_OPENURL, OUF_NEWWINDOW, (LPARAM)"http://wiki.miranda-ng.org/index.php?title=Langpacks/en#Download"); - break; - - case IDC_LANGUAGES: - if (HIWORD(wParam) == CBN_SELCHANGE) { - int idx = ComboBox_GetCurSel(hwndList); - LANGPACK_INFO *pack = (LANGPACK_INFO*)ComboBox_GetItemData(hwndList, idx); - DisplayPackInfo(hwndDlg, pack); - if (!(pack->flags & LPF_ENABLED)) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_RELOAD), (pack->flags & LPF_ENABLED) && !(pack->flags & LPF_DEFAULT)); - } - break; - - case IDC_RELOAD: - { - EnableWindow(GetDlgItem(hwndDlg, IDC_RELOAD), FALSE); - int idx = ComboBox_GetCurSel(hwndList); - LANGPACK_INFO *pack = (LANGPACK_INFO*)ComboBox_GetItemData(hwndList, idx); - ReloadLangpack(pack->tszFullPath); - DisplayPackInfo(hwndDlg, pack); - EnableWindow(GetDlgItem(hwndDlg, IDC_RELOAD), TRUE); - } - break; - } - break; - - case WM_NOTIFY: - if (LPNMHDR(lParam)->code == PSN_APPLY) { - TCHAR tszPath[MAX_PATH]; tszPath[0] = 0; - int idx = ComboBox_GetCurSel(hwndList); - int count = ComboBox_GetCount(hwndList); - for (int i = 0; i < count; i++) { - LANGPACK_INFO *pack = (LANGPACK_INFO*)ComboBox_GetItemData(hwndList, i); - if (i == idx) { - db_set_ts(NULL, "Langpack", "Current", pack->tszFileName); - mir_tstrcpy(tszPath, pack->tszFullPath); - pack->flags |= LPF_ENABLED; - } - else pack->flags &= ~LPF_ENABLED; - } - - if (tszPath[0]) { - ReloadLangpack(tszPath); - - if (LPPSHNOTIFY(lParam)->lParam == IDC_APPLY) { - HWND hwndParent = GetParent(hwndDlg); - PostMessage(hwndParent, WM_CLOSE, 1, 0); - mir_forkthread(ReloadOptions, hwndParent); - } - } - } - break; - - case WM_DESTROY: - int count = ListBox_GetCount(hwndList); - for (int i = 0; i < count; i++) - delete (LANGPACK_INFO*)ListBox_GetItemData(hwndList, i); - ComboBox_ResetContent(hwndList); - return TRUE; - } - return FALSE; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -int LangpackOptionsInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.hInstance = hInst; - odp.pfnDlgProc = DlgLangpackOpt; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_LANGUAGES); - odp.position = -1300000000; - odp.pszTitle = LPGEN("Languages"); - odp.pszGroup = LPGEN("Customize"); - odp.flags = ODPF_BOLDGROUPS; - Options_AddPage(wParam, &odp); - return 0; -} diff --git a/src/modules/langpack/lpservices.cpp b/src/modules/langpack/lpservices.cpp deleted file mode 100644 index 5bb898b709..0000000000 --- a/src/modules/langpack/lpservices.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR srvTranslateString(WPARAM wParam, LPARAM lParam) -{ - if (wParam & LANG_UNICODE) - return (INT_PTR)TranslateW_LP((const WCHAR*)lParam, wParam); - return (INT_PTR)TranslateA_LP((const char *)lParam, wParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR srvTranslateMenu(WPARAM wParam, LPARAM lParam) -{ - TranslateMenu_LP((HMENU)wParam, lParam); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR srvRegisterLP(WPARAM wParam, LPARAM lParam) -{ - PLUGININFOEX* ppi = (PLUGININFOEX*)lParam; - if (wParam && ppi) - *(int*)wParam = GetPluginFakeId(ppi->uuid, Langpack_MarkPluginLoaded(ppi)); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR srvGetDefaultCodePage(WPARAM, LPARAM) -{ - return Langpack_GetDefaultCodePage(); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR srvGetDefaultLocale(WPARAM, LPARAM) -{ - return Langpack_GetDefaultLocale(); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR srvPcharToTchar(WPARAM wParam, LPARAM lParam) -{ - char *pszStr = (char*)lParam; - if (pszStr == NULL) - return NULL; - - int len = (int)mir_strlen(pszStr); - TCHAR *result = (TCHAR*)alloca((len+1)*sizeof(TCHAR)); - MultiByteToWideChar(Langpack_GetDefaultCodePage(), 0, pszStr, -1, result, len); - result[len] = 0; - return (INT_PTR)mir_wstrdup(TranslateW_LP(result, wParam)); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR srvReloadLangpack(WPARAM wParam, LPARAM lParam) -{ - ReloadLangpack((TCHAR*)lParam); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR srvGetPluginLangpack(WPARAM wParam, LPARAM lParam) -{ - return GetPluginLangByInstance((HINSTANCE)lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -int LoadLangpackModule(void) -{ - LoadLangPackModule(); - - CreateServiceFunction(MS_LANGPACK_TRANSLATESTRING, srvTranslateString); - CreateServiceFunction(MS_LANGPACK_TRANSLATEMENU, srvTranslateMenu); - CreateServiceFunction(MS_LANGPACK_GETCODEPAGE, srvGetDefaultCodePage); - CreateServiceFunction(MS_LANGPACK_GETLOCALE, srvGetDefaultLocale); - CreateServiceFunction(MS_LANGPACK_PCHARTOTCHAR, srvPcharToTchar); - CreateServiceFunction(MS_LANGPACK_REGISTER, srvRegisterLP); - CreateServiceFunction(MS_LANGPACK_RELOAD, srvReloadLangpack); - CreateServiceFunction(MS_LANGPACK_LOOKUPHANDLE, srvGetPluginLangpack); - return 0; -} diff --git a/src/modules/metacontacts/meta_addto.cpp b/src/modules/metacontacts/meta_addto.cpp deleted file mode 100644 index 575ecbcb55..0000000000 --- a/src/modules/metacontacts/meta_addto.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* -former MetaContacts Plugin for Miranda IM. - -Copyright 2014 Miranda NG Team -Copyright 2004-07 Scott Ellis -Copyright 2004 Universite Louis PASTEUR, STRASBOURG. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "metacontacts.h" - -/** Adds all the metacontacts desired in the listview. -* -* Adds all the metacontacts present in the database in the list, -* -* @param list : HANDLE to the list which will contain the columns. -* @param nb_contacts : Number of loaded contacts. -* @param contacts : A list of the contacts' identifiers -* -* @param id : Reference to a list of the MetaContacts IDs loaded in the listview. -* Since this list is resized, its address must be passed. -* -* @return An integer specifying the number of rows added in the list. -*/ - -static int FillList(HWND list, BOOL sort) -{ - int i = 0; - - // The DB is searched through, to get all the metacontacts - for (MCONTACT hMetaUser = db_find_first(); hMetaUser; hMetaUser = db_find_next(hMetaUser)) { - // if it's not a MetaContact, go to the next - DBCachedContact *cc = CheckMeta(hMetaUser); - if (cc == NULL) - continue; - - // get contact display name from clist - TCHAR *swzContactDisplayName = cli.pfnGetContactDisplayName(hMetaUser, 0); - // don't insert huge strings that we have to compare with later - if (mir_tstrlen(swzContactDisplayName) > 1023) - swzContactDisplayName[1024] = 0; - - int pos = -1; - if (sort) { - for (pos = 0; pos < i; pos++) { - TCHAR buff[1024]; - SendMessage(list, LB_GETTEXT, pos, (LPARAM)buff); - if (mir_tstrcmp(buff, swzContactDisplayName) > 0) - break; - } - } - - int index = SendMessage(list, LB_INSERTSTRING, pos, (LPARAM)swzContactDisplayName); - SendMessage(list, LB_SETITEMDATA, index, hMetaUser); - i++; - } - return i; -} - -/** Build or update the list. -* -* @param list : HANDLE to the list which will contain the columns -* @param id : Reference to a list that will contain all the MetaContacts IDs loaded in the listview -* otherwise the list is only refilled \n (Warning : this value must be -* set to TRUE only once per Dialog display, otherwise all columns will be doubled) -* -* @returns An integer specifying the number of rows inserted or -1 if there was a problem -*/ - -static int BuildList(HWND list, BOOL sort) -{ - SendMessage(list, LB_RESETCONTENT, 0, 0); - return FillList(list, sort); -} - -/** Callback function for the 'Add To' Dialog. -* -* All the UI is controlled here, from display to functionnalities. -* -* @param hwndDlg : HANDLE to the 'Add To' Dialog. -* @param uMsg : Specifies the message received by this dialog. -* @param wParam : Specifies additional message-specific information. -* @param lParam : Specifies additional message-specific information. -* -* @return TRUE if the dialog processed the message, FALSE if it did not. -*/ - -#define szConvMsg LPGEN("Either there is no metacontact in the database (in this case you should first convert a contact into one)\n\ -or there is none that can host this contact.\n\ -Another solution could be to convert this contact into a new metacontact.\n\nConvert this contact into a new metacontact?") - -static INT_PTR CALLBACK Meta_SelectDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - { - DBCachedContact *cc = currDb->m_cache->GetCachedContact(lParam); - if (cc == NULL) { - DestroyWindow(hwndDlg); - return TRUE; - } - - if (cc->IsMeta()) { - MessageBox(hwndDlg, - TranslateT("This contact is a metacontact.\nYou can't add a metacontact to another metacontact.\n\nPlease choose another."), - TranslateT("Metacontact conflict"), MB_ICONERROR); - DestroyWindow(hwndDlg); - return TRUE; - } - - if (cc->IsSub()) { - MessageBox(hwndDlg, - TranslateT("This contact is already associated to a metacontact.\nYou cannot add a contact to multiple metacontacts."), - TranslateT("Multiple metacontacts"), MB_ICONERROR); - DestroyWindow(hwndDlg); - return TRUE; - } - } - - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); // user data is contact handle - - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIconEx(I_ADD)); - - // Initialize the graphical part - CheckDlgButton(hwndDlg, IDC_ONLYAVAIL, BST_CHECKED); // Initially checked; display all metacontacts is only an option - // Besides, we can check if there is at least one metacontact to add the contact to. - if (BuildList(GetDlgItem(hwndDlg, IDC_METALIST), FALSE) <= 0) { - if (MessageBox(hwndDlg, TranslateT(szConvMsg), TranslateT("No suitable metacontact found"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1) == IDYES) - Meta_Convert(lParam, 0); - DestroyWindow(hwndDlg); - return TRUE; - } - else { - // get contact display name from clist - TCHAR *ptszCDN = cli.pfnGetContactDisplayName(lParam, 0); - if (!ptszCDN) - ptszCDN = TranslateT("a contact"); - - // ... and set it to the Window title. - TCHAR buf[256]; - mir_sntprintf(buf, TranslateT("Adding %s..."), ptszCDN); - SetWindowText(hwndDlg, buf); - } - ShowWindow(hwndDlg, SW_SHOWNORMAL); - return TRUE; - - case WM_COMMAND: - if (HIWORD(wParam) == LBN_DBLCLK) // emulate click ok Ok - wParam = MAKEWPARAM(IDOK, BN_CLICKED); - - if (HIWORD(wParam) != BN_CLICKED) - break; // Only clicks of buttons are relevant, let other COMMANDs through - - switch (LOWORD(wParam)) { - case IDOK: - { - int item = SendDlgItemMessage(hwndDlg, IDC_METALIST, LB_GETCURSEL, 0, 0); // Get the index of the selected metacontact - if (item == -1) - return IDOK == MessageBox(hwndDlg, TranslateT("Please select a metacontact"), TranslateT("No metacontact selected"), MB_ICONHAND); - - MCONTACT hContact = (MCONTACT)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - MCONTACT hMeta = (MCONTACT)SendDlgItemMessage(hwndDlg, IDC_METALIST, LB_GETITEMDATA, item, 0); - if (!Meta_Assign(hContact, hMeta, FALSE)) - MessageBox(hwndDlg, TranslateT("Assignment to the metacontact failed."), TranslateT("Assignment failure"), MB_ICONERROR); - } - // fall through - case IDCANCEL: - DestroyWindow(hwndDlg); - break; - - case IDC_CHK_SRT: - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_METALIST), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_METALIST), GWL_STYLE) ^ LBS_SORT); - if (BuildList(GetDlgItem(hwndDlg, IDC_METALIST), IsDlgButtonChecked(hwndDlg, IDC_CHK_SRT) ? TRUE : FALSE) <= 0) { - if (MessageBox(hwndDlg, TranslateT(szConvMsg), TranslateT("No suitable metacontact found"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1) == IDYES) - Meta_Convert(lParam, 0); - DestroyWindow(hwndDlg); - return TRUE; - } - break; - } - break; - - case WM_DESTROY: - // Free all allocated memory and return the focus to the CList - HWND clist = GetParent(hwndDlg); - Skin_ReleaseIcon((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0)); - EndDialog(hwndDlg, TRUE); - SetFocus(clist); - return TRUE; - } - return FALSE; // All other Message are not handled -} - -/** Display the 'Add to' Dialog -* -* Present a dialog in which the user can choose to which MetaContact this -* contact will be added -* -* @param wParam : HANDLE to the contact that has been chosen. -* @param lParam : Allways set to 0. -*/ - -INT_PTR Meta_AddTo(WPARAM hContact, LPARAM) -{ - HWND clui = (HWND)CallService(MS_CLUI_GETHWND, 0, 0); - DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_METASELECT), clui, &Meta_SelectDialogProc, hContact); - return 0; -} diff --git a/src/modules/metacontacts/meta_api.cpp b/src/modules/metacontacts/meta_api.cpp deleted file mode 100644 index f1b0926ad1..0000000000 --- a/src/modules/metacontacts/meta_api.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* -former MetaContacts Plugin for Miranda IM. - -Copyright 2014 Miranda NG Team -Copyright 2004-07 Scott Ellis -Copyright 2004 Universite Louis PASTEUR, STRASBOURG. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "metacontacts.h" - -// gets the handle for the 'most online' contact -// wParam=(MCONTACT)hMetaContact -// lParam=0 -// returns a handle to the 'most online' contact - -static INT_PTR MetaAPI_GetMostOnline(WPARAM hMetaContact, LPARAM) -{ - DBCachedContact *cc = CheckMeta(hMetaContact); - return (cc == NULL) ? NULL : Meta_GetMostOnline(cc); -} - -// wParam=(HANDLE)hContact -// lParam=0 -// convert a given contact into a metacontact - -static INT_PTR MetaAPI_ConvertToMeta(WPARAM wParam, LPARAM lParam) -{ - return Meta_Convert(wParam, lParam); -} - -// wParam=(HANDLE)hContact -// lParam=(HANDLE)hMeta -// add an existing contact to a metacontact - -static INT_PTR MetaAPI_AddToMeta(WPARAM wParam, LPARAM lParam) -{ - return Meta_Assign(wParam, lParam, FALSE); -} - -// wParam=0 -// lParam=(HANDLE)hContact -// remove a contact from a metacontact - -static INT_PTR MetaAPI_RemoveFromMeta(WPARAM wParam, LPARAM lParam) -{ - // notice we switch args - to keep the API function consistent with the others - return Meta_Delete(lParam, wParam); -} - -void CreateApiServices() -{ - CreateServiceFunction(MS_MC_GETMOSTONLINECONTACT, MetaAPI_GetMostOnline); - CreateServiceFunction(MS_MC_CONVERTTOMETA, MetaAPI_ConvertToMeta); - CreateServiceFunction(MS_MC_ADDTOMETA, MetaAPI_AddToMeta); - CreateServiceFunction(MS_MC_REMOVEFROMMETA, MetaAPI_RemoveFromMeta); -} diff --git a/src/modules/metacontacts/meta_edit.cpp b/src/modules/metacontacts/meta_edit.cpp deleted file mode 100644 index 7aaa351545..0000000000 --- a/src/modules/metacontacts/meta_edit.cpp +++ /dev/null @@ -1,452 +0,0 @@ -/* -former MetaContacts Plugin for Miranda IM. - -Copyright 2014 Miranda NG Team -Copyright 2004-07 Scott Ellis -Copyright 2004 Universite Louis PASTEUR, STRASBOURG. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "metacontacts.h" - -// Holds the differents changes that have to made -struct -{ - MCONTACT hMeta; // HANDLE of the MetaContact that is edited. - DBCachedContact *cc; - MCONTACT hDefaultContact; // HANDLE of the new default contact - MCONTACT hOfflineContact; - int num_deleted, // DWORD number of deleted contacts - num_contacts; // DWORD number of contacts - MCONTACT hDeletedContacts[MAX_CONTACTS]; // HANDLEs of the subcontacts to be removed from this metacontact - MCONTACT hContact[MAX_CONTACTS]; // HANDLEs of the subcontacts, in the order they should be in -} -static g_data; // global CHANGES structure - -///////////////////////////////////////////////////////////////////////////////////////// - -static void FillContactList(HWND hList) -{ - TCHAR buff[256]; - - SendMessage(hList, LVM_DELETEALLITEMS, 0, 0); - - LVITEM LvItem = { 0 }; - LvItem.mask = LVIF_TEXT; // Text Style - - for (int i = 0; i < g_data.num_contacts; i++) { - LvItem.iItem = i; - - TCHAR *ptszCDN = cli.pfnGetContactDisplayName(g_data.hContact[i], 0); - if (ptszCDN == NULL) - ptszCDN = TranslateT("(Unknown contact)"); - - LvItem.iSubItem = 0; // clist display name - LvItem.pszText = ptszCDN; - ListView_InsertItem(hList, &LvItem); - - LvItem.iSubItem = 1; // id - char *szProto = GetContactProto(g_data.hContact[i]); - if (szProto) { - PROTOACCOUNT *pa = ProtoGetAccount(szProto); - - char *szField = (char *)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); - - DBVARIANT dbv; - if (!db_get(g_data.hContact[i], szProto, szField, &dbv)) { - switch (dbv.type) { - case DBVT_ASCIIZ: - _tcsncpy_s(buff, _A2T(dbv.pszVal), _TRUNCATE); - break; - case DBVT_WCHAR: - _tcsncpy_s(buff, dbv.ptszVal, _TRUNCATE); - break; - case DBVT_BYTE: - _itot(dbv.bVal, buff, 10); - break; - case DBVT_WORD: - _itot(dbv.wVal, buff, 10); - break; - case DBVT_DWORD: - _itot(dbv.dVal, buff, 10); - break; - default: - buff[0] = 0; - } - db_free(&dbv); - } - else buff[0] = 0; - - LvItem.pszText = buff; - SendMessage(hList, LVM_SETITEM, 0, (LPARAM)&LvItem); // Enter text to SubItems - - LvItem.iSubItem = 2; // protocol - _tcsncpy_s(buff, (pa == NULL) ? _A2T(szProto) : pa->tszAccountName, _TRUNCATE); - ListView_SetItem(hList, &LvItem); - } - else { - LvItem.pszText = TranslateT("Unknown"); - ListView_SetItem(hList, &LvItem); - - LvItem.iSubItem = 2; // protocol - ListView_SetItem(hList, &LvItem); - } - LvItem.iSubItem = 3; // Default (Yes/No) - LvItem.pszText = (g_data.hContact[i] == g_data.hDefaultContact ? TranslateT("Yes") : TranslateT("No")); - ListView_SetItem(hList, &LvItem); - - LvItem.iSubItem = 4; // Offline (Yes/No) - LvItem.pszText = (g_data.hContact[i] == g_data.hOfflineContact ? TranslateT("Yes") : TranslateT("No")); - ListView_SetItem(hList, &LvItem); - } -} - -static void SetListSelection(HWND hList, int sel) -{ - ListView_SetItemState(hList, sel, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); -} - -/** Scans the \c CHANGES and call the appropriate function for each change. -* -* @param chg : Structure holding all the change info (See CHANGES). -*/ - -static void ApplyChanges() -{ - // remove removed contacts - for (int i = 0; i < g_data.num_deleted; i++) { - if (Meta_Delete(g_data.hDeletedContacts[i], 0) != 0) // error, delete anyway - Meta_RemoveContactNumber(g_data.cc, Meta_GetContactNumber(g_data.cc, g_data.hDeletedContacts[i]), true); - if (g_data.hDeletedContacts[i] == g_data.hDefaultContact) - g_data.hDefaultContact = 0; - if (g_data.hDeletedContacts[i] == g_data.hOfflineContact) - g_data.hOfflineContact = 0; - } - - // set contact positions - for (int i = 0; i < g_data.num_contacts; i++) - if (Meta_GetContactNumber(g_data.cc, g_data.hContact[i]) != i) - Meta_SwapContacts(g_data.cc, Meta_GetContactNumber(g_data.cc, g_data.hContact[i]), i); - - NotifyEventHooks(hSubcontactsChanged, g_data.hMeta, g_data.hDefaultContact); - - // set default - db_mc_setDefaultNum(g_data.hMeta, (g_data.hDefaultContact) ? Meta_GetContactNumber(g_data.cc, g_data.hDefaultContact) : 0, true); - - // set offline - if (g_data.hOfflineContact) - db_set_dw(g_data.hMeta, META_PROTO, "OfflineSend", Meta_GetContactNumber(g_data.cc, g_data.hOfflineContact)); - else - db_set_dw(g_data.hMeta, META_PROTO, "OfflineSend", INVALID_CONTACT_ID); - - // fix nick - MCONTACT most_online = Meta_GetMostOnline(g_data.cc); - Meta_CopyContactNick(g_data.cc, most_online); - - // fix status - Meta_FixStatus(g_data.cc); - - // fix avatar - most_online = Meta_GetMostOnlineSupporting(g_data.cc, PFLAGNUM_4, PF4_AVATARS); - if (most_online) { - PROTO_AVATAR_INFORMATION ai = { 0 }; - ai.hContact = g_data.hMeta; - ai.format = PA_FORMAT_UNKNOWN; - _tcsncpy_s(ai.filename, _T("X"), _TRUNCATE); - if (CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&ai) == GAIR_SUCCESS) - db_set_ts(g_data.hMeta, "ContactPhoto", "File", ai.filename); - } -} - -LRESULT ProcessCustomDraw(LPARAM lParam) -{ - LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam; - switch (lplvcd->nmcd.dwDrawStage) { - case CDDS_PREPAINT: //Before the paint cycle begins - //request notifications for individual listview items - return CDRF_NOTIFYITEMDRAW; - - case CDDS_ITEMPREPAINT: //Before an item is drawn - if (g_data.hContact[(int)lplvcd->nmcd.dwItemSpec] == g_data.hDefaultContact) - lplvcd->clrText = RGB(255, 0, 0); - - return CDRF_NEWFONT; - } - - return 0; -} - -/** Callback function for the 'Edit' Dialog. -* -* All the UI is controlled here, from display to functionnalities. -* -* @param hwndDlg : HANDLE to the 'Edit' Dialog. -* @param uMsg : Specifies the message received by this dialog. -* @param wParam : Specifies additional message-specific information. -* @param lParam : Specifies additional message-specific information (handle of MetaContact to edit) -* -* @return TRUE if the dialog processed the message, FALSE if it did not. -*/ - -#define WMU_SETTITLE (WM_USER + 1) - -static INT_PTR CALLBACK Meta_EditDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HWND hwndList = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); - int sel; - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIconEx(I_EDIT)); - { - DBCachedContact *cc = currDb->m_cache->GetCachedContact(lParam); - if (cc == NULL) { - DestroyWindow(hwndDlg); - return FALSE; - } - - // Disable the 'Apply' button. - EnableWindow(GetDlgItem(hwndDlg, IDC_VALIDATE), FALSE); - - ListView_SetExtendedListViewStyle(hwndList, LVS_EX_FULLROWSELECT); - - // Create list columns - LVCOLUMN LvCol = { 0 }; - LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; - - LvCol.pszText = TranslateT("Contact"); - LvCol.cx = 150; - ListView_InsertColumn(hwndList, 0, &LvCol); - - LvCol.pszText = TranslateT("ID"); - LvCol.cx = 130; - ListView_InsertColumn(hwndList, 1, &LvCol); - - LvCol.pszText = TranslateT("Protocol"); - LvCol.cx = 100; - ListView_InsertColumn(hwndList, 2, &LvCol); - - LvCol.pszText = TranslateT("Default"); - LvCol.cx = 60; - ListView_InsertColumn(hwndList, 3, &LvCol); - - LvCol.pszText = TranslateT("Send offline"); - LvCol.cx = 85; - ListView_InsertColumn(hwndList, 4, &LvCol); - - int offline_contact_number = db_get_dw(lParam, META_PROTO, "OfflineSend", INVALID_CONTACT_ID); - - memset(&g_data, 0, sizeof(g_data)); - g_data.cc = cc; - g_data.hMeta = lParam; - g_data.num_contacts = cc->nSubs; - g_data.num_deleted = 0; - g_data.hDefaultContact = Meta_GetContactHandle(g_data.cc, cc->nDefault); - g_data.hOfflineContact = Meta_GetContactHandle(g_data.cc, offline_contact_number); - for (int i = 0; i < cc->nSubs; i++) - g_data.hContact[i] = Meta_GetContactHandle(g_data.cc, i); - - SendMessage(hwndDlg, WMU_SETTITLE, 0, lParam); - } - FillContactList(hwndList); - ListView_SetItemState(hwndList, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - return TRUE; - - case WMU_SETTITLE: - { - TCHAR *ptszCDN = cli.pfnGetContactDisplayName(lParam, 0); - if (ptszCDN == NULL) - ptszCDN = TranslateT("(Unknown contact)"); - - SetDlgItemText(hwndDlg, IDC_ED_NAME, ptszCDN); - } - return TRUE; - - case WM_NOTIFY: - if (LOWORD(wParam) == IDC_LST_CONTACTS) { - LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; - if (pnmv->hdr.code == LVN_ITEMCHANGED) { - int sel = ListView_GetNextItem(hwndList, -1, LVNI_FOCUSED | LVNI_SELECTED); // return item selected - - // enable buttons - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_REM), sel != -1); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_SETDEFAULT), sel != -1 && g_data.hContact[sel] != g_data.hDefaultContact); - - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UP), sel > 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_DOWN), (sel != -1 && sel < g_data.num_contacts - 1)); - - HWND hwndOffline = GetDlgItem(hwndDlg, IDC_BTN_SETOFFLINE); - EnableWindow(hwndOffline, sel != -1); - SetWindowText(hwndOffline, (sel != -1 && g_data.hContact[sel] != g_data.hOfflineContact) ? TranslateT("Send &offline") : TranslateT("Send &online")); - } - } - break; - - case WM_COMMAND: // the message that is being sent always - switch (HIWORD(wParam)) { - case BN_CLICKED: // A button ('Remove', 'OK', 'Cancel' or 'Apply', normally) has been clicked - switch (LOWORD(wParam)) { - case IDC_VALIDATE: // Apply changes, if there is still one contact attached to the metacontact. - if (g_data.num_contacts == 0) { // Otherwise, delete the metacontact. - if (IDYES == MessageBox(hwndDlg, TranslateT(szDelMsg), TranslateT("Delete metacontact?"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1)) { - Meta_Delete(g_data.hMeta, 0); - DestroyWindow(hwndDlg); - } - return TRUE; - } - ApplyChanges(); - - // Disable the 'Apply' button. - EnableWindow(GetDlgItem(hwndDlg, IDC_VALIDATE), FALSE); - break; - - case IDOK: - if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_VALIDATE))) { // If there are changes that could be made, - if (g_data.num_contacts == 0) { // do the work that would have be done if the 'Apply' button was clicked. - if (IDYES == MessageBox(hwndDlg, TranslateT(szDelMsg), TranslateT("Delete metacontact?"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1)) { - Meta_Delete(g_data.hMeta, 0); - DestroyWindow(hwndDlg); - } - return TRUE; - } - ApplyChanges(); - } - EndDialog(hwndDlg, IDOK); - return TRUE; - - case IDCANCEL: // Simply close the dialog - EndDialog(hwndDlg, IDCANCEL); - return TRUE; - - case IDC_BTN_SETDEFAULT: - sel = ListView_GetNextItem(hwndList, -1, LVNI_FOCUSED | LVNI_SELECTED); - InvalidateRect(hwndList, 0, TRUE); - g_data.hDefaultContact = g_data.hContact[sel]; - SendMessage(hwndDlg, WMU_SETTITLE, 0, (LPARAM)g_data.hContact[sel]); - - FillContactList(hwndList); - SetListSelection(hwndList, sel); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_SETDEFAULT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_VALIDATE), TRUE); - return TRUE; - - case IDC_BTN_SETOFFLINE: - sel = ListView_GetNextItem(hwndList, -1, LVNI_FOCUSED | LVNI_SELECTED); - InvalidateRect(hwndList, 0, TRUE); - if (g_data.hContact[sel] != g_data.hOfflineContact) - g_data.hOfflineContact = g_data.hContact[sel]; - else - g_data.hOfflineContact = 0; - - FillContactList(hwndList); - SetListSelection(hwndList, sel); - EnableWindow(GetDlgItem(hwndDlg, IDC_VALIDATE), TRUE); - return TRUE; - - case IDC_BTN_REM: - sel = ListView_GetNextItem(hwndList, -1, LVNI_FOCUSED | LVNI_SELECTED); - g_data.num_contacts--; - g_data.hDeletedContacts[g_data.num_deleted++] = g_data.hContact[sel]; - if (g_data.hDefaultContact == g_data.hContact[sel]) { - if (g_data.num_contacts > 0) { - g_data.hDefaultContact = g_data.hContact[0]; - SetDlgItemText(hwndDlg, IDC_ED_DEFAULT, cli.pfnGetContactDisplayName(g_data.hDefaultContact, 0)); - } - else { - g_data.hDefaultContact = 0; - SetDlgItemText(hwndDlg, IDC_ED_DEFAULT, _T("None")); - } - } - - for (int i = sel; i < g_data.num_contacts; i++) - g_data.hContact[i] = g_data.hContact[i + 1]; - FillContactList(hwndList); - - // disable buttons - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_REM), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_SETDEFAULT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UP), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_DOWN), FALSE); - - // Enable the 'Apply' button. - EnableWindow(GetDlgItem(hwndDlg, IDC_VALIDATE), TRUE); - return TRUE; - - case IDC_BTN_UP: - sel = ListView_GetNextItem(hwndList, -1, LVNI_FOCUSED | LVNI_SELECTED); - { - MCONTACT temp = g_data.hContact[sel]; - g_data.hContact[sel] = g_data.hContact[sel - 1]; - g_data.hContact[sel - 1] = temp; - } - FillContactList(hwndList); - sel--; - SetListSelection(hwndList, sel); - - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UP), (sel > 0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_DOWN), (sel < g_data.num_contacts - 1)); - EnableWindow(GetDlgItem(hwndDlg, IDC_VALIDATE), TRUE); - return TRUE; - - case IDC_BTN_DOWN: - sel = ListView_GetNextItem(hwndList, -1, LVNI_FOCUSED | LVNI_SELECTED); - { - MCONTACT temp = g_data.hContact[sel]; - g_data.hContact[sel] = g_data.hContact[sel + 1]; - g_data.hContact[sel + 1] = temp; - } - FillContactList(hwndList); - sel++; - SetListSelection(hwndList, sel); - - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UP), (sel > 0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_DOWN), (sel < g_data.num_contacts - 1)); - EnableWindow(GetDlgItem(hwndDlg, IDC_VALIDATE), TRUE); - return TRUE; - } - } - break; - - case WM_CLOSE: - DestroyWindow(hwndDlg); - return TRUE; - - case WM_DESTROY: - Skin_ReleaseIcon((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0)); - EndDialog(hwndDlg, IDCANCEL); - break; - } - - return FALSE; -} - -/** Display the 'Edit' Dialog -* -* Present a dialog in which the user can edit some properties of the MetaContact. -* -* @param wParam : HANDLE to the MetaContact to be edited. -* @param lParam : Allways set to 0. -*/ - -INT_PTR Meta_Edit(WPARAM wParam, LPARAM lParam) -{ - HWND clui = (HWND)CallService(MS_CLUI_GETHWND, 0, 0); - DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_METAEDIT), clui, Meta_EditDialogProc, (LPARAM)wParam); - return 0; -} diff --git a/src/modules/metacontacts/meta_main.cpp b/src/modules/metacontacts/meta_main.cpp deleted file mode 100644 index 8e2cd9c929..0000000000 --- a/src/modules/metacontacts/meta_main.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* -former MetaContacts Plugin for Miranda IM. - -Copyright 2014 Miranda NG Team -Copyright 2004-07 Scott Ellis -Copyright 2004 Universite Louis PASTEUR, STRASBOURG. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "metacontacts.h" - -///////////////////////////////////////////////////////////////////////////////////////// -// icolib support - -static IconItem iconList[] = { - { LPGEN("Toggle off"), "off", IDI_MCMENUOFF }, - { LPGEN("Toggle on"), "on", IDI_MCMENU }, - { LPGEN("Convert to metacontact"), "convert", IDI_MCCONVERT }, - { LPGEN("Add to existing"), "add", IDI_MCADD }, - { LPGEN("Edit"), "edit", IDI_MCEDIT }, - { LPGEN("Set to default"), "default", IDI_MCSETDEFAULT }, - { LPGEN("Remove"), "remove", IDI_MCREMOVE }, -}; - -HANDLE GetIconHandle(IconIndex i) -{ - return iconList[i].hIcolib; -} - -HICON LoadIconEx(IconIndex i) -{ - return Skin_GetIcon(iconList[i].szName); -} - -void UnloadMetacontacts(void) -{ - Meta_CloseHandles(); -} - -// Initializes the services provided and the link to those needed -// Called when the plugin is loaded into Miranda -int LoadMetacontacts(void) -{ - Icon_Register(hInst, LPGEN("MetaContacts"), iconList, SIZEOF(iconList), "mc"); - - db_set_resident(META_PROTO, "Status"); - db_set_resident(META_PROTO, "IdleTS"); - - //set all contacts to 'offline', and initialize subcontact counter for db consistency check - for (MCONTACT hContact = db_find_first(META_PROTO); hContact; hContact = db_find_next(hContact, META_PROTO)) { - db_set_w(hContact, META_PROTO, "Status", ID_STATUS_OFFLINE); - db_set_dw(hContact, META_PROTO, "IdleTS", 0); - } - - Meta_ReadOptions(); - - PROTOCOLDESCRIPTOR pd = { 0 }; - pd.cbSize = sizeof(pd); - pd.szName = META_FILTER; - pd.type = PROTOTYPE_FILTER; - CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); - - pd.szName = META_PROTO; - pd.type = PROTOTYPE_VIRTUAL; - CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); - - // further db setup done in modules loaded (nick [protocol string required] & clist display name) - Meta_InitServices(); - return 0; -} diff --git a/src/modules/metacontacts/meta_menu.cpp b/src/modules/metacontacts/meta_menu.cpp deleted file mode 100644 index e2a78aff38..0000000000 --- a/src/modules/metacontacts/meta_menu.cpp +++ /dev/null @@ -1,449 +0,0 @@ -/* -former MetaContacts Plugin for Miranda IM. - -Copyright 2014 Miranda NG Team -Copyright 2004-07 Scott Ellis -Copyright 2004 Universite Louis PASTEUR, STRASBOURG. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include -#include "metacontacts.h" - -static HGENMENU hMenuContact[MAX_CONTACTS]; - -static HGENMENU - hMenuRoot, // root menu item of all subs - hMenuConvert, // HANDLE to the convert menu item. - hMenuAdd, // HANDLE to the add to menu item. - hMenuEdit, // HANDLE to the edit menu item. - hMenuDelete, // HANDLE to the delete menu item. - hMenuDefault, // HANDLE to the delete menu item. - hMenuForceDefault, // HANDLE to the delete menu item. - hMenuOnOff; // HANDLE to the enable/disable menu item. - -///////////////////////////////////////////////////////////////////////////////////////// -// Convert the contact chosen into a MetaContact. -// -// Create a new MetaContact, remove the selected contact from the \c CList -// and attach it to the MetaContact. -// -// @param wParam : HANDLE to the contact that has been chosen. -// @param lParam : Allways set to 0. - -INT_PTR Meta_Convert(WPARAM wParam, LPARAM) -{ - ptrT tszGroup(db_get_tsa(wParam, "CList", "Group")); - - // Create a new metacontact - MCONTACT hMetaContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0); - if (hMetaContact == NULL) - return NULL; - - DBCachedContact *cc = currDb->m_cache->GetCachedContact(hMetaContact); - if (cc == NULL) - return 0; - - db_set_dw(hMetaContact, META_PROTO, "NumContacts", 0); - cc->nSubs = 0; - currDb->MetaSetDefault(cc); // explicitly write default sub to a db - - // Add the MetaContact protocol to the new meta contact - CallService(MS_PROTO_ADDTOCONTACT, hMetaContact, (LPARAM)META_PROTO); - - if (tszGroup) - db_set_ts(hMetaContact, "CList", "Group", tszGroup); - - // Assign the contact to the MetaContact just created (and make default). - if (!Meta_Assign(wParam, hMetaContact, TRUE)) { - MessageBox(0, TranslateT("There was a problem in assigning the contact to the metacontact"), TranslateT("Error"), MB_ICONEXCLAMATION); - CallService(MS_DB_CONTACT_DELETE, hMetaContact, 0); - return 0; - } - - // hide the contact if clist groups disabled (shouldn't create one anyway since menus disabled) - if (!db_mc_isEnabled()) - db_set_b(hMetaContact, "CList", "Hidden", 1); - - return hMetaContact; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Removes a sub from a metacontact - -void Meta_RemoveContactNumber(DBCachedContact *ccMeta, int number, bool bUpdateInfo) -{ - if (ccMeta == NULL) - return; - - // make sure this contact thinks it's part of this metacontact - DBCachedContact *ccSub = currDb->m_cache->GetCachedContact(Meta_GetContactHandle(ccMeta, number)); - if (ccSub != NULL) { - if (ccSub->parentID == ccMeta->contactID) { - db_unset(ccSub->contactID, "CList", "Hidden"); - - // stop ignoring, if we were - if (options.bSuppressStatus) - CallService(MS_IGNORE_UNIGNORE, ccSub->contactID, IGNOREEVENT_USERONLINE); - } - } - - // each contact from 'number' upwards will be moved down one - // and the last one will be deleted - for (int i = number+1; i < ccMeta->nSubs; i++) - Meta_SwapContacts(ccMeta, i, i - 1); - - // remove the last one - int id = ccMeta->nSubs - 1; - char buffer[512]; - mir_snprintf(buffer, "Handle%d", id); - db_unset(ccMeta->contactID, META_PROTO, buffer); - - mir_snprintf(buffer, "Protocol%d", id); - db_unset(ccMeta->contactID, META_PROTO, buffer); - - mir_snprintf(buffer, "Status%d", id); - db_unset(ccMeta->contactID, META_PROTO, buffer); - - mir_snprintf(buffer, "StatusString%d", id); - db_unset(ccMeta->contactID, META_PROTO, buffer); - - mir_snprintf(buffer, "Login%d", id); - db_unset(ccMeta->contactID, META_PROTO, buffer); - - mir_snprintf(buffer, "Nick%d", id); - db_unset(ccMeta->contactID, META_PROTO, buffer); - - mir_snprintf(buffer, "CListName%d", id); - db_unset(ccMeta->contactID, META_PROTO, buffer); - - if (ccSub != NULL) { - ccSub->parentID = 0; - currDb->MetaDetouchSub(ccMeta, ccMeta->nSubs - 1); - - currDb->MetaSplitHistory(ccMeta, ccSub); - } - - // if the default contact was equal to or greater than 'number', decrement it (and deal with ends) - if (ccMeta->nDefault >= number) { - int iNumber = ccMeta->nDefault-1; - if (iNumber < 0) - iNumber = 0; - db_mc_setDefaultNum(ccMeta->contactID, iNumber, true); - } - - ccMeta->nSubs--; - db_set_dw(ccMeta->contactID, META_PROTO, "NumContacts", ccMeta->nSubs); - - if (bUpdateInfo) { - // fix nick - Meta_CopyContactNick(ccMeta, Meta_GetMostOnline(ccMeta)); - - // fix status - Meta_FixStatus(ccMeta); - - // fix avatar - MCONTACT hContact = Meta_GetMostOnlineSupporting(ccMeta, PFLAGNUM_4, PF4_AVATARS); - if (hContact) { - PROTO_AVATAR_INFORMATION ai = { 0 }; - ai.hContact = ccMeta->contactID; - ai.format = PA_FORMAT_UNKNOWN; - _tcsncpy_s(ai.filename, _T("X"), _TRUNCATE); - - if (CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&ai) == GAIR_SUCCESS) - db_set_ts(ccMeta->contactID, "ContactPhoto", "File", ai.filename); - } - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Delete a MetaContact from the database -// -// Delete a MetaContact and remove all the information -// concerning this MetaContact in the contact linked to it. -// -// @param wParam : HANDLE to the MetaContact to be deleted, or to the subcontact to be removed from the MetaContact -// @param lParam : BOOL flag indicating whether to ask 'are you sure' when deleting a MetaContact - -INT_PTR Meta_Delete(WPARAM hContact, LPARAM bSkipQuestion) -{ - DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact); - if (cc == NULL) - return 1; - - // The wParam is a metacontact - if (cc->IsMeta()) { - // check from recursion - see second half of this function - if (!bSkipQuestion && IDYES != - MessageBox((HWND)CallService(MS_CLUI_GETHWND, 0, 0), - TranslateT("This will remove the metacontact permanently.\n\nProceed anyway?"), - TranslateT("Are you sure?"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2)) - return 0; - - for (int i = cc->nSubs-1; i >= 0; i--) - Meta_RemoveContactNumber(cc, i, false); - - NotifyEventHooks(hSubcontactsChanged, hContact, 0); - CallService(MS_DB_CONTACT_DELETE, hContact, 0); - } - else if (cc->IsSub()) { - if ((cc = currDb->m_cache->GetCachedContact(cc->parentID)) == NULL) - return 2; - - if (cc->nSubs == 1) { - if (IDYES == MessageBox(0, TranslateT(szDelMsg), TranslateT("Delete metacontact?"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1)) - Meta_Delete(cc->contactID, 1); - - return 0; - } - - Meta_RemoveContactNumber(cc, Meta_GetContactNumber(cc, hContact), true); - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Set contact as MetaContact default -// -// Set the given contact to be the default one for the metacontact to which it is linked. -// -// @param wParam : HANDLE to the MetaContact to be set as default -// @param lParam : HWND to the clist window -// (This means the function has been called via the contact menu). - -INT_PTR Meta_Default(WPARAM hSub, LPARAM) -{ - DBCachedContact *cc = currDb->m_cache->GetCachedContact(db_mc_getMeta(hSub)); - if (cc && cc->IsMeta()) - db_mc_setDefault(cc->contactID, hSub, true); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Called when the context-menu of a contact is about to be displayed -// -// This will test which of the 4 menu item should be displayed, depending -// on which contact triggered the event -// -// @param wParam : HANDLE to the contact that triggered the event -// @param lParam : Always set to 0; - -int Meta_ModifyMenu(WPARAM hMeta, LPARAM) -{ - DBCachedContact *cc = currDb->m_cache->GetCachedContact(hMeta); - if (cc == NULL) - return 0; - - CLISTMENUITEM mi = { sizeof(mi) }; - Menu_ShowItem(hMenuRoot, false); - - if (cc->IsMeta()) { - // save the mouse pos in case they open a subcontact menu - GetCursorPos(&menuMousePoint); - - // This is a MetaContact, show the edit, force default, and the delete menu, and hide the others - Menu_ShowItem(hMenuEdit, true); - Menu_ShowItem(hMenuAdd, false); - Menu_ShowItem(hMenuConvert, false); - Menu_ShowItem(hMenuDefault, false); - Menu_ShowItem(hMenuDelete, false); - - mi.flags = CMIM_NAME; - mi.pszName = LPGEN("Remove from metacontact"); - Menu_ModifyItem(hMenuDelete, &mi); - - // show subcontact menu items - CMString tszNick; - for (int i = 0; i < MAX_CONTACTS; i++) { - if (i >= cc->nSubs) { - Menu_ShowItem(hMenuContact[i], false); - continue; - } - - MCONTACT hContact = Meta_GetContactHandle(cc, i); - char *szProto = GetContactProto(hContact); - - if (options.menu_contact_label == DNT_UID) { - Meta_GetSubNick(hMeta, i, tszNick); - mi.ptszName = tszNick.GetBuffer(); - } - else mi.ptszName = cli.pfnGetContactDisplayName(hContact, 0); - - mi.flags = CMIF_TCHAR | CMIM_FLAGS | CMIM_NAME | CMIM_ICON; - - int iconIndex = CallService(MS_CLIST_GETCONTACTICON, hContact, 0); - mi.hIcon = ImageList_GetIcon((HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), iconIndex, 0); - - Menu_ModifyItem(hMenuContact[i], &mi); - DestroyIcon(mi.hIcon); - - Menu_ShowItem(hMenuRoot, true); - } - - // show hide nudge menu item - char serviceFunc[256]; - mir_snprintf(serviceFunc, SIZEOF(serviceFunc), "%s%s", GetContactProto(Meta_GetMostOnline(cc)), PS_SEND_NUDGE); - CallService(MS_NUDGE_SHOWMENU, (WPARAM)META_PROTO, ServiceExists(serviceFunc)); - return 0; - } - - PROTOACCOUNT *pa = Proto_GetAccount(cc->szProto); - if (!db_mc_isEnabled() || !pa || pa->bIsVirtual) { - // groups disabled - all meta menu options hidden - Menu_ShowItem(hMenuDefault, false); - Menu_ShowItem(hMenuDelete, false); - Menu_ShowItem(hMenuAdd, false); - Menu_ShowItem(hMenuConvert, false); - Menu_ShowItem(hMenuEdit, false); - return 0; - } - - // the contact is affected to a metacontact - if (cc->IsSub()) { - Menu_ShowItem(hMenuDefault, true); - - mi.flags = CMIM_NAME; - mi.pszName = LPGEN("Remove from metacontact"); - Menu_ModifyItem(hMenuDelete, &mi); - Menu_ShowItem(hMenuDelete, true); - - Menu_ShowItem(hMenuAdd, false); - Menu_ShowItem(hMenuConvert, false); - Menu_ShowItem(hMenuEdit, false); - } - else { - // The contact is neutral - bool bHideChat = db_get_b(hMeta, cc->szProto, "ChatRoom", 0) == 0; - Menu_ShowItem(hMenuAdd, bHideChat); - Menu_ShowItem(hMenuConvert, bHideChat); - Menu_ShowItem(hMenuEdit, false); - Menu_ShowItem(hMenuDelete, false); - Menu_ShowItem(hMenuDefault, false); - } - - for (int i = 0; i < MAX_CONTACTS; i++) - Menu_ShowItem(hMenuContact[i], false); - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Toggle metacontacts on/off - -INT_PTR Meta_OnOff(WPARAM, LPARAM) -{ - CLISTMENUITEM mi = { sizeof(mi) }; - mi.flags = CMIM_NAME | CMIM_ICON; - - bool bToggled = !db_mc_isEnabled(); - db_set_b(0, META_PROTO, "Enabled", bToggled); - if (bToggled) { - mi.icolibItem = GetIconHandle(I_MENUOFF); - mi.pszName = LPGEN("Toggle metacontacts off"); - } - else { - mi.icolibItem = GetIconHandle(I_MENU); - mi.pszName = LPGEN("Toggle metacontacts on"); - } - Menu_ModifyItem(hMenuOnOff, &mi); - - db_mc_enable(bToggled); - Meta_HideMetaContacts(!bToggled); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Menu initialization - -void InitMenus() -{ - CLISTMENUITEM mi = { sizeof(mi) }; - - // main menu item - mi.icolibItem = GetIconHandle(I_MENUOFF); - mi.pszName = LPGEN("Toggle metacontacts off"); - mi.pszService = "MetaContacts/OnOff"; - mi.position = 500010000; - hMenuOnOff = Menu_AddMainMenuItem(&mi); - - // contact menu items - mi.icolibItem = GetIconHandle(I_CONVERT); - mi.position = -200010; - mi.pszName = LPGEN("Convert to metacontact"); - mi.pszService = "MetaContacts/Convert"; - hMenuConvert = Menu_AddContactMenuItem(&mi); - - mi.icolibItem = GetIconHandle(I_ADD); - mi.position = -200009; - mi.pszName = LPGEN("Add to existing metacontact..."); - mi.pszService = "MetaContacts/AddTo"; - hMenuAdd = Menu_AddContactMenuItem(&mi); - - mi.icolibItem = GetIconHandle(I_EDIT); - mi.position = -200010; - mi.pszName = LPGEN("Edit metacontact..."); - mi.pszService = "MetaContacts/Edit"; - hMenuEdit = Menu_AddContactMenuItem(&mi); - - mi.icolibItem = GetIconHandle(I_SETDEFAULT); - mi.position = -200009; - mi.pszName = LPGEN("Set as metacontact default"); - mi.pszService = "MetaContacts/Default"; - hMenuDefault = Menu_AddContactMenuItem(&mi); - - mi.icolibItem = GetIconHandle(I_REMOVE); - mi.position = -200008; - mi.pszName = LPGEN("Delete metacontact"); - mi.pszService = "MetaContacts/Delete"; - hMenuDelete = Menu_AddContactMenuItem(&mi); - - mi.position = -99000; - mi.flags = CMIF_HIDDEN | CMIF_ROOTPOPUP; - mi.icolibItem = 0; - mi.pszName = LPGEN("Subcontacts"); - hMenuRoot = Menu_AddContactMenuItem(&mi); - - mi.flags = CMIF_HIDDEN | CMIF_CHILDPOPUP; - mi.hParentMenu = hMenuRoot; - for (int i = 0; i < MAX_CONTACTS; i++) { - mi.position--; - mi.pszName = ""; - - char buffer[512]; - mir_snprintf(buffer, "MetaContacts/MenuFunc%d", i); - mi.pszService = buffer; - mi.position++; - hMenuContact[i] = Menu_AddContactMenuItem(&mi); - } - - Meta_HideLinkedContacts(); - - if (!db_mc_isEnabled()) { - // modify main menu item - mi.flags = CMIM_NAME | CMIM_ICON; - mi.icolibItem = GetIconHandle(I_MENU); - mi.pszName = LPGEN("Toggle metacontacts on"); - Menu_ModifyItem(hMenuOnOff, &mi); - - Meta_HideMetaContacts(true); - } - else { - Meta_SuppressStatus(options.bSuppressStatus); - Meta_HideMetaContacts(false); - } -} diff --git a/src/modules/metacontacts/meta_options.cpp b/src/modules/metacontacts/meta_options.cpp deleted file mode 100644 index 0ff0b9b48c..0000000000 --- a/src/modules/metacontacts/meta_options.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* -former MetaContacts Plugin for Miranda IM. - -Copyright 2014 Miranda NG Team -Copyright 2004-07 Scott Ellis -Copyright 2004 Universite Louis PASTEUR, STRASBOURG. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "metacontacts.h" - -MetaOptions options; - -int Meta_WriteOptions() -{ - db_set_b(NULL, META_PROTO, "LockHandle", options.bLockHandle); - db_set_b(NULL, META_PROTO, "SuppressStatus", options.bSuppressStatus); - db_set_w(NULL, META_PROTO, "MenuContactLabel", (WORD)options.menu_contact_label); - db_set_w(NULL, META_PROTO, "MenuContactFunction", (WORD)options.menu_function); - db_set_w(NULL, META_PROTO, "CListContactName", (WORD)options.clist_contact_name); - db_set_dw(NULL, META_PROTO, "SetStatusFromOfflineDelay", (DWORD)(options.set_status_from_offline_delay)); - return 0; -} - -int Meta_ReadOptions() -{ - db_mc_enable(db_get_b(NULL, META_PROTO, "Enabled", true) != 0); - options.bSuppressStatus = db_get_b(NULL, META_PROTO, "SuppressStatus", true) != 0; - options.menu_contact_label = (int)db_get_w(NULL, META_PROTO, "MenuContactLabel", DNT_UID); - options.menu_function = (int)db_get_w(NULL, META_PROTO, "MenuContactFunction", FT_MENU); - options.clist_contact_name = (int)db_get_w(NULL, META_PROTO, "CListContactName", CNNT_DISPLAYNAME); - options.set_status_from_offline_delay = (int)db_get_dw(NULL, META_PROTO, "SetStatusFromOfflineDelay", DEFAULT_SET_STATUS_SLEEP_TIME); - options.bLockHandle = db_get_b(NULL, META_PROTO, "LockHandle", false) != 0; - return 0; -} - -class CMetaOptionsDlg : public CDlgBase -{ - CCtrlCheck m_btnUid, m_btnDid, m_btnCheck; - CCtrlCheck m_btnMsg, m_btnMenu, m_btnInfo; - CCtrlCheck m_btnNick, m_btnName, m_btnLock; - -public: - CMetaOptionsDlg() : - CDlgBase(hInst, IDD_METAOPTIONS), - m_btnUid(this, IDC_RAD_UID), - m_btnDid(this, IDC_RAD_DID), - m_btnMsg(this, IDC_RAD_MSG), - m_btnMenu(this, IDC_RAD_MENU), - m_btnInfo(this, IDC_RAD_INFO), - m_btnNick(this, IDC_RAD_NICK), - m_btnName(this, IDC_RAD_NAME), - m_btnLock(this, IDC_CHK_LOCKHANDLE), - m_btnCheck(this, IDC_CHK_SUPPRESSSTATUS) - { - } - - virtual void OnInitDialog() - { - m_btnLock.SetState(options.bLockHandle); - m_btnCheck.SetState(options.bSuppressStatus); - - if (options.menu_contact_label == DNT_UID) - m_btnUid.SetState(true); - else - m_btnDid.SetState(true); - - switch (options.menu_function) { - case FT_MSG: m_btnMsg.SetState(true); break; - case FT_MENU: m_btnMenu.SetState(true); break; - case FT_INFO: m_btnInfo.SetState(true); break; - } - - if (options.clist_contact_name == CNNT_NICK) - m_btnNick.SetState(true); - else - m_btnName.SetState(true); - } - - virtual void OnApply() - { - options.bLockHandle = m_btnLock.GetState() != 0; - options.bSuppressStatus = m_btnCheck.GetState() != 0; - - if (m_btnUid.GetState()) options.menu_contact_label = DNT_UID; - else if (m_btnDid.GetState()) options.menu_contact_label = DNT_DID; - - if (m_btnMsg.GetState()) options.menu_function = FT_MSG; - else if (m_btnMenu.GetState()) options.menu_function = FT_MENU; - else if (m_btnInfo.GetState()) options.menu_function = FT_INFO; - - if (m_btnNick.GetState()) options.clist_contact_name = CNNT_NICK; - else if (m_btnName.GetState()) options.clist_contact_name = CNNT_DISPLAYNAME; - - Meta_WriteOptions(); - - Meta_SuppressStatus(options.bSuppressStatus); - Meta_SetAllNicks(); - } -}; - -///////////////////////////////////////////////////////////////////////////////////////// - -int Meta_OptInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.position = -790000000; - odp.flags = ODPF_BOLDGROUPS; - odp.pszTitle = LPGEN("Metacontacts"); - odp.pszGroup = LPGEN("Contacts"); - odp.pDialog = new CMetaOptionsDlg(); - Options_AddPage(wParam, &odp); - return 0; -} diff --git a/src/modules/metacontacts/meta_services.cpp b/src/modules/metacontacts/meta_services.cpp deleted file mode 100644 index 72f60c5f71..0000000000 --- a/src/modules/metacontacts/meta_services.cpp +++ /dev/null @@ -1,912 +0,0 @@ -/* -former MetaContacts Plugin for Miranda IM. - -Copyright 2014 Miranda NG Team -Copyright 2004-07 Scott Ellis -Copyright 2004 Universite Louis PASTEUR, STRASBOURG. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include - -#include "metacontacts.h" - -extern "C" MIR_CORE_DLL(void) db_mc_notifyDefChange(WPARAM wParam, LPARAM lParam); - -char *pendingACK = 0; // Name of the protocol in which an ACK is about to come. - -int previousMode, // Previous status of the MetaContacts Protocol -mcStatus; // Current status of the MetaContacts Protocol - -HANDLE -hSubcontactsChanged, // HANDLE to the 'contacts changed' event -hEventNudge; - -UINT_PTR setStatusTimerId = 0; -BOOL firstSetOnline = TRUE; // see Meta_SetStatus function - -OBJLIST arMetaWindows(1, NumericKeySortT); - -/** Get the capabilities of the "MetaContacts" protocol. -* -* @param wParam : equals to one of the following values :\n - PFLAGNUM_1 | PFLAGNUM_2 | PFLAGNUM_3 | PFLAGNUM_4 | PFLAG_UNIQUEIDTEXT | PFLAG_MAXLENOFMESSAGE | PFLAG_UNIQUEIDSETTING . -* @param lParam : Allways set to 0. -* -* @return Depending on the \c WPARAM. -*/ -INT_PTR Meta_GetCaps(WPARAM wParam, LPARAM lParam) -{ - switch (wParam) { - case PFLAGNUM_1: - return PF1_IM | PF1_CHAT | PF1_FILESEND | PF1_MODEMSGRECV | PF1_NUMERICUSERID; - - case PFLAGNUM_2: - return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE; - - case PFLAGNUM_3: - return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE; - - case PFLAGNUM_4: - return PF4_SUPPORTTYPING | PF4_AVATARS; - - case PFLAGNUM_5: - return PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE; - - case PFLAG_MAXLENOFMESSAGE: - return 2000; - } - return 0; -} - -/** Copy the name of the protocole into lParam -* @param wParam : max size of the name -* @param lParam : reference to a char *, which will hold the name -*/ - -INT_PTR Meta_GetName(WPARAM wParam, LPARAM lParam) -{ - char *name = (char *)Translate(META_PROTO); - size_t size = min(mir_strlen(name), wParam - 1); // copy only the first size bytes. - if (strncpy((char *)lParam, name, size) == NULL) - return 1; - ((char *)lParam)[size] = '\0'; - return 0; -} - -/** Loads the icon corresponding to the status -* Called by the CList when the status changes. -* @param wParam : one of the following values : \n -PLI_PROTOCOL | PLI_ONLINE | PLI_OFFLINE -* @return an \c HICON in which the icon has been loaded. -*/ - -INT_PTR Meta_LoadIcon(WPARAM wParam, LPARAM lParam) -{ - UINT id; - switch (wParam & 0xFFFF) { - case PLI_PROTOCOL: - id = IDI_MCMENU; - break; - case PLI_ONLINE: - id = IDI_MCMENU; - break; - case PLI_OFFLINE: - id = IDI_MCMENU; - break; - default: - return 0; - } - - return (INT_PTR)LoadImage(hInst, MAKEINTRESOURCE(id), IMAGE_ICON, - GetSystemMetrics(wParam & PLIF_SMALL ? SM_CXSMICON : SM_CXICON), - GetSystemMetrics(wParam & PLIF_SMALL ? SM_CYSMICON : SM_CYICON), 0); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static void Meta_SetSrmmSub(MCONTACT hMeta, MCONTACT hSub) -{ - MetaSrmmData tmp = { hMeta }; - if (MetaSrmmData *p = arMetaWindows.find(&tmp)) - p->m_hSub = hSub; -} - -static INT_PTR MetaFilter_RecvMessage(WPARAM wParam, LPARAM lParam) -{ - CCSDATA *ccs = (CCSDATA*)lParam; - DBCachedContact *cc = currDb->m_cache->GetCachedContact(ccs->hContact); - if (cc && cc->IsSub()) - Meta_SetSrmmSub(cc->parentID, cc->contactID); - - CallService(MS_PROTO_CHAINRECV, wParam, lParam); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void CALLBACK SetStatusThread(HWND hWnd, UINT msg, UINT_PTR id, DWORD dw) -{ - previousMode = mcStatus; - - mcStatus = ID_STATUS_ONLINE; - ProtoBroadcastAck(META_PROTO, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)previousMode, mcStatus); - - KillTimer(0, setStatusTimerId); -} - -/** Changes the status and notifies everybody -* @param wParam : The new mode -* @param lParam : Allways set to 0. -*/ - -INT_PTR Meta_SetStatus(WPARAM wParam, LPARAM lParam) -{ - // firstSetOnline starts out true - used to delay metacontact's 'onlineness' to prevent double status notifications on startup - if (mcStatus == ID_STATUS_OFFLINE && firstSetOnline) { - // causes crash on exit if miranda is closed in under options.set_status_from_offline milliseconds! - setStatusTimerId = SetTimer(0, 0, options.set_status_from_offline_delay, SetStatusThread); - firstSetOnline = FALSE; - } - else { - previousMode = mcStatus; - mcStatus = (int)wParam; - ProtoBroadcastAck(META_PROTO, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)previousMode, mcStatus); - } - return 0; -} - -/** Returns the current status -*/ -INT_PTR Meta_GetStatus(WPARAM wParam, LPARAM lParam) -{ - return mcStatus; -} - -////////////////////////////////////////////////////////// -/// Copied from MSN plugin - sent acks need to be from different thread :( -////////////////////////////////////////////////////////// - -struct TFakeAckParams -{ - HANDLE hEvent; - MCONTACT hContact; - LONG id; - char msg[512]; -}; - -static void __cdecl sttFakeAckFail(void *param) -{ - TFakeAckParams *tParam = (TFakeAckParams*)param; - WaitForSingleObject(tParam->hEvent, INFINITE); - - Sleep(100); - ProtoBroadcastAck(META_PROTO, tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)tParam->id, (WPARAM)tParam->msg); - - CloseHandle(tParam->hEvent); - mir_free(tParam); -} - -INT_PTR Meta_SendNudge(WPARAM wParam, LPARAM lParam) -{ - DBCachedContact *cc = CheckMeta(wParam); - if (cc == NULL) - return 1; - - MCONTACT hSubContact = Meta_GetMostOnline(cc); - return CallProtoService(GetContactProto(hSubContact), PS_SEND_NUDGE, hSubContact, lParam); -} - -/** Send a message to the protocol specific network. -* -* Call the function specific to the protocol that belongs -* to the contact chosen to send the message. -* -* @param wParam : index of the protocol in the protocol chain. -* @param lParam : CCSDATA structure holding all the information abour rhe message. -* -* @return 0 on success, 1 otherwise. -*/ - -INT_PTR Meta_SendMessage(WPARAM wParam, LPARAM lParam) -{ - CCSDATA *ccs = (CCSDATA*)lParam; - - DBCachedContact *cc = CheckMeta(ccs->hContact); - if (cc == NULL || cc->nDefault == -1) { - // This is a simple contact, let through the stack of protocols - // (this should normally not happen, since linked contacts do not appear on the list.) - return CallService(MS_PROTO_CHAINSEND, wParam, lParam); - } - - MCONTACT hMostOnline = db_mc_getSrmmSub(cc->contactID); - if (!hMostOnline) { - // send failure to notify user of reason - HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - - TFakeAckParams *tfap = (TFakeAckParams *)mir_alloc(sizeof(TFakeAckParams)); - tfap->hContact = ccs->hContact; - tfap->hEvent = hEvent; - tfap->id = 10; - strncpy(tfap->msg, Translate("No online contacts found."), SIZEOF(tfap->msg) - 1); - - CloseHandle(mir_forkthread(sttFakeAckFail, (void*)tfap)); - SetEvent(hEvent); - return 10; - } - - Meta_CopyContactNick(cc, hMostOnline); - - ccs->hContact = hMostOnline; - char *proto = GetContactProto(hMostOnline); - Meta_SetNick(proto); // (no matter what was there before) - - return CallContactService(ccs->hContact, PSS_MESSAGE, ccs->wParam, ccs->lParam); -} - -/** Called when an ACK is received. -* -* Retransmit the ACK sent by a simple contact so that it -* looks like it was the MetaContact that sends the ACK. -* -* @param wParam : Allways set to 0. -* @param lParam : Reference to a ACKDATA that contains information about the ACK. -* @returns 0 on success, 1 otherwise. -*/ - -int Meta_HandleACK(WPARAM, LPARAM lParam) -{ - ACKDATA *ack = (ACKDATA*)lParam; - if (ack == NULL) - return 0; - DBCachedContact *cc = CheckMeta(ack->hContact); - if (cc == NULL) - return 0; - - if (!mir_strcmp(ack->szModule, META_PROTO)) - return 0; // don't rebroadcast our own acks - - // if it's for something we don't support, ignore - if (ack->type != ACKTYPE_MESSAGE && ack->type != ACKTYPE_CHAT && ack->type != ACKTYPE_FILE && ack->type != ACKTYPE_AWAYMSG && ack->type != ACKTYPE_AVATAR && ack->type != ACKTYPE_GETINFO) - return 0; - - // change the hContact in the avatar info struct, if it's the avatar we're using - else drop it - if (ack->type == ACKTYPE_AVATAR) { - if (ack->result == ACKRESULT_SUCCESS || ack->result == ACKRESULT_FAILED || ack->result == ACKRESULT_STATUS) { - DBVARIANT dbv; - - // change avatar if the most online supporting avatars changes, or if we don't have one - MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS); - if (ack->hContact == 0 || ack->hContact != hMostOnline) - return 0; - - if (!db_get(ack->hContact, "ContactPhoto", "File", &dbv)) { - db_set_ts(cc->contactID, "ContactPhoto", "File", dbv.ptszVal); - db_free(&dbv); - } - - if (ack->hProcess) { - PROTO_AVATAR_INFORMATION ai; - memcpy(&ai, (PROTO_AVATAR_INFORMATION*)ack->hProcess, sizeof(ai)); - if (ai.hContact) - ai.hContact = cc->contactID; - - return ProtoBroadcastAck(META_PROTO, cc->contactID, ack->type, ack->result, (HANDLE)&ai, ack->lParam); - } - - return ProtoBroadcastAck(META_PROTO, cc->contactID, ack->type, ack->result, 0, ack->lParam); - } - } - - return ProtoBroadcastAck(META_PROTO, cc->contactID, ack->type, ack->result, ack->hProcess, ack->lParam); -} - -/** Call whenever a contact changes one of its settings (for example, the status) -** -* @param wParam HANDLE to the contact that has change of its setting. -* @param lParam Reference to a structure that contains the setting that has changed (not used) -*/ - -int Meta_SettingChanged(WPARAM hContact, LPARAM lParam) -{ - DBCONTACTWRITESETTING *dcws = (DBCONTACTWRITESETTING *)lParam; - char buffer[512]; - - // the only global options we're interested in - if (hContact == 0) - return 0; - - DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact); - if (cc == NULL || !cc->IsSub()) - return 0; - - DBCachedContact *ccMeta = currDb->m_cache->GetCachedContact(cc->parentID); - if (ccMeta == NULL || !ccMeta->IsMeta()) - return 0; - - // This contact is attached to a MetaContact. - int contact_number = Meta_GetContactNumber(ccMeta, hContact); - if (contact_number == -1) - return 0; // exit - db corruption - - if (!mir_strcmp(dcws->szSetting, "IP")) { - if (dcws->value.type == DBVT_DWORD) - db_set_dw(ccMeta->contactID, META_PROTO, "IP", dcws->value.dVal); - else - db_unset(ccMeta->contactID, META_PROTO, "IP"); - } - else if (!mir_strcmp(dcws->szSetting, "RealIP")) { - if (dcws->value.type == DBVT_DWORD) - db_set_dw(ccMeta->contactID, META_PROTO, "RealIP", dcws->value.dVal); - else - db_unset(ccMeta->contactID, META_PROTO, "RealIP"); - } - else if (!mir_strcmp(dcws->szSetting, "ListeningTo")) { - switch (dcws->value.type) { - case DBVT_ASCIIZ: - db_set_s(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal); - break; - case DBVT_UTF8: - db_set_utf(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal); - break; - case DBVT_WCHAR: - db_set_ws(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pwszVal); - break; - case DBVT_DELETED: - db_unset(ccMeta->contactID, META_PROTO, "ListeningTo"); - break; - } - } - else if (!mir_strcmp(dcws->szSetting, "Nick") && dcws->value.type != DBVT_DELETED) { - // subcontact nick has changed - update metacontact - mir_snprintf(buffer, "Nick%d", contact_number); - db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value); - - ptrT tszMyhandle(db_get_tsa(hContact, "CList", "MyHandle")); - if (tszMyhandle == NULL) { - mir_snprintf(buffer, "CListName%d", contact_number); - db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value); - } - - // copy nick to metacontact, if it's the most online - MCONTACT hMostOnline = Meta_GetMostOnline(ccMeta); - Meta_CopyContactNick(ccMeta, hMostOnline); - } - else if (!mir_strcmp(dcws->szSetting, "IdleTS")) { - if (dcws->value.type == DBVT_DWORD) - db_set_dw(ccMeta->contactID, META_PROTO, "IdleTS", dcws->value.dVal); - else if (dcws->value.type == DBVT_DELETED) - db_set_dw(ccMeta->contactID, META_PROTO, "IdleTS", 0); - } - else if (!mir_strcmp(dcws->szSetting, "LogonTS")) { - if (dcws->value.type == DBVT_DWORD) - db_set_dw(ccMeta->contactID, META_PROTO, "LogonTS", dcws->value.dVal); - else if (dcws->value.type == DBVT_DELETED) - db_set_dw(ccMeta->contactID, META_PROTO, "LogonTS", 0); - } - else if (!mir_strcmp(dcws->szModule, "CList") && !mir_strcmp(dcws->szSetting, "MyHandle")) { - if (dcws->value.type == DBVT_DELETED) { - char *proto = GetContactProto(hContact); - mir_snprintf(buffer, "CListName%d", contact_number); - - DBVARIANT dbv; - if (proto && !db_get_ts(hContact, proto, "Nick", &dbv)) { - db_set_ts(ccMeta->contactID, META_PROTO, buffer, dbv.ptszVal); - db_free(&dbv); - } - else db_unset(ccMeta->contactID, META_PROTO, buffer); - } - else { - // subcontact clist displayname has changed - update metacontact - mir_snprintf(buffer, "CListName%d", contact_number); - db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value); - } - - // copy nick to metacontact, if it's the most online - Meta_CopyContactNick(ccMeta, Meta_GetMostOnline(ccMeta)); - } - // subcontact changing status - else if (!mir_strcmp(dcws->szSetting, "Status") && dcws->value.type != DBVT_DELETED) { - // update subcontact status setting - mir_snprintf(buffer, "Status%d", contact_number); - db_set_w(ccMeta->contactID, META_PROTO, buffer, dcws->value.wVal); - - mir_snprintf(buffer, "StatusString%d", contact_number); - db_set_ts(ccMeta->contactID, META_PROTO, buffer, cli.pfnGetStatusModeDescription(dcws->value.wVal, 0)); - - // set status to that of most online contact - MCONTACT hMostOnline = Meta_GetMostOnline(ccMeta); - if (hMostOnline != db_mc_getDefault(ccMeta->contactID)) - db_mc_notifyDefChange(ccMeta->contactID, hMostOnline); - - Meta_CopyContactNick(ccMeta, hMostOnline); - Meta_FixStatus(ccMeta); - - // most online contact with avatar support might have changed - update avatar - hMostOnline = Meta_GetMostOnlineSupporting(ccMeta, PFLAGNUM_4, PF4_AVATARS); - if (hMostOnline) { - PROTO_AVATAR_INFORMATION ai = { 0 }; - ai.hContact = ccMeta->contactID; - ai.format = PA_FORMAT_UNKNOWN; - _tcsncpy_s(ai.filename, _T("X"), _TRUNCATE); - if (CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&ai) == GAIR_SUCCESS) - db_set_ts(ccMeta->contactID, "ContactPhoto", "File", ai.filename); - } - } - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Contact's deletion hook - -int Meta_ContactDeleted(WPARAM hContact, LPARAM lParam) -{ - DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact); - if (cc == NULL) - return 0; - - // is a subcontact - update meta contact - if (cc->IsSub()) { - DBCachedContact *ccMeta = CheckMeta(cc->parentID); - if (ccMeta) { - Meta_RemoveContactNumber(ccMeta, Meta_GetContactNumber(ccMeta, hContact), true); - NotifyEventHooks(hSubcontactsChanged, ccMeta->contactID, 0); - - // no more subs? remove the meta itself - if (ccMeta->nSubs == 0) - CallService(MS_DB_CONTACT_DELETE, ccMeta->contactID, 0); - } - return 0; - } - - // not a subcontact - is it a metacontact? - if (!cc->IsMeta()) - return 0; - - if (cc->nSubs > 0) - NotifyEventHooks(hSubcontactsChanged, hContact, 0); - - // remove & restore all subcontacts - for (int i = 0; i < cc->nSubs; i++) { - currDb->MetaDetouchSub(cc, i); - - // stop ignoring, if we were - if (options.bSuppressStatus) - CallService(MS_IGNORE_UNIGNORE, cc->pSubs[i], IGNOREEVENT_USERONLINE); - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Call when we want to send a user is typing message -// -// @param wParam HANDLE to the contact that we are typing to -// @param lParam either PROTOTYPE_SELFTYPING_ON or PROTOTYPE_SELFTYPING_OFF - -static INT_PTR Meta_UserIsTyping(WPARAM hMeta, LPARAM lParam) -{ - DBCachedContact *cc = CheckMeta(hMeta); - if (cc == NULL) - return 0; - - // forward to sending protocol, if supported - MCONTACT hMostOnline = Meta_GetMostOnline(cc); - Meta_CopyContactNick(cc, hMostOnline); - if (!hMostOnline) - return 0; - - char *proto = GetContactProto(hMostOnline); - if (proto) - if (ProtoServiceExists(proto, PSS_USERISTYPING)) - CallProtoService(proto, PSS_USERISTYPING, hMostOnline, lParam); - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Called when user info is about to be shown -// -// Returns 1 to stop event processing and opens page for metacontact default -// contact (returning 1 to stop it doesn't work!) - -static int Meta_UserInfo(WPARAM wParam, LPARAM hMeta) -{ - DBCachedContact *cc = CheckMeta(hMeta); - if (cc == NULL || cc->nDefault == -1) - return 0; - - CallService(MS_USERINFO_SHOWDIALOG, Meta_GetContactHandle(cc, cc->nDefault), 0); - return 1; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// record window open/close status for subs & metas - -static int Meta_MessageWindowEvent(WPARAM wParam, LPARAM lParam) -{ - MessageWindowEventData *mwed = (MessageWindowEventData*)lParam; - if (mwed->uType == MSG_WINDOW_EVT_OPEN) { - DBCachedContact *cc = currDb->m_cache->GetCachedContact(mwed->hContact); - if (cc != NULL) { - Meta_UpdateSrmmIcon(cc, db_get_w(cc->contactID, META_PROTO, "Status", ID_STATUS_OFFLINE)); - if (cc->IsMeta()) { - MetaSrmmData *p = new MetaSrmmData; - p->m_hMeta = cc->contactID; - p->m_hSub = db_mc_getMostOnline(cc->contactID); - p->m_hWnd = mwed->hwndWindow; - arMetaWindows.insert(p); - - if (p->m_hSub != db_mc_getDefault(cc->contactID)) - db_mc_setDefault(cc->contactID, p->m_hSub, false); - } - } - } - else if (mwed->uType == MSG_WINDOW_EVT_CLOSING) { - for (int i = 0; i < arMetaWindows.getCount(); i++) - if (arMetaWindows[i].m_hWnd == mwed->hwndWindow) - arMetaWindows.remove(i); - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// returns manually chosen sub in the meta window - -static INT_PTR Meta_SrmmCurrentSub(WPARAM hMeta, LPARAM lParam) -{ - MetaSrmmData tmp = { hMeta }; - if (MetaSrmmData *p = arMetaWindows.find(&tmp)) - return p->m_hSub; - - return db_mc_getMostOnline(hMeta); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// we assume that it could be called only for the metacontacts - -static int Meta_SrmmIconClicked(WPARAM hMeta, LPARAM lParam) -{ - StatusIconClickData *sicd = (StatusIconClickData*)lParam; - if (mir_strcmp(sicd->szModule, META_PROTO)) - return 0; - - DBCachedContact *cc = CheckMeta(hMeta); - if (cc == NULL) - return 0; - - HMENU hMenu = CreatePopupMenu(); - int iDefault = Meta_GetContactNumber(cc, db_mc_getSrmmSub(cc->contactID)); - - MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_ID | MIIM_STATE | MIIM_STRING; - for (int i = 0; i < cc->nSubs; i++) { - char *szProto = GetContactProto(cc->pSubs[i]); - if (szProto == NULL) continue; - - PROTOACCOUNT *pa = ProtoGetAccount(szProto); - if (pa == NULL) - continue; - - CMString tszNick; - if (options.menu_contact_label == DNT_DID) - tszNick = cli.pfnGetContactDisplayName(cc->pSubs[i], 0); - else - Meta_GetSubNick(hMeta, i, tszNick); - tszNick.AppendFormat(_T(" [%s]"), pa->tszAccountName); - - mii.wID = i + 1; - mii.fState = (i == iDefault) ? MFS_CHECKED : MFS_ENABLED; - mii.dwTypeData = tszNick.GetBuffer(); - mii.cch = tszNick.GetLength(); - InsertMenuItem(hMenu, i, TRUE, &mii); - } - - UINT res = TrackPopupMenu(hMenu, TPM_NONOTIFY | TPM_RETURNCMD | TPM_BOTTOMALIGN | TPM_LEFTALIGN, sicd->clickLocation.x, sicd->clickLocation.y, 0, cli.hwndContactTree, NULL); - if (res > 0) { - MCONTACT hChosen = Meta_GetContactHandle(cc, res - 1); - - MetaSrmmData tmp = { cc->contactID }; - if (MetaSrmmData *p = arMetaWindows.find(&tmp)) - p->m_hSub = hChosen; - - db_mc_setDefault(cc->contactID, hChosen, true); - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Called when all the plugin are loaded into Miranda. -// -// Initializes the 4 menus present in the context-menu - -int Meta_ModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - HookEvent(ME_CLIST_PREBUILDCONTACTMENU, Meta_ModifyMenu); - - // hook srmm window close/open events - HookEvent(ME_MSG_WINDOWEVENT, Meta_MessageWindowEvent); - HookEvent(ME_MSG_ICONPRESSED, Meta_SrmmIconClicked); - - // create menu items - InitMenus(); - - // create srmm icon - StatusIconData sid = { sizeof(sid) }; - sid.szModule = META_PROTO; - sid.flags = MBF_TCHAR; - sid.tszTooltip = LPGENT("Select metacontact"); - sid.hIcon = LoadSkinnedProtoIcon(META_PROTO, ID_STATUS_ONLINE); - Srmm_AddIcon(&sid); - return 0; -} - -static VOID CALLBACK sttMenuThread(PVOID param) -{ - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)param, 0); - - TPMPARAMS tpmp = { 0 }; - tpmp.cbSize = sizeof(tpmp); - BOOL menuRet = TrackPopupMenuEx(hMenu, TPM_RETURNCMD, menuMousePoint.x, menuMousePoint.y, (HWND)CallService(MS_CLUI_GETHWND, 0, 0), &tpmp); - - CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(menuRet), MPCF_CONTACTMENU), (LPARAM)param); - - DestroyMenu(hMenu); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -INT_PTR Meta_ContactMenuFunc(WPARAM hMeta, LPARAM lParam) -{ - DBCachedContact *cc = CheckMeta(hMeta); - if (cc == NULL) - return 0; - - MCONTACT hContact = Meta_GetContactHandle(cc, (int)lParam); - - if (options.menu_function == FT_MSG) { - // open message window if protocol supports message sending or chat, else simulate double click - char *proto = GetContactProto(hContact); - if (proto) { - INT_PTR caps = CallProtoService(proto, PS_GETCAPS, PFLAGNUM_1, 0); - if ((caps & PF1_IMSEND) || (caps & PF1_CHAT)) { - // set default contact for sending/status and open message window - Meta_SetSrmmSub(hMeta, hContact); - db_mc_setDefaultNum(hMeta, lParam, false); - CallService(MS_MSG_SENDMESSAGET, hMeta, 0); - } - else // protocol does not support messaging - simulate double click - CallService(MS_CLIST_CONTACTDOUBLECLICKED, hContact, 0); - } - else // protocol does not support messaging - simulate double click - CallService(MS_CLIST_CONTACTDOUBLECLICKED, hContact, 0); - } - else if (options.menu_function == FT_MENU) // show contact's context menu - CallFunctionAsync(sttMenuThread, (void*)hContact); - else if (options.menu_function == FT_INFO) // show user info for subcontact - CallService(MS_USERINFO_SHOWDIALOG, hContact, 0); - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// file transfer support - mostly not required, since subcontacts do the receiving - -INT_PTR Meta_FileSend(WPARAM wParam, LPARAM lParam) -{ - CCSDATA *ccs = (CCSDATA*)lParam; - DBCachedContact *cc = CheckMeta(ccs->hContact); - if (cc == NULL || cc->nDefault == -1) - return 0; - - MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_FILESEND); - if (!hMostOnline) - return 0; - - char *proto = GetContactProto(hMostOnline); - if (proto) - return CallContactService(hMostOnline, PSS_FILE, ccs->wParam, ccs->lParam); - - return 0; // fail -} - -INT_PTR Meta_GetAwayMsg(WPARAM wParam, LPARAM lParam) -{ - CCSDATA *ccs = (CCSDATA*)lParam; - DBCachedContact *cc = CheckMeta(ccs->hContact); - if (cc == NULL || cc->nDefault == -1) - return 0; - - MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_MODEMSGRECV); - if (!hMostOnline) - return 0; - - char *proto = GetContactProto(hMostOnline); - if (!proto) - return 0; - - ccs->hContact = hMostOnline; - return CallContactService(ccs->hContact, PSS_GETAWAYMSG, ccs->wParam, ccs->lParam); -} - -INT_PTR Meta_GetAvatarInfo(WPARAM wParam, LPARAM lParam) -{ - PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam; - DBCachedContact *cc = CheckMeta(pai->hContact); - if (cc == NULL) - return GAIR_NOAVATAR; - - if (cc->nDefault == -1) - return 0; - - MCONTACT hSub = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS); - if (!hSub) - return GAIR_NOAVATAR; - - char *proto = GetContactProto(hSub); - if (!proto) - return GAIR_NOAVATAR; - - pai->hContact = hSub; - INT_PTR result = CallProtoService(proto, PS_GETAVATARINFO, wParam, lParam); - pai->hContact = cc->contactID; - if (result != CALLSERVICE_NOTFOUND) - return result; - - return GAIR_NOAVATAR; // fail -} - -INT_PTR Meta_GetInfo(WPARAM wParam, LPARAM lParam) -{ - CCSDATA *ccs = (CCSDATA*)lParam; - - // This is a simple contact - // (this should normally not happen, since linked contacts do not appear on the list.) - DBCachedContact *cc = CheckMeta(ccs->hContact); - if (cc == NULL || cc->nDefault == -1) - return 0; - - MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS); - if (!hMostOnline) - return 0; - - char *proto = GetContactProto(hMostOnline); - if (!proto) - return 0; - - PROTO_AVATAR_INFORMATION ai; - ai.hContact = ccs->hContact; - ai.format = PA_FORMAT_UNKNOWN; - _tcsncpy_s(ai.filename, _T("X"), _TRUNCATE); - if (CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&ai) == GAIR_SUCCESS) - db_set_ts(ccs->hContact, "ContactPhoto", "File", ai.filename); - - hMostOnline = Meta_GetMostOnline(cc); - Meta_CopyContactNick(cc, hMostOnline); - - if (!hMostOnline) - return 0; - - ccs->hContact = hMostOnline; - if (!ProtoServiceExists(proto, PSS_GETINFO)) - return 0; // fail - - return CallContactService(ccs->hContact, PSS_GETINFO, ccs->wParam, ccs->lParam); -} - -int Meta_CallMostOnline(WPARAM hContact, LPARAM lParam) -{ - DBCachedContact *cc = CheckMeta(hContact); - if (cc == NULL) - return 0; - - Meta_CopyContactNick(cc, db_mc_getSrmmSub(cc->contactID)); - Meta_FixStatus(cc); - return 0; -} - -int Meta_PreShutdown(WPARAM wParam, LPARAM lParam) -{ - Meta_SetStatus(ID_STATUS_OFFLINE, 0); - Meta_SuppressStatus(FALSE); - if (setStatusTimerId) - KillTimer(0, setStatusTimerId); - return 0; -} - -INT_PTR MenuFunc(WPARAM wParam, LPARAM lParam, LPARAM param) -{ - return Meta_ContactMenuFunc(wParam, param); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Initializes all services provided by the plugin -// -// Creates every function and hooks the event desired. - -void Meta_InitServices() -{ - previousMode = mcStatus = ID_STATUS_OFFLINE; - - CreateServiceFunction("MetaContacts/Convert", Meta_Convert); - CreateServiceFunction("MetaContacts/AddTo", Meta_AddTo); - CreateServiceFunction("MetaContacts/Edit", Meta_Edit); - CreateServiceFunction("MetaContacts/Delete", Meta_Delete); - CreateServiceFunction("MetaContacts/Default", Meta_Default); - - // hidden contact menu items...ho hum - for (int i = 0; i < MAX_CONTACTS; i++) { - char szServiceName[100]; - mir_snprintf(szServiceName, SIZEOF(szServiceName), "MetaContacts/MenuFunc%d", i); - CreateServiceFunctionParam(szServiceName, MenuFunc, i); - } - - CreateProtoServiceFunction(META_PROTO, PS_GETCAPS, Meta_GetCaps); - CreateProtoServiceFunction(META_PROTO, PS_GETNAME, Meta_GetName); - CreateProtoServiceFunction(META_PROTO, PS_LOADICON, Meta_LoadIcon); - - CreateProtoServiceFunction(META_PROTO, PS_SETSTATUS, Meta_SetStatus); - - CreateProtoServiceFunction(META_PROTO, PS_GETSTATUS, Meta_GetStatus); - CreateProtoServiceFunction(META_PROTO, PSS_MESSAGE, Meta_SendMessage); - - CreateProtoServiceFunction(META_PROTO, PSS_USERISTYPING, Meta_UserIsTyping); - - // file recv is done by subcontacts - CreateProtoServiceFunction(META_PROTO, PSS_FILE, Meta_FileSend); - CreateProtoServiceFunction(META_PROTO, PSS_GETAWAYMSG, Meta_GetAwayMsg); - CreateProtoServiceFunction(META_PROTO, PS_GETAVATARINFO, Meta_GetAvatarInfo); - CreateProtoServiceFunction(META_PROTO, PSS_GETINFO, Meta_GetInfo); - - // receive filter - CreateProtoServiceFunction(META_FILTER, PSR_MESSAGE, MetaFilter_RecvMessage); - - // API services and events - CreateApiServices(); - - CreateServiceFunction("MetaContacts/OnOff", Meta_OnOff); - CreateServiceFunction(MS_MC_GETSRMMSUB, Meta_SrmmCurrentSub); - - CreateProtoServiceFunction(META_PROTO, PS_SEND_NUDGE, Meta_SendNudge); - - // create our hookable events - hSubcontactsChanged = CreateHookableEvent(ME_MC_SUBCONTACTSCHANGED); - - // hook other module events we need - HookEvent(ME_PROTO_ACK, Meta_HandleACK); - HookEvent(ME_DB_CONTACT_DELETED, Meta_ContactDeleted); - HookEvent(ME_DB_CONTACT_SETTINGCHANGED, Meta_SettingChanged); - HookEvent(ME_OPT_INITIALISE, Meta_OptInit); - HookEvent(ME_SYSTEM_MODULESLOADED, Meta_ModulesLoaded); - HookEvent(ME_SYSTEM_PRESHUTDOWN, Meta_PreShutdown); - - // hook our own events, used to call Meta_GetMostOnline which sets nick for metacontact - HookEvent(ME_MC_DEFAULTTCHANGED, Meta_CallMostOnline); - - // redirect nudge events - hEventNudge = CreateHookableEvent(META_PROTO "/Nudge"); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Destroy created events - -void Meta_CloseHandles() -{ - DestroyHookableEvent(hSubcontactsChanged); - DestroyHookableEvent(hEventNudge); -} diff --git a/src/modules/metacontacts/meta_utils.cpp b/src/modules/metacontacts/meta_utils.cpp deleted file mode 100644 index e58f509fcf..0000000000 --- a/src/modules/metacontacts/meta_utils.cpp +++ /dev/null @@ -1,576 +0,0 @@ -/* -former MetaContacts Plugin for Miranda IM. - -Copyright 2014 Miranda NG Team -Copyright 2004-07 Scott Ellis -Copyright 2004 Universite Louis PASTEUR, STRASBOURG. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "metacontacts.h" - -HANDLE invisiGroup; -POINT menuMousePoint; - -/** Update the MetaContact login, depending on the protocol desired -* -* The login of the "MetaContacts" protocol will be copied from the login -* of the specified protocol. -* -* @param szProto : The name of the protocol used to get the login that will be -* affected to the "MetaContacts" protocol. -* -* @return O on success, 1 otherwise. -*/ - -int Meta_SetNick(char *szProto) -{ - CONTACTINFO ci = { sizeof(ci) }; - ci.dwFlag = CNF_DISPLAY | CNF_TCHAR; - ci.szProto = szProto; - if (CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci)) - return 1; - - switch (ci.type) { - case CNFT_BYTE: - if (db_set_b(NULL, META_PROTO, "Nick", ci.bVal)) - return 1; - break; - case CNFT_WORD: - if (db_set_w(NULL, META_PROTO, "Nick", ci.wVal)) - return 1; - break; - case CNFT_DWORD: - if (db_set_dw(NULL, META_PROTO, "Nick", ci.dVal)) - return 1; - break; - case CNFT_ASCIIZ: - if (db_set_ts(NULL, META_PROTO, "Nick", ci.pszVal)) - return 1; - mir_free(ci.pszVal); - break; - default: - if (db_set_s(NULL, META_PROTO, "Nick", (char *)TranslateT("Sender"))) - return 1; - break; - } - return 0; -} - -/** Assign a contact (hSub) to a metacontact (hMeta) -* -* @param hSub : HANDLE to a contact that should be assigned -* @param hMeta : HANDLE to a metacontact that will host the contact -* @param set_as_default : bool flag to indicate whether the new contact becomes the default -* -* @return TRUE on success, FALSE otherwise -*/ - -BOOL Meta_Assign(MCONTACT hSub, MCONTACT hMeta, BOOL set_as_default) -{ - DBCachedContact *ccDest = CheckMeta(hMeta), *ccSub = currDb->m_cache->GetCachedContact(hSub); - if (ccDest == NULL || ccSub == NULL) - return FALSE; - - char *szProto = GetContactProto(hSub); - if (szProto == NULL) { - MessageBox(0, TranslateT("Could not retrieve contact protocol"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); - return FALSE; - } - - // Get the login of the subcontact - char *field = (char *)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); - DBVARIANT dbv; - if (db_get(hSub, szProto, field, &dbv)) { - MessageBox(0, TranslateT("Could not get unique ID of contact"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); - return FALSE; - } - - // Check that is is 'on the list' - if (db_get_b(hSub, "CList", "NotOnList", 0) == 1) { - MessageBox(0, TranslateT("Contact is 'not on list' - please add the contact to your contact list before assigning."), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); - db_free(&dbv); - return FALSE; - } - - if (ccDest->nSubs >= MAX_CONTACTS) { - MessageBox(0, TranslateT("Metacontact is full"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); - db_free(&dbv); - return FALSE; - } - - // write the contact's protocol - char buffer[512]; - mir_snprintf(buffer, "Protocol%d", ccDest->nSubs); - if (db_set_s(hMeta, META_PROTO, buffer, szProto)) { - MessageBox(0, TranslateT("Could not write contact protocol to metacontact"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); - db_free(&dbv); - return FALSE; - } - - // write the login - mir_snprintf(buffer, "Login%d", ccDest->nSubs); - if (db_set(hMeta, META_PROTO, buffer, &dbv)) { - MessageBox(0, TranslateT("Could not write unique ID of contact to metacontact"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); - db_free(&dbv); - return FALSE; - } - - db_free(&dbv); - - // If we can get the nickname of the subcontact... - if (!db_get(hSub, szProto, "Nick", &dbv)) { - // write the nickname - mir_snprintf(buffer, "Nick%d", ccDest->nSubs); - if (db_set(hMeta, META_PROTO, buffer, &dbv)) { - MessageBox(0, TranslateT("Could not write nickname of contact to metacontact"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); - db_free(&dbv); - return FALSE; - } - - db_free(&dbv); - } - - // write the display name - mir_snprintf(buffer, "CListName%d", ccDest->nSubs); - db_set_ts(hMeta, META_PROTO, buffer, cli.pfnGetContactDisplayName(hSub, 0)); - - // Get the status - WORD status = db_get_w(hSub, szProto, "Status", ID_STATUS_OFFLINE); - - // write the status - mir_snprintf(buffer, "Status%d", ccDest->nSubs); - db_set_w(hMeta, META_PROTO, buffer, status); - - // write the handle - mir_snprintf(buffer, "Handle%d", ccDest->nSubs); - db_set_dw(hMeta, META_PROTO, buffer, hSub); - - // write status string - mir_snprintf(buffer, "StatusString%d", ccDest->nSubs); - - TCHAR *szStatus = cli.pfnGetStatusModeDescription(status, 0); - db_set_ts(hMeta, META_PROTO, buffer, szStatus); - - // Write the link in the contact - db_set_dw(hSub, META_PROTO, "ParentMeta", hMeta); - db_set_b(hSub, META_PROTO, "IsSubcontact", true); - - // update count of contacts - db_set_dw(hMeta, META_PROTO, "NumContacts", ccDest->nSubs+1); - ccDest->nSubs++; - ccDest->pSubs = (MCONTACT*)mir_realloc(ccDest->pSubs, sizeof(MCONTACT)*ccDest->nSubs); - ccDest->pSubs[ccDest->nSubs-1] = hSub; - ccSub->parentID = hMeta; - - if (set_as_default) - db_mc_setDefaultNum(hMeta, ccDest->nSubs-1, true); - - // set nick to most online contact that can message - MCONTACT most_online = Meta_GetMostOnline(ccDest); - Meta_CopyContactNick(ccDest, most_online); - - // set status to that of most online contact - Meta_FixStatus(ccDest); - - // if the new contact is the most online contact with avatar support, get avatar info - most_online = Meta_GetMostOnlineSupporting(ccDest, PFLAGNUM_4, PF4_AVATARS); - if (most_online == hSub) { - PROTO_AVATAR_INFORMATION ai; - ai.hContact = hMeta; - ai.format = PA_FORMAT_UNKNOWN; - _tcsncpy_s(ai.filename, _T("X"), _TRUNCATE); - - if (CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&ai) == GAIR_SUCCESS) - db_set_ts(hMeta, "ContactPhoto", "File", ai.filename); - } - - // merge sub's events to the meta-history - currDb->MetaMergeHistory(ccDest, ccSub); - - // Ignore status if the option is on - if (options.bSuppressStatus) - CallService(MS_IGNORE_IGNORE, hSub, IGNOREEVENT_USERONLINE); - - NotifyEventHooks(hSubcontactsChanged, hMeta, 0); - return TRUE; -} - -/** -* Convenience method - get most online contact supporting messaging -* -*/ - -MCONTACT Meta_GetMostOnline(DBCachedContact *cc) -{ - return Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_IM); -} - -/** Get the 'most online' contact for a meta contact (according to above order) which supports the specified -* protocol service, and copies nick from that contact -* -* @param hMetaHANDLE to a metacontact -* -* @return HANDLE to a contact -*/ - -static int GetStatusPriority(int status) -{ - switch (status) { - case ID_STATUS_OFFLINE: return 8; - case ID_STATUS_AWAY: return 4; - case ID_STATUS_DND: return 7; - case ID_STATUS_NA: return 6; - case ID_STATUS_OCCUPIED: return 5; - case ID_STATUS_FREECHAT: return 1; - case ID_STATUS_ONTHEPHONE: return 2; - case ID_STATUS_OUTTOLUNCH: return 3; - } - - return 0; -} - -MCONTACT Meta_GetMostOnlineSupporting(DBCachedContact *cc, int pflagnum, unsigned long capability) -{ - if (cc == NULL || cc->nDefault == -1) - return NULL; - - // if the default is beyond the end of the list (eek!) return null - if (cc->nDefault >= cc->nSubs) - return NULL; - - int most_online_status = ID_STATUS_OFFLINE; - MCONTACT most_online_contact = Meta_GetContactHandle(cc, cc->nDefault); - char *szProto = GetContactProto(most_online_contact); - if (szProto && CallProtoService(szProto, PS_GETSTATUS, 0, 0) >= ID_STATUS_ONLINE) { - DWORD caps = CallProtoService(szProto, PS_GETCAPS, pflagnum, 0); - if (capability == -1 || (caps & capability) == capability) { - most_online_status = db_get_w(most_online_contact, szProto, "Status", ID_STATUS_OFFLINE); - - // if our default is not offline, and option to use default is set - return default - // and also if our default is online, return it - if (most_online_status != ID_STATUS_OFFLINE) - return most_online_contact; - } - else most_online_status = ID_STATUS_OFFLINE; - } - else most_online_status = ID_STATUS_OFFLINE; - - char *most_online_proto = szProto; - // otherwise, check all the subcontacts for the one closest to the ONLINE state which supports the required capability - for (int i = 0; i < cc->nSubs; i++) { - if (i == cc->nDefault) // already checked that (i.e. initial value of most_online_contact and most_online_status are those of the default contact) - continue; - - MCONTACT hContact = Meta_GetContactHandle(cc, i); - szProto = GetContactProto(hContact); - if (szProto == NULL || CallProtoService(szProto, PS_GETSTATUS, 0, 0) < ID_STATUS_ONLINE) // szProto offline or connecting - continue; - - DWORD caps = CallProtoService(szProto, PS_GETCAPS, pflagnum, 0); - if (capability == -1 || (caps & capability) == capability) { - int status = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); - if (status == ID_STATUS_ONLINE) { - most_online_contact = hContact; - most_online_proto = szProto; - return most_online_contact; - } - if (status <= ID_STATUS_OFFLINE) // status below ID_STATUS_OFFLINE is a connecting status - continue; - - if (GetStatusPriority(status) < GetStatusPriority(most_online_status)) { - most_online_status = status; - most_online_contact = hContact; - most_online_proto = szProto; - } - } - } - - // no online contacts? if we're trying to message, use 'send offline' contact - if (most_online_status == ID_STATUS_OFFLINE && capability == PF1_IM) { - MCONTACT hOffline = Meta_GetContactHandle(cc, db_get_dw(cc->contactID, META_PROTO, "OfflineSend", INVALID_CONTACT_ID)); - if (hOffline) - most_online_contact = hOffline; - } - - return most_online_contact; -} - -DBCachedContact* CheckMeta(MCONTACT hMeta) -{ - DBCachedContact *cc = currDb->m_cache->GetCachedContact(hMeta); - return (cc == NULL || cc->nSubs == -1) ? NULL : cc; -} - -int Meta_GetContactNumber(DBCachedContact *cc, MCONTACT hContact) -{ - for (int i = 0; i < cc->nSubs; i++) - if (cc->pSubs[i] == hContact) - return i; - - return -1; -} - -MCONTACT Meta_GetContactHandle(DBCachedContact *cc, int contact_number) -{ - if (contact_number >= cc->nSubs || contact_number < 0) - return 0; - - return cc->pSubs[contact_number]; -} - -/** Hide all contacts linked to any meta contact, and set handle links -* -* Additionally, set all sub contacts and metacontacts to offline so that status notifications are always sent -* -* and ensure metafilter in place -*/ -int Meta_HideLinkedContacts(void) -{ - DBVARIANT dbv, dbv2; - char buffer[512]; - - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact); - if (cc == NULL || cc->parentID == 0) - continue; - - DBCachedContact *ccMeta = CheckMeta(cc->parentID); - if (ccMeta == NULL) - continue; - - // get contact number - int contact_number = Meta_GetContactNumber(cc, hContact); - - // find metacontact - if (contact_number < 0 || contact_number >= ccMeta->nSubs) - continue; - - // update metacontact's record of status for this contact - mir_snprintf(buffer, "Status%d",contact_number); - - // prepare to update metacontact record of subcontat status - char *szProto = GetContactProto(hContact); - - WORD status = (!szProto) ? ID_STATUS_OFFLINE : db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); - db_set_w(ccMeta->contactID, META_PROTO, buffer, status); - - // update metacontact's record of nick for this contact - if (szProto && !db_get(hContact, szProto, "Nick", &dbv)) { - mir_snprintf(buffer, "Nick%d",contact_number); - db_set(ccMeta->contactID, META_PROTO, buffer, &dbv); - - mir_snprintf(buffer, "CListName%d",contact_number); - if (db_get(hContact, "CList", "MyHandle", &dbv2)) - db_set(ccMeta->contactID, META_PROTO, buffer, &dbv); - else { - db_set(ccMeta->contactID, META_PROTO, buffer, &dbv2); - db_free(&dbv2); - } - - db_free(&dbv); - } - else { - if (!db_get(hContact, "CList", "MyHandle", &dbv)) { - mir_snprintf(buffer,"CListName%d",contact_number); - db_set(ccMeta->contactID, META_PROTO, buffer, &dbv); - db_free(&dbv); - } - } - - if (options.bSuppressStatus) - CallService(MS_IGNORE_IGNORE, hContact, IGNOREEVENT_USERONLINE); - - MCONTACT hMostOnline = Meta_GetMostOnline(ccMeta); // set nick - Meta_CopyContactNick(ccMeta, hMostOnline); - Meta_FixStatus(ccMeta); - } - - return 0; -} - -int Meta_HideMetaContacts(bool bHide) -{ - // set status suppression - bool bSuppress = bHide ? FALSE : options.bSuppressStatus; - - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - bool bSet; - DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact); - if (cc->IsSub()) { // show on hide, reverse flag - bSet = !bHide; - CallService(bSuppress ? MS_IGNORE_IGNORE : MS_IGNORE_UNIGNORE, hContact, IGNOREEVENT_USERONLINE); - } - else if (cc->IsMeta()) - bSet = bHide; - else - continue; - - db_set_b(hContact, "CList", "Hidden", bSet); - } - - if (bHide) { - for (int i = 0; i < arMetaWindows.getCount(); i++) - SendMessage(arMetaWindows[i].m_hWnd, WM_CLOSE, 0, 0); - arMetaWindows.destroy(); - } - - return 0; -} - -int Meta_SuppressStatus(BOOL suppress) -{ - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) - if (db_mc_isSub(hContact)) - CallService((suppress) ? MS_IGNORE_IGNORE : MS_IGNORE_UNIGNORE, hContact, IGNOREEVENT_USERONLINE); - - return 0; -} - -int Meta_CopyContactNick(DBCachedContact *ccMeta, MCONTACT hContact) -{ - if (options.bLockHandle) - hContact = Meta_GetContactHandle(ccMeta, 0); - - if (!hContact) - return 1; - - char *szProto = GetContactProto(hContact); - if (szProto == NULL) - return 1; - - if (options.clist_contact_name == CNNT_NICK) { - ptrT tszNick(db_get_tsa(hContact, szProto, "Nick")); - if (tszNick) { - db_set_ts(ccMeta->contactID, META_PROTO, "Nick", tszNick); - return 0; - } - } - else if (options.clist_contact_name == CNNT_DISPLAYNAME) { - TCHAR *name = cli.pfnGetContactDisplayName(hContact, 0); - if (name && mir_tstrcmp(name, TranslateT("(Unknown contact)")) != 0) { - db_set_ts(ccMeta->contactID, META_PROTO, "Nick", name); - return 0; - } - } - return 1; -} - -int Meta_SetAllNicks() -{ - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - DBCachedContact *cc = CheckMeta(hContact); - if (cc == NULL) - continue; - MCONTACT most_online = Meta_GetMostOnline(cc); - Meta_CopyContactNick(cc, most_online); - Meta_FixStatus(cc); - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static void SwapValues(MCONTACT hContact, LPCSTR szSetting, int n1, int n2) -{ - char buf1[100], buf2[100]; - mir_snprintf(buf1, SIZEOF(buf1), "%s%d", szSetting, n1); - mir_snprintf(buf2, SIZEOF(buf2), "%s%d", szSetting, n2); - - DBVARIANT dbv1, dbv2; - int ok1 = !db_get(hContact, META_PROTO, buf1, &dbv1); - int ok2 = !db_get(hContact, META_PROTO, buf2, &dbv2); - if (ok1) { - db_set(hContact, META_PROTO, buf2, &dbv1); - db_free(&dbv1); - } - if (ok2) { - db_set(hContact, META_PROTO, buf1, &dbv2); - db_free(&dbv2); - } -} - -int Meta_SwapContacts(DBCachedContact *cc, int n1, int n2) -{ - SwapValues(cc->contactID, "Protocol", n1, n2); - SwapValues(cc->contactID, "Status", n1, n2); - SwapValues(cc->contactID, "StatusString", n1, n2); - SwapValues(cc->contactID, "Login", n1, n2); - SwapValues(cc->contactID, "Nick", n1, n2); - SwapValues(cc->contactID, "CListName", n1, n2); - SwapValues(cc->contactID, "Handle", n1, n2); - - MCONTACT tmp = cc->pSubs[n1]; - cc->pSubs[n1] = cc->pSubs[n2]; - cc->pSubs[n2] = tmp; - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void Meta_GetSubNick(MCONTACT hMeta, int i, CMString &tszDest) -{ - char idStr[50]; - mir_snprintf(idStr, SIZEOF(idStr), "Login%d", i); - - DBVARIANT dbv; - if(db_get(hMeta, META_PROTO, idStr, &dbv)) - return; - switch (dbv.type) { - case DBVT_ASCIIZ: - tszDest = dbv.pszVal; - break; - case DBVT_BYTE: - tszDest.Format(_T("%d"), dbv.bVal); - break; - case DBVT_WORD: - tszDest.Format(_T("%d"), dbv.wVal); - break; - case DBVT_DWORD: - tszDest.Format(_T("%d"), dbv.dVal); - break; - default: - tszDest.Empty(); - } - db_free(&dbv); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void Meta_FixStatus(DBCachedContact *ccMeta) -{ - WORD status = ID_STATUS_OFFLINE; - - MCONTACT most_online = db_mc_getMostOnline(ccMeta->contactID); - if (most_online) { - char *szProto = GetContactProto(most_online); - if (szProto) - status = db_get_w(most_online, szProto, "Status", ID_STATUS_OFFLINE); - } - - db_set_w(ccMeta->contactID, META_PROTO, "Status", status); - Meta_UpdateSrmmIcon(ccMeta, status); -} - -void Meta_UpdateSrmmIcon(DBCachedContact *ccMeta, int iStatus) -{ - StatusIconData sid = { sizeof(sid) }; - sid.szModule = META_PROTO; - sid.flags = (ccMeta->IsMeta()) ? 0 : MBF_HIDDEN; - Srmm_ModifyIcon(ccMeta->contactID, &sid); -} diff --git a/src/modules/metacontacts/metacontacts.h b/src/modules/metacontacts/metacontacts.h deleted file mode 100644 index 2c4ff0715c..0000000000 --- a/src/modules/metacontacts/metacontacts.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -former MetaContacts Plugin for Miranda IM. - -Copyright 2014 Miranda NG Team -Copyright 2004-07 Scott Ellis -Copyright 2004 Universite Louis PASTEUR, STRASBOURG. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#define MAX_CONTACTS 20 - -#define META_FILTER "MetaContactsFilter" - -INT_PTR TranslateMenuFunc(MCONTACT hContact, int i); - -// contact menu items -void InitMenus(); -extern int mcStatus; - -struct MetaSrmmData -{ - MCONTACT m_hMeta, m_hSub; - HWND m_hWnd; -}; -extern OBJLIST arMetaWindows; - -INT_PTR Meta_Convert(WPARAM wParam,LPARAM lParam); -INT_PTR Meta_AddTo(WPARAM wParam,LPARAM lParam); -INT_PTR Meta_Edit(WPARAM wParam,LPARAM lParam); -INT_PTR Meta_Delete(WPARAM wParam,LPARAM lParam); -INT_PTR Meta_Default(WPARAM wParam,LPARAM lParam); - -INT_PTR Meta_OnOff(WPARAM wParam, LPARAM lParam); -int Meta_ModifyMenu(WPARAM wParam,LPARAM lParam); -BOOL Meta_Assign(MCONTACT src, MCONTACT dest, BOOL set_as_default); -void Meta_RemoveContactNumber(DBCachedContact *cc, int number, bool bUpdateInfo); -int Meta_SetNick(char *proto); -int Meta_HideLinkedContacts(void); -int Meta_GetContactNumber(DBCachedContact *cc, MCONTACT hContact); -int Meta_HideMetaContacts(bool hide); -int Meta_SuppressStatus(int suppress); -int Meta_CopyContactNick(DBCachedContact *cc, MCONTACT hContact); -int Meta_SetAllNicks(); -int Meta_SwapContacts(DBCachedContact *cc, int contact_number1, int contact_number2); -void Meta_GetSubNick(MCONTACT hMeta, int i, CMString &tszDest); - -MCONTACT Meta_GetMostOnline(DBCachedContact *cc); -MCONTACT Meta_GetMostOnlineSupporting(DBCachedContact *cc, int pflagnum, unsigned long capability); -MCONTACT Meta_GetContactHandle(DBCachedContact *cc, int contact_number); - -DBCachedContact* CheckMeta(MCONTACT hMeta); - -// function to copy history from one contact to another - courtesy JdGordon with mods (thx) -void Meta_FixStatus(DBCachedContact *ccMeta); -void Meta_UpdateSrmmIcon(DBCachedContact *ccMeta, int iStatus); - -char *Meta_GetUniqueIdentifier(MCONTACT hContact, DWORD *pused); - -INT_PTR Meta_GetCaps(WPARAM wParam,LPARAM lParam); -INT_PTR Meta_GetName(WPARAM wParam,LPARAM lParam); -INT_PTR Meta_LoadIcon(WPARAM wParam,LPARAM lParam); -INT_PTR Meta_SetStatus(WPARAM wParam,LPARAM lParam); -INT_PTR Meta_GetStatus(WPARAM wParam,LPARAM lParam); -INT_PTR Meta_SendMessage(WPARAM wParam,LPARAM lParam); -INT_PTR Meta_ContactMenuFunc(WPARAM wParam, LPARAM lParam); - -void Meta_InitServices(); -void Meta_CloseHandles(); - -enum MenuDisplayNameType {DNT_UID = 0, DNT_DID = 1}; -enum MenuFunctionType {FT_MSG = 0, FT_MENU = 1, FT_INFO = 2}; -enum CListDisplayNameType {CNNT_NICK = 0, CNNT_DISPLAYNAME = 1}; - -struct MetaOptions -{ - bool bLockHandle; - bool bSuppressStatus; - - int menu_contact_label; - int menu_function; - int clist_contact_name; - int set_status_from_offline_delay; -}; - -extern MetaOptions options; - -int Meta_OptInit(WPARAM wParam, LPARAM lParam); -int Meta_ReadOptions(); - -// API function headers -void CreateApiServices(); - -typedef enum {I_MENUOFF, I_MENU, I_CONVERT, I_ADD, I_EDIT, I_SETDEFAULT, I_REMOVE} IconIndex; -HICON LoadIconEx(IconIndex i); -HANDLE GetIconHandle(IconIndex i); - -extern HANDLE hEventForceSend, hEventUnforceSend, hSubcontactsChanged; -extern POINT menuMousePoint; - -#define MAX_PROTOCOLS 20 - -// used for the 'jabber' hack - i.e. hide contacts instead of moving them to the hidden group -#define JABBER_UNIQUE_ID_SETTING "jid" - -// delay setting status from offline - to help reduce innapropriate status notification popups -#define DEFAULT_SET_STATUS_SLEEP_TIME 15000 // milliseconds - -// service from clist_meta_mw, existence means we don't need to hide subcontacts (woohoo - thanks FYR) -#define MS_CLUI_METASUPPORT "CLUI/MetaContactSupport" - -#ifndef MS_CLUI_GETVERSION -#define MS_CLUI_GETVERSION "CLUI/GetVersion" - -#define szDelMsg LPGEN("You are going to remove all the contacts associated with this metacontact.\nThis will delete the metacontact.\n\nProceed anyway?") - -#endif diff --git a/src/modules/netlib/netlib.cpp b/src/modules/netlib/netlib.cpp deleted file mode 100644 index a900c77f93..0000000000 --- a/src/modules/netlib/netlib.cpp +++ /dev/null @@ -1,527 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "netlib.h" - -static BOOL bModuleInitialized = FALSE; - -HANDLE hConnectionHeaderMutex, hConnectionOpenMutex; -DWORD g_LastConnectionTick; -int connectionTimeout; -HANDLE hSendEvent = NULL, hRecvEvent = NULL; - -typedef BOOL (WINAPI *tGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD); - -static int CompareNetlibUser(const NetlibUser* p1, const NetlibUser* p2) -{ - return mir_strcmp(p1->user.szSettingsModule, p2->user.szSettingsModule); -} - -LIST netlibUser(5, CompareNetlibUser); -mir_cs csNetlibUser; - -SSL_API si; - -void NetlibFreeUserSettingsStruct(NETLIBUSERSETTINGS *settings) -{ - mir_free(settings->szIncomingPorts); - mir_free(settings->szOutgoingPorts); - mir_free(settings->szProxyAuthPassword); - mir_free(settings->szProxyAuthUser); - mir_free(settings->szProxyServer); -} - -int GetNetlibHandleType(void *p) -{ - __try { - return *(int*)p; - } - __except(EXCEPTION_EXECUTE_HANDLER) - {} - - return NLH_INVALID; -} - -void NetlibInitializeNestedCS(NetlibNestedCriticalSection *nlncs) -{ - nlncs->dwOwningThreadId = 0; - nlncs->lockCount = 0; - nlncs->hMutex = CreateMutex(NULL, FALSE, NULL); -} - -void NetlibDeleteNestedCS(NetlibNestedCriticalSection *nlncs) -{ - CloseHandle(nlncs->hMutex); -} - -int NetlibEnterNestedCS(NetlibConnection *nlc, int which) -{ - NetlibNestedCriticalSection *nlncs; - DWORD dwCurrentThreadId = GetCurrentThreadId(); - - WaitForSingleObject(hConnectionHeaderMutex, INFINITE); - if (nlc == NULL || nlc->handleType != NLH_CONNECTION) { - ReleaseMutex(hConnectionHeaderMutex); - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - nlncs = (which == NLNCS_SEND) ? &nlc->ncsSend : &nlc->ncsRecv; - if (nlncs->lockCount && nlncs->dwOwningThreadId == dwCurrentThreadId) { - nlncs->lockCount++; - ReleaseMutex(hConnectionHeaderMutex); - return 1; - } - InterlockedIncrement(&nlc->dontCloseNow); - ResetEvent(nlc->hOkToCloseEvent); - ReleaseMutex(hConnectionHeaderMutex); - WaitForSingleObject(nlncs->hMutex, INFINITE); - nlncs->dwOwningThreadId = dwCurrentThreadId; - nlncs->lockCount = 1; - if (InterlockedDecrement(&nlc->dontCloseNow) == 0) - SetEvent(nlc->hOkToCloseEvent); - return 1; -} - -void NetlibLeaveNestedCS(NetlibNestedCriticalSection *nlncs) -{ - if (--nlncs->lockCount == 0) { - nlncs->dwOwningThreadId = 0; - ReleaseMutex(nlncs->hMutex); - } -} - -static INT_PTR GetNetlibUserSettingInt(const char *szUserModule, const char *szSetting, int defValue) -{ - DBVARIANT dbv; - if (db_get(NULL, szUserModule, szSetting, &dbv) && db_get(NULL, "Netlib", szSetting, &dbv)) - return defValue; - - if (dbv.type == DBVT_BYTE) return dbv.bVal; - if (dbv.type == DBVT_WORD) return dbv.wVal; - return dbv.dVal; -} - -static char *GetNetlibUserSettingString(const char *szUserModule, const char *szSetting) -{ - char *szRet = db_get_sa(NULL, szUserModule, szSetting); - if (szRet == NULL) - if ((szRet = db_get_sa(NULL, "Netlib", szSetting)) == NULL) - return NULL; - - return szRet; -} - -static INT_PTR NetlibRegisterUser(WPARAM, LPARAM lParam) -{ - NETLIBUSER *nlu = (NETLIBUSER*)lParam; - if (nlu == NULL || nlu->cbSize != sizeof(NETLIBUSER) || nlu->szSettingsModule == NULL || - (!(nlu->flags & NUF_NOOPTIONS) && nlu->szDescriptiveName == NULL) || - (nlu->flags & NUF_HTTPGATEWAY && (nlu->pfnHttpGatewayInit == NULL))) - { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - NetlibUser *thisUser = (NetlibUser*)mir_calloc(sizeof(NetlibUser)); - thisUser->handleType = NLH_USER; - thisUser->user = *nlu; - - int idx; - { - mir_cslock lck(csNetlibUser); - idx = netlibUser.getIndex(thisUser); - } - if (idx != -1) { - mir_free(thisUser); - SetLastError(ERROR_DUP_NAME); - return 0; - } - - if (nlu->szDescriptiveName) - thisUser->user.ptszDescriptiveName = (thisUser->user.flags&NUF_UNICODE ? mir_u2t((WCHAR*)nlu->ptszDescriptiveName) : mir_a2t(nlu->szDescriptiveName)); - - if ((thisUser->user.szSettingsModule = mir_strdup(nlu->szSettingsModule)) == NULL - || (nlu->szDescriptiveName && thisUser->user.ptszDescriptiveName == NULL) - || (nlu->szHttpGatewayUserAgent && (thisUser->user.szHttpGatewayUserAgent = mir_strdup(nlu->szHttpGatewayUserAgent)) == NULL)) - { - mir_free(thisUser); - SetLastError(ERROR_OUTOFMEMORY); - return 0; - } - if (nlu->szHttpGatewayHello) - thisUser->user.szHttpGatewayHello = mir_strdup(nlu->szHttpGatewayHello); - else - thisUser->user.szHttpGatewayHello = NULL; - - thisUser->settings.cbSize = sizeof(NETLIBUSERSETTINGS); - thisUser->settings.useProxy = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLUseProxy", 0); - thisUser->settings.proxyType = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLProxyType", PROXYTYPE_SOCKS5); - if (thisUser->user.flags&NUF_NOHTTPSOPTION && thisUser->settings.proxyType == PROXYTYPE_HTTPS) - thisUser->settings.proxyType = PROXYTYPE_HTTP; - if (!(thisUser->user.flags&(NUF_HTTPCONNS|NUF_HTTPGATEWAY)) && thisUser->settings.proxyType == PROXYTYPE_HTTP) { - thisUser->settings.useProxy = 0; - thisUser->settings.proxyType = PROXYTYPE_SOCKS5; - } - thisUser->settings.szProxyServer = GetNetlibUserSettingString(thisUser->user.szSettingsModule, "NLProxyServer"); - thisUser->settings.wProxyPort = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLProxyPort", 1080); - thisUser->settings.useProxyAuth = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLUseProxyAuth", 0); - thisUser->settings.szProxyAuthUser = GetNetlibUserSettingString(thisUser->user.szSettingsModule, "NLProxyAuthUser"); - thisUser->settings.szProxyAuthPassword = GetNetlibUserSettingString(thisUser->user.szSettingsModule, "NLProxyAuthPassword"); - thisUser->settings.dnsThroughProxy = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLDnsThroughProxy", 1); - thisUser->settings.specifyIncomingPorts = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLSpecifyIncomingPorts", 0); - thisUser->settings.szIncomingPorts = GetNetlibUserSettingString(thisUser->user.szSettingsModule, "NLIncomingPorts"); - thisUser->settings.specifyOutgoingPorts = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLSpecifyOutgoingPorts", 0); - thisUser->settings.szOutgoingPorts = GetNetlibUserSettingString(thisUser->user.szSettingsModule, "NLOutgoingPorts"); - thisUser->settings.enableUPnP = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLEnableUPnP", 1); //default to on - thisUser->settings.validateSSL = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLValidateSSL", 0); - - thisUser->toLog = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLlog", 1); - - mir_cslock lck(csNetlibUser); - netlibUser.insert(thisUser); - return (INT_PTR)thisUser; -} - -static INT_PTR NetlibGetUserSettings(WPARAM wParam, LPARAM lParam) -{ - NETLIBUSERSETTINGS *nlus = (NETLIBUSERSETTINGS*)lParam; - NetlibUser *nlu = (NetlibUser*)wParam; - - if (GetNetlibHandleType(nlu) != NLH_USER || nlus == NULL || nlus->cbSize != sizeof(NETLIBUSERSETTINGS)) { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - *nlus = nlu->settings; - return 1; -} - -static INT_PTR NetlibSetUserSettings(WPARAM wParam, LPARAM lParam) -{ - NETLIBUSERSETTINGS *nlus = (NETLIBUSERSETTINGS*)lParam; - NetlibUser *nlu = (NetlibUser*)wParam; - - if (GetNetlibHandleType(nlu) != NLH_USER || nlus == NULL || nlus->cbSize != sizeof(NETLIBUSERSETTINGS)) { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - NetlibSaveUserSettingsStruct(nlu->user.szSettingsModule, nlus); - return 1; -} - -void NetlibDoClose(NetlibConnection *nlc, bool noShutdown) -{ - if (nlc->s == INVALID_SOCKET) return; - - NetlibLogf(nlc->nlu, "(%p:%u) Connection closed internal", nlc, nlc->s); - if (nlc->hSsl) { - if (!noShutdown) si.shutdown(nlc->hSsl); - si.sfree(nlc->hSsl); - nlc->hSsl = NULL; - } - closesocket(nlc->s); - nlc->s = INVALID_SOCKET; -} - -INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM) -{ - if (wParam == NULL) - return 0; - - switch(GetNetlibHandleType((void*)wParam)) { - case NLH_USER: - { - NetlibUser *nlu = (NetlibUser*)wParam; - { - mir_cslock lck(csNetlibUser); - int i = netlibUser.getIndex(nlu); - if (i >= 0) - netlibUser.remove(i); - } - - NetlibFreeUserSettingsStruct(&nlu->settings); - mir_free(nlu->user.szSettingsModule); - mir_free(nlu->user.szDescriptiveName); - mir_free(nlu->user.szHttpGatewayHello); - mir_free(nlu->user.szHttpGatewayUserAgent); - mir_free(nlu->szStickyHeaders); - break; - } - case NLH_CONNECTION: - { - NetlibConnection *nlc = (struct NetlibConnection*)wParam; - HANDLE waitHandles[4]; - DWORD waitResult; - - WaitForSingleObject(hConnectionHeaderMutex, INFINITE); - if (nlc->usingHttpGateway) - HttpGatewayRemovePacket(nlc, -1); - else { - if (nlc->s != INVALID_SOCKET) - NetlibDoClose(nlc, nlc->termRequested); - if (nlc->s2 != INVALID_SOCKET) closesocket(nlc->s2); - nlc->s2 = INVALID_SOCKET; - } - ReleaseMutex(hConnectionHeaderMutex); - - waitHandles[0] = hConnectionHeaderMutex; - waitHandles[1] = nlc->hOkToCloseEvent; - waitHandles[2] = nlc->ncsRecv.hMutex; - waitHandles[3] = nlc->ncsSend.hMutex; - waitResult = WaitForMultipleObjects(SIZEOF(waitHandles), waitHandles, TRUE, INFINITE); - if (waitResult >= WAIT_OBJECT_0 + SIZEOF(waitHandles)) { - ReleaseMutex(hConnectionHeaderMutex); - SetLastError(ERROR_INVALID_PARAMETER); //already been closed - return 0; - } - nlc->handleType = 0; - mir_free(nlc->nlhpi.szHttpPostUrl); - mir_free(nlc->nlhpi.szHttpGetUrl); - mir_free(nlc->dataBuffer); - mir_free((char*)nlc->nloc.szHost); - mir_free(nlc->szNewUrl); - mir_free(nlc->szProxyServer); - NetlibDeleteNestedCS(&nlc->ncsRecv); - NetlibDeleteNestedCS(&nlc->ncsSend); - CloseHandle(nlc->hOkToCloseEvent); - DeleteCriticalSection(&nlc->csHttpSequenceNums); - ReleaseMutex(hConnectionHeaderMutex); - NetlibLogf(nlc->nlu, "(%p:%u) Connection closed", nlc, nlc->s); - } - break; - - case NLH_BOUNDPORT: - return NetlibFreeBoundPort((struct NetlibBoundPort*)wParam); - - case NLH_PACKETRECVER: - { - struct NetlibPacketRecver *nlpr = (struct NetlibPacketRecver*)wParam; - mir_free(nlpr->packetRecver.buffer); - } - break; - - default: - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - mir_free((void*)wParam); - return 1; -} - -static INT_PTR NetlibGetSocket(WPARAM wParam, LPARAM) -{ - SOCKET s; - if (wParam == 0) { - s = INVALID_SOCKET; - SetLastError(ERROR_INVALID_PARAMETER); - } - else { - WaitForSingleObject(hConnectionHeaderMutex, INFINITE); - switch (GetNetlibHandleType((void*)wParam)) { - case NLH_CONNECTION: - s = ((struct NetlibConnection*)wParam)->s; - break; - case NLH_BOUNDPORT: - s = ((struct NetlibBoundPort*)wParam)->s; - break; - default: - s = INVALID_SOCKET; - SetLastError(ERROR_INVALID_PARAMETER); - break; - } - ReleaseMutex(hConnectionHeaderMutex); - } - return s; -} - -INT_PTR NetlibStringToAddressSrv(WPARAM wParam, LPARAM lParam) -{ - return (INT_PTR)!NetlibStringToAddress((char*)wParam, (SOCKADDR_INET_M*)lParam); -} - -INT_PTR NetlibAddressToStringSrv(WPARAM wParam, LPARAM lParam) -{ - if (wParam) { - SOCKADDR_INET_M iaddr = {0}; - iaddr.Ipv4.sin_family = AF_INET; - iaddr.Ipv4.sin_addr.s_addr = htonl((unsigned)lParam); - return (INT_PTR)NetlibAddressToString(&iaddr); - } - return (INT_PTR)NetlibAddressToString((SOCKADDR_INET_M*)lParam); -} - -INT_PTR NetlibGetConnectionInfoSrv(WPARAM wParam, LPARAM lParam) -{ - NetlibGetConnectionInfo((NetlibConnection*)wParam, (NETLIBCONNINFO*)lParam); - return 0; -} - -INT_PTR NetlibGetMyIp(WPARAM wParam, LPARAM) -{ - return (INT_PTR)GetMyIp((unsigned)wParam); -} - -INT_PTR NetlibShutdown(WPARAM wParam, LPARAM) -{ - if (wParam) { - WaitForSingleObject(hConnectionHeaderMutex, INFINITE); - switch(GetNetlibHandleType((void*)wParam)) { - case NLH_CONNECTION: - { - NetlibConnection *nlc = (NetlibConnection*)wParam; - if (!nlc->termRequested) { - if (nlc->hSsl) si.shutdown(nlc->hSsl); - if (nlc->s != INVALID_SOCKET) shutdown(nlc->s, 2); - if (nlc->s2 != INVALID_SOCKET) shutdown(nlc->s2, 2); - nlc->termRequested = true; - } - } - break; - - case NLH_BOUNDPORT: - struct NetlibBoundPort* nlb = (struct NetlibBoundPort*)wParam; - if (nlb->s != INVALID_SOCKET) - shutdown(nlb->s, 2); - break; - } - ReleaseMutex(hConnectionHeaderMutex); - } - return 0; -} - -void UnloadNetlibModule(void) -{ - if (!bModuleInitialized || hConnectionHeaderMutex == NULL) return; - - NetlibUnloadIeProxy(); - NetlibUPnPDestroy(); - NetlibLogShutdown(); - - DestroyHookableEvent(hRecvEvent); hRecvEvent = NULL; - DestroyHookableEvent(hSendEvent); hSendEvent = NULL; - - for (int i = netlibUser.getCount(); i > 0; i--) - NetlibCloseHandle((WPARAM)netlibUser[i-1], 0); - - CloseHandle(hConnectionHeaderMutex); - if (hConnectionOpenMutex) - CloseHandle(hConnectionOpenMutex); - WSACleanup(); -} - -int LoadNetlibModule(void) -{ - WSADATA wsadata; - - bModuleInitialized = TRUE; - - WSAStartup(MAKEWORD(2, 2), &wsadata); - - HookEvent(ME_OPT_INITIALISE, NetlibOptInitialise); - - hConnectionHeaderMutex = CreateMutex(NULL, FALSE, NULL); - NetlibLogInit(); - - connectionTimeout = 0; - - OSVERSIONINFOEX osvi = {0}; - osvi.dwOSVersionInfoSize = sizeof(osvi); - if (GetVersionEx((LPOSVERSIONINFO)&osvi)) { - // Connection limiting was introduced in Windows XP SP2 and later and set to 10 / sec - if (osvi.dwMajorVersion == 5 && ((osvi.dwMinorVersion == 1 && osvi.wServicePackMajor >= 2) || osvi.dwMinorVersion > 1)) - connectionTimeout = 150; - // Connection limiting has limits based on addition Windows Vista pre SP2 - else if (osvi.dwMajorVersion == 6 && osvi.wServicePackMajor < 2) { - DWORD dwType = 0; - tGetProductInfo pGetProductInfo = (tGetProductInfo) GetProcAddress(GetModuleHandleA("kernel32"), "GetProductInfo"); - if (pGetProductInfo != NULL) pGetProductInfo(6, 0, 0, 0, &dwType); - switch(dwType) { - case 0x01: // Vista Ultimate edition have connection limit of 25 / sec - plenty for Miranda - case 0x1c: - break; - - case 0x02: // Vista Home Basic edition have connection limit of 2 / sec - case 0x05: - connectionTimeout = 1000; - break; - - default: // all other editions have connection limit of 10 / sec - connectionTimeout = 150; - break; - } - } - // Connection limiting is disabled by default and is controlled by registry setting in Windows Vista SP2 and later - else if (osvi.dwMajorVersion >= 6) { - static const char keyn[] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"; - static const char valn[] = "EnableConnectionRateLimiting"; - - HKEY hSettings; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyn, 0, KEY_QUERY_VALUE, &hSettings) == ERROR_SUCCESS) { - DWORD tValueLen, enabled; - tValueLen = sizeof(enabled); - if (RegQueryValueExA(hSettings, valn, NULL, NULL, (BYTE*)&enabled, &tValueLen) == ERROR_SUCCESS && enabled) - connectionTimeout = 150; // if enabled limit is set to 10 / sec - RegCloseKey(hSettings); - } - } - } - - hConnectionOpenMutex = connectionTimeout ? CreateMutex(NULL, FALSE, NULL) : NULL; - g_LastConnectionTick = GetTickCount(); - - CreateServiceFunction(MS_NETLIB_REGISTERUSER, NetlibRegisterUser); - CreateServiceFunction(MS_NETLIB_GETUSERSETTINGS, NetlibGetUserSettings); - CreateServiceFunction(MS_NETLIB_SETUSERSETTINGS, NetlibSetUserSettings); - CreateServiceFunction(MS_NETLIB_CLOSEHANDLE, NetlibCloseHandle); - CreateServiceFunction(MS_NETLIB_BINDPORT, NetlibBindPort); - CreateServiceFunction(MS_NETLIB_OPENCONNECTION, NetlibOpenConnection); - CreateServiceFunction(MS_NETLIB_SETHTTPPROXYINFO, NetlibHttpGatewaySetInfo); - CreateServiceFunction(MS_NETLIB_SETSTICKYHEADERS, NetlibHttpSetSticky); - CreateServiceFunction(MS_NETLIB_GETSOCKET, NetlibGetSocket); - CreateServiceFunction(MS_NETLIB_SENDHTTPREQUEST, NetlibHttpSendRequest); - CreateServiceFunction(MS_NETLIB_RECVHTTPHEADERS, NetlibHttpRecvHeaders); - CreateServiceFunction(MS_NETLIB_FREEHTTPREQUESTSTRUCT, NetlibHttpFreeRequestStruct); - CreateServiceFunction(MS_NETLIB_HTTPTRANSACTION, NetlibHttpTransaction); - CreateServiceFunction(MS_NETLIB_SEND, NetlibSend); - CreateServiceFunction(MS_NETLIB_RECV, NetlibRecv); - CreateServiceFunction(MS_NETLIB_SELECT, NetlibSelect); - CreateServiceFunction(MS_NETLIB_SELECTEX, NetlibSelectEx); - CreateServiceFunction(MS_NETLIB_SHUTDOWN, NetlibShutdown); - CreateServiceFunction(MS_NETLIB_CREATEPACKETRECVER, NetlibPacketRecverCreate); - CreateServiceFunction(MS_NETLIB_GETMOREPACKETS, NetlibPacketRecverGetMore); - CreateServiceFunction(MS_NETLIB_SETPOLLINGTIMEOUT, NetlibHttpSetPollingTimeout); - CreateServiceFunction(MS_NETLIB_STARTSSL, NetlibStartSsl); - CreateServiceFunction(MS_NETLIB_STRINGTOADDRESS, NetlibStringToAddressSrv); - CreateServiceFunction(MS_NETLIB_ADDRESSTOSTRING, NetlibAddressToStringSrv); - CreateServiceFunction(MS_NETLIB_GETCONNECTIONINFO, NetlibGetConnectionInfoSrv); - CreateServiceFunction(MS_NETLIB_GETMYIP, NetlibGetMyIp); - - hRecvEvent = CreateHookableEvent(ME_NETLIB_FASTRECV); - hSendEvent = CreateHookableEvent(ME_NETLIB_FASTSEND); - - NetlibUPnPInit(); - NetlibSecurityInit(); - NetlibLoadIeProxy(); - return 0; -} diff --git a/src/modules/netlib/netlib.h b/src/modules/netlib/netlib.h deleted file mode 100644 index 949d1755b2..0000000000 --- a/src/modules/netlib/netlib.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 NLH_INVALID 0 -#define NLH_USER 'USER' -#define NLH_CONNECTION 'CONN' -#define NLH_BOUNDPORT 'BIND' -#define NLH_PACKETRECVER 'PCKT' -int GetNetlibHandleType(void*); - -struct NetlibUser -{ - int handleType; - NETLIBUSER user; - NETLIBUSERSETTINGS settings; - char * szStickyHeaders; - int toLog; - int inportnum; - int outportnum; -}; - -struct NetlibNestedCriticalSection -{ - HANDLE hMutex; - DWORD dwOwningThreadId; - int lockCount; -}; - -struct NetlibHTTPProxyPacketQueue -{ - NetlibHTTPProxyPacketQueue *next; - PBYTE dataBuffer; - int dataBufferLen; -}; - -typedef union _SOCKADDR_INET_M { - SOCKADDR_IN Ipv4; - SOCKADDR_IN6 Ipv6; - USHORT si_family; -} SOCKADDR_INET_M, *PSOCKADDR_INET_M; - -struct NetlibConnection -{ - int handleType; - SOCKET s, s2; - bool usingHttpGateway; - bool usingDirectHttpGateway; - bool proxyAuthNeeded; - bool dnsThroughProxy; - bool termRequested; - NetlibUser *nlu; - NETLIBHTTPPROXYINFO nlhpi; - PBYTE dataBuffer; - int dataBufferLen; - CRITICAL_SECTION csHttpSequenceNums; - HANDLE hOkToCloseEvent; - LONG dontCloseNow; - NetlibNestedCriticalSection ncsSend, ncsRecv; - HSSL hSsl; - NetlibHTTPProxyPacketQueue * pHttpProxyPacketQueue; - char *szNewUrl; - char *szProxyServer; - WORD wProxyPort; - int proxyType; - int pollingTimeout; - unsigned lastPost; - NETLIBOPENCONNECTION nloc; -}; - -struct NetlibBoundPort { - int handleType; - SOCKET s; - SOCKET s6; - WORD wPort; - WORD wExPort; - NetlibUser *nlu; - NETLIBNEWCONNECTIONPROC_V2 pfnNewConnectionV2; - HANDLE hThread; - void *pExtra; -}; - -struct NetlibPacketRecver { - int handleType; - NetlibConnection *nlc; - NETLIBPACKETRECVER packetRecver; -}; - -//netlib.c -void NetlibFreeUserSettingsStruct(NETLIBUSERSETTINGS *settings); -void NetlibDoClose(NetlibConnection *nlc, bool noShutdown = false); -INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM lParam); -void NetlibInitializeNestedCS(NetlibNestedCriticalSection *nlncs); -void NetlibDeleteNestedCS(NetlibNestedCriticalSection *nlncs); -#define NLNCS_SEND 0 -#define NLNCS_RECV 1 -int NetlibEnterNestedCS(NetlibConnection *nlc, int which); -void NetlibLeaveNestedCS(NetlibNestedCriticalSection *nlncs); -INT_PTR NetlibBase64Encode(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibBase64Decode(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibHttpUrlEncode(WPARAM wParam, LPARAM lParam); - -extern mir_cs csNetlibUser; -extern LIST netlibUser; - -//netlibautoproxy.c -void NetlibLoadIeProxy(void); -void NetlibUnloadIeProxy(void); -char* NetlibGetIeProxy(char *szUrl); -bool NetlibGetIeProxyConn(NetlibConnection *nlc, bool forceHttps); - -//netlibbind.c -int NetlibFreeBoundPort(NetlibBoundPort *nlbp); -INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam); -bool BindSocketToPort(const char *szPorts, SOCKET s, SOCKET s6, int* portn); - -//netlibhttp.c -INT_PTR NetlibHttpSendRequest(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibHttpRecvHeaders(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibHttpFreeRequestStruct(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibHttpTransaction(WPARAM wParam, LPARAM lParam); -void NetlibHttpSetLastErrorUsingHttpResult(int result); -NETLIBHTTPREQUEST* NetlibHttpRecv(NetlibConnection* nlc, DWORD hflags, DWORD dflags, bool isConnect = false); -void NetlibConnFromUrl(const char* szUrl, bool secur, NETLIBOPENCONNECTION &nloc); - -//netlibhttpproxy.c -int NetlibInitHttpConnection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc); -int NetlibHttpGatewayRecv(NetlibConnection *nlc, char *buf, int len, int flags); -int NetlibHttpGatewayPost(NetlibConnection *nlc, const char *buf, int len, int flags); -void HttpGatewayRemovePacket(NetlibConnection *nlc, int pck); - -INT_PTR NetlibHttpGatewaySetInfo(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibHttpSetPollingTimeout(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibHttpSetSticky(WPARAM wParam, LPARAM lParam); - -//netliblog.c -void NetlibLogShowOptions(void); -void NetlibDumpData(NetlibConnection *nlc, PBYTE buf, int len, int sent, int flags); -void NetlibLogf(NetlibUser* nlu, const char *fmt, ...); -void NetlibLogInit(void); -void NetlibLogShutdown(void); - -//netlibopenconn.c -DWORD DnsLookup(NetlibUser *nlu, const char *szHost); -int WaitUntilReadable(SOCKET s, DWORD dwTimeout, bool check = false); -int WaitUntilWritable(SOCKET s, DWORD dwTimeout); -bool NetlibDoConnect(NetlibConnection *nlc); -bool NetlibReconnect(NetlibConnection *nlc); -INT_PTR NetlibOpenConnection(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibStartSsl(WPARAM wParam, LPARAM lParam); - -//netlibopts.c -int NetlibOptInitialise(WPARAM wParam, LPARAM lParam); -void NetlibSaveUserSettingsStruct(const char *szSettingsModule, NETLIBUSERSETTINGS *settings); - -//netlibpktrecver.c -INT_PTR NetlibPacketRecverCreate(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibPacketRecverGetMore(WPARAM wParam, LPARAM lParam); - -//netlibsock.c -#define NL_SELECT_READ 0x0001 -#define NL_SELECT_WRITE 0x0002 -#define NL_SELECT_ALL (NL_SELECT_READ+NL_SELECT_WRITE) - -INT_PTR NetlibSend(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibRecv(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibSelect(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibSelectEx(WPARAM wParam, LPARAM lParam); -INT_PTR NetlibShutdown(WPARAM wParam, LPARAM lParam); - -bool NetlibStringToAddress(const char* str, SOCKADDR_INET_M* addr); -char* NetlibAddressToString(SOCKADDR_INET_M* addr); -void NetlibGetConnectionInfo(NetlibConnection* nlc, NETLIBCONNINFO *connInfo); -NETLIBIPLIST* GetMyIp(unsigned flags); - -//netlibupnp.c -bool NetlibUPnPAddPortMapping(WORD intport, char *proto, - WORD *extport, DWORD *extip, bool search); -void NetlibUPnPDeletePortMapping(WORD extport, char* proto); -void NetlibUPnPCleanup(void*); -void NetlibUPnPInit(void); -void NetlibUPnPDestroy(void); - -//netlibsecurity.c -void NetlibSecurityInit(void); -void NetlibDestroySecurityProvider(HANDLE hSecurity); -HANDLE NetlibInitSecurityProvider(const TCHAR* szProvider, const TCHAR* szPrincipal); -HANDLE NetlibInitSecurityProvider(const char* szProvider, const char* szPrincipal); -char* NtlmCreateResponseFromChallenge(HANDLE hSecurity, const char *szChallenge, const TCHAR* login, const TCHAR* psw, - bool http, unsigned& complete); - -static __inline INT_PTR NLSend(NetlibConnection *nlc, const char *buf, int len, int flags) { - NETLIBBUFFER nlb = {(char*)buf, len, flags}; - return NetlibSend((WPARAM)nlc, (LPARAM)&nlb); -} - -static __inline INT_PTR NLRecv(NetlibConnection *nlc, char *buf, int len, int flags) { - NETLIBBUFFER nlb = {buf, len, flags}; - return NetlibRecv((WPARAM)nlc, (LPARAM)&nlb); -} diff --git a/src/modules/netlib/netlibautoproxy.cpp b/src/modules/netlib/netlibautoproxy.cpp deleted file mode 100644 index 6410c49e74..0000000000 --- a/src/modules/netlib/netlibautoproxy.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "netlib.h" - -#include - -/* -///////////////////////////////////////////////////////////////////// -// ResolveHostName (a helper function) -///////////////////////////////////////////////////////////////////// -DWORD __stdcall ResolveHostName(LPSTR lpszHostName, - LPSTR lpszIPAddress, LPDWORD lpdwIPAddressSize) -{ - if (*lpdwIPAddressSize < 17 || lpszIPAddress == NULL) - { - *lpdwIPAddressSize = 17; - return ERROR_INSUFFICIENT_BUFFER; - } - - IN_ADDR ip; - ip.s_addr = inet_addr(lpszHostName); - if (ip.s_addr == INADDR_NONE) - { - PHOSTENT myhost = gethostbyname(lpszHostName); - if (myhost != NULL) - ip = *(PIN_ADDR)myhost->h_addr; - else - return SOCKET_ERROR; - } - mir_snprintf(lpszIPAddress, *lpdwIPAddressSize, "%u.%u.%u.%u", - ip.s_net, ip.s_host, ip.s_lh, ip.s_impno); - - return 0; -} - -///////////////////////////////////////////////////////////////////// -// IsResolvable (a helper function) -///////////////////////////////////////////////////////////////////// -BOOL __stdcall IsResolvable(LPSTR lpszHost) -{ - char szDummy[255]; - DWORD dwDummySize = sizeof (szDummy) - 1; - - if (ResolveHostName(lpszHost, szDummy, &dwDummySize)) - return FALSE; - return TRUE; -} - -///////////////////////////////////////////////////////////////////// -// GetIPAddress (a helper function) -///////////////////////////////////////////////////////////////////// -DWORD __stdcall GetIPAddress(LPSTR lpszIPAddress, LPDWORD lpdwIPAddressSize) -{ - char szHostBuffer[255]; - - if (gethostname(szHostBuffer, sizeof (szHostBuffer) - 1) != ERROR_SUCCESS) - return (ERROR_INTERNET_INTERNAL_ERROR); - return (ResolveHostName(szHostBuffer, lpszIPAddress, lpdwIPAddressSize)); -} - -///////////////////////////////////////////////////////////////////// -// IsInNet (a helper function) -///////////////////////////////////////////////////////////////////// -BOOL __stdcall IsInNet(LPSTR lpszIPAddress, LPSTR lpszDest, LPSTR lpszMask) -{ - DWORD dwDest; - DWORD dwIpAddr; - DWORD dwMask; - - dwIpAddr = inet_addr(lpszIPAddress); - dwDest = inet_addr(lpszDest); - dwMask = inet_addr(lpszMask); - - if ((dwDest == INADDR_NONE) || - (dwIpAddr == INADDR_NONE) || ((dwIpAddr & dwMask) != dwDest)) - return (FALSE); - - return (TRUE); -} - -static const AutoProxyHelperVtbl OurVtbl = -{ - IsResolvable, - GetIPAddress, - ResolveHostName, - IsInNet, - NULL, - NULL, - NULL, - NULL -}; - -static AutoProxyHelperFunctions HelperFunctions = { &OurVtbl }; -*/ - -static char *szProxyHost[3]; -static LIST proxyBypass(5); - -static HMODULE hModJS; - -static pfnInternetInitializeAutoProxyDll pInternetInitializeAutoProxyDll; -static pfnInternetDeInitializeAutoProxyDll pInternetDeInitializeAutoProxyDll; -static pfnInternetGetProxyInfo pInternetGetProxyInfo; - -static bool bEnabled, bOneProxy; - -static void GetFile(char* szUrl, AUTO_PROXY_SCRIPT_BUFFER &buf) -{ - NetlibUser nlu = {0}; - NETLIBHTTPREQUEST nlhr = {0}; - - nlu.handleType = NLH_USER; - nlu.user.flags = NUF_OUTGOING | NUF_HTTPCONNS; - nlu.user.szSettingsModule = "(NULL)"; - nlu.toLog = 1; - - // initialize the netlib request - nlhr.cbSize = sizeof(nlhr); - nlhr.requestType = REQUEST_GET; - nlhr.flags = NLHRF_HTTP11 | NLHRF_DUMPASTEXT | NLHRF_REDIRECT; - nlhr.szUrl = szUrl; - - // download the page - NETLIBHTTPREQUEST *nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpTransaction((WPARAM)&nlu, (LPARAM)&nlhr); - - if (nlhrReply) - { - if (nlhrReply->resultCode == 200) - { - buf.lpszScriptBuffer = nlhrReply->pData; - buf.dwScriptBufferSize = nlhrReply->dataLength + 1; - - nlhrReply->dataLength = 0; - nlhrReply->pData = NULL; - } - CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply); - } -} - -bool NetlibGetIeProxyConn(NetlibConnection *nlc, bool forceHttps) -{ - bool noHttp = false; - bool usingSsl = false; - char szUrl[256]; - - if ((nlc->nloc.flags & (NLOCF_HTTP | NLOCF_HTTPGATEWAY) && nlc->nloc.flags & NLOCF_SSL) || - nlc->nloc.wPort == 443 || forceHttps) - { - mir_snprintf(szUrl, "https://%s", nlc->nloc.szHost); - usingSsl = true; - } - else if (nlc->nloc.flags & (NLOCF_HTTPGATEWAY | NLOCF_HTTP) || nlc->usingHttpGateway) - mir_snprintf(szUrl, "http://%s", nlc->nloc.szHost); - else - { - strncpy_s(szUrl, nlc->nloc.szHost, _TRUNCATE); - noHttp = true; - } - - mir_free(nlc->szProxyServer); nlc->szProxyServer = NULL; - nlc->wProxyPort = 0; - nlc->proxyType = 0; - - char *mt = NetlibGetIeProxy(szUrl); - char *m = NEWSTR_ALLOCA(mt); - mir_free(mt); - - if (m == NULL) return false; - - // if multiple servers, use the first one - char *c = strchr(m, ';'); if (c) *c = 0; - - // if 'direct' no proxy - if (_stricmp(lrtrim(m), "direct") == 0) return false; - - // find proxy address - char *h = strchr(m, ' '); - if (h) { *h = 0; ++h; } else return false; - - // find proxy port - char *p = strchr(h, ':'); - if (p) { *p = 0; ++p; } - - lrtrim(h); ltrim(p); - if (_stricmp(m, "proxy") == 0 && h[0]) - { - nlc->proxyType = (usingSsl || noHttp) ? PROXYTYPE_HTTPS : PROXYTYPE_HTTP; - nlc->wProxyPort = p ? atol(p) : 8080; - nlc->szProxyServer = mir_strdup(h); - } - else if (_stricmp(m, "socks") == 0 && h[0]) - { - nlc->proxyType = PROXYTYPE_SOCKS4; - nlc->wProxyPort = p ? atol(p) : 1080; - nlc->szProxyServer = mir_strdup(h); - } - else if (_stricmp(m, "socks5") == 0 && h[0]) - { - nlc->proxyType = PROXYTYPE_SOCKS5; - nlc->wProxyPort = p ? atol(p) : 1080; - nlc->szProxyServer = mir_strdup(h); - } - else - return false; - - return true; -} - -static char szAutoUrlStr[MAX_PATH] = ""; -static AUTO_PROXY_SCRIPT_BUFFER abuf = {0}; -static HANDLE hIeProxyMutex; -static bool bAutoProxyInit; - -static void NetlibInitAutoProxy(void) -{ - if (bAutoProxyInit) return; - - if (!hModJS) - { - if (!(hModJS = LoadLibraryA("jsproxy.dll"))) - return; - - pInternetInitializeAutoProxyDll = (pfnInternetInitializeAutoProxyDll) - GetProcAddress(hModJS, "InternetInitializeAutoProxyDll"); - - pInternetDeInitializeAutoProxyDll = (pfnInternetDeInitializeAutoProxyDll) - GetProcAddress(hModJS, "InternetDeInitializeAutoProxyDll"); - - pInternetGetProxyInfo = (pfnInternetGetProxyInfo) - GetProcAddress(hModJS, "InternetGetProxyInfo"); - } - - if (strstr(szAutoUrlStr, "file://") == NULL && strstr(szAutoUrlStr, "://") != NULL) - { - abuf.dwStructSize = sizeof(abuf); - GetFile(szAutoUrlStr, abuf); - } - bAutoProxyInit = true; -} - -struct IeProxyParam -{ - char *szUrl; - char *szHost; - char *szProxy; -}; - -static void NetlibIeProxyThread(void *arg) -{ - IeProxyParam *param = (IeProxyParam*)arg; - param->szProxy = NULL; - - if (!bAutoProxyInit) { - WaitForSingleObject(hIeProxyMutex, INFINITE); - NetlibInitAutoProxy(); - ReleaseMutex(hIeProxyMutex); - } - - BOOL res; - char *loc = strstr(szAutoUrlStr, "file://"); - if (loc || strstr(szAutoUrlStr, "://") == NULL) { - NetlibLogf(NULL, "Autoproxy Init file: %s", loc); - loc = loc ? loc + 7 : szAutoUrlStr; - res = pInternetInitializeAutoProxyDll(0, loc, NULL, NULL /*&HelperFunctions*/, NULL); - } - else { - NetlibLogf(NULL, "Autoproxy Init %d", abuf.dwScriptBufferSize); - if (abuf.dwScriptBufferSize) - res = pInternetInitializeAutoProxyDll(0, NULL, NULL, NULL /*&HelperFunctions*/, &abuf); - else - res = false; - } - - if (res) { - char proxyBuffer[1024]; - char *proxy = proxyBuffer; - DWORD dwProxyLen = sizeof(proxyBuffer); - - if (pInternetGetProxyInfo(param->szUrl, (DWORD)mir_strlen(param->szUrl), - param->szHost, (DWORD)mir_strlen(param->szHost), &proxy, &dwProxyLen)) - param->szProxy = mir_strdup(lrtrim(proxy)); - - NetlibLogf(NULL, "Autoproxy got response %s, Param: %s %s", param->szProxy, param->szUrl, param->szHost); - pInternetDeInitializeAutoProxyDll(NULL, 0); - } - else NetlibLogf(NULL, "Autoproxy init failed"); -} - -char* NetlibGetIeProxy(char *szUrl) -{ - char *res = NULL; - char* p = strstr(szUrl, "://"); - if (p) p += 3; else p = szUrl; - - char *szHost = NEWSTR_ALLOCA(p); - p = strchr(szHost, '/'); if (p) *p = 0; - p = strchr(szHost, ':'); if (p) *p = 0; - _strlwr(szHost); - - if (bEnabled) - { - for (int i=0; i < proxyBypass.getCount(); i++) - { - if (mir_strcmp(proxyBypass[i], "") == 0) - { - if (strchr(szHost, '.') == NULL) return NULL; - } - else if (wildcmp(szHost, proxyBypass[i])) return NULL; - } - - int ind = -1; - if (strstr(szUrl, "http://")) - ind = szProxyHost[0] ? 0 : 2; - else if (strstr(szUrl, "https://")) - ind = bOneProxy ? 0 : (szProxyHost[1] ? 1 : 2); - else - ind = szProxyHost[2] ? 2 : (bOneProxy ? 0 : (szProxyHost[1] ? 1 : 2)); - - if (ind < 0 || !szProxyHost[ind]) return NULL; - - size_t len = mir_strlen(szHost) + 20; - res = (char*)mir_alloc(len); - mir_snprintf(res, len, "%s %s", ind == 2 ? "SOCKS" : "PROXY", szProxyHost[ind]); - return res; - } - - if (szAutoUrlStr[0]) { - IeProxyParam param = { szUrl, szHost, NULL }; - HANDLE hThread = mir_forkthread(NetlibIeProxyThread, ¶m); - WaitForSingleObject(hThread, INFINITE); - res = param.szProxy; - } - return res; -} - -void NetlibLoadIeProxy(void) -{ - HKEY hSettings; - if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", - 0, KEY_QUERY_VALUE, &hSettings)) - return; - - DWORD tValueLen, enabled = 0; - char szHostStr[256] = "", szProxyBypassStr[4096] = ""; - - tValueLen = sizeof(enabled); - int tResult = RegQueryValueExA(hSettings, "ProxyEnable", NULL, NULL, (BYTE*)&enabled, &tValueLen); - bEnabled = enabled && tResult == ERROR_SUCCESS; - - tValueLen = SIZEOF(szHostStr); - tResult = RegQueryValueExA(hSettings, "ProxyServer", NULL, NULL, (BYTE*)szHostStr, &tValueLen); - bEnabled = bEnabled && tResult == ERROR_SUCCESS; - - tValueLen = SIZEOF(szAutoUrlStr); - RegQueryValueExA(hSettings, "AutoConfigUrl", NULL, NULL, (BYTE*)szAutoUrlStr, &tValueLen); - - tValueLen = SIZEOF(szProxyBypassStr); - RegQueryValueExA(hSettings, "ProxyOverride", NULL, NULL, (BYTE*)szProxyBypassStr, &tValueLen); - - RegCloseKey(hSettings); - - if (bEnabled) - { - char* szProxy = ltrim(szHostStr); - if (szProxy[0] == 0) { enabled = false; return; } - - while(true) - { - char *szProxyEnd = strchr(szProxy, ';'); - if (szProxyEnd) *szProxyEnd = 0; - - int ind = -1; - if (strncmp(szProxy, "http = ", 5) == 0) { ind = 0; szProxy += 5; } - else if (strncmp(szProxy, "https = ", 6) == 0) { ind = 1; szProxy += 6; } - else if (strncmp(szProxy, "socks = ", 6) == 0) { ind = 2; szProxy += 6; } - else if (strchr(szProxy, '=')) ind = -2; - - if (ind != -2) - { - bOneProxy = ind < 0; if (ind < 0) ind = 0; - - lrtrim(szProxy); - - if (strchr(szProxy, ':')) - szProxyHost[ind] = mir_strdup(szProxy); - else - { - size_t len = mir_strlen(szProxy) + 10; - szProxyHost[ind] = (char*)mir_alloc(len); - mir_snprintf(szProxyHost[ind], len, "%s:%u", szProxy, ind == 2 ? 1080 : 8080); - } - if (bOneProxy) break; - } - if (szProxyEnd == NULL) break; - szProxy = szProxyEnd + 1; - } - - char* szProxyBypass = szProxyBypassStr; - while(true) - { - char *szProxyBypassEnd = strchr(szProxyBypass, ';'); - if (szProxyBypassEnd) *szProxyBypassEnd = 0; - - lrtrim(szProxyBypass); - - proxyBypass.insert(_strlwr(mir_strdup(szProxyBypass))); - if (szProxyBypassEnd == NULL) break; - - szProxyBypass = szProxyBypassEnd + 1; - } - } - - if (bEnabled || szAutoUrlStr[0]) - hIeProxyMutex = CreateMutex(NULL, FALSE, NULL); -} - -void NetlibUnloadIeProxy(void) -{ - int i; - - for (i=0; i < 3; i++) - mir_free(szProxyHost[i]); - - for (i=0; i < proxyBypass.getCount(); i++) - mir_free(proxyBypass[i]); - - mir_free(abuf.lpszScriptBuffer); - - CloseHandle(hIeProxyMutex); -} diff --git a/src/modules/netlib/netlibbind.cpp b/src/modules/netlib/netlibbind.cpp deleted file mode 100644 index 699799dd17..0000000000 --- a/src/modules/netlib/netlibbind.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "netlib.h" - -bool BindSocketToPort(const char *szPorts, SOCKET s, SOCKET s6, int* portn) -{ - SOCKADDR_IN sin = {0}; - sin.sin_family = AF_INET; - - SOCKADDR_IN6 sin6 = {0}; - sin6.sin6_family = AF_INET6; - - mir_cslock lck(csNetlibUser); - - if (--*portn < 0 && (s != INVALID_SOCKET || s6 != INVALID_SOCKET)) { - BindSocketToPort(szPorts, INVALID_SOCKET, INVALID_SOCKET, portn); - if (*portn == 0) - return false; - - WORD num; - CallService(MS_UTILS_GETRANDOM, sizeof(WORD), (LPARAM)&num); - *portn = num % *portn; - } - - bool before = false; - while (true) { - const char *psz; - char *pszEnd; - int portMin, portMax, port, portnum = 0; - - for (psz = szPorts;*psz;) { - while (*psz == ' ' || *psz == ',') psz++; - portMin = strtol(psz, &pszEnd, 0); - if (pszEnd == psz) - break; - while (*pszEnd == ' ') - pszEnd++; - if (*pszEnd == '-') { - psz = pszEnd + 1; - portMax = strtol(psz, &pszEnd, 0); - if (pszEnd == psz) portMax = 65535; - if (portMin > portMax) { - port = portMin; - portMin = portMax; - portMax = port; - } - } - else portMax = portMin; - if (portMax >= 1) { - if (portMin <= 0) portMin = 1; - for (port = portMin; port <= portMax; port++) { - if (port > 65535) - break; - - ++portnum; - - if (s == INVALID_SOCKET) continue; - if (!before && portnum <= *portn) continue; - if (before && portnum >= *portn) - return false; - - sin.sin_port = htons((WORD)port); - bool bV4Mapped = s == INVALID_SOCKET || bind(s, (SOCKADDR*)&sin, sizeof(sin)) == 0; - - sin6.sin6_port = htons((WORD)port); - bool bV6Mapped = s6 == INVALID_SOCKET || bind(s6, (PSOCKADDR)&sin6, sizeof(sin6)) == 0; - - if (bV4Mapped && bV6Mapped) { - *portn = portnum + 1; - return true; - } - } - } - psz = pszEnd; - } - - if (*portn < 0) { - *portn = portnum; - return true; - } - - if (*portn >= portnum) - *portn = 0; - else - before = true; - } -} - -int NetlibFreeBoundPort(struct NetlibBoundPort *nlbp) -{ - closesocket(nlbp->s); - closesocket(nlbp->s6); - if (nlbp->hThread) - WaitForSingleObject(nlbp->hThread, INFINITE); - NetlibLogf(nlbp->nlu, "(%u) Port %u closed for incoming connections", nlbp->s, nlbp->wPort); - mir_free(nlbp); - return 1; -} - -static void NetlibBindAcceptThread(void* param) -{ - NetlibBoundPort *nlbp = (NetlibBoundPort*)param; - NetlibLogf(nlbp->nlu, "(%u) Port %u opened for incoming connections", nlbp->s, nlbp->wPort); - - while (true) { - fd_set r; - FD_ZERO(&r); - if (nlbp->s != INVALID_SOCKET) - FD_SET(nlbp->s, &r); - if (nlbp->s6 != INVALID_SOCKET) - FD_SET(nlbp->s6, &r); - if (select(0, &r, NULL, NULL, NULL) == SOCKET_ERROR) { - NetlibLogf(nlbp->nlu, "NetlibBindAcceptThread (%p): select failed (%d)", nlbp->s, GetLastError()); - break; - } - - SOCKADDR_INET_M sin; - int sinLen = sizeof(sin); - memset(&sin, 0, sizeof(sin)); - - SOCKET s; - if (FD_ISSET(nlbp->s, &r)) { - s = accept(nlbp->s, (sockaddr*)&sin, &sinLen); - if (s == INVALID_SOCKET) { - NetlibLogf(nlbp->nlu, "NetlibBindAcceptThread (%p): accept V4 failed (%d)", nlbp->s, GetLastError()); - break; - } - } - else if (FD_ISSET(nlbp->s6, &r)) { - s = accept(nlbp->s6, (sockaddr*)&sin, &sinLen); - if (s == INVALID_SOCKET) { - NetlibLogf(nlbp->nlu, "NetlibBindAcceptThread (%p): accept V6 failed (%d)", nlbp->s, GetLastError()); - break; - } - } - - NetlibLogf(nlbp->nlu, "New incoming connection on port %u from %s (%p)", nlbp->wPort, ptrA(NetlibAddressToString(&sin)), s); - - NetlibConnection *nlc = (NetlibConnection*)mir_calloc(sizeof(NetlibConnection)); - nlc->handleType = NLH_CONNECTION; - nlc->nlu = nlbp->nlu; - nlc->s = s; - nlc->s2 = INVALID_SOCKET; - InitializeCriticalSection(&nlc->csHttpSequenceNums); - nlc->hOkToCloseEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - NetlibInitializeNestedCS(&nlc->ncsSend); - NetlibInitializeNestedCS(&nlc->ncsRecv); - - if (nlbp->pfnNewConnectionV2) - nlbp->pfnNewConnectionV2(nlc, ntohl(sin.Ipv4.sin_addr.S_un.S_addr), nlbp->pExtra); - } - - NetlibUPnPDeletePortMapping(nlbp->wExPort, "TCP"); - nlbp->hThread = 0; - - NetlibLogf(nlbp->nlu, "NetlibBindAcceptThread: (%p) thread for port %u closed", nlbp->s, nlbp->wPort); -} - -INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam) -{ - NETLIBBIND *nlb = (NETLIBBIND*)lParam; - NetlibUser *nlu = (NetlibUser*)wParam; - struct NetlibBoundPort *nlbp; - SOCKADDR_IN sin = { 0 }; - SOCKADDR_IN6 sin6 = { 0 }; - int foundPort = 0; - - if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_INCOMING) || - nlb == NULL || nlb->pfnNewConnection == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - if (nlb->cbSize != sizeof(NETLIBBIND)) - return 0; - - nlbp = (NetlibBoundPort*)mir_calloc(sizeof(NetlibBoundPort)); - nlbp->handleType = NLH_BOUNDPORT; - nlbp->nlu = nlu; - nlbp->pfnNewConnectionV2 = nlb->pfnNewConnectionV2; - - nlbp->s = socket(PF_INET, SOCK_STREAM, 0); - nlbp->s6 = socket(PF_INET6, SOCK_STREAM, 0); - nlbp->pExtra = nlb->pExtra; - if (nlbp->s == INVALID_SOCKET && nlbp->s6 == INVALID_SOCKET) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "socket", WSAGetLastError()); - mir_free(nlbp); - return 0; - } - sin.sin_family = AF_INET; - sin6.sin6_family = AF_INET6; - - /* if the netlib user wanted a free port given in the range, then - they better have given wPort == 0, let's hope so */ - if (nlu->settings.specifyIncomingPorts && nlu->settings.szIncomingPorts && nlb->wPort == 0) { - if (!BindSocketToPort(nlu->settings.szIncomingPorts, nlbp->s, nlbp->s6, &nlu->outportnum)) { - NetlibLogf(nlu, "Netlib bind: Not enough ports for incoming connections specified"); - SetLastError(WSAEADDRINUSE); - } - else foundPort = 1; - } - else { - /* if ->wPort == 0 then they'll get any free port, otherwise they'll - be asking for whatever was in nlb->wPort*/ - if (nlb->wPort != 0) { - NetlibLogf(nlu, "%s %d: trying to bind port %d, this 'feature' can be abused, please be sure you want to allow it.", __FILE__, __LINE__, nlb->wPort); - sin.sin_port = htons(nlb->wPort); - sin6.sin6_port = htons(nlb->wPort); - } - - if (nlbp->s != INVALID_SOCKET) - if (bind(nlbp->s, (PSOCKADDR)&sin, sizeof(sin)) == 0) { - SOCKADDR_IN sin = { 0 }; - int len = sizeof(sin); - if (!getsockname(nlbp->s, (PSOCKADDR)&sin, &len)) - sin6.sin6_port = sin.sin_port; - foundPort = 1; - } - - if (nlbp->s6 != INVALID_SOCKET) - if (bind(nlbp->s6, (PSOCKADDR)&sin6, sizeof(sin6)) == 0) - foundPort = 1; - } - if (!foundPort) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "bind", WSAGetLastError()); -LBL_Error: - closesocket(nlbp->s); - closesocket(nlbp->s6); - mir_free(nlbp); - return 0; - } - - if (nlbp->s != INVALID_SOCKET && listen(nlbp->s, 5)) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "listen", WSAGetLastError()); - goto LBL_Error; - } - - if (nlbp->s6 != INVALID_SOCKET && listen(nlbp->s6, 5)) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "listen", WSAGetLastError()); - goto LBL_Error; - } - - SOCKADDR_INET_M sinm = { 0 }; - int len = sizeof(sinm); - if (!getsockname(nlbp->s, (PSOCKADDR)&sinm, &len)) { - nlb->wPort = ntohs(sinm.Ipv4.sin_port); - nlb->dwInternalIP = ntohl(sinm.Ipv4.sin_addr.S_un.S_addr); - } - else if (!getsockname(nlbp->s6, (PSOCKADDR)&sinm, &len)) - nlb->wPort = ntohs(sinm.Ipv6.sin6_port); - else { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "getsockname", WSAGetLastError()); - goto LBL_Error; - } - nlbp->wPort = nlb->wPort; - - if (nlb->dwInternalIP == 0) { - char hostname[64] = ""; - gethostname(hostname, SIZEOF(hostname)); - - PHOSTENT he = gethostbyname(hostname); - if (he && he->h_addr) - nlb->dwInternalIP = ntohl(*(PDWORD)he->h_addr); - } - - DWORD extIP; - if (nlu->settings.enableUPnP && NetlibUPnPAddPortMapping(nlb->wPort, "TCP", &nlbp->wExPort, &extIP, true)) { - NetlibLogf(NULL, "UPnP port mapping succeeded. Internal Port: %u External Port: %u\n", nlb->wPort, nlbp->wExPort); - nlb->wExPort = nlbp->wExPort; - nlb->dwExternalIP = extIP; - } - else { - if (nlu->settings.enableUPnP) - NetlibLogf(NULL, "UPnP port mapping failed. Internal Port: %u\n", nlb->wPort); - else - NetlibLogf(NULL, "UPnP disabled. Internal Port: %u\n", nlb->wPort); - - nlbp->wExPort = 0; - nlb->wExPort = nlb->wPort; - nlb->dwExternalIP = nlb->dwInternalIP; - } - - nlbp->hThread = mir_forkthread(NetlibBindAcceptThread, nlbp); - return (INT_PTR)nlbp; -} diff --git a/src/modules/netlib/netlibhttp.cpp b/src/modules/netlib/netlibhttp.cpp deleted file mode 100644 index 3fe48d5dc1..0000000000 --- a/src/modules/netlib/netlibhttp.cpp +++ /dev/null @@ -1,1168 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "../plugins/zlib/src/zlib.h" -#include "netlib.h" - -#define HTTPRECVHEADERSTIMEOUT 30000 //in ms -#define HTTPRECVDATATIMEOUT 20000 - -struct ResizableCharBuffer -{ - char *sz; - int iEnd, cbAlloced; -}; - -struct ProxyAuth -{ - char *szServer; - char *szMethod; -// char *szUserName; -// char *szPassword; - - ProxyAuth(const char *pszServer, const char *pszMethod) - { - szServer = mir_strdup(pszServer); - szMethod = mir_strdup(pszMethod); - } - ~ProxyAuth() - { - mir_free(szServer); - mir_free(szMethod); - } - static int Compare(const ProxyAuth* p1, const ProxyAuth* p2) - { return mir_strcmpi(p1->szServer, p2->szServer); } -}; - -struct ProxyAuthList : OBJLIST -{ - ProxyAuthList() : OBJLIST(2, ProxyAuth::Compare) {} - - void add(const char *szServer, const char *szMethod) - { - if (szServer == NULL) return; - int i = getIndex((ProxyAuth*)&szServer); - if (i >= 0) { - ProxyAuth &rec = (*this)[i]; - if (szMethod == NULL) - remove(i); - else if (_stricmp(rec.szMethod, szMethod)) { - mir_free(rec.szMethod); - rec.szMethod = mir_strdup(szMethod); - } - } - else insert(new ProxyAuth(szServer, szMethod)); - } - - const char* find(const char *szServer) - { - ProxyAuth * rec = szServer ? OBJLIST::find((ProxyAuth*)&szServer) : NULL; - return rec ? rec->szMethod : NULL; - } -}; - -ProxyAuthList proxyAuthList; - -static void AppendToCharBuffer(struct ResizableCharBuffer *rcb, const char *fmt, ...) -{ - va_list va; - int charsDone; - - if (rcb->cbAlloced == 0) { - rcb->cbAlloced = 512; - rcb->sz = (char*)mir_alloc(rcb->cbAlloced); - } - va_start(va, fmt); - while (true) { - charsDone = mir_vsnprintf(rcb->sz + rcb->iEnd, rcb->cbAlloced-rcb->iEnd, fmt, va); - if (charsDone >= 0) break; - rcb->cbAlloced += 512; - rcb->sz = (char*)mir_realloc(rcb->sz, rcb->cbAlloced); - } - va_end(va); - rcb->iEnd += charsDone; -} - -static int RecvWithTimeoutTime(NetlibConnection *nlc, unsigned dwTimeoutTime, char *buf, int len, int flags) -{ - DWORD dwTimeNow; - - if (!si.pending(nlc->hSsl)) { - while ((dwTimeNow = GetTickCount()) < dwTimeoutTime) { - unsigned dwDeltaTime = min(dwTimeoutTime - dwTimeNow, 1000); - int res = WaitUntilReadable(nlc->s, dwDeltaTime); - - switch (res) { - case SOCKET_ERROR: - return SOCKET_ERROR; - - case 1: - return NLRecv(nlc, buf, len, flags); - } - - if (nlc->termRequested || Miranda_Terminated()) - return 0; - } - SetLastError(ERROR_TIMEOUT); - return SOCKET_ERROR; - } - return NLRecv(nlc, buf, len, flags); -} - -static char* NetlibHttpFindHeader(NETLIBHTTPREQUEST *nlhrReply, const char *hdr) -{ - for (int i=0; i < nlhrReply->headersCount; i++) { - NETLIBHTTPHEADER &p = nlhrReply->headers[i]; - if (_stricmp(p.szName, hdr) == 0) - return p.szValue; - } - - return NULL; -} - -static char* NetlibHttpFindAuthHeader(NETLIBHTTPREQUEST *nlhrReply, const char *hdr, const char *szProvider) -{ - char *szBasicHdr = NULL; - char *szNegoHdr = NULL; - char *szNtlmHdr = NULL; - - for (int i=0; i < nlhrReply->headersCount; i++) { - NETLIBHTTPHEADER &p = nlhrReply->headers[i]; - if (_stricmp(p.szName, hdr) == 0) { - if (_strnicmp(p.szValue, "Negotiate", 9) == 0) - szNegoHdr = p.szValue; - else if (_strnicmp(p.szValue, "NTLM", 4) == 0) - szNtlmHdr = p.szValue; - else if (_strnicmp(p.szValue, "Basic", 5) == 0) - szBasicHdr = p.szValue; - } - } - - if (szNegoHdr && (!szProvider || !_stricmp(szProvider, "Negotiate"))) return szNegoHdr; - if (szNtlmHdr && (!szProvider || !_stricmp(szProvider, "NTLM"))) return szNtlmHdr; - if (!szProvider || !_stricmp(szProvider, "Basic")) return szBasicHdr; - return NULL; -} - -void NetlibConnFromUrl(const char* szUrl, bool secur, NETLIBOPENCONNECTION &nloc) -{ - secur = secur || _strnicmp(szUrl, "https", 5) == 0; - const char* phost = strstr(szUrl, "://"); - - char* szHost = mir_strdup(phost ? phost + 3 : szUrl); - - char* ppath = strchr(szHost, '/'); - if (ppath) *ppath = '\0'; - - memset(&nloc, 0, sizeof(nloc)); - nloc.cbSize = sizeof(nloc); - nloc.szHost = szHost; - - char* pcolon = strrchr(szHost, ':'); - if (pcolon) { - *pcolon = '\0'; - nloc.wPort = (WORD)strtol(pcolon+1, NULL, 10); - } - else nloc.wPort = secur ? 443 : 80; - nloc.flags = (secur ? NLOCF_SSL : 0); -} - -static NetlibConnection* NetlibHttpProcessUrl(NETLIBHTTPREQUEST *nlhr, NetlibUser *nlu, NetlibConnection* nlc, const char* szUrl = NULL) -{ - NETLIBOPENCONNECTION nloc; - - if (szUrl == NULL) - NetlibConnFromUrl(nlhr->szUrl, (nlhr->flags & NLHRF_SSL) != 0, nloc); - else - NetlibConnFromUrl(szUrl, false, nloc); - - nloc.flags |= NLOCF_HTTP; - if (nloc.flags & NLOCF_SSL) nlhr->flags |= NLHRF_SSL; else nlhr->flags &= ~NLHRF_SSL; - - if (nlc != NULL) { - bool httpProxy = !(nloc.flags & NLOCF_SSL) && nlc->proxyType == PROXYTYPE_HTTP; - bool sameHost = mir_strcmp(nlc->nloc.szHost, nloc.szHost) == 0 && nlc->nloc.wPort == nloc.wPort; - - if (!httpProxy && !sameHost) { - NetlibDoClose(nlc); - - mir_free((char*)nlc->nloc.szHost); - nlc->nloc = nloc; - return NetlibDoConnect(nlc) ? nlc : NULL; - } - } - else nlc = (NetlibConnection*)NetlibOpenConnection((WPARAM)nlu, (LPARAM)&nloc); - - mir_free((char*)nloc.szHost); - - return nlc; -} - -struct HttpSecurityContext -{ - HANDLE m_hNtlmSecurity; - char *m_szHost; - char *m_szProvider; - - HttpSecurityContext() - { m_hNtlmSecurity = NULL; m_szHost = NULL; m_szProvider = NULL; } - - ~HttpSecurityContext() { Destroy(); } - - void Destroy(void) - { - if (!m_hNtlmSecurity) return; - - NetlibDestroySecurityProvider(m_hNtlmSecurity); - m_hNtlmSecurity = NULL; - mir_free(m_szHost); m_szHost = NULL; - mir_free(m_szProvider); m_szProvider = NULL; - } - - bool TryBasic(void) - { - return m_hNtlmSecurity && m_szProvider && _stricmp(m_szProvider, "Basic"); - } - - char* Execute(NetlibConnection *nlc, char* szHost, const char* szProvider, - const char* szChallenge, unsigned& complete) - { - char* szAuthHdr = NULL; - bool justCreated = false; - - if (m_hNtlmSecurity) { - bool newAuth = !m_szProvider || !szProvider || _stricmp(m_szProvider, szProvider); - newAuth = newAuth || (m_szHost != szHost && (!m_szHost || !szHost || _stricmp(m_szHost, szHost))); - if (newAuth) - Destroy(); - } - - if (m_hNtlmSecurity == NULL) { - char szSpnStr[256] = ""; - if (szHost && _stricmp(szProvider, "Basic")) { - unsigned long ip = inet_addr(szHost); - PHOSTENT host = (ip == INADDR_NONE) ? gethostbyname(szHost) : gethostbyaddr((char*)&ip, 4, AF_INET); - mir_snprintf(szSpnStr, SIZEOF(szSpnStr), "HTTP/%s", host && host->h_name ? host->h_name : szHost); - _strlwr(szSpnStr + 5); - NetlibLogf(nlc->nlu, "Host SPN: %s", szSpnStr); - } - m_hNtlmSecurity = NetlibInitSecurityProvider(szProvider, szSpnStr[0] ? szSpnStr : NULL); - if (m_hNtlmSecurity) { - m_szProvider = mir_strdup(szProvider); - m_szHost = mir_strdup(szHost); - justCreated = true; - } - } - - if (m_hNtlmSecurity) { - TCHAR *szLogin = NULL, *szPassw = NULL; - - if (nlc->nlu->settings.useProxyAuth) { - mir_cslock lck(csNetlibUser); - szLogin = mir_a2t(nlc->nlu->settings.szProxyAuthUser); - szPassw = mir_a2t(nlc->nlu->settings.szProxyAuthPassword); - } - - szAuthHdr = NtlmCreateResponseFromChallenge(m_hNtlmSecurity, - szChallenge, szLogin, szPassw, true, complete); - - if (!szAuthHdr) { - NetlibLogf(NULL, "Security login %s failed, user: %S pssw: %S", - szProvider, szLogin ? szLogin : _T("(no user)"), szPassw ? _T("(exist)") : _T("(no psw)")); - } - else if (justCreated) - proxyAuthList.add(m_szHost, m_szProvider); - - mir_free(szLogin); - mir_free(szPassw); - } - else complete = 1; - - return szAuthHdr; - } -}; - -static int HttpPeekFirstResponseLine(NetlibConnection *nlc, DWORD dwTimeoutTime, DWORD recvFlags, int *resultCode, char **ppszResultDescr, int *length) -{ - int bytesPeeked; - char buffer[2048]; - char *peol; - - while(true) { - bytesPeeked = RecvWithTimeoutTime(nlc, dwTimeoutTime, buffer, SIZEOF(buffer) - 1, MSG_PEEK | recvFlags); - - if (bytesPeeked == 0) { - SetLastError(ERROR_HANDLE_EOF); - return 0; - } - if (bytesPeeked == SOCKET_ERROR) - return 0; - - buffer[bytesPeeked] = '\0'; - if ((peol = strchr(buffer, '\n')) != NULL) - break; - - if ((int)mir_strlen(buffer) < bytesPeeked) { - SetLastError(ERROR_BAD_FORMAT); - return 0; - } - if (bytesPeeked == SIZEOF(buffer) - 1) { - SetLastError(ERROR_BUFFER_OVERFLOW); - return 0; - } - if (Miranda_Terminated()) return 0; - Sleep(10); - } - - if (peol == buffer) { - SetLastError(ERROR_BAD_FORMAT); - return 0; - } - - *peol = '\0'; - - if (_strnicmp(buffer, "HTTP/", 5)) { - SetLastError(ERROR_BAD_FORMAT); - return 0; - } - - size_t off = strcspn(buffer, " \t"); - if (off >= (unsigned)bytesPeeked) - return 0; - - char* pResultCode = buffer + off; - *(pResultCode++) = 0; - - char* pResultDescr; - *resultCode = strtol(pResultCode, &pResultDescr, 10); - - if (ppszResultDescr) - *ppszResultDescr = mir_strdup(lrtrimp(pResultDescr)); - - if (length) *length = peol - buffer + 1; - return 1; -} - -static int SendHttpRequestAndData(NetlibConnection *nlc, struct ResizableCharBuffer *httpRequest, NETLIBHTTPREQUEST *nlhr, int sendContentLengthHeader) -{ - bool sendData = (nlhr->requestType == REQUEST_POST || nlhr->requestType == REQUEST_PUT); - - if (sendContentLengthHeader && sendData) - AppendToCharBuffer(httpRequest, "Content-Length: %d\r\n\r\n", nlhr->dataLength); - else - AppendToCharBuffer(httpRequest, "\r\n"); - - DWORD hflags = (nlhr->flags & NLHRF_DUMPASTEXT ? MSG_DUMPASTEXT : 0) | - (nlhr->flags & (NLHRF_NODUMP | NLHRF_NODUMPSEND | NLHRF_NODUMPHEADERS) ? - MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) | - (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0); - - int bytesSent = NLSend(nlc, httpRequest->sz, httpRequest->iEnd, hflags); - if (bytesSent != SOCKET_ERROR && sendData && nlhr->dataLength) { - DWORD sflags = (nlhr->flags & NLHRF_DUMPASTEXT ? MSG_DUMPASTEXT : 0) | - (nlhr->flags & (NLHRF_NODUMP | NLHRF_NODUMPSEND) ? - MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) | - (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0); - - int sendResult = NLSend(nlc, nlhr->pData, nlhr->dataLength, sflags); - - bytesSent = sendResult != SOCKET_ERROR ? bytesSent + sendResult : SOCKET_ERROR; - } - mir_free(httpRequest->sz); - memset(httpRequest, 0, sizeof(*httpRequest)); - - return bytesSent; -} - -INT_PTR NetlibHttpSendRequest(WPARAM wParam, LPARAM lParam) -{ - NetlibConnection *nlc = (struct NetlibConnection*)wParam; - NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST*)lParam; - NETLIBHTTPREQUEST *nlhrReply = NULL; - HttpSecurityContext httpSecurity; - - struct ResizableCharBuffer httpRequest = {0}; - char *szHost = NULL, *szNewUrl = NULL; - char *pszProxyAuthHdr = NULL, *pszAuthHdr = NULL; - int i, doneHostHeader, doneContentLengthHeader, doneProxyAuthHeader, doneAuthHeader; - int bytesSent; - bool lastFirstLineFail = false; - - if (nlhr == NULL || nlhr->cbSize != sizeof(NETLIBHTTPREQUEST) || nlhr->szUrl == NULL || nlhr->szUrl[0] == '\0') { - SetLastError(ERROR_INVALID_PARAMETER); - return SOCKET_ERROR; - } - - int hdrTimeout = (nlhr->timeout) ? nlhr->timeout : HTTPRECVHEADERSTIMEOUT; - - const char *pszRequest; - switch(nlhr->requestType) { - case REQUEST_GET: pszRequest = "GET"; break; - case REQUEST_POST: pszRequest = "POST"; break; - case REQUEST_CONNECT: pszRequest = "CONNECT"; break; - case REQUEST_HEAD: pszRequest = "HEAD"; break; - case REQUEST_PUT: pszRequest = "PUT"; break; - case REQUEST_DELETE: pszRequest = "DELETE"; break; - default: - SetLastError(ERROR_INVALID_PARAMETER); - return SOCKET_ERROR; - } - - if (!nlc->usingHttpGateway) - if (!NetlibEnterNestedCS(nlc, NLNCS_SEND)) - return SOCKET_ERROR; - - const char *pszFullUrl = nlhr->szUrl; - const char *pszUrl = NULL; - - unsigned complete = false; - int count = 11; - while (--count) { - if (!NetlibReconnect(nlc)) { - bytesSent = SOCKET_ERROR; - break; - } - - if (!pszUrl) { - pszUrl = pszFullUrl; - if (nlhr->flags & (NLHRF_SMARTREMOVEHOST | NLHRF_REMOVEHOST | NLHRF_GENERATEHOST)) { - bool usingProxy = nlc->proxyType == PROXYTYPE_HTTP && !(nlhr->flags & NLHRF_SSL); - - mir_free(szHost); - szHost = NULL; - - const char *ppath, *phost; - phost = strstr(pszUrl, "://"); - if (phost == NULL) phost = pszUrl; - else phost += 3; - ppath = strchr(phost, '/'); - if (ppath == phost) phost = NULL; - - if (nlhr->flags & NLHRF_GENERATEHOST) { - szHost = mir_strdup(phost); - if (ppath && phost) szHost[ppath - phost] = 0; - } - - if (nlhr->flags & NLHRF_REMOVEHOST || (nlhr->flags & NLHRF_SMARTREMOVEHOST && !usingProxy)) - pszUrl = ppath ? ppath : "/"; - - if (usingProxy && phost && !nlc->dnsThroughProxy) { - char* tszHost = mir_strdup(phost); - if (ppath && phost) tszHost[ppath - phost] = 0; - char* cln = strchr(tszHost, ':'); if (cln) *cln = 0; - - if (inet_addr(tszHost) == INADDR_NONE) { - DWORD ip = DnsLookup(nlc->nlu, tszHost); - if (ip && szHost) { - mir_free(szHost); - szHost = (char*)mir_alloc(64); - if (cln) *cln = ':'; - mir_snprintf(szHost, 64, "%s%s", inet_ntoa(*(PIN_ADDR)&ip), cln ? cln : ""); - } - } - mir_free(tszHost); - } - } - } - - if (nlc->proxyAuthNeeded && proxyAuthList.getCount()) { - if (httpSecurity.m_szProvider == NULL && nlc->szProxyServer) { - const char* szAuthMethodNlu = proxyAuthList.find(nlc->szProxyServer); - if (szAuthMethodNlu) { - mir_free(pszProxyAuthHdr); - pszProxyAuthHdr = httpSecurity.Execute(nlc, nlc->szProxyServer, szAuthMethodNlu, "", complete); - } - } - } - nlc->proxyAuthNeeded = false; - - AppendToCharBuffer(&httpRequest, "%s %s HTTP/1.%d\r\n", pszRequest, pszUrl, (nlhr->flags & NLHRF_HTTP11) != 0); - - //HTTP headers - doneHostHeader = doneContentLengthHeader = doneProxyAuthHeader = doneAuthHeader = 0; - for (i=0; i < nlhr->headersCount; i++) { - NETLIBHTTPHEADER &p = nlhr->headers[i]; - if (!mir_strcmpi(p.szName, "Host")) doneHostHeader = 1; - else if (!mir_strcmpi(p.szName, "Content-Length")) doneContentLengthHeader = 1; - else if (!mir_strcmpi(p.szName, "Proxy-Authorization")) doneProxyAuthHeader = 1; - else if (!mir_strcmpi(p.szName, "Authorization")) doneAuthHeader = 1; - else if (!mir_strcmpi(p.szName, "Connection")) continue; - if (p.szValue == NULL) continue; - AppendToCharBuffer(&httpRequest, "%s: %s\r\n", p.szName, p.szValue); - } - if (szHost && !doneHostHeader) - AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Host", szHost); - if (pszProxyAuthHdr && !doneProxyAuthHeader) - AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Proxy-Authorization", pszProxyAuthHdr); - if (pszAuthHdr && !doneAuthHeader) - AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Authorization", pszAuthHdr); - AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Connection", "Keep-Alive"); - AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Proxy-Connection", "Keep-Alive"); - - // Add Sticky Headers - if (nlc->nlu->szStickyHeaders != NULL) - AppendToCharBuffer(&httpRequest, "%s\r\n", nlc->nlu->szStickyHeaders); - - //send it - bytesSent = SendHttpRequestAndData(nlc, &httpRequest, nlhr, !doneContentLengthHeader); - if (bytesSent == SOCKET_ERROR) - break; - - //ntlm reply - if (doneContentLengthHeader && nlhr->requestType != REQUEST_HEAD) - break; - - DWORD fflags = MSG_PEEK | MSG_NODUMP | ((nlhr->flags & NLHRF_NOPROXY) ? MSG_RAW : 0); - DWORD dwTimeOutTime = hdrTimeout < 0 ? -1 : GetTickCount() + hdrTimeout; - if (!HttpPeekFirstResponseLine(nlc, dwTimeOutTime, fflags, &nlhr->resultCode, NULL, NULL)) { - NetlibLogf(nlc->nlu, "%s %d: %s Failed (%u %u)", __FILE__, __LINE__, "HttpPeekFirstResponseLine", GetLastError(), count); - DWORD err = GetLastError(); - if (err == ERROR_TIMEOUT || err == ERROR_BAD_FORMAT || err == ERROR_BUFFER_OVERFLOW || lastFirstLineFail || nlc->termRequested || nlhr->requestType == REQUEST_CONNECT) { - bytesSent = SOCKET_ERROR; - break; - } - - lastFirstLineFail = true; - continue; - } - - int resultCode = nlhr->resultCode; - lastFirstLineFail = false; - - DWORD hflags = (nlhr->flags & (NLHRF_NODUMP|NLHRF_NODUMPHEADERS|NLHRF_NODUMPSEND) ? - MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) | - (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0); - - DWORD dflags = (nlhr->flags & (NLHRF_NODUMP | NLHRF_NODUMPSEND) ? MSG_NODUMP : MSG_DUMPASTEXT | MSG_DUMPPROXY) | - (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0) | MSG_NODUMP; - - if (resultCode == 100) - nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags); - - else if (resultCode == 307 || ((resultCode == 301 || resultCode == 302) && (nlhr->flags & NLHRF_REDIRECT))) { // redirect - pszUrl = NULL; - - if (nlhr->requestType == REQUEST_HEAD) - nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags); - else - nlhrReply = NetlibHttpRecv(nlc, hflags, dflags); - - if (nlhrReply) { - char* tmpUrl = NetlibHttpFindHeader(nlhrReply, "Location"); - if (tmpUrl) { - size_t rlen = 0; - if (tmpUrl[0] == '/') { - const char *ppath, *phost; - phost = strstr(pszFullUrl, "://"); - phost = phost ? phost + 3 : pszFullUrl; - ppath = strchr(phost, '/'); - rlen = ppath ? ppath - pszFullUrl : mir_strlen(pszFullUrl); - } - - nlc->szNewUrl = (char*)mir_realloc(nlc->szNewUrl, rlen + mir_strlen(tmpUrl) * 3 + 1); - - strncpy(nlc->szNewUrl, pszFullUrl, rlen); - mir_strcpy(nlc->szNewUrl + rlen, tmpUrl); - pszFullUrl = nlc->szNewUrl; - pszUrl = NULL; - - if (NetlibHttpProcessUrl(nlhr, nlc->nlu, nlc, pszFullUrl) == NULL) { - bytesSent = SOCKET_ERROR; - break; - } - } - else { - NetlibHttpSetLastErrorUsingHttpResult(resultCode); - bytesSent = SOCKET_ERROR; - break; - } - } - else { - NetlibHttpSetLastErrorUsingHttpResult(resultCode); - bytesSent = SOCKET_ERROR; - break; - } - } - else if (resultCode == 401 && !doneAuthHeader) { //auth required - if (nlhr->requestType == REQUEST_HEAD) - nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags); - else - nlhrReply = NetlibHttpRecv(nlc, hflags, dflags); - - mir_free(pszAuthHdr); pszAuthHdr = NULL; - if (nlhrReply) { - char *szAuthStr = NULL; - if (!complete) { - szAuthStr = NetlibHttpFindAuthHeader(nlhrReply, "WWW-Authenticate", httpSecurity.m_szProvider); - if (szAuthStr) { - char *szChallenge = strchr(szAuthStr, ' '); - if (!szChallenge || !*lrtrimp(szChallenge)) - complete = true; - } - } - if (complete && httpSecurity.m_hNtlmSecurity) - szAuthStr = httpSecurity.TryBasic() ? NetlibHttpFindAuthHeader(nlhrReply, "WWW-Authenticate", "Basic") : NULL; - - if (szAuthStr) { - char *szChallenge = strchr(szAuthStr, ' '); - if (szChallenge) { *szChallenge = 0; szChallenge = lrtrimp(szChallenge + 1); } - - pszAuthHdr = httpSecurity.Execute(nlc, szHost, szAuthStr, szChallenge, complete); - } - } - if (pszAuthHdr == NULL) { - proxyAuthList.add(szHost, NULL); - NetlibHttpSetLastErrorUsingHttpResult(resultCode); - bytesSent = SOCKET_ERROR; - break; - } - } - else if (resultCode == 407 && !doneProxyAuthHeader) { //proxy auth required - if (nlhr->requestType == REQUEST_HEAD) - nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags); - else - nlhrReply = NetlibHttpRecv(nlc, hflags, dflags); - - mir_free(pszProxyAuthHdr); pszProxyAuthHdr = NULL; - if (nlhrReply) { - char *szAuthStr = NULL; - if (!complete) { - szAuthStr = NetlibHttpFindAuthHeader(nlhrReply, "Proxy-Authenticate", httpSecurity.m_szProvider); - if (szAuthStr) { - char *szChallenge = strchr(szAuthStr, ' '); - if (!szChallenge || !*lrtrimp(szChallenge + 1)) - complete = true; - } - } - if (complete && httpSecurity.m_hNtlmSecurity) - szAuthStr = httpSecurity.TryBasic() ? NetlibHttpFindAuthHeader(nlhrReply, "Proxy-Authenticate", "Basic") : NULL; - - if (szAuthStr) { - char *szChallenge = strchr(szAuthStr, ' '); - if (szChallenge) { *szChallenge = 0; szChallenge = lrtrimp(szChallenge + 1); } - - pszProxyAuthHdr = httpSecurity.Execute(nlc, nlc->szProxyServer, szAuthStr, szChallenge, complete); - } - } - if (pszProxyAuthHdr == NULL) { - proxyAuthList.add(nlc->szProxyServer, NULL); - NetlibHttpSetLastErrorUsingHttpResult(resultCode); - bytesSent = SOCKET_ERROR; - break; - } - } - else break; - - if (pszProxyAuthHdr && resultCode != 407 && !doneProxyAuthHeader) - replaceStr(pszProxyAuthHdr, NULL); - - if (pszAuthHdr && resultCode != 401 && !doneAuthHeader) - replaceStr(pszAuthHdr, NULL); - - if (nlhrReply) { - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - nlhrReply = NULL; - } - } - - if (count == 0) bytesSent = SOCKET_ERROR; - if (nlhrReply) NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - - //clean up - mir_free(pszProxyAuthHdr); - mir_free(pszAuthHdr); - mir_free(szHost); - mir_free(szNewUrl); - - if (!nlc->usingHttpGateway) - NetlibLeaveNestedCS(&nlc->ncsSend); - - return bytesSent; -} - -INT_PTR NetlibHttpFreeRequestStruct(WPARAM, LPARAM lParam) -{ - NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST*)lParam; - - if (nlhr == NULL || nlhr->cbSize != sizeof(NETLIBHTTPREQUEST) || nlhr->requestType != REQUEST_RESPONSE) { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - if (nlhr->headers) { - for (int i=0; i < nlhr->headersCount; i++) { - NETLIBHTTPHEADER &p = nlhr->headers[i]; - mir_free(p.szName); - mir_free(p.szValue); - } - mir_free(nlhr->headers); - } - mir_free(nlhr->pData); - mir_free(nlhr->szResultDescr); - mir_free(nlhr->szUrl); - mir_free(nlhr); - return 1; -} - -INT_PTR NetlibHttpRecvHeaders(WPARAM wParam, LPARAM lParam) -{ - NetlibConnection *nlc = (struct NetlibConnection*)wParam; - if (!NetlibEnterNestedCS(nlc, NLNCS_RECV)) - return 0; - - char *peol, *pbuffer; - int headersCount = 0, bufferSize = 8192; - - DWORD dwRequestTimeoutTime = GetTickCount() + HTTPRECVDATATIMEOUT; - NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST*)mir_calloc(sizeof(NETLIBHTTPREQUEST)); - nlhr->cbSize = sizeof(NETLIBHTTPREQUEST); - nlhr->nlc = nlc; // Needed to id connection in the protocol HTTP gateway wrapper functions - nlhr->requestType = REQUEST_RESPONSE; - - int firstLineLength = 0; - if (!HttpPeekFirstResponseLine(nlc, dwRequestTimeoutTime, lParam | MSG_PEEK, &nlhr->resultCode, &nlhr->szResultDescr, &firstLineLength)) { - NetlibLeaveNestedCS(&nlc->ncsRecv); - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr); - return 0; - } - - char *buffer = (char*)mir_alloc(bufferSize + 1); - int bytesPeeked = NLRecv(nlc, buffer, min(firstLineLength, bufferSize), lParam | MSG_DUMPASTEXT); - if (bytesPeeked != firstLineLength) { - NetlibLeaveNestedCS(&nlc->ncsRecv); - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr); - if (bytesPeeked != SOCKET_ERROR) SetLastError(ERROR_HANDLE_EOF); - mir_free(buffer); - return 0; - } - - // Make sure all headers arrived - bytesPeeked = 0; - for (bool headersCompleted = false; !headersCompleted; ) { - if (bytesPeeked >= bufferSize) { - bufferSize += 8192; - mir_free(buffer); - if (bufferSize > 32 * 1024) { - bytesPeeked = 0; - break; - } - buffer = (char*)mir_alloc(bufferSize + 1); - } - - bytesPeeked = RecvWithTimeoutTime(nlc, dwRequestTimeoutTime, buffer, bufferSize, MSG_PEEK | MSG_NODUMP | lParam); - if (bytesPeeked == 0) - break; - - if (bytesPeeked == SOCKET_ERROR) { - bytesPeeked = 0; - break; - } - buffer[bytesPeeked] = 0; - - for (pbuffer = buffer, headersCount = 0;; pbuffer = peol + 1, ++headersCount) { - peol = strchr(pbuffer, '\n'); - if (peol == NULL) break; - if (peol == pbuffer || (peol == (pbuffer + 1) && *pbuffer == '\r')) { - bytesPeeked = peol - buffer + 1; - headersCompleted = true; - break; - } - } - } - - // Receive headers - if (bytesPeeked > 0) - bytesPeeked = NLRecv(nlc, buffer, bytesPeeked, lParam | MSG_DUMPASTEXT); - if (bytesPeeked <= 0) { - NetlibLeaveNestedCS(&nlc->ncsRecv); - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr); - mir_free(buffer); - return 0; - } - buffer[bytesPeeked] = 0; - - nlhr->headersCount = headersCount; - nlhr->headers = (NETLIBHTTPHEADER*)mir_calloc(sizeof(NETLIBHTTPHEADER) * headersCount); - - for (pbuffer = buffer, headersCount = 0;; pbuffer = peol + 1, ++headersCount) { - peol = strchr(pbuffer, '\n'); - if (peol == NULL || peol == pbuffer || (peol == (pbuffer + 1) && *pbuffer == '\r')) break; - *peol = 0; - - char *pColon = strchr(pbuffer, ':'); - if (pColon == NULL) { - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr); nlhr = NULL; - SetLastError(ERROR_INVALID_DATA); - break; - } - - *(pColon++) = 0; - nlhr->headers[headersCount].szName = mir_strdup(rtrim(pbuffer)); - nlhr->headers[headersCount].szValue = mir_strdup(lrtrimp(pColon)); - } - - NetlibLeaveNestedCS(&nlc->ncsRecv); - mir_free(buffer); - return (INT_PTR)nlhr; -} - -INT_PTR NetlibHttpTransaction(WPARAM wParam, LPARAM lParam) -{ - NetlibUser *nlu = (NetlibUser*)wParam; - NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST*)lParam, *nlhrReply; - - if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_OUTGOING) || - nlhr == NULL || nlhr->cbSize != sizeof(NETLIBHTTPREQUEST) || - nlhr->szUrl == NULL || nlhr->szUrl[0] == 0) - { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - if (nlhr->nlc != NULL && GetNetlibHandleType(nlhr->nlc) != NLH_CONNECTION) - nlhr->nlc = NULL; - - NetlibConnection* nlc = NetlibHttpProcessUrl(nlhr, nlu, (NetlibConnection*)nlhr->nlc); - if (nlc == NULL) - return 0; - - NETLIBHTTPREQUEST nlhrSend; - char szUserAgent[64]; - - nlhrSend = *nlhr; - nlhrSend.flags &= ~NLHRF_REMOVEHOST; - nlhrSend.flags |= NLHRF_GENERATEHOST | NLHRF_SMARTREMOVEHOST | NLHRF_SMARTAUTHHEADER; - - bool doneUserAgentHeader = NetlibHttpFindHeader(nlhr, "User-Agent") != NULL; - bool doneAcceptEncoding = NetlibHttpFindHeader(nlhr, "Accept-Encoding") != NULL; - - if (!doneUserAgentHeader || !doneAcceptEncoding) { - nlhrSend.headers = (NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER) * (nlhrSend.headersCount + 2)); - memcpy(nlhrSend.headers, nlhr->headers, sizeof(NETLIBHTTPHEADER) * nlhr->headersCount); - } - - if (!doneUserAgentHeader) { - nlhrSend.headers[nlhrSend.headersCount].szName = "User-Agent"; - nlhrSend.headers[nlhrSend.headersCount].szValue = szUserAgent; - ++nlhrSend.headersCount; - - char szMirandaVer[64]; - CallService(MS_SYSTEM_GETVERSIONTEXT, SIZEOF(szMirandaVer), (LPARAM)szMirandaVer); - char *pspace = strchr(szMirandaVer, ' '); - if (pspace) { - *pspace++='\0'; - mir_snprintf(szUserAgent, SIZEOF(szUserAgent), "Miranda/%s (%s)", szMirandaVer, pspace); - } - else mir_snprintf(szUserAgent, SIZEOF(szUserAgent), "Miranda/%s", szMirandaVer); - } - if (!doneAcceptEncoding) { - nlhrSend.headers[nlhrSend.headersCount].szName = "Accept-Encoding"; - nlhrSend.headers[nlhrSend.headersCount].szValue = "deflate, gzip"; - ++nlhrSend.headersCount; - } - if (NetlibHttpSendRequest((WPARAM)nlc, (LPARAM)&nlhrSend) == SOCKET_ERROR) { - if (!doneUserAgentHeader || !doneAcceptEncoding) mir_free(nlhrSend.headers); - nlhr->resultCode = nlhrSend.resultCode; - NetlibCloseHandle((WPARAM)nlc, 0); - return 0; - } - if (!doneUserAgentHeader || !doneAcceptEncoding) - mir_free(nlhrSend.headers); - - DWORD dflags = (nlhr->flags & NLHRF_DUMPASTEXT ? MSG_DUMPASTEXT : 0) | - (nlhr->flags & NLHRF_NODUMP ? MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) | - (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0); - - DWORD hflags = - (nlhr->flags & NLHRF_NODUMP ? MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) | - (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0); - - if (nlhr->requestType == REQUEST_HEAD) - nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, 0); - else - nlhrReply = NetlibHttpRecv(nlc, hflags, dflags); - - if (nlhrReply) { - nlhrReply->szUrl = nlc->szNewUrl; - nlc->szNewUrl = NULL; - } - - if ((nlhr->flags & NLHRF_PERSISTENT) == 0 || nlhrReply == NULL) { - NetlibCloseHandle((WPARAM)nlc, 0); - if (nlhrReply) - nlhrReply->nlc = NULL; - } - else nlhrReply->nlc = nlc; - - return (INT_PTR)nlhrReply; -} - -void NetlibHttpSetLastErrorUsingHttpResult(int result) -{ - if (result >= 200 && result < 300) { - SetLastError(ERROR_SUCCESS); - return; - } - switch(result) { - case 400: SetLastError(ERROR_BAD_FORMAT); break; - case 401: - case 402: - case 403: - case 407: SetLastError(ERROR_ACCESS_DENIED); break; - case 404: SetLastError(ERROR_FILE_NOT_FOUND); break; - case 405: - case 406: SetLastError(ERROR_INVALID_FUNCTION); break; - case 408: SetLastError(ERROR_TIMEOUT); break; - default: SetLastError(ERROR_GEN_FAILURE); break; - } -} - -char* gzip_decode(char *gzip_data, int *len_ptr, int window) -{ - if (*len_ptr == 0) return NULL; - - int gzip_len = *len_ptr * 5; - char* output_data = NULL; - - int gzip_err; - z_stream zstr; - - do { - output_data = (char*)mir_realloc(output_data, gzip_len+1); - - zstr.next_in = (Bytef*)gzip_data; - zstr.avail_in = *len_ptr; - zstr.zalloc = Z_NULL; - zstr.zfree = Z_NULL; - zstr.opaque = Z_NULL; - inflateInit2_(&zstr, window, ZLIB_VERSION, sizeof(z_stream)); - - zstr.next_out = (Bytef*)output_data; - zstr.avail_out = gzip_len; - - gzip_err = inflate(&zstr, Z_FINISH); - - inflateEnd(&zstr); - gzip_len *= 2; - } - while (gzip_err == Z_BUF_ERROR); - - gzip_len = gzip_err == Z_STREAM_END ? zstr.total_out : -1; - - if (gzip_len <= 0) { - mir_free(output_data); - output_data = NULL; - } - else output_data[gzip_len] = 0; - - *len_ptr = gzip_len; - return output_data; -} - -static int NetlibHttpRecvChunkHeader(NetlibConnection* nlc, bool first, DWORD flags) -{ - char data[64], *peol1; - - while(true) { - int recvResult = NLRecv(nlc, data, 31, MSG_RAW | MSG_PEEK); - if (recvResult <= 0) - return SOCKET_ERROR; - - data[recvResult] = 0; - - peol1 = strchr(data, '\n'); - if (peol1 != NULL) { - char *peol2 = first ? peol1 : strchr(peol1 + 1, '\n'); - if (peol2 != NULL) { - int sz = peol2 - data + 1; - int r = strtol(first ? data : peol1 + 1, NULL, 16); - if (r == 0) { - char *peol3 = strchr(peol2 + 1, '\n'); - if (peol3 == NULL) continue; - sz = peol3 - data + 1; - } - NLRecv(nlc, data, sz, MSG_RAW | flags); - return r; - } - else if (recvResult >= 31) - return SOCKET_ERROR; - } - } -} - -NETLIBHTTPREQUEST* NetlibHttpRecv(NetlibConnection* nlc, DWORD hflags, DWORD dflags, bool isConnect) -{ - int dataLen = -1, i, chunkhdr = 0; - bool chunked = false; - int cenc = 0, cenctype = 0, close = 0; - -next: - NETLIBHTTPREQUEST *nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags); - if (nlhrReply == NULL) - return NULL; - - if (nlhrReply->resultCode == 100) { - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - goto next; - } - - for (i=0; iheadersCount; i++) { - NETLIBHTTPHEADER &p = nlhrReply->headers[i]; - if (!mir_strcmpi(p.szName, "Content-Length")) - dataLen = atoi(p.szValue); - - if (!mir_strcmpi(p.szName, "Content-Encoding")) { - cenc = i; - if (strstr(p.szValue, "gzip")) - cenctype = 1; - else if (strstr(p.szValue, "deflate")) - cenctype = 2; - } - - if (!mir_strcmpi(p.szName, "Connection")) - close = !mir_strcmpi(p.szValue, "close"); - - if (!mir_strcmpi(p.szName, "Transfer-Encoding") && - !mir_strcmpi(p.szValue, "chunked")) - { - chunked = true; - chunkhdr = i; - dataLen = -1; - } - } - - if (nlhrReply->resultCode >= 200 && (dataLen > 0 || (!isConnect && dataLen < 0))) { - int recvResult, chunksz = -1; - int dataBufferAlloced; - - if (chunked) { - chunksz = NetlibHttpRecvChunkHeader(nlc, true, dflags); - if (chunksz == SOCKET_ERROR) { - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - return NULL; - } - dataLen = chunksz; - } - dataBufferAlloced = dataLen < 0 ? 2048 : dataLen + 1; - nlhrReply->pData = (char*)mir_realloc(nlhrReply->pData, dataBufferAlloced); - - while (chunksz != 0) { - while(true) { - recvResult = RecvWithTimeoutTime(nlc, GetTickCount() + HTTPRECVDATATIMEOUT, - nlhrReply->pData + nlhrReply->dataLength, - dataBufferAlloced - nlhrReply->dataLength - 1, - dflags | (cenctype ? MSG_NODUMP : 0)); - - if (recvResult == 0) break; - if (recvResult == SOCKET_ERROR) { - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - return NULL; - } - nlhrReply->dataLength += recvResult; - - if (dataLen >= 0) - { - if (nlhrReply->dataLength >= dataLen) - break; - } - else if ((dataBufferAlloced - nlhrReply->dataLength) < 256) { - dataBufferAlloced += 2048; - nlhrReply->pData = (char*)mir_realloc(nlhrReply->pData, dataBufferAlloced); - if (nlhrReply->pData == NULL) { - SetLastError(ERROR_OUTOFMEMORY); - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - return NULL; - } - } - Sleep(10); - } - - if (!chunked) - break; - - chunksz = NetlibHttpRecvChunkHeader(nlc, false, dflags); - if (chunksz == SOCKET_ERROR) { - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - return NULL; - } - dataLen += chunksz; - dataBufferAlloced += chunksz; - - nlhrReply->pData = (char*)mir_realloc(nlhrReply->pData, dataBufferAlloced); - } - - nlhrReply->pData[nlhrReply->dataLength] = '\0'; - } - - if (chunked) { - nlhrReply->headers[chunkhdr].szName = (char*)mir_realloc(nlhrReply->headers[chunkhdr].szName, 16); - mir_strcpy(nlhrReply->headers[chunkhdr].szName, "Content-Length"); - - nlhrReply->headers[chunkhdr].szValue = (char*)mir_realloc(nlhrReply->headers[chunkhdr].szValue, 16); - mir_snprintf(nlhrReply->headers[chunkhdr].szValue, 16, "%u", nlhrReply->dataLength); - } - - if (cenctype) { - int bufsz = nlhrReply->dataLength; - char* szData = NULL; - - switch (cenctype) { - case 1: - szData = gzip_decode(nlhrReply->pData, &bufsz, 0x10 | MAX_WBITS); - break; - - case 2: - szData = gzip_decode(nlhrReply->pData, &bufsz, -MAX_WBITS); - if (bufsz < 0) - { - bufsz = nlhrReply->dataLength; - szData = gzip_decode(nlhrReply->pData, &bufsz, MAX_WBITS); - } - break; - } - - if (bufsz > 0) { - NetlibDumpData(nlc, (PBYTE)szData, bufsz, 0, dflags); - mir_free(nlhrReply->pData); - nlhrReply->pData = szData; - nlhrReply->dataLength = bufsz; - - mir_free(nlhrReply->headers[cenc].szName); - mir_free(nlhrReply->headers[cenc].szValue); - memmove(&nlhrReply->headers[cenc], &nlhrReply->headers[cenc+1], (--nlhrReply->headersCount-cenc)*sizeof(nlhrReply->headers[0])); - } - else if (bufsz == 0) { - mir_free(nlhrReply->pData); - nlhrReply->pData = NULL; - nlhrReply->dataLength = 0; - } - } - - if (close && - (nlc->proxyType != PROXYTYPE_HTTP || nlc->nloc.flags & NLOCF_SSL) && - (!isConnect || nlhrReply->resultCode != 200)) - NetlibDoClose(nlc); - - return nlhrReply; -} diff --git a/src/modules/netlib/netlibhttpproxy.cpp b/src/modules/netlib/netlibhttpproxy.cpp deleted file mode 100644 index 892554542d..0000000000 --- a/src/modules/netlib/netlibhttpproxy.cpp +++ /dev/null @@ -1,459 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "netlib.h" - -typedef enum -{ - reqHelloGet, - reqOldGet, - reqOldPost, - reqNewPost, -} -RequestType; - -static int HttpGatewayReadSetResult(NetlibConnection *nlc, char *buf, int num, int peek) -{ - if (nlc->dataBufferLen == 0) return 0; - - int bytes = min(num, nlc->dataBufferLen); - int rbytes = nlc->dataBufferLen - bytes; - - memcpy(buf, nlc->dataBuffer, bytes); - if (!peek) { - memmove(nlc->dataBuffer, nlc->dataBuffer + bytes, rbytes); - nlc->dataBufferLen = rbytes; - } - - return bytes; -} - -void HttpGatewayRemovePacket(NetlibConnection *nlc, int pck) -{ - mir_cslock lck(nlc->csHttpSequenceNums); - while (pck-- && nlc->pHttpProxyPacketQueue != NULL) { - NetlibHTTPProxyPacketQueue *p = nlc->pHttpProxyPacketQueue; - nlc->pHttpProxyPacketQueue = nlc->pHttpProxyPacketQueue->next; - - mir_free(p->dataBuffer); - mir_free(p); - } -} - -static bool NetlibHttpGatewaySend(NetlibConnection *nlc, RequestType reqType, const char *buf, int len) -{ - NETLIBHTTPREQUEST nlhrSend = { 0 }; - char szUrl[512]; - - nlhrSend.cbSize = sizeof(nlhrSend); - nlhrSend.nlc = nlc; - - nlhrSend.pData = (char*)buf; - nlhrSend.dataLength = len; - - nlhrSend.flags = NLHRF_GENERATEHOST | NLHRF_DUMPPROXY | NLHRF_SMARTAUTHHEADER | NLHRF_NOPROXY | NLHRF_REDIRECT; - if (nlc->nlhpi.flags & NLHPIF_HTTP11) - nlhrSend.flags |= NLHRF_HTTP11; - - switch (reqType) { - case reqHelloGet: - nlhrSend.requestType = REQUEST_GET; - nlhrSend.szUrl = nlc->nlu->user.szHttpGatewayHello; - break; - - case reqOldGet: - nlhrSend.requestType = REQUEST_GET; - nlhrSend.timeout = -1; - if ((nlc->nlhpi.flags & NLHPIF_USEGETSEQUENCE) && (nlc->nlhpi.szHttpGetUrl != NULL)) { - mir_cslock lck(nlc->csHttpSequenceNums); - mir_snprintf(szUrl, "%s%u", nlc->nlhpi.szHttpGetUrl, nlc->nlhpi.firstGetSequence++); - if (nlc->nlhpi.flags & NLHPIF_GETPOSTSAMESEQUENCE) - nlc->nlhpi.firstPostSequence++; - nlhrSend.szUrl = szUrl; - } - else nlhrSend.szUrl = nlc->nlhpi.szHttpGetUrl; - break; - - case reqOldPost: - nlhrSend.requestType = REQUEST_POST; - if ((nlc->nlhpi.flags & NLHPIF_USEPOSTSEQUENCE) && (nlc->nlhpi.szHttpPostUrl != NULL)) { - mir_snprintf(szUrl, "%s%u", nlc->nlhpi.szHttpPostUrl, nlc->nlhpi.firstPostSequence); - nlhrSend.szUrl = szUrl; - } - else nlhrSend.szUrl = nlc->nlhpi.szHttpPostUrl; - break; - - case reqNewPost: - nlhrSend.requestType = REQUEST_POST; - nlhrSend.szUrl = nlc->nlhpi.szHttpPostUrl; - break; - } - - if (nlc->usingDirectHttpGateway) { - NETLIBOPENCONNECTION nloc; - NetlibConnFromUrl(nlhrSend.szUrl, false, nloc); - - bool sameHost = mir_strcmp(nlc->nloc.szHost, nloc.szHost) == 0 && nlc->nloc.wPort == nloc.wPort; - if (!sameHost) { - NetlibDoClose(nlc); - - mir_free((char*)nlc->nloc.szHost); - nlc->nloc = nloc; - if (!NetlibDoConnect(nlc)) - return false; - } - else mir_free((char*)nloc.szHost); - } - - nlhrSend.headersCount = 3; - nlhrSend.headers = (NETLIBHTTPHEADER*)alloca(sizeof(NETLIBHTTPHEADER) * nlhrSend.headersCount); - nlhrSend.headers[0].szName = "User-Agent"; - nlhrSend.headers[0].szValue = nlc->nlu->user.szHttpGatewayUserAgent; - nlhrSend.headers[1].szName = "Cache-Control"; - nlhrSend.headers[1].szValue = "no-cache, no-store "; - nlhrSend.headers[2].szName = "Pragma"; - nlhrSend.headers[2].szValue = "no-cache"; - return NetlibHttpSendRequest((WPARAM)nlc, (LPARAM)&nlhrSend) != SOCKET_ERROR; -} - -static bool NetlibHttpGatewayStdPost(NetlibConnection *nlc, int &numPackets) -{ - int np = 0, len = 0; - char *buf; - NetlibHTTPProxyPacketQueue *p; - { - mir_cslock lck(nlc->csHttpSequenceNums); - - for (p = nlc->pHttpProxyPacketQueue; p != NULL && np < nlc->nlhpi.combinePackets; p = p->next) { - np++; - len += p->dataBufferLen; - } - - int dlen = 0; - buf = (char*)alloca(len); - numPackets = np; - - for (p = nlc->pHttpProxyPacketQueue; np--; p = p->next) { - memcpy(buf + dlen, p->dataBuffer, p->dataBufferLen); - dlen += p->dataBufferLen; - } - } - - return NetlibHttpGatewaySend(nlc, reqNewPost, buf, len); -} - -static bool NetlibHttpGatewayOscarPost(NetlibConnection *nlc, const char *buf, int len, int flags) -{ - NetlibConnection nlcSend = { 0 }; - nlcSend.handleType = NLH_CONNECTION; - nlcSend.nlu = nlc->nlu; - nlcSend.nlhpi = nlc->nlhpi; - nlcSend.s = nlc->s2; - nlcSend.usingHttpGateway = nlc->usingHttpGateway; - nlcSend.szProxyServer = nlc->szProxyServer; - nlcSend.wProxyPort = nlc->wProxyPort; - nlcSend.proxyType = nlc->proxyType; - - if (!NetlibReconnect(&nlcSend)) return false; - nlc->s2 = nlcSend.s; - - nlcSend.hOkToCloseEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - NetlibInitializeNestedCS(&nlcSend.ncsRecv); - NetlibInitializeNestedCS(&nlcSend.ncsSend); - - bool res = NetlibHttpGatewaySend(&nlcSend, reqOldPost, buf, len); - if (res) { - NETLIBHTTPREQUEST *nlhrReply = NetlibHttpRecv(&nlcSend, flags | MSG_RAW | MSG_DUMPPROXY, MSG_RAW | MSG_DUMPPROXY); - if (nlhrReply != NULL) { - if (nlhrReply->resultCode != 200) { - NetlibHttpSetLastErrorUsingHttpResult(nlhrReply->resultCode); - res = false; - } - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - } - else res = false; - } - - NetlibDeleteNestedCS(&nlcSend.ncsSend); - NetlibDeleteNestedCS(&nlcSend.ncsRecv); - CloseHandle(nlcSend.hOkToCloseEvent); - - nlc->s2 = nlcSend.s; - mir_free((char*)nlcSend.nloc.szHost); - - mir_cslock lck(nlc->csHttpSequenceNums); - nlc->nlhpi.firstPostSequence++; - if (nlc->nlhpi.flags & NLHPIF_GETPOSTSAMESEQUENCE) - nlc->nlhpi.firstGetSequence++; - - return res; -} - -int NetlibHttpGatewayPost(NetlibConnection *nlc, const char *buf, int len, int flags) -{ - if (nlc->nlhpi.szHttpGetUrl != NULL) - return NetlibHttpGatewayOscarPost(nlc, buf, len, flags) ? len : SOCKET_ERROR; - - /* - * Gena01 - many changes here, do compare against the other version. - * - * Change #1: simplify to use similar code to GET - * Change #2: we need to allow to parse POST reply if szHttpGetUrl is NULL - * Change #3: Keep connection open if we need to. - * - * Impact: NONE! Since currently miranda doesn't allow szHttpGetUrl to be NULL, it will not connect - * with the new plugins that use this code. - */ - - NetlibHTTPProxyPacketQueue *p = (NetlibHTTPProxyPacketQueue*)mir_alloc(sizeof(struct NetlibHTTPProxyPacketQueue)); - p->dataBuffer = (PBYTE)mir_alloc(len); - memcpy(p->dataBuffer, buf, len); - p->dataBufferLen = len; - p->next = NULL; - - /* - * Now check to see where to insert this in our queue - */ - - mir_cslock lck(nlc->csHttpSequenceNums); - if (nlc->pHttpProxyPacketQueue == NULL) - nlc->pHttpProxyPacketQueue = p; - else { - NetlibHTTPProxyPacketQueue *t = nlc->pHttpProxyPacketQueue; - while (t->next != NULL) - t = t->next; - t->next = p; - } - - /* - * Gena01 - fake a Send!! tell 'em all is ok. We catch errors in Recv. - */ - return len; -} - -#define NETLIBHTTP_RETRYCOUNT 3 -#define NETLIBHTTP_RETRYTIMEOUT 2000 - -int NetlibHttpGatewayRecv(NetlibConnection *nlc, char *buf, int len, int flags) -{ - bool peek = (flags & MSG_PEEK) != 0; - - if (nlc->dataBufferLen != 0 && (!peek || nlc->dataBufferLen >= len)) { - return HttpGatewayReadSetResult(nlc, buf, len, peek); - } - - for (int retryCount = 0; retryCount < NETLIBHTTP_RETRYCOUNT;) { - if (nlc->nlhpi.szHttpGetUrl == NULL && retryCount == 0) { - if (nlc->pollingTimeout == 0) nlc->pollingTimeout = 30; - - /* We Need to sleep/wait for the data to send before we do receive */ - for (int pollCount = nlc->pollingTimeout; pollCount--;) { - if (nlc->pHttpProxyPacketQueue != NULL && GetTickCount() - nlc->lastPost > 1000) - break; - - if (nlc->termRequested || (SleepEx(1000, TRUE) && Miranda_Terminated())) - return SOCKET_ERROR; - } - - nlc->lastPost = GetTickCount(); - if (nlc->pHttpProxyPacketQueue == NULL && nlc->nlu->user.pfnHttpGatewayWrapSend != NULL) { - if (nlc->nlu->user.pfnHttpGatewayWrapSend(nlc, (PBYTE)"", 0, MSG_NOHTTPGATEWAYWRAP, NetlibSend) == SOCKET_ERROR) - return SOCKET_ERROR; - } - } - - int numPackets = 0; - if (nlc->nlhpi.szHttpGetUrl) { - if (!NetlibHttpGatewaySend(nlc, reqOldGet, NULL, 0)) { - if (GetLastError() == ERROR_ACCESS_DENIED || nlc->termRequested) - break; - - ++retryCount; - continue; - } - } - else { - if (!NetlibHttpGatewayStdPost(nlc, numPackets)) { - if (GetLastError() == ERROR_ACCESS_DENIED || nlc->termRequested) - break; - - ++retryCount; - continue; - } - } - NETLIBHTTPREQUEST *nlhrReply = NetlibHttpRecv(nlc, flags | MSG_RAW | MSG_DUMPPROXY, MSG_RAW | MSG_DUMPPROXY); - if (nlhrReply == NULL) return SOCKET_ERROR; - - if (nlc->nlu->user.pfnHttpGatewayUnwrapRecv && !(flags & MSG_NOHTTPGATEWAYWRAP)) { - nlhrReply->pData = (char*)nlc->nlu->user.pfnHttpGatewayUnwrapRecv(nlhrReply, - (PBYTE)nlhrReply->pData, nlhrReply->dataLength, &nlhrReply->dataLength, mir_realloc); - } - - if (nlhrReply->resultCode >= 300) { - int resultCode = nlhrReply->resultCode; - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - - if (nlc->nlhpi.szHttpGetUrl && resultCode != 404) { - NetlibLogf(nlc->nlu, "Error received from proxy, retrying"); - continue; - } - else { - NetlibLogf(nlc->nlu, "Error received from proxy, retry attempts exceeded (%u)", retryCount); - SetLastError(ERROR_GEN_FAILURE); - return SOCKET_ERROR; - } - } - else { - retryCount = 0; - HttpGatewayRemovePacket(nlc, numPackets); - } - - if (nlhrReply->dataLength) { - if (peek) { - int rbytes = nlc->dataBufferLen + nlhrReply->dataLength; - - nlc->dataBuffer = (PBYTE)mir_realloc(nlc->dataBuffer, rbytes); - memcpy(nlc->dataBuffer + nlc->dataBufferLen, nlhrReply->pData, nlhrReply->dataLength); - nlc->dataBufferLen = rbytes; - - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - - return HttpGatewayReadSetResult(nlc, buf, len, peek); - } - else { - int bytes = min(len, nlhrReply->dataLength); - int rbytes = nlhrReply->dataLength - bytes; - - memcpy(buf, nlhrReply->pData, bytes); - - nlc->dataBuffer = (PBYTE)mir_realloc(nlc->dataBuffer, rbytes); - if (rbytes) memcpy(nlc->dataBuffer, nlhrReply->pData + bytes, rbytes); - nlc->dataBufferLen = rbytes; - - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - return bytes; - } - } - else { - if ((peek && nlc->dataBufferLen != 0) || nlhrReply->pData) { - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - return HttpGatewayReadSetResult(nlc, buf, len, peek); - } - } - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - } - - SetLastError(ERROR_GEN_FAILURE); - return SOCKET_ERROR; -} - -int NetlibInitHttpConnection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc) -{ - NETLIBHTTPREQUEST *nlhrReply = NULL; - { - mir_cslock lck(nlc->csHttpSequenceNums); - nlc->nlhpi.firstGetSequence = 1; - nlc->nlhpi.firstPostSequence = 1; - } - - if (nlu->user.szHttpGatewayHello != NULL) { - nlc->usingHttpGateway = true; - if (NetlibHttpGatewaySend(nlc, reqHelloGet, NULL, 0)) - nlhrReply = NetlibHttpRecv(nlc, MSG_DUMPPROXY | MSG_RAW, MSG_DUMPPROXY | MSG_RAW); - nlc->usingHttpGateway = false; - if (nlhrReply == NULL) return 0; - - if (nlhrReply->resultCode != 200) { - NetlibHttpSetLastErrorUsingHttpResult(nlhrReply->resultCode); - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - return 0; - } - } - if (!nlu->user.pfnHttpGatewayInit(nlc, nloc, nlhrReply)) { - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - return 0; - } - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - - /* - * Gena01 - Ok, we should be able to use just POST. Needed for Yahoo, NO GET requests - */ - if (nlc->nlhpi.szHttpPostUrl == NULL) { - SetLastError(ERROR_BAD_FORMAT); - return 0; - } - - nlc->usingHttpGateway = true; - - //now properly connected - if (nlu->user.pfnHttpGatewayBegin && !nlu->user.pfnHttpGatewayBegin(nlc, nloc)) - return 0; - - return 1; -} - -INT_PTR NetlibHttpGatewaySetInfo(WPARAM wParam, LPARAM lParam) -{ - NETLIBHTTPPROXYINFO *nlhpi = (NETLIBHTTPPROXYINFO*)lParam; - NetlibConnection *nlc = (struct NetlibConnection*)wParam; - - if (GetNetlibHandleType(nlc) != NLH_CONNECTION || nlhpi == NULL || - nlhpi->cbSize < (sizeof(NETLIBHTTPPROXYINFO) - sizeof(int)) || - nlhpi->szHttpPostUrl == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - mir_free(nlc->nlhpi.szHttpGetUrl); - mir_free(nlc->nlhpi.szHttpPostUrl); - - nlc->nlhpi.combinePackets = 1; - memcpy(&nlc->nlhpi, nlhpi, min(nlhpi->cbSize, sizeof(*nlhpi))); - if (nlc->nlhpi.combinePackets == 0) nlc->nlhpi.combinePackets = 1; - - nlc->nlhpi.szHttpGetUrl = mir_strdup(nlc->nlhpi.szHttpGetUrl); - nlc->nlhpi.szHttpPostUrl = mir_strdup(nlc->nlhpi.szHttpPostUrl); - - return 1; -} - -INT_PTR NetlibHttpSetSticky(WPARAM wParam, LPARAM lParam) -{ - NetlibUser * nu = (NetlibUser*)wParam; - if (GetNetlibHandleType(nu) != NLH_USER) return ERROR_INVALID_PARAMETER; - mir_free(nu->szStickyHeaders); - nu->szStickyHeaders = mir_strdup((char*)lParam); // pointer is ours - return 0; -} - -INT_PTR NetlibHttpSetPollingTimeout(WPARAM wParam, LPARAM lParam) -{ - int oldTimeout; - NetlibConnection *nlc = (struct NetlibConnection*)wParam; - if (GetNetlibHandleType(nlc) != NLH_CONNECTION) return -1; - oldTimeout = nlc->pollingTimeout; - nlc->pollingTimeout = lParam; - return oldTimeout; -} diff --git a/src/modules/netlib/netliblog.cpp b/src/modules/netlib/netliblog.cpp deleted file mode 100644 index 2d3db45941..0000000000 --- a/src/modules/netlib/netliblog.cpp +++ /dev/null @@ -1,532 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "netlib.h" - -#define MS_NETLIB_LOGWIN "Netlib/Log/Win" - -extern HANDLE hConnectionHeaderMutex; - -#define TIMEFORMAT_NONE 0 -#define TIMEFORMAT_HHMMSS 1 -#define TIMEFORMAT_MILLISECONDS 2 -#define TIMEFORMAT_MICROSECONDS 3 -struct { - HWND hwndOpts; - int toOutputDebugString; - int toFile; - int toLog; - int timeFormat; - int showUser; - int dumpSent, dumpRecv, dumpProxy, dumpSsl; - int textDumps, autoDetectText; - CMString tszFile, tszUserFile; -} -static logOptions = { 0 }; - -struct LOGMSG -{ - const char* pszHead; - const char* pszMsg; -}; - -static __int64 mirandaStartTime, perfCounterFreq; -static int bIsActive = TRUE; -static HANDLE hLogEvent = NULL; -static HANDLE hLogger = NULL; - -static void InitLog() -{ - if (hLogger) { - mir_closeLog(hLogger); - hLogger = NULL; - } - - ptrT szBuf(db_get_tsa(NULL, "Netlib", "File")); - if (mir_tstrlen(szBuf)) { - logOptions.tszUserFile = szBuf; - - TCHAR path[MAX_PATH]; - PathToAbsoluteT(VARST(szBuf), path); - logOptions.tszFile = path; - } - else { - db_set_ts(NULL, "Netlib", "File", logOptions.tszUserFile = _T("%miranda_logpath%\\netlog.txt")); - logOptions.tszFile = Utils_ReplaceVarsT(logOptions.tszUserFile); - } - - if (logOptions.toFile) - hLogger = mir_createLog("Netlib", LPGENT("Standard netlib log"), logOptions.tszFile, 0); -} - -static const TCHAR* szTimeFormats[] = -{ - LPGENT("No times"), - LPGENT("Standard hh:mm:ss times"), - LPGENT("Times in milliseconds"), - LPGENT("Times in microseconds") -}; - -static INT_PTR CALLBACK LogOptionsDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - TCHAR str[MAX_PATH]; - - switch (message) { - case WM_INITDIALOG: - logOptions.hwndOpts = hwndDlg; - TranslateDialogDefault(hwndDlg); - CheckDlgButton(hwndDlg, IDC_DUMPRECV, logOptions.dumpRecv ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DUMPSENT, logOptions.dumpSent ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DUMPPROXY, logOptions.dumpProxy ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DUMPSSL, logOptions.dumpSsl ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_TEXTDUMPS, logOptions.textDumps ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_AUTODETECTTEXT, logOptions.autoDetectText ? BST_CHECKED : BST_UNCHECKED); - { - for (int i=0; i < SIZEOF(szTimeFormats); i++) - SendDlgItemMessage(hwndDlg, IDC_TIMEFORMAT, CB_ADDSTRING, 0, (LPARAM)TranslateTS(szTimeFormats[i])); - } - SendDlgItemMessage(hwndDlg, IDC_TIMEFORMAT, CB_SETCURSEL, logOptions.timeFormat, 0); - CheckDlgButton(hwndDlg, IDC_SHOWNAMES, logOptions.showUser ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_TOOUTPUTDEBUGSTRING, logOptions.toOutputDebugString ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_TOFILE, logOptions.toFile ? BST_CHECKED : BST_UNCHECKED); - SetDlgItemText(hwndDlg, IDC_FILENAME, logOptions.tszUserFile); - SetDlgItemText(hwndDlg, IDC_PATH, logOptions.tszFile); - CheckDlgButton(hwndDlg, IDC_SHOWTHISDLGATSTART, db_get_b(NULL, "Netlib", "ShowLogOptsAtStart", 0) ? BST_CHECKED : BST_UNCHECKED); - { - ptrA szRun(db_get_sa(NULL, "Netlib", "RunAtStart")); - if (szRun) - SetDlgItemTextA(hwndDlg, IDC_RUNATSTART, szRun); - - HWND hwndFilter = GetDlgItem(hwndDlg, IDC_FILTER); - SetWindowLongPtr(hwndFilter, GWL_STYLE, GetWindowLongPtr(hwndFilter, GWL_STYLE) | (TVS_NOHSCROLL | TVS_CHECKBOXES)); - - TVINSERTSTRUCT tvis = { 0 }; - tvis.hInsertAfter = TVI_SORT; - tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE; - tvis.item.stateMask = TVIS_STATEIMAGEMASK; - - for (int i = 0; i < netlibUser.getCount(); i++) { - tvis.item.pszText = netlibUser[i]->user.ptszDescriptiveName; - tvis.item.lParam = i; - tvis.item.state = INDEXTOSTATEIMAGEMASK((netlibUser[i]->toLog) ? 2 : 1); - TreeView_InsertItem(hwndFilter, &tvis); - } - tvis.item.lParam = -1; - tvis.item.pszText = TranslateT("(Miranda core logging)"); - tvis.item.state = INDEXTOSTATEIMAGEMASK((logOptions.toLog) ? 2 : 1); - TreeView_InsertItem(hwndFilter, &tvis); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_FILENAME: - if (HIWORD(wParam) == EN_CHANGE) { - if ((HWND)lParam == GetFocus()) - CheckDlgButton(hwndDlg, IDC_TOFILE, BST_CHECKED); - - TCHAR path[MAX_PATH]; - GetWindowText((HWND)lParam, path, SIZEOF(path)); - - PathToAbsoluteT(VARST(path), path); - SetDlgItemText(hwndDlg, IDC_PATH, path); - } - break; - - case IDC_FILENAMEBROWSE: - case IDC_RUNATSTARTBROWSE: - GetWindowText(GetWindow((HWND)lParam, GW_HWNDPREV), str, SIZEOF(str)); - { - TCHAR filter[200]; - mir_sntprintf(filter, SIZEOF(filter), _T("%s (*)%c*%c"), TranslateT("All files"), 0, 0); - - OPENFILENAME ofn = { 0 }; - ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; - ofn.hwndOwner = hwndDlg; - ofn.Flags = OFN_HIDEREADONLY | OFN_DONTADDTORECENT; - if (LOWORD(wParam) == IDC_FILENAMEBROWSE) - ofn.lpstrTitle = TranslateT("Select where log file will be created"); - else { - ofn.Flags |= OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - ofn.lpstrTitle = TranslateT("Select program to be run"); - } - ofn.lpstrFilter = filter; - ofn.lpstrFile = str; - ofn.nMaxFile = SIZEOF(str) - 2; - ofn.nMaxFileTitle = MAX_PATH; - if (LOWORD(wParam) == IDC_FILENAMEBROWSE) { - if (!GetSaveFileName(&ofn)) return 1; - } - else if (!GetOpenFileName(&ofn)) - return 1; - - if (LOWORD(wParam) == IDC_RUNATSTARTBROWSE && _tcschr(str, ' ') != NULL) { - memmove(str + 1, str, ((SIZEOF(str) - 2) * sizeof(TCHAR))); - str[0] = '"'; - mir_tstrcat(str, _T("\"")); - } - SetWindowText(GetWindow((HWND)lParam, GW_HWNDPREV), str); - } - break; - - case IDC_RUNNOW: - GetDlgItemText(hwndDlg, IDC_RUNATSTART, str, SIZEOF(str)); - if (str[0]) { - STARTUPINFO si = { sizeof(si) }; - PROCESS_INFORMATION pi; - CreateProcess(NULL, str, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); - } - break; - - case IDOK: - GetDlgItemText(hwndDlg, IDC_RUNATSTART, str, SIZEOF(str)); - db_set_ts(NULL, "Netlib", "RunAtStart", str); - db_set_b(NULL, "Netlib", "ShowLogOptsAtStart", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_SHOWTHISDLGATSTART)); - - GetDlgItemText(hwndDlg, IDC_FILENAME, str, SIZEOF(str)); - logOptions.tszUserFile = rtrimt(str); - db_set_ts(NULL, "Netlib", "File", str); - - GetDlgItemText(hwndDlg, IDC_PATH, str, SIZEOF(str)); - logOptions.tszFile = rtrimt(str); - - db_set_b(NULL, "Netlib", "DumpRecv", logOptions.dumpRecv = IsDlgButtonChecked(hwndDlg, IDC_DUMPRECV)); - db_set_b(NULL, "Netlib", "DumpSent", logOptions.dumpSent = IsDlgButtonChecked(hwndDlg, IDC_DUMPSENT)); - db_set_b(NULL, "Netlib", "DumpProxy", logOptions.dumpProxy = IsDlgButtonChecked(hwndDlg, IDC_DUMPPROXY)); - db_set_b(NULL, "Netlib", "DumpSsl", logOptions.dumpSsl = IsDlgButtonChecked(hwndDlg, IDC_DUMPSSL)); - db_set_b(NULL, "Netlib", "TextDumps", logOptions.textDumps = IsDlgButtonChecked(hwndDlg, IDC_TEXTDUMPS)); - db_set_b(NULL, "Netlib", "AutoDetectText", logOptions.autoDetectText = IsDlgButtonChecked(hwndDlg, IDC_AUTODETECTTEXT)); - db_set_b(NULL, "Netlib", "TimeFormat", logOptions.timeFormat = SendDlgItemMessage(hwndDlg, IDC_TIMEFORMAT, CB_GETCURSEL, 0, 0)); - db_set_b(NULL, "Netlib", "ShowUser", logOptions.showUser = IsDlgButtonChecked(hwndDlg, IDC_SHOWNAMES)); - db_set_b(NULL, "Netlib", "ToOutputDebugString", logOptions.toOutputDebugString = IsDlgButtonChecked(hwndDlg, IDC_TOOUTPUTDEBUGSTRING)); - db_set_b(NULL, "Netlib", "ToFile", logOptions.toFile = IsDlgButtonChecked(hwndDlg, IDC_TOFILE)); - { - HWND hwndFilter = GetDlgItem(logOptions.hwndOpts, IDC_FILTER); - TVITEM tvi = { 0 }; - BOOL checked; - - tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE | TVIF_TEXT; - tvi.hItem = TreeView_GetRoot(hwndFilter); - - while (tvi.hItem) { - TreeView_GetItem(hwndFilter, &tvi); - checked = ((tvi.state & TVIS_STATEIMAGEMASK) >> 12 == 2); - - if (tvi.lParam == -1) { - logOptions.toLog = checked; - db_set_dw(NULL, "Netlib", "NLlog", checked); - } - else if (tvi.lParam < netlibUser.getCount()) { - netlibUser[tvi.lParam]->toLog = checked; - db_set_dw(NULL, netlibUser[tvi.lParam]->user.szSettingsModule, "NLlog", checked); - } - - tvi.hItem = TreeView_GetNextSibling(hwndFilter, tvi.hItem); - } - } - InitLog(); - // fall through - case IDCANCEL: - DestroyWindow(hwndDlg); - } - break; - - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - - case WM_DESTROY: - ImageList_Destroy(TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_FILTER), TVSIL_STATE)); - logOptions.hwndOpts = NULL; - break; - } - return FALSE; -} - -void NetlibLogShowOptions(void) -{ - if (logOptions.hwndOpts == NULL) - logOptions.hwndOpts = CreateDialog(hInst, MAKEINTRESOURCE(IDD_NETLIBLOGOPTS), NULL, LogOptionsDlgProc); - SetForegroundWindow(logOptions.hwndOpts); -} - -static INT_PTR ShowOptions(WPARAM, LPARAM) -{ - NetlibLogShowOptions(); - return 0; -} - -static INT_PTR NetlibLog(WPARAM wParam, LPARAM lParam) -{ - if (!bIsActive) - return 0; - - DWORD dwOriginalLastError = GetLastError(); - - NetlibUser *nlu = (NetlibUser*)wParam; - const char *pszMsg = (const char*)lParam; - if ((nlu != NULL && GetNetlibHandleType(nlu) != NLH_USER) || pszMsg == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - /* if the Netlib user handle is NULL, just pretend its not */ - if (!(nlu != NULL ? nlu->toLog : logOptions.toLog)) - return 1; - - LARGE_INTEGER liTimeNow; - char szTime[32], szHead[128]; - switch (logOptions.timeFormat) { - case TIMEFORMAT_HHMMSS: - GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER, NULL, NULL, szTime, SIZEOF(szTime)); - mir_strcat(szTime, " "); - break; - - case TIMEFORMAT_MILLISECONDS: - QueryPerformanceCounter(&liTimeNow); - liTimeNow.QuadPart -= mirandaStartTime; - mir_snprintf(szTime, SIZEOF(szTime), "%I64u.%03I64u ", liTimeNow.QuadPart / perfCounterFreq, - 1000 * (liTimeNow.QuadPart % perfCounterFreq) / perfCounterFreq); - break; - - case TIMEFORMAT_MICROSECONDS: - QueryPerformanceCounter(&liTimeNow); - liTimeNow.QuadPart -= mirandaStartTime; - mir_snprintf(szTime, SIZEOF(szTime), "%I64u.%06I64u ", liTimeNow.QuadPart / perfCounterFreq, - 1000000 * (liTimeNow.QuadPart % perfCounterFreq) / perfCounterFreq); - break; - - default: - szTime[0] = '\0'; - break; - } - - char *szUser = (logOptions.showUser) ? (nlu == NULL ? NULL : nlu->user.szSettingsModule) : NULL; - if (szUser) - mir_snprintf(szHead, SIZEOF(szHead), "[%s%04X] [%s] ", szTime, GetCurrentThreadId(), szUser); - else - mir_snprintf(szHead, SIZEOF(szHead), "[%s%04X] ", szTime, GetCurrentThreadId()); - - if (logOptions.toOutputDebugString) { - if (szHead[0]) - OutputDebugStringA(szHead); - OutputDebugStringA(pszMsg); - OutputDebugStringA("\n"); - } - - if (logOptions.toFile && !logOptions.tszFile.IsEmpty()) { - size_t len = mir_strlen(pszMsg); - mir_writeLogA(hLogger, "%s%s%s", szHead, pszMsg, pszMsg[len-1] == '\n' ? "" : "\r\n"); - } - - LOGMSG logMsg = { szHead, pszMsg }; - NotifyFastHook(hLogEvent, (WPARAM)nlu, (LPARAM)&logMsg); - - SetLastError(dwOriginalLastError); - return 1; -} - -static INT_PTR NetlibLogW(WPARAM wParam, LPARAM lParam) -{ - const wchar_t *pszMsg = (const wchar_t*)lParam; - char* szMsg = Utf8EncodeW(pszMsg); - INT_PTR res = NetlibLog(wParam, (LPARAM)szMsg); - mir_free(szMsg); - return res; -} - -void NetlibLogf(NetlibUser* nlu, const char *fmt, ...) -{ - if (nlu == NULL) { - if (!logOptions.toLog) - return; - } - else if (!nlu->toLog) - return; - - va_list va; - char szText[1024]; - - va_start(va, fmt); - mir_vsnprintf(szText, sizeof(szText), fmt, va); - va_end(va); - - NetlibLog((WPARAM)nlu, (LPARAM)szText); -} - -void NetlibDumpData(NetlibConnection *nlc, PBYTE buf, int len, int sent, int flags) -{ - char szTitleLine[128]; - char *szBuf; - bool useStack = false; - - // This section checks a number of conditions and aborts - // the dump if the data should not be written to the log - - // Check packet flags - if (flags & (MSG_PEEK | MSG_NODUMP)) - return; - - // Check user's log settings - if (!(logOptions.toOutputDebugString || GetSubscribersCount(hLogEvent) != 0 || (logOptions.toFile && !logOptions.tszFile.IsEmpty()))) - return; - if ((sent && !logOptions.dumpSent) || (!sent && !logOptions.dumpRecv)) - return; - if ((flags & MSG_DUMPPROXY) && !logOptions.dumpProxy) - return; - if ((flags & MSG_DUMPSSL) && !logOptions.dumpSsl) - return; - - WaitForSingleObject(hConnectionHeaderMutex, INFINITE); - NetlibUser *nlu = nlc ? nlc->nlu : NULL; - int titleLineLen = mir_snprintf(szTitleLine, SIZEOF(szTitleLine), "(%p:%u) Data %s%s\r\n", - nlc, nlc ? nlc->s : 0, sent ? "sent" : "received", flags & MSG_DUMPPROXY ? " (proxy)" : ""); - ReleaseMutex(hConnectionHeaderMutex); - - // check filter settings - if (nlu == NULL) { - if (!logOptions.toLog) - return; - } - else if (!nlu->toLog) - return; - - bool isText = true; - if (!logOptions.textDumps) - isText = false; - else if (!(flags & MSG_DUMPASTEXT)) { - if (logOptions.autoDetectText) { - for (int i = 0; i < len; i++) { - if ((buf[i] < ' ' && buf[i] != '\t' && buf[i] != '\r' && buf[i] != '\n') || buf[i] >= 0x80) { - isText = false; - break; - } - } - } - else isText = false; - } - - // Text data - if (isText) { - int sz = titleLineLen + len + 1; - useStack = sz <= 8192; - szBuf = (char*)(useStack ? alloca(sz) : mir_alloc(sz)); - memcpy(szBuf, szTitleLine, titleLineLen); - memcpy(szBuf + titleLineLen, (const char*)buf, len); - szBuf[titleLineLen + len] = '\0'; - } - // Binary data - else { - int line, col, colsInLine; - int sz = titleLineLen + ((len + 16) >> 4) * 78 + 1; - useStack = sz <= 8192; - - szBuf = (char*)(useStack ? alloca(sz) : mir_alloc(sz)); - memcpy(szBuf, szTitleLine, titleLineLen); - char *pszBuf = szBuf + titleLineLen; - for (line = 0;; line += 16) { - colsInLine = min(16, len - line); - - if (colsInLine == 16) { - PBYTE p = buf + line; - pszBuf += wsprintfA( - pszBuf, "%08X: %02X %02X %02X %02X-%02X %02X %02X %02X-%02X %02X %02X %02X-%02X %02X %02X %02X ", - line, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); //!!!!!!!!!! - } - else { - pszBuf += wsprintfA(pszBuf, "%08X: ", line); //!!!!!!!!!! - // Dump data as hex - for (col = 0; col < colsInLine; col++) - pszBuf += wsprintfA(pszBuf, "%02X%c", buf[line + col], ((col & 3) == 3 && col != 15) ? '-' : ' '); //!!!!!!!!!! - // Fill out last line with blanks - for (; col < 16; col++) { - mir_strcpy(pszBuf, " "); - pszBuf += 3; - } - *pszBuf++ = ' '; - } - - for (col = 0; col < colsInLine; col++) - *pszBuf++ = (buf[line + col] < ' ') ? '.' : (char)buf[line + col]; - - if (len - line <= 16) - break; - - *pszBuf++ = '\r'; // End each line with a break - *pszBuf++ = '\n'; // End each line with a break - } - *pszBuf = '\0'; - } - - NetlibLog((WPARAM)nlu, (LPARAM)szBuf); - if (!useStack) - mir_free(szBuf); -} - -void NetlibLogInit(void) -{ - LARGE_INTEGER li; - QueryPerformanceFrequency(&li); - perfCounterFreq = li.QuadPart; - QueryPerformanceCounter(&li); - mirandaStartTime = li.QuadPart; - - CreateServiceFunction(MS_NETLIB_LOGWIN, ShowOptions); - CreateServiceFunction(MS_NETLIB_LOG, NetlibLog); - CreateServiceFunction(MS_NETLIB_LOGW, NetlibLogW); - hLogEvent = CreateHookableEvent(ME_NETLIB_FASTDUMP); - - logOptions.dumpRecv = db_get_b(NULL, "Netlib", "DumpRecv", 1); - logOptions.dumpSent = db_get_b(NULL, "Netlib", "DumpSent", 1); - logOptions.dumpProxy = db_get_b(NULL, "Netlib", "DumpProxy", 1); - logOptions.dumpSsl = db_get_b(NULL, "Netlib", "DumpSsl", 0); - logOptions.textDumps = db_get_b(NULL, "Netlib", "TextDumps", 1); - logOptions.autoDetectText = db_get_b(NULL, "Netlib", "AutoDetectText", 1); - logOptions.timeFormat = db_get_b(NULL, "Netlib", "TimeFormat", TIMEFORMAT_HHMMSS); - logOptions.showUser = db_get_b(NULL, "Netlib", "ShowUser", 1); - logOptions.toOutputDebugString = db_get_b(NULL, "Netlib", "ToOutputDebugString", 0); - logOptions.toFile = db_get_b(NULL, "Netlib", "ToFile", 0); - logOptions.toLog = db_get_dw(NULL, "Netlib", "NLlog", 1); - - InitLog(); - - if (db_get_b(NULL, "Netlib", "ShowLogOptsAtStart", 0)) - NetlibLogShowOptions(); - - ptrT szBuf(db_get_tsa(NULL, "Netlib", "RunAtStart")); - if (szBuf) { - STARTUPINFO si = { sizeof(si) }; - PROCESS_INFORMATION pi; - CreateProcess(NULL, szBuf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); - } -} - -void NetlibLogShutdown(void) -{ - bIsActive = FALSE; - DestroyHookableEvent(hLogEvent); hLogEvent = NULL; - if (IsWindow(logOptions.hwndOpts)) - DestroyWindow(logOptions.hwndOpts); -} diff --git a/src/modules/netlib/netlibopenconn.cpp b/src/modules/netlib/netlibopenconn.cpp deleted file mode 100644 index 1eb1ba633c..0000000000 --- a/src/modules/netlib/netlibopenconn.cpp +++ /dev/null @@ -1,890 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "netlib.h" - -extern mir_cs csNetlibUser; -extern HANDLE hConnectionOpenMutex; -extern DWORD g_LastConnectionTick; -extern int connectionTimeout; -static int iUPnPCleanup = 0; - -#define RECV_DEFAULT_TIMEOUT 60000 - -//returns in network byte order -DWORD DnsLookup(NetlibUser *nlu, const char *szHost) -{ - HOSTENT* host; - DWORD ip = inet_addr(szHost); - if (ip != INADDR_NONE) - return ip; - - __try - { - host = gethostbyname(szHost); - if (host) - return *(u_long*)host->h_addr_list[0]; - - NetlibLogf(nlu, "%s %d: %s() for host %s failed (%u)", __FILE__, __LINE__, "gethostbyname", szHost, WSAGetLastError()); - } - __except(EXCEPTION_EXECUTE_HANDLER) {} - - return 0; -} - -int WaitUntilReadable(SOCKET s, DWORD dwTimeout, bool check) -{ - fd_set readfd; - TIMEVAL tv; - - if (s == INVALID_SOCKET) return SOCKET_ERROR; - - tv.tv_sec = dwTimeout / 1000; - tv.tv_usec = (dwTimeout % 1000) * 1000; - - FD_ZERO(&readfd); - FD_SET(s, &readfd); - - int result = select(0, &readfd, 0, 0, &tv); - if (result == 0 && !check) SetLastError(ERROR_TIMEOUT); - return result; -} - -int WaitUntilWritable(SOCKET s, DWORD dwTimeout) -{ - fd_set writefd; - TIMEVAL tv; - - tv.tv_sec = dwTimeout / 1000; - tv.tv_usec = (dwTimeout % 1000) * 1000; - - FD_ZERO(&writefd); - FD_SET(s, &writefd); - - switch(select(0, 0, &writefd, 0, &tv)) { - case 0: - SetLastError(ERROR_TIMEOUT); - case SOCKET_ERROR: - return 0; - } - return 1; -} - -bool RecvUntilTimeout(NetlibConnection *nlc, char *buf, int len, int flags, DWORD dwTimeout) -{ - int nReceived = 0; - DWORD dwTimeNow, dwCompleteTime = GetTickCount() + dwTimeout; - - while ((dwTimeNow = GetTickCount()) < dwCompleteTime) { - if (WaitUntilReadable(nlc->s, dwCompleteTime - dwTimeNow) <= 0) return false; - nReceived = NLRecv(nlc, buf, len, flags); - if (nReceived <= 0) return false; - - buf += nReceived; - len -= nReceived; - if (len <= 0) return true; - } - SetLastError(ERROR_TIMEOUT); - return false; -} - -static int NetlibInitSocks4Connection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc) -{ - // http://www.socks.nec.com/protocol/socks4.protocol and http://www.socks.nec.com/protocol/socks4a.protocol - if (!nloc || !nloc->szHost || !nloc->szHost[0]) return 0; - - size_t nHostLen = mir_strlen(nloc->szHost) + 1; - size_t nUserLen = nlu->settings.szProxyAuthUser ? mir_strlen(nlu->settings.szProxyAuthUser) + 1 : 1; - size_t len = 8 + nUserLen; - - char* pInit = (char*)alloca(len + nHostLen); - pInit[0] = 4; // SOCKS4 - pInit[1] = 1; //connect - *(PWORD)&pInit[2] = htons(nloc->wPort); - - if (nUserLen <= 1) pInit[8] = 0; - else memcpy(&pInit[8], nlu->settings.szProxyAuthUser, nUserLen); - - //if cannot resolve host, try resolving through proxy (requires SOCKS4a) - DWORD ip = DnsLookup(nlu, nloc->szHost); - *(PDWORD)&pInit[4] = ip ? ip : 0x01000000; - if (!ip) { - memcpy(&pInit[len], nloc->szHost, nHostLen); - len += nHostLen; - } - - if (NLSend(nlc, pInit, (int)len, MSG_DUMPPROXY) == SOCKET_ERROR) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "NLSend", GetLastError()); - return 0; - } - - char reply[8]; - if (!RecvUntilTimeout(nlc, reply, sizeof(reply), MSG_DUMPPROXY, RECV_DEFAULT_TIMEOUT)) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "RecvUntilTimeout", GetLastError()); - return 0; - } - - switch ((BYTE)reply[1]) { - case 90: return 1; - case 91: SetLastError(ERROR_ACCESS_DENIED); break; - case 92: SetLastError(ERROR_CONNECTION_UNAVAIL); break; - case 93: SetLastError(ERROR_INVALID_ACCESS); break; - default: SetLastError(ERROR_INVALID_DATA); break; - } - NetlibLogf(nlu, "%s %d: Proxy connection failed (%x %u)", __FILE__, __LINE__, (BYTE)reply[1], GetLastError()); - return 0; -} - -static int NetlibInitSocks5Connection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc) -{ - //rfc1928 - BYTE buf[258]; - - buf[0] = 5; //yep, socks5 - buf[1] = 1; //one auth method - buf[2] = nlu->settings.useProxyAuth?2:0; - if (NLSend(nlc, (char*)buf, 3, MSG_DUMPPROXY) == SOCKET_ERROR) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "NLSend", GetLastError()); - return 0; - } - - //confirmation of auth method - if (!RecvUntilTimeout(nlc, (char*)buf, 2, MSG_DUMPPROXY, RECV_DEFAULT_TIMEOUT)) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "RecvUntilTimeout", GetLastError()); - return 0; - } - if ((buf[1] != 0 && buf[1] != 2)) { - SetLastError(ERROR_INVALID_ID_AUTHORITY); - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "NLRecv", GetLastError()); - return 0; - } - - if (buf[1] == 2) { //rfc1929 - size_t nUserLen = mir_strlen(nlu->settings.szProxyAuthUser); - size_t nPassLen = mir_strlen(nlu->settings.szProxyAuthPassword); - PBYTE pAuthBuf = (PBYTE)mir_alloc(3 + nUserLen + nPassLen); - pAuthBuf[0] = 1; //auth version - pAuthBuf[1] = (BYTE)nUserLen; - memcpy(pAuthBuf + 2, nlu->settings.szProxyAuthUser, nUserLen); - pAuthBuf[2 + nUserLen] = (BYTE)nPassLen; - memcpy(pAuthBuf + 3 + nUserLen, nlu->settings.szProxyAuthPassword, nPassLen); - if (NLSend(nlc, (char*)pAuthBuf, int(3 + nUserLen + nPassLen), MSG_DUMPPROXY) == SOCKET_ERROR) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "NLSend", GetLastError()); - mir_free(pAuthBuf); - return 0; - } - mir_free(pAuthBuf); - - if (!RecvUntilTimeout(nlc, (char*)buf, 2, MSG_DUMPPROXY, RECV_DEFAULT_TIMEOUT)) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "RecvUntilTimeout", GetLastError()); - return 0; - } - if (buf[1]) { - SetLastError(ERROR_ACCESS_DENIED); - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "RecvUntilTimeout", GetLastError()); - return 0; - } - } - - size_t nHostLen; - DWORD hostIP; - - if (nlc->dnsThroughProxy) { - hostIP = inet_addr(nloc->szHost); - nHostLen = (hostIP == INADDR_NONE) ? mir_strlen(nloc->szHost) + 1 : 4; - } - else { - hostIP = DnsLookup(nlu, nloc->szHost); - if (hostIP == 0) - return 0; - nHostLen = 4; - } - PBYTE pInit = (PBYTE)mir_alloc(6 + nHostLen); - pInit[0] = 5; //SOCKS5 - pInit[1] = nloc->flags & NLOCF_UDP ? 3 : 1; //connect or UDP - pInit[2] = 0; //reserved - if (hostIP == INADDR_NONE) { //DNS lookup through proxy - pInit[3] = 3; - pInit[4] = BYTE(nHostLen - 1); - memcpy(pInit + 5, nloc->szHost, nHostLen - 1); - } - else { - pInit[3] = 1; - *(PDWORD)(pInit + 4) = hostIP; - } - *(PWORD)(pInit + 4 + nHostLen) = htons(nloc->wPort); - if (NLSend(nlc, (char*)pInit, int(6 + nHostLen), MSG_DUMPPROXY) == SOCKET_ERROR) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "NLSend", GetLastError()); - mir_free(pInit); - return 0; - } - mir_free(pInit); - - if (!RecvUntilTimeout(nlc, (char*)buf, 5, MSG_DUMPPROXY, RECV_DEFAULT_TIMEOUT)) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "RecvUntilTimeout", GetLastError()); - return 0; - } - - if (buf[0] != 5 || buf[1]) { - const char* err = "Unknown response"; - if (buf[0] != 5) - SetLastError(ERROR_BAD_FORMAT); - else { - switch (buf[1]) { - case 1: SetLastError(ERROR_GEN_FAILURE); err = "General failure"; break; - case 2: SetLastError(ERROR_ACCESS_DENIED); err = "Connection not allowed by ruleset"; break; - case 3: SetLastError(WSAENETUNREACH); err = "Network unreachable"; break; - case 4: SetLastError(WSAEHOSTUNREACH); err = "Host unreachable"; break; - case 5: SetLastError(WSAECONNREFUSED); err = "Connection refused by destination host"; break; - case 6: SetLastError(WSAETIMEDOUT); err = "TTL expired"; break; - case 7: SetLastError(ERROR_CALL_NOT_IMPLEMENTED); err = "Command not supported / protocol error"; break; - case 8: SetLastError(ERROR_INVALID_ADDRESS); err = "Address type not supported"; break; - default: SetLastError(ERROR_INVALID_DATA); break; - } - } - NetlibLogf(nlu, "%s %d: Proxy conection failed. %s.", __FILE__, __LINE__, err); - return 0; - } - - int nRecvSize = 0; - switch (buf[3]) { - case 1:// ipv4 addr - nRecvSize = 5; - break; - case 3:// dns name addr - nRecvSize = buf[4] + 2; - break; - case 4:// ipv6 addr - nRecvSize = 17; - break; - default: - NetlibLogf(nlu, "%s %d: %s() unknown address type (%u)", __FILE__, __LINE__, "NetlibInitSocks5Connection", (int)buf[3]); - return 0; - } - if (!RecvUntilTimeout(nlc, (char*)buf, nRecvSize, MSG_DUMPPROXY, RECV_DEFAULT_TIMEOUT)) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "RecvUntilTimeout", GetLastError()); - return 0; - } - - //connected - return 1; -} - -static bool NetlibInitHttpsConnection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc) -{ - //rfc2817 - NETLIBHTTPREQUEST nlhrSend = { 0 }; - char szUrl[512]; - - nlhrSend.cbSize = sizeof(nlhrSend); - nlhrSend.requestType = REQUEST_CONNECT; - nlhrSend.flags = NLHRF_GENERATEHOST | NLHRF_DUMPPROXY | NLHRF_SMARTAUTHHEADER | NLHRF_HTTP11 | NLHRF_NOPROXY | NLHRF_REDIRECT; - if (nlc->dnsThroughProxy) - mir_snprintf(szUrl, "%s:%u", nloc->szHost, nloc->wPort); - else { - DWORD ip = DnsLookup(nlu, nloc->szHost); - if (ip == 0) return false; - mir_snprintf(szUrl, "%s:%u", inet_ntoa(*(PIN_ADDR)&ip), nloc->wPort); - } - nlhrSend.szUrl = szUrl; - - nlc->usingHttpGateway = true; - - if (NetlibHttpSendRequest((WPARAM)nlc, (LPARAM)&nlhrSend) == SOCKET_ERROR) { - nlc->usingHttpGateway = false; - return 0; - } - - NETLIBHTTPREQUEST *nlhrReply = NetlibHttpRecv(nlc, MSG_DUMPPROXY | MSG_RAW, MSG_DUMPPROXY | MSG_RAW, true); - nlc->usingHttpGateway = false; - if (nlhrReply == NULL) - return false; - - if (nlhrReply->resultCode < 200 || nlhrReply->resultCode >= 300) { - if (nlhrReply->resultCode == 403 && nlc->dnsThroughProxy) { - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - nlc->dnsThroughProxy = 0; - return NetlibInitHttpsConnection(nlc, nlu, nloc); - } - - NetlibHttpSetLastErrorUsingHttpResult(nlhrReply->resultCode); - NetlibLogf(nlu, "%s %d: %s request failed (%u %s)", __FILE__, __LINE__, nlu->settings.proxyType == PROXYTYPE_HTTP ? "HTTP" : "HTTPS", nlhrReply->resultCode, nlhrReply->szResultDescr); - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - return 0; - } - NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); - //connected - return true; -} - -static void FreePartiallyInitedConnection(NetlibConnection *nlc) -{ - DWORD dwOriginalLastError = GetLastError(); - - if (nlc->s != INVALID_SOCKET) closesocket(nlc->s); - mir_free(nlc->nlhpi.szHttpPostUrl); - mir_free(nlc->nlhpi.szHttpGetUrl); - mir_free((char*)nlc->nloc.szHost); - mir_free(nlc->szProxyServer); - NetlibDeleteNestedCS(&nlc->ncsSend); - NetlibDeleteNestedCS(&nlc->ncsRecv); - CloseHandle(nlc->hOkToCloseEvent); - DeleteCriticalSection(&nlc->csHttpSequenceNums); - mir_free(nlc); - SetLastError(dwOriginalLastError); -} - -static bool my_connectIPv4(NetlibConnection *nlc, NETLIBOPENCONNECTION *nloc) -{ - int rc = 0, retrycnt = 0; - u_long notblocking = 1; - DWORD lasterr = 0; - static const TIMEVAL tv = { 1, 0 }; - - // if dwTimeout is zero then its an old style connection or new with a 0 timeout, select() will error quicker anyway - unsigned int dwTimeout = (nloc && (nloc->cbSize == sizeof(NETLIBOPENCONNECTION)) && (nloc->flags & NLOCF_V2) && (nloc->timeout>0)) ? nloc->timeout : 30; - - // this is for XP SP2 where there is a default connection attempt limit of 10/second - if (connectionTimeout) { - WaitForSingleObject(hConnectionOpenMutex, 10000); - int waitdiff = GetTickCount() - g_LastConnectionTick; - if (waitdiff < connectionTimeout) SleepEx(connectionTimeout, TRUE); - g_LastConnectionTick = GetTickCount(); - ReleaseMutex(hConnectionOpenMutex); - - // might of died in between the wait - if (Miranda_Terminated()) return false; - } - - PHOSTENT he; - SOCKADDR_IN sin = { 0 }; - sin.sin_family = AF_INET; - - if (nlc->proxyType) { - if (!nlc->szProxyServer) return false; - - if (nloc) - NetlibLogf(nlc->nlu, "(%p) Connecting to proxy %s:%d for %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort, nloc->szHost, nloc->wPort); - else - NetlibLogf(nlc->nlu, "(%p) Connecting to proxy %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort); - - sin.sin_port = htons(nlc->wProxyPort); - he = gethostbyname(nlc->szProxyServer); - } - else { - if (!nloc || !nloc->szHost || nloc->szHost[0] == '[' || strchr(nloc->szHost, ':')) return false; - NetlibLogf(nlc->nlu, "(%p) Connecting to server %s:%d....", nlc, nloc->szHost, nloc->wPort); - - sin.sin_port = htons(nloc->wPort); - he = gethostbyname(nloc->szHost); - } - - for (char** har = he->h_addr_list; *har && !Miranda_Terminated(); ++har) { - sin.sin_addr.s_addr = *(u_long*)*har; - - char* szIp = NetlibAddressToString((SOCKADDR_INET_M*)&sin); - NetlibLogf(nlc->nlu, "(%p) Connecting to ip %s ....", nlc, szIp); - mir_free(szIp); - -retry: - nlc->s = socket(AF_INET, nloc->flags & NLOCF_UDP ? SOCK_DGRAM : SOCK_STREAM, 0); - if (nlc->s == INVALID_SOCKET) - return false; - - // return the socket to non blocking - if (ioctlsocket(nlc->s, FIONBIO, ¬blocking) != 0) - return false; - - if (nlc->nlu->settings.specifyOutgoingPorts && nlc->nlu->settings.szOutgoingPorts && nlc->nlu->settings.szOutgoingPorts[0]) { - if (!BindSocketToPort(nlc->nlu->settings.szOutgoingPorts, nlc->s, INVALID_SOCKET, &nlc->nlu->inportnum)) - NetlibLogf(nlc->nlu, "Netlib connect: Not enough ports for outgoing connections specified"); - } - - // try a connect - if (connect(nlc->s, (LPSOCKADDR)&sin, sizeof(sin)) == 0) { - rc = 0; - break; - } - - // didn't work, was it cos of nonblocking? - if (WSAGetLastError() != WSAEWOULDBLOCK) { - rc = SOCKET_ERROR; - closesocket(nlc->s); - nlc->s = INVALID_SOCKET; - continue; - } - - while (true) { - fd_set r, w, e; - FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e); - FD_SET(nlc->s, &r); - FD_SET(nlc->s, &w); - FD_SET(nlc->s, &e); - if ((rc = select(0, &r, &w, &e, &tv)) == SOCKET_ERROR) - break; - - if (rc > 0) { - if (FD_ISSET(nlc->s, &w)) { - // connection was successful - rc = 0; - } - if (FD_ISSET(nlc->s, &r)) { - // connection was closed - rc = SOCKET_ERROR; - lasterr = WSAECONNRESET; - } - if (FD_ISSET(nlc->s, &e)) { - // connection failed. - int len = sizeof(lasterr); - rc = SOCKET_ERROR; - getsockopt(nlc->s, SOL_SOCKET, SO_ERROR, (char*)&lasterr, &len); - if (lasterr == WSAEADDRINUSE && ++retrycnt <= 2) { - closesocket(nlc->s); - goto retry; - } - } - break; - } - else if (Miranda_Terminated()) { - rc = SOCKET_ERROR; - lasterr = ERROR_TIMEOUT; - break; - } - else if (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2 && nloc->waitcallback != NULL && nloc->waitcallback(&dwTimeout) == 0) { - rc = SOCKET_ERROR; - lasterr = ERROR_TIMEOUT; - break; - } - if (--dwTimeout == 0) { - rc = SOCKET_ERROR; - lasterr = ERROR_TIMEOUT; - break; - } - } - - if (rc == 0) break; - - closesocket(nlc->s); - nlc->s = INVALID_SOCKET; - } - - notblocking = 0; - if (nlc->s != INVALID_SOCKET) ioctlsocket(nlc->s, FIONBIO, ¬blocking); - if (rc && lasterr) SetLastError(lasterr); - return rc == 0; -} - -static bool my_connectIPv6(NetlibConnection *nlc, NETLIBOPENCONNECTION *nloc) -{ - if (!nloc) - return false; - - int rc = SOCKET_ERROR, retrycnt = 0; - u_long notblocking = 1; - DWORD lasterr = 0; - static const TIMEVAL tv = { 1, 0 }; - unsigned int dwTimeout = (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2) ? nloc->timeout : 0; - // if dwTimeout is zero then its an old style connection or new with a 0 timeout, select() will error quicker anyway - if (dwTimeout == 0) dwTimeout = 30; - - // this is for XP SP2 where there is a default connection attempt limit of 10/second - if (connectionTimeout) { - WaitForSingleObject(hConnectionOpenMutex, 10000); - int waitdiff = GetTickCount() - g_LastConnectionTick; - if (waitdiff < connectionTimeout) SleepEx(connectionTimeout, TRUE); - g_LastConnectionTick = GetTickCount(); - ReleaseMutex(hConnectionOpenMutex); - - // might of died in between the wait - if (Miranda_Terminated()) return false; - } - - char szPort[6]; - addrinfo *air = NULL, *ai, hints = { 0 }; - - hints.ai_family = AF_UNSPEC; - - if (nloc->flags & NLOCF_UDP) { - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - } - else { - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - } - - if (nlc->proxyType) { - if (!nlc->szProxyServer) - return false; - - NetlibLogf(nlc->nlu, "(%p) Connecting to proxy %s:%d for %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort, nloc->szHost, nloc->wPort); - - _itoa(nlc->wProxyPort, szPort, 10); - if (GetAddrInfoA(nlc->szProxyServer, szPort, &hints, &air)) { - NetlibLogf(nlc->nlu, "%s %d: %s() for host %s failed (%u)", __FILE__, __LINE__, "getaddrinfo", nlc->szProxyServer, WSAGetLastError()); - return false; - } - } - else { - if (!nloc->szHost) - return false; - - NetlibLogf(nlc->nlu, "(%p) Connecting to server %s:%d....", nlc, nloc->szHost, nloc->wPort); - - _itoa(nlc->nloc.wPort, szPort, 10); - - if (GetAddrInfoA(nlc->nloc.szHost, szPort, &hints, &air)) { - NetlibLogf(nlc->nlu, "%s %d: %s() for host %s failed (%u)", __FILE__, __LINE__, "getaddrinfo", nlc->nloc.szHost, WSAGetLastError()); - return false; - } - } - - for (ai = air; ai && !Miranda_Terminated(); ai = ai->ai_next) { - NetlibLogf(nlc->nlu, "(%p) Connecting to ip %s ....", nlc, ptrA(NetlibAddressToString((SOCKADDR_INET_M*)ai->ai_addr))); -retry: - nlc->s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (nlc->s == INVALID_SOCKET) { - FreeAddrInfoA(air); - return false; - } - - // return the socket to non blocking - if (ioctlsocket(nlc->s, FIONBIO, ¬blocking) != 0) { - FreeAddrInfoA(air); - return false; - } - - if (nlc->nlu->settings.specifyOutgoingPorts && nlc->nlu->settings.szOutgoingPorts && nlc->nlu->settings.szOutgoingPorts[0]) { - SOCKET s = ai->ai_family == AF_INET ? nlc->s : INVALID_SOCKET; - SOCKET s6 = ai->ai_family == AF_INET6 ? nlc->s : INVALID_SOCKET; - if (!BindSocketToPort(nlc->nlu->settings.szOutgoingPorts, s, s6, &nlc->nlu->inportnum)) - NetlibLogf(nlc->nlu, "Netlib connect: Not enough ports for outgoing connections specified"); - } - - // try a connect - if (connect(nlc->s, ai->ai_addr, (int)ai->ai_addrlen) == 0) { - rc = 0; - break; - } - - // didn't work, was it cos of nonblocking? - if (WSAGetLastError() != WSAEWOULDBLOCK) { - rc = SOCKET_ERROR; - closesocket(nlc->s); - nlc->s = INVALID_SOCKET; - continue; - } - - while (true) { // timeout loop - fd_set r, w, e; - FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e); - FD_SET(nlc->s, &r); - FD_SET(nlc->s, &w); - FD_SET(nlc->s, &e); - if ((rc = select(0, &r, &w, &e, &tv)) == SOCKET_ERROR) - break; - - if (rc > 0) { - if (FD_ISSET(nlc->s, &w)) { - // connection was successful - rc = 0; - lasterr = 0; - } - if (FD_ISSET(nlc->s, &r)) { - // connection was closed - rc = SOCKET_ERROR; - lasterr = WSAECONNRESET; - } - if (FD_ISSET(nlc->s, &e)) { - // connection failed. - int len = sizeof(lasterr); - rc = SOCKET_ERROR; - getsockopt(nlc->s, SOL_SOCKET, SO_ERROR, (char*)&lasterr, &len); - if (lasterr == WSAEADDRINUSE && ++retrycnt <= 2) { - closesocket(nlc->s); - nlc->s = INVALID_SOCKET; - goto retry; - } - } - break; - } - else if (Miranda_Terminated()) { - rc = SOCKET_ERROR; - lasterr = ERROR_TIMEOUT; - break; - } - else if (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2 && nloc->waitcallback != NULL && nloc->waitcallback(&dwTimeout) == 0) { - rc = SOCKET_ERROR; - lasterr = ERROR_TIMEOUT; - break; - } - if (--dwTimeout == 0) { - rc = SOCKET_ERROR; - lasterr = ERROR_TIMEOUT; - break; - } - } - - if (rc == 0) break; - - closesocket(nlc->s); - nlc->s = INVALID_SOCKET; - } - - FreeAddrInfoA(air); - - notblocking = 0; - if (nlc->s != INVALID_SOCKET) ioctlsocket(nlc->s, FIONBIO, ¬blocking); - if (rc && lasterr) SetLastError(lasterr); - return rc == 0; -} - -static bool my_connect(NetlibConnection *nlc, NETLIBOPENCONNECTION *nloc) -{ - return my_connectIPv6(nlc, nloc); -} - -static int NetlibHttpFallbackToDirect(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc) -{ - NetlibDoClose(nlc, true); - - NetlibLogf(nlu, "Fallback to direct connection"); - - nlc->proxyAuthNeeded = false; - nlc->proxyType = 0; - mir_free(nlc->szProxyServer); nlc->szProxyServer = NULL; - if (!my_connect(nlc, nloc)) { - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "connect", WSAGetLastError()); - return false; - } - return true; -} - -bool NetlibDoConnect(NetlibConnection *nlc) -{ - NETLIBOPENCONNECTION *nloc = &nlc->nloc; - NetlibUser *nlu = nlc->nlu; - - mir_free(nlc->szProxyServer); nlc->szProxyServer = NULL; - - bool usingProxy = false, forceHttps = false; - if (nlu->settings.useProxy) { - if (nlu->settings.proxyType == PROXYTYPE_IE) - usingProxy = NetlibGetIeProxyConn(nlc, false); - else { - if (nlu->settings.szProxyServer && nlu->settings.szProxyServer[0]) { - nlc->szProxyServer = mir_strdup(nlu->settings.szProxyServer); - nlc->wProxyPort = nlu->settings.wProxyPort; - nlc->proxyType = nlu->settings.proxyType; - usingProxy = true; - } - } - } - - while (!my_connect(nlc, nloc)) { - // if connection failed, the state of nlc might be unpredictable - if (GetNetlibHandleType(nlc) == NLH_CONNECTION) { - // Fallback to direct only when using HTTP proxy, as this is what used by companies - // If other type of proxy used it's an indication of security nutcase, leave him alone - if (usingProxy && (nlc->proxyType == PROXYTYPE_HTTPS || nlc->proxyType == PROXYTYPE_HTTP)) { - usingProxy = false; - nlc->proxyType = 0; - NetlibLogf(nlu, "Fallback to direct connection"); - continue; - } - if (nlu->settings.useProxy && !usingProxy && nlu->settings.proxyType == PROXYTYPE_IE && !forceHttps) { - forceHttps = true; - usingProxy = NetlibGetIeProxyConn(nlc, true); - if (usingProxy) - continue; - } - } - NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "connect", WSAGetLastError()); - return false; - } - - if (usingProxy && !((nloc->flags & (NLOCF_HTTP | NLOCF_SSL)) == NLOCF_HTTP && (nlc->proxyType == PROXYTYPE_HTTP || nlc->proxyType == PROXYTYPE_HTTPS))) { - if (!WaitUntilWritable(nlc->s, 30000)) - return false; - - switch (nlc->proxyType) { - case PROXYTYPE_SOCKS4: - if (!NetlibInitSocks4Connection(nlc, nlu, nloc)) - return false; - break; - - case PROXYTYPE_SOCKS5: - if (!NetlibInitSocks5Connection(nlc, nlu, nloc)) - return false; - break; - - case PROXYTYPE_HTTPS: - nlc->proxyAuthNeeded = true; - if (!NetlibInitHttpsConnection(nlc, nlu, nloc)) { - usingProxy = false; - if (!NetlibHttpFallbackToDirect(nlc, nlu, nloc)) - return false; - } - break; - - case PROXYTYPE_HTTP: - nlc->proxyAuthNeeded = true; - if (!(nlu->user.flags & NUF_HTTPGATEWAY || nloc->flags & NLOCF_HTTPGATEWAY) || nloc->flags & NLOCF_SSL) { - //NLOCF_HTTP not specified and no HTTP gateway available: try HTTPS - if (!NetlibInitHttpsConnection(nlc, nlu, nloc)) { - //can't do HTTPS: try direct - usingProxy = false; - if (!NetlibHttpFallbackToDirect(nlc, nlu, nloc)) - return false; - } - } - else if (!NetlibInitHttpConnection(nlc, nlu, nloc)) - return false; - - break; - - default: - SetLastError(ERROR_INVALID_PARAMETER); - FreePartiallyInitedConnection(nlc); - return false; - } - } - else if (nloc->flags & NLOCF_HTTPGATEWAY) { - if (!NetlibInitHttpConnection(nlc, nlu, nloc)) return false; - nlc->usingDirectHttpGateway = true; - } - - NetlibLogf(nlu, "(%d) Connected to %s:%d", nlc->s, nloc->szHost, nloc->wPort); - - if (NLOCF_SSL & nloc->flags) - return NetlibStartSsl((WPARAM)nlc, 0) != 0; - - return true; -} - -bool NetlibReconnect(NetlibConnection *nlc) -{ - // a connection might be freed already - if (GetNetlibHandleType(nlc) != NLH_CONNECTION) - return false; - - char buf[4]; - bool opened = nlc->s != INVALID_SOCKET; - if (opened) { - switch (WaitUntilReadable(nlc->s, 0, true)) { - case SOCKET_ERROR: - opened = false; - break; - - case 0: - opened = true; - break; - - case 1: - opened = recv(nlc->s, buf, 1, MSG_PEEK) > 0; - break; - } - - if (!opened) - NetlibDoClose(nlc, true); - } - - if (!opened) { - if (Miranda_Terminated()) - return false; - - if (nlc->usingHttpGateway) { - nlc->proxyAuthNeeded = true; - return my_connect(nlc, &nlc->nloc); - } - return NetlibDoConnect(nlc); - } - return true; -} - -INT_PTR NetlibOpenConnection(WPARAM wParam, LPARAM lParam) -{ - NETLIBOPENCONNECTION *nloc = (NETLIBOPENCONNECTION*)lParam; - if (nloc == NULL || nloc->cbSize != sizeof(NETLIBOPENCONNECTION) || nloc->szHost == NULL || nloc->wPort == 0) { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - NetlibUser *nlu = (NetlibUser*)wParam; - if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_OUTGOING)) - return 0; - - NetlibLogf(nlu, "Connection request to %s:%d (Flags %x)....", nloc->szHost, nloc->wPort, nloc->flags); - - NetlibConnection *nlc = (NetlibConnection*)mir_calloc(sizeof(struct NetlibConnection)); - nlc->handleType = NLH_CONNECTION; - nlc->nlu = nlu; - nlc->nloc = *nloc; - nlc->nloc.szHost = mir_strdup(nloc->szHost); - nlc->s = INVALID_SOCKET; - nlc->s2 = INVALID_SOCKET; - nlc->dnsThroughProxy = nlu->settings.dnsThroughProxy != 0; - - InitializeCriticalSection(&nlc->csHttpSequenceNums); - nlc->hOkToCloseEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - nlc->dontCloseNow = 0; - NetlibInitializeNestedCS(&nlc->ncsSend); - NetlibInitializeNestedCS(&nlc->ncsRecv); - - if (!NetlibDoConnect(nlc)) { - FreePartiallyInitedConnection(nlc); - return 0; - } - - if (iUPnPCleanup == 0) { - mir_cslock lck(csNetlibUser); - if (iUPnPCleanup == 0) { - iUPnPCleanup = 1; - forkthread(NetlibUPnPCleanup, 0, NULL); - } - } - - return (INT_PTR)nlc; -} - -INT_PTR NetlibStartSsl(WPARAM wParam, LPARAM lParam) -{ - NetlibConnection *nlc = (NetlibConnection*)wParam; - if (nlc == NULL) - return 0; - - NETLIBSSL *sp = (NETLIBSSL*)lParam; - const char *szHost = sp ? sp->host : nlc->nloc.szHost; - - NetlibLogf(nlc->nlu, "(%d %s) Starting SSL negotiation", nlc->s, szHost); - nlc->hSsl = si.connect(nlc->s, szHost, nlc->nlu->settings.validateSSL); - - if (nlc->hSsl == NULL) - NetlibLogf(nlc->nlu, "(%d %s) Failure to negotiate SSL connection", nlc->s, szHost); - else - NetlibLogf(nlc->nlu, "(%d %s) SSL negotiation successful", nlc->s, szHost); - - return nlc->hSsl != NULL; -} diff --git a/src/modules/netlib/netlibopts.cpp b/src/modules/netlib/netlibopts.cpp deleted file mode 100644 index fff81944d3..0000000000 --- a/src/modules/netlib/netlibopts.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "netlib.h" - -struct NetlibTempSettings -{ - DWORD flags; - char *szSettingsModule; - NETLIBUSERSETTINGS settings; -}; - -static LIST tempSettings(5); - -static const UINT outgoingConnectionsControls[] = -{ - IDC_STATIC12, - IDC_USEPROXY, - IDC_STATIC21, IDC_PROXYTYPE, - IDC_STATIC22, IDC_PROXYHOST, IDC_STATIC23, IDC_PROXYPORT, IDC_STOFTENPORT, - IDC_PROXYAUTH, - IDC_STATIC31, IDC_PROXYUSER, IDC_STATIC32, IDC_PROXYPASS, - IDC_PROXYDNS, - IDC_SPECIFYPORTSO, - IDC_PORTSRANGEO, - IDC_STATIC54, - IDC_VALIDATESSL}; -static const UINT useProxyControls[] = { - IDC_STATIC21, IDC_PROXYTYPE, - IDC_STATIC22, IDC_PROXYHOST, IDC_STATIC23, IDC_PROXYPORT, IDC_STOFTENPORT, - IDC_PROXYAUTH, - IDC_STATIC31, IDC_PROXYUSER, IDC_STATIC32, IDC_PROXYPASS, - IDC_PROXYDNS}; -static const UINT specifyOPortsControls[] = { - IDC_PORTSRANGEO, - IDC_STATIC54 -}; -static const UINT incomingConnectionsControls[] = { - IDC_STATIC43, - IDC_SPECIFYPORTS, - IDC_PORTSRANGE, - IDC_STATIC52, - IDC_ENABLEUPNP}; -static const UINT specifyPortsControls[] = { - IDC_PORTSRANGE, - IDC_STATIC52}; - -static const TCHAR* szProxyTypes[] = {LPGENT(""), _T("SOCKS4"), _T("SOCKS5"), _T("HTTP"), _T("HTTPS"), _T("Internet Explorer")}; -static const WORD oftenProxyPorts[] = {1080, 1080, 1080, 8080, 8080, 8080}; - -#define M_REFRESHALL (WM_USER+100) -#define M_REFRESHENABLING (WM_USER+101) - -static void ShowMultipleControls(HWND hwndDlg, const UINT *controls, int cControls, int state) -{ - for (int i = 0; i < cControls; i++) - ShowWindow(GetDlgItem(hwndDlg, controls[i]), state); -} - -static void EnableMultipleControls(HWND hwndDlg, const UINT *controls, int cControls, int state) -{ - for (int i = 0; i < cControls; i++) - EnableWindow(GetDlgItem(hwndDlg, controls[i]), state); -} - -static void AddProxyTypeItem(HWND hwndDlg, int type, int selectType) -{ - int i = SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_ADDSTRING, 0, (LPARAM)(type == 0 ? TranslateTS(szProxyTypes[type]) : szProxyTypes[type])); - SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_SETITEMDATA, i, type); - if (type == selectType) - SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_SETCURSEL, i, 0); -} - -static void CopySettingsStruct(NETLIBUSERSETTINGS *dest, NETLIBUSERSETTINGS *source) -{ - *dest = *source; - if (dest->szIncomingPorts) dest->szIncomingPorts = mir_strdup(dest->szIncomingPorts); - if (dest->szOutgoingPorts) dest->szOutgoingPorts = mir_strdup(dest->szOutgoingPorts); - if (dest->szProxyAuthPassword) dest->szProxyAuthPassword = mir_strdup(dest->szProxyAuthPassword); - if (dest->szProxyAuthUser) dest->szProxyAuthUser = mir_strdup(dest->szProxyAuthUser); - if (dest->szProxyServer) dest->szProxyServer = mir_strdup(dest->szProxyServer); -} - -static void CombineSettingsStrings(char **dest, char **source) -{ - if (*dest != NULL && (*source == NULL || mir_strcmpi(*dest, *source))) { mir_free(*dest); *dest = NULL; } -} - -static void CombineSettingsStructs(NETLIBUSERSETTINGS *dest, DWORD *destFlags, NETLIBUSERSETTINGS *source, DWORD sourceFlags) -{ - if (sourceFlags&NUF_OUTGOING) { - if (*destFlags&NUF_OUTGOING) { - if (dest->validateSSL != source->validateSSL) dest->validateSSL = 2; - if (dest->useProxy != source->useProxy) dest->useProxy = 2; - if (dest->proxyType != source->proxyType) dest->proxyType = 0; - CombineSettingsStrings(&dest->szProxyServer, &source->szProxyServer); - if (dest->wProxyPort != source->wProxyPort) dest->wProxyPort = 0; - if (dest->useProxyAuth != source->useProxyAuth) dest->useProxyAuth = 2; - CombineSettingsStrings(&dest->szProxyAuthUser, &source->szProxyAuthUser); - CombineSettingsStrings(&dest->szProxyAuthPassword, &source->szProxyAuthPassword); - if (dest->dnsThroughProxy != source->dnsThroughProxy) dest->dnsThroughProxy = 2; - if (dest->specifyOutgoingPorts != source->specifyOutgoingPorts) dest->specifyOutgoingPorts = 2; - CombineSettingsStrings(&dest->szOutgoingPorts, &source->szOutgoingPorts); - } - else { - dest->validateSSL = source->validateSSL; - dest->useProxy = source->useProxy; - dest->proxyType = source->proxyType; - dest->szProxyServer = source->szProxyServer; - if (dest->szProxyServer) dest->szProxyServer = mir_strdup(dest->szProxyServer); - dest->wProxyPort = source->wProxyPort; - dest->useProxyAuth = source->useProxyAuth; - dest->szProxyAuthUser = source->szProxyAuthUser; - if (dest->szProxyAuthUser) dest->szProxyAuthUser = mir_strdup(dest->szProxyAuthUser); - dest->szProxyAuthPassword = source->szProxyAuthPassword; - if (dest->szProxyAuthPassword) dest->szProxyAuthPassword = mir_strdup(dest->szProxyAuthPassword); - dest->dnsThroughProxy = source->dnsThroughProxy; - dest->specifyOutgoingPorts = source->specifyOutgoingPorts; - dest->szOutgoingPorts = source->szOutgoingPorts; - if (dest->szOutgoingPorts) dest->szOutgoingPorts = mir_strdup(dest->szOutgoingPorts); - } - } - if (sourceFlags&NUF_INCOMING) { - if (*destFlags&NUF_INCOMING) { - if (dest->enableUPnP != source->enableUPnP) dest->enableUPnP = 2; - if (dest->specifyIncomingPorts != source->specifyIncomingPorts) dest->specifyIncomingPorts = 2; - CombineSettingsStrings(&dest->szIncomingPorts, &source->szIncomingPorts); - } - else { - dest->enableUPnP = source->enableUPnP; - dest->specifyIncomingPorts = source->specifyIncomingPorts; - dest->szIncomingPorts = source->szIncomingPorts; - if (dest->szIncomingPorts) dest->szIncomingPorts = mir_strdup(dest->szIncomingPorts); - } - } - if ((*destFlags&NUF_NOHTTPSOPTION) != (sourceFlags&NUF_NOHTTPSOPTION)) - *destFlags = (*destFlags | sourceFlags)&~NUF_NOHTTPSOPTION; - else *destFlags |= sourceFlags; -} - -static void ChangeSettingIntByCheckbox(HWND hwndDlg, UINT ctrlId, int iUser, int memberOffset) -{ - int newValue = IsDlgButtonChecked(hwndDlg, ctrlId) != BST_CHECKED; - CheckDlgButton(hwndDlg, ctrlId, newValue ? BST_CHECKED : BST_UNCHECKED); - if (iUser == -1) { - for (int i = 0; i < tempSettings.getCount(); i++) { - NetlibTempSettings *p = tempSettings[i]; - if (!(p->flags & NUF_NOOPTIONS)) - *(int*)(((PBYTE)&p->settings) + memberOffset) = newValue; - } - } - else *(int*)(((PBYTE)&tempSettings[iUser]->settings) + memberOffset) = newValue; - SendMessage(hwndDlg, M_REFRESHENABLING, 0, 0); -} - -static void ChangeSettingStringByEdit(HWND hwndDlg, UINT ctrlId, int iUser, int memberOffset) -{ - int newValueLen = GetWindowTextLength(GetDlgItem(hwndDlg, ctrlId)); - char *szNewValue = (char*)mir_alloc(newValueLen+1); - GetDlgItemTextA(hwndDlg, ctrlId, szNewValue, newValueLen+1); - if (iUser == -1) { - for (int i = 0; i < tempSettings.getCount(); i++) { - NetlibTempSettings *p = tempSettings[i]; - if (!(p->flags & NUF_NOOPTIONS)) { - char **ppszNew = (char**)(((PBYTE)&p->settings) + memberOffset); - mir_free(*ppszNew); - *ppszNew = mir_strdup(szNewValue); - } - } - mir_free(szNewValue); - } - else { - char **ppszNew = (char**)(((PBYTE)&tempSettings[iUser]->settings) + memberOffset); - mir_free(*ppszNew); - *ppszNew = szNewValue; - } -} - -static void WriteSettingsStructToDb(const char *szSettingsModule, NETLIBUSERSETTINGS *settings, DWORD flags) -{ - if (flags & NUF_OUTGOING) { - db_set_b(NULL, szSettingsModule, "NLValidateSSL", (BYTE)settings->validateSSL); - db_set_b(NULL, szSettingsModule, "NLUseProxy", (BYTE)settings->useProxy); - db_set_b(NULL, szSettingsModule, "NLProxyType", (BYTE)settings->proxyType); - db_set_s(NULL, szSettingsModule, "NLProxyServer", settings->szProxyServer ? settings->szProxyServer : ""); - db_set_w(NULL, szSettingsModule, "NLProxyPort", (WORD)settings->wProxyPort); - db_set_b(NULL, szSettingsModule, "NLUseProxyAuth", (BYTE)settings->useProxyAuth); - db_set_s(NULL, szSettingsModule, "NLProxyAuthUser", settings->szProxyAuthUser ? settings->szProxyAuthUser : ""); - db_set_s(NULL, szSettingsModule, "NLProxyAuthPassword", settings->szProxyAuthPassword ? settings->szProxyAuthPassword : ""); - db_set_b(NULL, szSettingsModule, "NLDnsThroughProxy", (BYTE)settings->dnsThroughProxy); - db_set_b(NULL, szSettingsModule, "NLSpecifyOutgoingPorts", (BYTE)settings->specifyOutgoingPorts); - db_set_s(NULL, szSettingsModule, "NLOutgoingPorts", settings->szOutgoingPorts ? settings->szOutgoingPorts : ""); - } - if (flags & NUF_INCOMING) { - db_set_b(NULL, szSettingsModule, "NLEnableUPnP", (BYTE)settings->enableUPnP); - db_set_b(NULL, szSettingsModule, "NLSpecifyIncomingPorts", (BYTE)settings->specifyIncomingPorts); - db_set_s(NULL, szSettingsModule, "NLIncomingPorts", settings->szIncomingPorts ? settings->szIncomingPorts : ""); - } -} - -void NetlibSaveUserSettingsStruct(const char *szSettingsModule, NETLIBUSERSETTINGS *settings) -{ - mir_cslock lck(csNetlibUser); - - NetlibUser tUser; - tUser.user.szSettingsModule = (char*)szSettingsModule; - NetlibUser *thisUser = netlibUser.find(&tUser); - if (thisUser == NULL) - return; - - NetlibFreeUserSettingsStruct(&thisUser->settings); - CopySettingsStruct(&thisUser->settings, settings); - WriteSettingsStructToDb(thisUser->user.szSettingsModule, &thisUser->settings, thisUser->user.flags); - - NETLIBUSERSETTINGS combinedSettings = { 0 }; - combinedSettings.cbSize = sizeof(combinedSettings); - - DWORD flags = 0; - for (int i = 0; i < netlibUser.getCount(); i++) { - if (thisUser->user.flags & NUF_NOOPTIONS) - continue; - CombineSettingsStructs(&combinedSettings, &flags, &thisUser->settings, thisUser->user.flags); - } - if (combinedSettings.validateSSL == 2) combinedSettings.validateSSL = 0; - if (combinedSettings.useProxy == 2) combinedSettings.useProxy = 0; - if (combinedSettings.proxyType == 0) combinedSettings.proxyType = PROXYTYPE_SOCKS5; - if (combinedSettings.useProxyAuth == 2) combinedSettings.useProxyAuth = 0; - if (combinedSettings.dnsThroughProxy == 2) combinedSettings.dnsThroughProxy = 1; - if (combinedSettings.enableUPnP == 2) combinedSettings.enableUPnP = 1; - if (combinedSettings.specifyIncomingPorts == 2) combinedSettings.specifyIncomingPorts = 0; - WriteSettingsStructToDb("Netlib", &combinedSettings, flags); - NetlibFreeUserSettingsStruct(&combinedSettings); -} - -static INT_PTR CALLBACK DlgProcNetlibOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int iUser; - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - { - int iItem = SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_ADDSTRING, 0, (LPARAM)TranslateT("")); - SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_SETITEMDATA, iItem, (LPARAM)-1); - SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_SETCURSEL, iItem, 0); - { - mir_cslock lck(csNetlibUser); - for (int i = 0; i < netlibUser.getCount(); ++i) { - NetlibTempSettings *thisSettings = (NetlibTempSettings*)mir_calloc(sizeof(NetlibTempSettings)); - thisSettings->flags = netlibUser[i]->user.flags; - thisSettings->szSettingsModule = mir_strdup(netlibUser[i]->user.szSettingsModule); - CopySettingsStruct(&thisSettings->settings, &netlibUser[i]->settings); - tempSettings.insert(thisSettings); - - if (netlibUser[i]->user.flags & NUF_NOOPTIONS) - continue; - iItem = SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_ADDSTRING, 0, (LPARAM)netlibUser[i]->user.ptszDescriptiveName); - SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_SETITEMDATA, iItem, i); - } - } - } - - SendMessage(hwndDlg, M_REFRESHALL, 0, 0); - return TRUE; - - case M_REFRESHALL: - iUser = SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_GETCURSEL, 0, 0), 0); - { - NETLIBUSERSETTINGS settings = { 0 }; - DWORD flags = 0; - - if (iUser == -1) { - settings.cbSize = sizeof(settings); - for (int i = 0; i < tempSettings.getCount(); i++) { - NetlibTempSettings *p = tempSettings[i]; - if (!(p->flags & NUF_NOOPTIONS)) - CombineSettingsStructs(&settings, &flags, &p->settings, p->flags); - } - } - else { - NetlibFreeUserSettingsStruct(&settings); - CopySettingsStruct(&settings, &tempSettings[iUser]->settings); - flags = tempSettings[iUser]->flags; - } - ShowMultipleControls(hwndDlg, outgoingConnectionsControls, SIZEOF(outgoingConnectionsControls), flags&NUF_OUTGOING ? SW_SHOW : SW_HIDE); - CheckDlgButton(hwndDlg, IDC_USEPROXY, settings.useProxy ? BST_CHECKED : BST_UNCHECKED); - SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_RESETCONTENT, 0, 0); - if (settings.proxyType == 0) AddProxyTypeItem(hwndDlg, 0, settings.proxyType); - AddProxyTypeItem(hwndDlg, PROXYTYPE_SOCKS4, settings.proxyType); - AddProxyTypeItem(hwndDlg, PROXYTYPE_SOCKS5, settings.proxyType); - if (flags & (NUF_HTTPCONNS | NUF_HTTPGATEWAY)) AddProxyTypeItem(hwndDlg, PROXYTYPE_HTTP, settings.proxyType); - if (!(flags & NUF_NOHTTPSOPTION)) AddProxyTypeItem(hwndDlg, PROXYTYPE_HTTPS, settings.proxyType); - if (flags & (NUF_HTTPCONNS | NUF_HTTPGATEWAY) || !(flags & NUF_NOHTTPSOPTION)) - AddProxyTypeItem(hwndDlg, PROXYTYPE_IE, settings.proxyType); - SetDlgItemTextA(hwndDlg, IDC_PROXYHOST, settings.szProxyServer ? settings.szProxyServer : ""); - if (settings.wProxyPort) SetDlgItemInt(hwndDlg, IDC_PROXYPORT, settings.wProxyPort, FALSE); - else SetDlgItemTextA(hwndDlg, IDC_PROXYPORT, ""); - CheckDlgButton(hwndDlg, IDC_PROXYAUTH, settings.useProxyAuth ? BST_CHECKED : BST_UNCHECKED); - SetDlgItemTextA(hwndDlg, IDC_PROXYUSER, settings.szProxyAuthUser ? settings.szProxyAuthUser : ""); - SetDlgItemTextA(hwndDlg, IDC_PROXYPASS, settings.szProxyAuthPassword ? settings.szProxyAuthPassword : ""); - CheckDlgButton(hwndDlg, IDC_PROXYDNS, settings.dnsThroughProxy ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_VALIDATESSL, settings.validateSSL ? BST_CHECKED : BST_UNCHECKED); - - ShowMultipleControls(hwndDlg, incomingConnectionsControls, SIZEOF(incomingConnectionsControls), flags&NUF_INCOMING ? SW_SHOW : SW_HIDE); - CheckDlgButton(hwndDlg, IDC_SPECIFYPORTS, settings.specifyIncomingPorts ? BST_CHECKED : BST_UNCHECKED); - SetDlgItemTextA(hwndDlg, IDC_PORTSRANGE, settings.szIncomingPorts ? settings.szIncomingPorts : ""); - - CheckDlgButton(hwndDlg, IDC_SPECIFYPORTSO, settings.specifyOutgoingPorts ? BST_CHECKED : BST_UNCHECKED); - SetDlgItemTextA(hwndDlg, IDC_PORTSRANGEO, settings.szOutgoingPorts ? settings.szOutgoingPorts : ""); - - CheckDlgButton(hwndDlg, IDC_ENABLEUPNP, settings.enableUPnP ? BST_CHECKED : BST_UNCHECKED); - - NetlibFreeUserSettingsStruct(&settings); - SendMessage(hwndDlg, M_REFRESHENABLING, 0, 0); - } - break; - - case M_REFRESHENABLING: - TCHAR str[80]; - { - int selectedProxyType = SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_GETCURSEL, 0, 0), 0); - mir_sntprintf(str, SIZEOF(str), TranslateT("(often %d)"), oftenProxyPorts[selectedProxyType]); - SetDlgItemText(hwndDlg, IDC_STOFTENPORT, str); - if (IsDlgButtonChecked(hwndDlg, IDC_USEPROXY) != BST_UNCHECKED) { - int enableAuth = 0, enableUser = 0, enablePass = 0, enableServer = 1; - EnableMultipleControls(hwndDlg, useProxyControls, SIZEOF(useProxyControls), TRUE); - if (selectedProxyType == 0) { - for (int i = 0; i < tempSettings.getCount(); i++) { - NetlibTempSettings *p = tempSettings[i]; - if (!p->settings.useProxy || - p->flags & NUF_NOOPTIONS || !(p->flags & NUF_OUTGOING)) - continue; - - if (p->settings.proxyType == PROXYTYPE_SOCKS4) enableUser = 1; - else { - enableAuth = 1; - if (p->settings.useProxyAuth) - enableUser = enablePass = 1; - } - } - } - else { - if (selectedProxyType == PROXYTYPE_SOCKS4) enableUser = 1; - else { - if (selectedProxyType == PROXYTYPE_IE) enableServer = 0; - enableAuth = 1; - if (IsDlgButtonChecked(hwndDlg, IDC_PROXYAUTH) != BST_UNCHECKED) - enableUser = enablePass = 1; - } - } - EnableWindow(GetDlgItem(hwndDlg, IDC_PROXYAUTH), enableAuth); - EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC31), enableUser); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROXYUSER), enableUser); - EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC32), enablePass); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROXYPASS), enablePass); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROXYHOST), enableServer); - EnableWindow(GetDlgItem(hwndDlg, IDC_PROXYPORT), enableServer); - } - else EnableMultipleControls(hwndDlg, useProxyControls, SIZEOF(useProxyControls), FALSE); - EnableMultipleControls(hwndDlg, specifyPortsControls, SIZEOF(specifyPortsControls), IsDlgButtonChecked(hwndDlg, IDC_SPECIFYPORTS) != BST_UNCHECKED); - EnableMultipleControls(hwndDlg, specifyOPortsControls, SIZEOF(specifyOPortsControls), IsDlgButtonChecked(hwndDlg, IDC_SPECIFYPORTSO) != BST_UNCHECKED); - } - break; - - case WM_COMMAND: - iUser = SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_GETCURSEL, 0, 0), 0); - switch (LOWORD(wParam)) { - case IDC_NETLIBUSERS: - if (HIWORD(wParam) == CBN_SELCHANGE) SendMessage(hwndDlg, M_REFRESHALL, 0, 0); - return 0; - - case IDC_LOGOPTIONS: - NetlibLogShowOptions(); - return 0; - - case IDC_PROXYTYPE: - if (HIWORD(wParam) != CBN_SELCHANGE) return 0; - { - int newValue = SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_GETCURSEL, 0, 0), 0); - if (iUser == -1) { - if (newValue == 0) return 0; - for (int i=0; i < tempSettings.getCount(); i++) { - NetlibTempSettings *p = tempSettings[i]; - if (p->flags & NUF_NOOPTIONS) continue; - if (newValue == PROXYTYPE_HTTP && !(p->flags & (NUF_HTTPCONNS | NUF_HTTPGATEWAY))) - p->settings.proxyType = PROXYTYPE_HTTPS; - else if (newValue == PROXYTYPE_HTTPS && p->flags & NUF_NOHTTPSOPTION) - p->settings.proxyType = PROXYTYPE_HTTP; - else p->settings.proxyType = newValue; - } - SendMessage(hwndDlg, M_REFRESHALL, 0, 0); - } - else { - tempSettings[iUser]->settings.proxyType = newValue; - SendMessage(hwndDlg, M_REFRESHENABLING, 0, 0); - } - } - break; - case IDC_USEPROXY: - ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, useProxy)); - break; - case IDC_PROXYAUTH: - ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, useProxyAuth)); - break; - case IDC_PROXYDNS: - ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, dnsThroughProxy)); - break; - case IDC_SPECIFYPORTS: - ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, specifyIncomingPorts)); - break; - case IDC_SPECIFYPORTSO: - ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, specifyOutgoingPorts)); - break; - case IDC_ENABLEUPNP: - ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, enableUPnP)); - break; - case IDC_VALIDATESSL: - ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, validateSSL)); - break; - case IDC_PROXYHOST: - if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return 0; - ChangeSettingStringByEdit(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, szProxyServer)); - break; - case IDC_PROXYPORT: - if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return 0; - { - int newValue = GetDlgItemInt(hwndDlg, LOWORD(wParam), NULL, FALSE); - if (iUser == -1) { - for (int i = 0; i < tempSettings.getCount(); i++) { - NetlibTempSettings *p = tempSettings[i]; - if (!(p->flags & NUF_NOOPTIONS)) - p->settings.wProxyPort = newValue; - } - } - else tempSettings[iUser]->settings.wProxyPort = newValue; - } - break; - case IDC_PROXYUSER: - if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return 0; - ChangeSettingStringByEdit(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, szProxyAuthUser)); - break; - case IDC_PROXYPASS: - if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return 0; - ChangeSettingStringByEdit(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, szProxyAuthPassword)); - break; - case IDC_PORTSRANGE: - if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return 0; - ChangeSettingStringByEdit(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, szIncomingPorts)); - break; - case IDC_PORTSRANGEO: - if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return 0; - ChangeSettingStringByEdit(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, szOutgoingPorts)); - break; - } - ShowWindow(GetDlgItem(hwndDlg, IDC_RECONNECTREQD), SW_SHOW); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - for (iUser = 0; iUser < tempSettings.getCount(); iUser++) - NetlibSaveUserSettingsStruct(tempSettings[iUser]->szSettingsModule, - &tempSettings[iUser]->settings); - return TRUE; - } - break; - } - break; - - case WM_DESTROY: - for (int i = 0; i < tempSettings.getCount(); ++i) { - NetlibTempSettings *p = tempSettings[i]; - mir_free(p->szSettingsModule); - NetlibFreeUserSettingsStruct(&p->settings); - mir_free(tempSettings[i]); - } - tempSettings.destroy(); - break; - } - return FALSE; -} - -int NetlibOptInitialise(WPARAM wParam, LPARAM) -{ - int optionsCount = 0; - { - mir_cslock lck(csNetlibUser); - for (int i=0; i < netlibUser.getCount(); i++) - if (!(netlibUser[i]->user.flags & NUF_NOOPTIONS)) - ++optionsCount; - } - - if (optionsCount == 0) - return 0; - - OPTIONSDIALOGPAGE odp = { 0 }; - odp.position = 900000000; - odp.hInstance = hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_NETLIB); - odp.pszTitle = LPGEN("Network"); - odp.pfnDlgProc = DlgProcNetlibOpts; - odp.flags = ODPF_BOLDGROUPS; - Options_AddPage(wParam, &odp); - return 0; -} diff --git a/src/modules/netlib/netlibpktrecver.cpp b/src/modules/netlib/netlibpktrecver.cpp deleted file mode 100644 index 5783cda6b3..0000000000 --- a/src/modules/netlib/netlibpktrecver.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "netlib.h" - -INT_PTR NetlibPacketRecverCreate(WPARAM wParam, LPARAM lParam) -{ - NetlibConnection *nlc = (struct NetlibConnection*)wParam; - struct NetlibPacketRecver *nlpr; - - if (GetNetlibHandleType(nlc) != NLH_CONNECTION || lParam == 0) { - SetLastError(ERROR_INVALID_PARAMETER); - return (INT_PTR)(struct NetlibPacketRecver*)NULL; - } - nlpr = (struct NetlibPacketRecver*)mir_calloc(sizeof(struct NetlibPacketRecver)); - if (nlpr == NULL) { - SetLastError(ERROR_OUTOFMEMORY); - return (INT_PTR)(struct NetlibPacketRecver*)NULL; - } - nlpr->handleType = NLH_PACKETRECVER; - nlpr->nlc = nlc; - nlpr->packetRecver.cbSize = sizeof(nlpr->packetRecver); - nlpr->packetRecver.bufferSize = lParam; - nlpr->packetRecver.buffer = (PBYTE)mir_alloc(nlpr->packetRecver.bufferSize); - nlpr->packetRecver.bytesUsed = 0; - nlpr->packetRecver.bytesAvailable = 0; - return (INT_PTR)nlpr; -} - -INT_PTR NetlibPacketRecverGetMore(WPARAM wParam, LPARAM lParam) -{ - struct NetlibPacketRecver *nlpr = (struct NetlibPacketRecver*)wParam; - NETLIBPACKETRECVER *nlprParam = (NETLIBPACKETRECVER*)lParam; - - if (GetNetlibHandleType(nlpr) != NLH_PACKETRECVER || nlprParam == NULL || nlprParam->cbSize != sizeof(NETLIBPACKETRECVER) || nlprParam->bytesUsed > nlpr->packetRecver.bytesAvailable) { - SetLastError(ERROR_INVALID_PARAMETER); - return SOCKET_ERROR; - } - if (Miranda_Terminated()) { /* HACK: Lame, break while loops of protocols that can't kill their while loops, (cough, ICQ, cough) */ - SetLastError(ERROR_TIMEOUT); - return SOCKET_ERROR; - } - nlpr->packetRecver.dwTimeout = nlprParam->dwTimeout; - if (nlprParam->bytesUsed == 0) { - if (nlpr->packetRecver.bytesAvailable == nlpr->packetRecver.bufferSize) { - nlpr->packetRecver.bytesAvailable = 0; - NetlibLogf(nlpr->nlc->nlu, "Packet recver: packet overflowed buffer, ditching"); - } - } - else { - memmove(nlpr->packetRecver.buffer, nlpr->packetRecver.buffer + nlprParam->bytesUsed, nlpr->packetRecver.bytesAvailable - nlprParam->bytesUsed); - nlpr->packetRecver.bytesAvailable -= nlprParam->bytesUsed; - } - - if (nlprParam->dwTimeout != INFINITE) { - if (!si.pending(nlpr->nlc->hSsl) && WaitUntilReadable(nlpr->nlc->s, nlprParam->dwTimeout) <= 0) { - *nlprParam = nlpr->packetRecver; - return SOCKET_ERROR; - } - } - - INT_PTR recvResult = NLRecv(nlpr->nlc, (char*)nlpr->packetRecver.buffer + nlpr->packetRecver.bytesAvailable, nlpr->packetRecver.bufferSize - nlpr->packetRecver.bytesAvailable, 0); - if (recvResult > 0) - nlpr->packetRecver.bytesAvailable += recvResult; - *nlprParam = nlpr->packetRecver; - return recvResult; -} diff --git a/src/modules/netlib/netlibsecurity.cpp b/src/modules/netlib/netlibsecurity.cpp deleted file mode 100644 index 4c3cb4301c..0000000000 --- a/src/modules/netlib/netlibsecurity.cpp +++ /dev/null @@ -1,427 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "netlib.h" - -#define SECURITY_WIN32 -#include -#include - -#pragma comment(lib, "secur32.lib") - -struct NtlmHandleType -{ - CtxtHandle hClientContext; - CredHandle hClientCredential; - TCHAR* szProvider; - TCHAR* szPrincipal; - unsigned cbMaxToken; - bool hasDomain; -}; - -struct NTLM_String -{ - WORD len; - WORD allocedSpace; - DWORD offset; -}; - -struct NtlmType2packet -{ - char sign[8]; - DWORD type; // == 2 - NTLM_String targetName; - DWORD flags; - BYTE challenge[8]; - BYTE context[8]; - NTLM_String targetInfo; -}; - -static unsigned ntlmCnt = 0; -static mir_cs csSec; - -static void ReportSecError(SECURITY_STATUS scRet, int line) -{ - char szMsgBuf[256]; - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, scRet, LANG_USER_DEFAULT, szMsgBuf, SIZEOF(szMsgBuf), NULL); - - char *p = strchr(szMsgBuf, 13); if (p) *p = 0; - - NetlibLogf(NULL, "Security error 0x%x on line %u (%s)", scRet, line, szMsgBuf); -} - -HANDLE NetlibInitSecurityProvider(const TCHAR* szProvider, const TCHAR* szPrincipal) -{ - HANDLE hSecurity = NULL; - - if (mir_tstrcmpi(szProvider, _T("Basic")) == 0) { - NtlmHandleType* hNtlm = (NtlmHandleType*)mir_calloc(sizeof(NtlmHandleType)); - hNtlm->szProvider = mir_tstrdup(szProvider); - SecInvalidateHandle(&hNtlm->hClientContext); - SecInvalidateHandle(&hNtlm->hClientCredential); - ntlmCnt++; - - return hNtlm; - } - - mir_cslock lck(csSec); - - PSecPkgInfo ntlmSecurityPackageInfo; - bool isGSSAPI = mir_tstrcmpi(szProvider, _T("GSSAPI")) == 0; - const TCHAR *szProviderC = isGSSAPI ? _T("Kerberos") : szProvider; - SECURITY_STATUS sc = QuerySecurityPackageInfo((LPTSTR)szProviderC, &ntlmSecurityPackageInfo); - if (sc == SEC_E_OK) { - NtlmHandleType* hNtlm; - - hSecurity = hNtlm = (NtlmHandleType*)mir_calloc(sizeof(NtlmHandleType)); - hNtlm->cbMaxToken = ntlmSecurityPackageInfo->cbMaxToken; - FreeContextBuffer(ntlmSecurityPackageInfo); - - hNtlm->szProvider = mir_tstrdup(szProvider); - hNtlm->szPrincipal = mir_tstrdup(szPrincipal ? szPrincipal : _T("")); - SecInvalidateHandle(&hNtlm->hClientContext); - SecInvalidateHandle(&hNtlm->hClientCredential); - ntlmCnt++; - } - return hSecurity; -} - -HANDLE NetlibInitSecurityProvider(const char* szProvider, const char* szPrincipal) -{ - return NetlibInitSecurityProvider(_A2T(szProvider), _A2T(szPrincipal)); -} - -void NetlibDestroySecurityProvider(HANDLE hSecurity) -{ - if (hSecurity == NULL) - return; - - mir_cslock lck(csSec); - - if (ntlmCnt != 0) { - NtlmHandleType* hNtlm = (NtlmHandleType*)hSecurity; - if (hNtlm != NULL) { - if (SecIsValidHandle(&hNtlm->hClientContext)) - DeleteSecurityContext(&hNtlm->hClientContext); - if (SecIsValidHandle(&hNtlm->hClientCredential)) - FreeCredentialsHandle(&hNtlm->hClientCredential); - mir_free(hNtlm->szProvider); - mir_free(hNtlm->szPrincipal); - mir_free(hNtlm); - } - - --ntlmCnt; - } -} - -char* CompleteGssapi(HANDLE hSecurity, unsigned char *szChallenge, unsigned chlsz) -{ - if (!szChallenge || !szChallenge[0]) return NULL; - - NtlmHandleType* hNtlm = (NtlmHandleType*)hSecurity; - unsigned char inDataBuffer[1024]; - - SecBuffer inBuffers[2] = - { - { sizeof(inDataBuffer), SECBUFFER_DATA, inDataBuffer }, - { chlsz, SECBUFFER_STREAM, szChallenge } - }; - - SecBufferDesc inBuffersDesc = { SECBUFFER_VERSION, 2, inBuffers }; - - unsigned long qop = 0; - SECURITY_STATUS sc = DecryptMessage(&hNtlm->hClientContext, &inBuffersDesc, 0, &qop); - if (sc != SEC_E_OK) { - ReportSecError(sc, __LINE__); - return NULL; - } - - unsigned char LayerMask = inDataBuffer[0]; - unsigned int MaxMessageSize = htonl(*(unsigned*)&inDataBuffer[1]); - - SecPkgContext_Sizes sizes; - sc = QueryContextAttributes(&hNtlm->hClientContext, SECPKG_ATTR_SIZES, &sizes); - if (sc != SEC_E_OK) { - ReportSecError(sc, __LINE__); - return NULL; - } - - unsigned char *tokenBuffer = (unsigned char*)alloca(sizes.cbSecurityTrailer); - unsigned char *paddingBuffer = (unsigned char*)alloca(sizes.cbBlockSize); - - unsigned char outDataBuffer[4] = { 1, 0, 16, 0 }; - - SecBuffer outBuffers[3] = - { - { sizes.cbSecurityTrailer, SECBUFFER_TOKEN, tokenBuffer }, - { sizeof(outDataBuffer), SECBUFFER_DATA, outDataBuffer }, - { sizes.cbBlockSize, SECBUFFER_PADDING, paddingBuffer } - }; - SecBufferDesc outBuffersDesc = { SECBUFFER_VERSION, 3, outBuffers }; - - sc = EncryptMessage(&hNtlm->hClientContext, SECQOP_WRAP_NO_ENCRYPT, &outBuffersDesc, 0); - if (sc != SEC_E_OK) { - ReportSecError(sc, __LINE__); - return NULL; - } - - unsigned i, ressz = 0; - for (i = 0; i < outBuffersDesc.cBuffers; i++) - ressz += outBuffersDesc.pBuffers[i].cbBuffer; - - unsigned char *response = (unsigned char*)alloca(ressz), *p = response; - for (i = 0; i < outBuffersDesc.cBuffers; i++) { - memcpy(p, outBuffersDesc.pBuffers[i].pvBuffer, outBuffersDesc.pBuffers[i].cbBuffer); - p += outBuffersDesc.pBuffers[i].cbBuffer; - } - - return mir_base64_encode(response, ressz); -} - -char* NtlmCreateResponseFromChallenge(HANDLE hSecurity, const char *szChallenge, const TCHAR* login, const TCHAR* psw, bool http, unsigned& complete) -{ - if (hSecurity == NULL || ntlmCnt == 0) - return NULL; - - SecBufferDesc outputBufferDescriptor, inputBufferDescriptor; - SecBuffer outputSecurityToken, inputSecurityToken; - TimeStamp tokenExpiration; - ULONG contextAttributes; - char *szOutputToken; - - NtlmHandleType* hNtlm = (NtlmHandleType*)hSecurity; - if (mir_tstrcmpi(hNtlm->szProvider, _T("Basic"))) { - bool isGSSAPI = mir_tstrcmpi(hNtlm->szProvider, _T("GSSAPI")) == 0; - TCHAR *szProvider = isGSSAPI ? _T("Kerberos") : hNtlm->szProvider; - bool hasChallenge = szChallenge != NULL && szChallenge[0] != '\0'; - if (hasChallenge) { - unsigned tokenLen; - BYTE *token = (BYTE*)mir_base64_decode(szChallenge, &tokenLen); - if (token == NULL) - return NULL; - - if (isGSSAPI && complete) - return CompleteGssapi(hSecurity, token, tokenLen); - - inputBufferDescriptor.cBuffers = 1; - inputBufferDescriptor.pBuffers = &inputSecurityToken; - inputBufferDescriptor.ulVersion = SECBUFFER_VERSION; - inputSecurityToken.BufferType = SECBUFFER_TOKEN; - inputSecurityToken.cbBuffer = tokenLen; - inputSecurityToken.pvBuffer = token; - - // try to decode the domain name from the NTLM challenge - if (login != NULL && login[0] != '\0' && !hNtlm->hasDomain) { - NtlmType2packet* pkt = (NtlmType2packet*)token; - if (!strncmp(pkt->sign, "NTLMSSP", 8) && pkt->type == 2) { - - wchar_t* domainName = (wchar_t*)&token[pkt->targetName.offset]; - int domainLen = pkt->targetName.len; - - // Negotiate ANSI? if yes, convert the ANSI name to unicode - if ((pkt->flags & 1) == 0) { - int bufsz = MultiByteToWideChar(CP_ACP, 0, (char*)domainName, domainLen, NULL, 0); - wchar_t* buf = (wchar_t*)alloca(bufsz * sizeof(wchar_t)); - domainLen = MultiByteToWideChar(CP_ACP, 0, (char*)domainName, domainLen, buf, bufsz) - 1; - domainName = buf; - } - else domainLen /= sizeof(wchar_t); - - if (domainLen) { - size_t newLoginLen = mir_tstrlen(login) + domainLen + 1; - TCHAR *newLogin = (TCHAR*)alloca(newLoginLen * sizeof(TCHAR)); - - _tcsncpy(newLogin, domainName, domainLen); - newLogin[domainLen] = '\\'; - mir_tstrcpy(newLogin + domainLen + 1, login); - - char* szChl = NtlmCreateResponseFromChallenge(hSecurity, NULL, newLogin, psw, http, complete); - mir_free(szChl); - } - } - } - } - else { - if (SecIsValidHandle(&hNtlm->hClientContext)) - DeleteSecurityContext(&hNtlm->hClientContext); - if (SecIsValidHandle(&hNtlm->hClientCredential)) - FreeCredentialsHandle(&hNtlm->hClientCredential); - - SEC_WINNT_AUTH_IDENTITY auth; - - if (login != NULL && login[0] != '\0') { - memset(&auth, 0, sizeof(auth)); - - NetlibLogf(NULL, "Security login requested, user: %S pssw: %s", login, psw ? "(exist)" : "(no psw)"); - - const TCHAR* loginName = login; - const TCHAR* domainName = _tcschr(login, '\\'); - size_t domainLen = 0; - size_t loginLen = mir_tstrlen(loginName); - if (domainName != NULL) { - loginName = domainName + 1; - loginLen = mir_tstrlen(loginName); - domainLen = domainName - login; - domainName = login; - } - else if ((domainName = _tcschr(login, '@')) != NULL) { - loginName = login; - loginLen = domainName - login; - domainLen = mir_tstrlen(++domainName); - } - - auth.User = (PWORD)loginName; - auth.UserLength = (ULONG)loginLen; - auth.Password = (PWORD)psw; - auth.PasswordLength = (ULONG)mir_tstrlen(psw); - auth.Domain = (PWORD)domainName; - auth.DomainLength = (ULONG)domainLen; - auth.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; - - hNtlm->hasDomain = domainLen != 0; - } - - SECURITY_STATUS sc = AcquireCredentialsHandle(NULL, szProvider, - SECPKG_CRED_OUTBOUND, NULL, hNtlm->hasDomain ? &auth : NULL, NULL, NULL, - &hNtlm->hClientCredential, &tokenExpiration); - if (sc != SEC_E_OK) { - ReportSecError(sc, __LINE__); - return NULL; - } - } - - outputBufferDescriptor.cBuffers = 1; - outputBufferDescriptor.pBuffers = &outputSecurityToken; - outputBufferDescriptor.ulVersion = SECBUFFER_VERSION; - outputSecurityToken.BufferType = SECBUFFER_TOKEN; - outputSecurityToken.cbBuffer = hNtlm->cbMaxToken; - outputSecurityToken.pvBuffer = alloca(outputSecurityToken.cbBuffer); - - SECURITY_STATUS sc = InitializeSecurityContext(&hNtlm->hClientCredential, - hasChallenge ? &hNtlm->hClientContext : NULL, - hNtlm->szPrincipal, isGSSAPI ? ISC_REQ_MUTUAL_AUTH | ISC_REQ_STREAM : 0, 0, SECURITY_NATIVE_DREP, - hasChallenge ? &inputBufferDescriptor : NULL, 0, &hNtlm->hClientContext, - &outputBufferDescriptor, &contextAttributes, &tokenExpiration); - - complete = (sc != SEC_I_COMPLETE_AND_CONTINUE && sc != SEC_I_CONTINUE_NEEDED); - - if (sc == SEC_I_COMPLETE_NEEDED || sc == SEC_I_COMPLETE_AND_CONTINUE) - sc = CompleteAuthToken(&hNtlm->hClientContext, &outputBufferDescriptor); - - if (sc != SEC_E_OK && sc != SEC_I_CONTINUE_NEEDED) { - ReportSecError(sc, __LINE__); - return NULL; - } - - szOutputToken = mir_base64_encode((PBYTE)outputSecurityToken.pvBuffer, outputSecurityToken.cbBuffer); - } - else { - if (!login || !psw) return NULL; - - char *szLogin = mir_t2a(login); - char *szPassw = mir_t2a(psw); - - size_t authLen = mir_strlen(szLogin) + mir_strlen(szPassw) + 5; - char *szAuth = (char*)alloca(authLen); - - int len = mir_snprintf(szAuth, authLen, "%s:%s", szLogin, szPassw); - szOutputToken = mir_base64_encode((BYTE*)szAuth, len); - complete = true; - - mir_free(szPassw); - mir_free(szLogin); - } - - if (szOutputToken == NULL) - return NULL; - - if (!http) - return szOutputToken; - - ptrA szProvider(mir_t2a(hNtlm->szProvider)); - size_t resLen = mir_strlen(szOutputToken) + mir_strlen(szProvider) + 10; - char *result = (char*)mir_alloc(resLen); - mir_snprintf(result, resLen, "%s %s", szProvider, szOutputToken); - mir_free(szOutputToken); - return result; -} - -/////////////////////////////////////////////////////////////////////////////// - -static INT_PTR InitSecurityProviderService(WPARAM, LPARAM lParam) -{ - HANDLE hSecurity = NetlibInitSecurityProvider((char*)lParam, NULL); - return (INT_PTR)hSecurity; -} - -static INT_PTR InitSecurityProviderService2(WPARAM, LPARAM lParam) -{ - NETLIBNTLMINIT2 *req = (NETLIBNTLMINIT2*)lParam; - if (req == NULL || req->cbSize < sizeof(*req)) - return 0; - - if (req->flags & NNR_UNICODE) - return (INT_PTR)NetlibInitSecurityProvider(req->szProviderName, req->szPrincipal); - return (INT_PTR)NetlibInitSecurityProvider((char*)req->szProviderName, (char*)req->szPrincipal); -} - -static INT_PTR DestroySecurityProviderService(WPARAM, LPARAM lParam) -{ - NetlibDestroySecurityProvider((HANDLE)lParam); - return 0; -} - -static INT_PTR NtlmCreateResponseService(WPARAM wParam, LPARAM lParam) -{ - NETLIBNTLMREQUEST *req = (NETLIBNTLMREQUEST*)lParam; - if (req == NULL) - return 0; - - unsigned complete = 0; - char *response = NtlmCreateResponseFromChallenge((HANDLE)wParam, req->szChallenge, _A2T(req->userName), _A2T(req->password), false, complete); - return (INT_PTR)response; -} - -static INT_PTR NtlmCreateResponseService2(WPARAM wParam, LPARAM lParam) -{ - NETLIBNTLMREQUEST2 *req = (NETLIBNTLMREQUEST2*)lParam; - if (req == NULL || req->cbSize < sizeof(*req)) - return 0; - - if (req->flags & NNR_UNICODE) - return (INT_PTR)NtlmCreateResponseFromChallenge((HANDLE)wParam, req->szChallenge, req->szUserName, req->szPassword, false, req->complete); - - return (INT_PTR)NtlmCreateResponseFromChallenge((HANDLE)wParam, req->szChallenge, _A2T((char*)req->szUserName), _A2T((char*)req->szPassword), false, req->complete); -} - -void NetlibSecurityInit(void) -{ - CreateServiceFunction(MS_NETLIB_INITSECURITYPROVIDER, InitSecurityProviderService); - CreateServiceFunction(MS_NETLIB_INITSECURITYPROVIDER2, InitSecurityProviderService2); - CreateServiceFunction(MS_NETLIB_DESTROYSECURITYPROVIDER, DestroySecurityProviderService); - CreateServiceFunction(MS_NETLIB_NTLMCREATERESPONSE, NtlmCreateResponseService); - CreateServiceFunction(MS_NETLIB_NTLMCREATERESPONSE2, NtlmCreateResponseService2); -} diff --git a/src/modules/netlib/netlibsock.cpp b/src/modules/netlib/netlibsock.cpp deleted file mode 100644 index e53e73bd89..0000000000 --- a/src/modules/netlib/netlibsock.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "netlib.h" - -extern HANDLE hConnectionHeaderMutex, hSendEvent, hRecvEvent; - -INT_PTR NetlibSend(WPARAM wParam, LPARAM lParam) -{ - NetlibConnection *nlc = (NetlibConnection*)wParam; - NETLIBBUFFER *nlb = (NETLIBBUFFER*)lParam; - INT_PTR result; - - if (nlb == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); - return SOCKET_ERROR; - } - - if (!NetlibEnterNestedCS(nlc, NLNCS_SEND)) - return SOCKET_ERROR; - - if (nlc->usingHttpGateway && !(nlb->flags & MSG_RAW)) { - if (!(nlb->flags & MSG_NOHTTPGATEWAYWRAP) && nlc->nlu->user.pfnHttpGatewayWrapSend) { - NetlibDumpData(nlc, (PBYTE)nlb->buf, nlb->len, 1, nlb->flags); - result = nlc->nlu->user.pfnHttpGatewayWrapSend((HANDLE)nlc, (PBYTE)nlb->buf, nlb->len, nlb->flags | MSG_NOHTTPGATEWAYWRAP, NetlibSend); - } - else result = NetlibHttpGatewayPost(nlc, nlb->buf, nlb->len, nlb->flags); - } - else { - NetlibDumpData(nlc, (PBYTE)nlb->buf, nlb->len, 1, nlb->flags); - if (nlc->hSsl) - result = si.write(nlc->hSsl, nlb->buf, nlb->len); - else - result = send(nlc->s, nlb->buf, nlb->len, nlb->flags & 0xFFFF); - } - NetlibLeaveNestedCS(&nlc->ncsSend); - - NETLIBNOTIFY nln = { nlb, result }; - NotifyFastHook(hSendEvent, (WPARAM)&nln, (LPARAM)&nlc->nlu->user); - - return result; -} - -INT_PTR NetlibRecv(WPARAM wParam, LPARAM lParam) -{ - NetlibConnection *nlc = (NetlibConnection*)wParam; - NETLIBBUFFER* nlb = (NETLIBBUFFER*)lParam; - int recvResult; - - if (nlb == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); - return SOCKET_ERROR; - } - - if (!NetlibEnterNestedCS(nlc, NLNCS_RECV)) - return SOCKET_ERROR; - - if (nlc->usingHttpGateway && !(nlb->flags & MSG_RAW)) - recvResult = NetlibHttpGatewayRecv(nlc, nlb->buf, nlb->len, nlb->flags); - else { - if (nlc->hSsl) - recvResult = si.read(nlc->hSsl, nlb->buf, nlb->len, (nlb->flags & MSG_PEEK) != 0); - else - recvResult = recv(nlc->s, nlb->buf, nlb->len, nlb->flags & 0xFFFF); - } - NetlibLeaveNestedCS(&nlc->ncsRecv); - if (recvResult <= 0) - return recvResult; - - NetlibDumpData(nlc, (PBYTE)nlb->buf, recvResult, 0, nlb->flags); - - if ((nlb->flags & MSG_PEEK) == 0) { - NETLIBNOTIFY nln = { nlb, recvResult }; - NotifyFastHook(hRecvEvent, (WPARAM)&nln, (LPARAM)&nlc->nlu->user); - } - return recvResult; -} - -static int ConnectionListToSocketList(HANDLE *hConns, fd_set *fd, int& pending) -{ - FD_ZERO(fd); - for (int i = 0; hConns[i] && hConns[i] != INVALID_HANDLE_VALUE && i < FD_SETSIZE; i++) { - NetlibConnection *nlcCheck = (NetlibConnection*)hConns[i]; - if (nlcCheck->handleType != NLH_CONNECTION && nlcCheck->handleType != NLH_BOUNDPORT) { - SetLastError(ERROR_INVALID_DATA); - return 0; - } - FD_SET(nlcCheck->s, fd); - if (si.pending(nlcCheck->hSsl)) - pending++; - } - return 1; -} - -INT_PTR NetlibSelect(WPARAM, LPARAM lParam) -{ - NETLIBSELECT *nls = (NETLIBSELECT*)lParam; - if (nls == NULL || nls->cbSize != sizeof(NETLIBSELECT)) { - SetLastError(ERROR_INVALID_PARAMETER); - return SOCKET_ERROR; - } - - TIMEVAL tv; - tv.tv_sec = nls->dwTimeout/1000; - tv.tv_usec = (nls->dwTimeout%1000)*1000; - - int pending = 0; - fd_set readfd, writefd, exceptfd; - WaitForSingleObject(hConnectionHeaderMutex, INFINITE); - if (!ConnectionListToSocketList(nls->hReadConns, &readfd, pending) - || !ConnectionListToSocketList(nls->hWriteConns, &writefd, pending) - || !ConnectionListToSocketList(nls->hExceptConns, &exceptfd, pending)) - { - ReleaseMutex(hConnectionHeaderMutex); - return SOCKET_ERROR; - } - ReleaseMutex(hConnectionHeaderMutex); - if (pending) - return 1; - - return select(0, &readfd, &writefd, &exceptfd, nls->dwTimeout == INFINITE ? NULL : &tv); -} - -INT_PTR NetlibSelectEx(WPARAM, LPARAM lParam) -{ - NETLIBSELECTEX *nls = (NETLIBSELECTEX*)lParam; - if (nls == NULL || nls->cbSize != sizeof(NETLIBSELECTEX)) { - SetLastError(ERROR_INVALID_PARAMETER); - return SOCKET_ERROR; - } - - TIMEVAL tv; - tv.tv_sec = nls->dwTimeout / 1000; - tv.tv_usec = (nls->dwTimeout % 1000) * 1000; - WaitForSingleObject(hConnectionHeaderMutex, INFINITE); - - int pending = 0; - fd_set readfd, writefd, exceptfd; - if (!ConnectionListToSocketList(nls->hReadConns, &readfd, pending) - || !ConnectionListToSocketList(nls->hWriteConns, &writefd, pending) - || !ConnectionListToSocketList(nls->hExceptConns, &exceptfd, pending)) - { - ReleaseMutex(hConnectionHeaderMutex); - return SOCKET_ERROR; - } - ReleaseMutex(hConnectionHeaderMutex); - - int rc = (pending) ? pending : select(0, &readfd, &writefd, &exceptfd, nls->dwTimeout == INFINITE ? NULL : &tv); - - WaitForSingleObject(hConnectionHeaderMutex, INFINITE); - /* go thru each passed HCONN array and grab its socket handle, then give it to FD_ISSET() - to see if an event happened for that socket, if it has it will be returned as TRUE (otherwise not) - This happens for read/write/except */ - NetlibConnection *conn = NULL; - int j; - for (j = 0; j < FD_SETSIZE; j++) { - conn = (NetlibConnection*)nls->hReadConns[j]; - if (conn == NULL || conn == INVALID_HANDLE_VALUE) break; - - if (si.pending(conn->hSsl)) - nls->hReadStatus[j] = TRUE; - if (conn->usingHttpGateway && conn->nlhpi.szHttpGetUrl == NULL && conn->dataBuffer == NULL) - nls->hReadStatus[j] = (conn->pHttpProxyPacketQueue != NULL); - else - nls->hReadStatus[j] = FD_ISSET(conn->s, &readfd); - } - for (j = 0; j < FD_SETSIZE; j++) { - conn = (NetlibConnection*)nls->hWriteConns[j]; - if (conn == NULL || conn == INVALID_HANDLE_VALUE) break; - nls->hWriteStatus[j] = FD_ISSET(conn->s, &writefd); - } - for (j = 0; j < FD_SETSIZE; j++) { - conn = (NetlibConnection*)nls->hExceptConns[j]; - if (conn == NULL || conn == INVALID_HANDLE_VALUE) break; - nls->hExceptStatus[j] = FD_ISSET(conn->s, &exceptfd); - } - ReleaseMutex(hConnectionHeaderMutex); - return rc; -} - -bool NetlibStringToAddress(const char* str, SOCKADDR_INET_M* addr) -{ - if (!str) return false; - - int len = sizeof(SOCKADDR_INET_M); - return !WSAStringToAddressA((char*)str, AF_INET6, NULL, (PSOCKADDR)addr, &len); -} - -char* NetlibAddressToString(SOCKADDR_INET_M* addr) -{ - char saddr[128]; - DWORD len = sizeof(saddr); - if (!WSAAddressToStringA((PSOCKADDR)addr, sizeof(*addr), NULL, saddr, &len)) - return mir_strdup(saddr); - - if (addr->si_family == AF_INET) { - char *szIp = inet_ntoa(addr->Ipv4.sin_addr); - if (addr->Ipv4.sin_port != 0) { - mir_snprintf(saddr, SIZEOF(saddr), "%s:%d", szIp, htons(addr->Ipv4.sin_port)); - return mir_strdup(saddr); - } - return mir_strdup(szIp); - } - return NULL; -} - -void NetlibGetConnectionInfo(NetlibConnection* nlc, NETLIBCONNINFO *connInfo) -{ - if (!nlc || !connInfo || connInfo->cbSize < sizeof(NETLIBCONNINFO)) return; - - SOCKADDR_INET_M sin = { 0 }; - int len = sizeof(sin); - if (!getsockname(nlc->s, (PSOCKADDR)&sin, &len)) { - connInfo->wPort = ntohs(sin.Ipv4.sin_port); - connInfo->dwIpv4 = sin.si_family == AF_INET ? htonl(sin.Ipv4.sin_addr.s_addr) : 0; - - char *szTmp = NetlibAddressToString(&sin); - strncpy(connInfo->szIpPort, szTmp, sizeof(connInfo->szIpPort)); - connInfo->szIpPort[sizeof(connInfo->szIpPort) - 1] = 0; - mir_free(szTmp); - } -} - -inline bool IsAddrGlobal(const IN6_ADDR *a) -{ - unsigned char High = a->s6_bytes[0] & 0xf0; - return High != 0 && High != 0xf0; -} - -static NETLIBIPLIST* GetMyIpv6(unsigned flags) -{ - addrinfo *air = NULL, *ai, hints = { 0 }; - const char *szMyHost = ""; - - hints.ai_family = AF_UNSPEC; - hints.ai_flags = AI_PASSIVE; - - if (GetAddrInfoA(szMyHost, NULL, &hints, &air)) - return NULL; - - unsigned n = 0; - for (ai = air; ai; ai = ai->ai_next) { - SOCKADDR_INET_M *iaddr = (SOCKADDR_INET_M*)ai->ai_addr; - if (ai->ai_family == AF_INET || (ai->ai_family == AF_INET6 && (!(flags & 1) || IsAddrGlobal(&iaddr->Ipv6.sin6_addr)))) - ++n; - } - - NETLIBIPLIST *addr = (NETLIBIPLIST*)mir_calloc(n * 64 + 4); - addr->cbNum = n; - - unsigned i = 0; - for (ai = air; ai; ai = ai->ai_next) { - SOCKADDR_INET_M *iaddr = (SOCKADDR_INET_M*)ai->ai_addr; - if (ai->ai_family == AF_INET || - (ai->ai_family == AF_INET6 && - (!(flags & 1) || IsAddrGlobal(&iaddr->Ipv6.sin6_addr)))) - { - char *szIp = NetlibAddressToString(iaddr); - if (szIp) - strncpy_s(addr->szIp[i++], szIp, _TRUNCATE); - mir_free(szIp); - } - } - FreeAddrInfoA(air); - return addr; -} - -static NETLIBIPLIST* GetMyIpv4(void) -{ - char hostname[256] = ""; - - gethostname(hostname, sizeof(hostname)); - PHOSTENT he = gethostbyname(hostname); - - unsigned n; - for (n = 0; he->h_addr_list[n]; ++n) - ; - - NETLIBIPLIST *addr = (NETLIBIPLIST*)mir_calloc(n * 64 + 4); - addr->cbNum = n; - - for (unsigned i = 0; i < n; i++) - strncpy_s(addr->szIp[i], inet_ntoa(*(PIN_ADDR)he->h_addr_list[i]), _TRUNCATE); - - return addr; -} - -NETLIBIPLIST* GetMyIp(unsigned flags) -{ - return GetMyIpv6(flags); -} diff --git a/src/modules/netlib/netlibupnp.cpp b/src/modules/netlib/netlibupnp.cpp deleted file mode 100644 index d3f30498d6..0000000000 --- a/src/modules/netlib/netlibupnp.cpp +++ /dev/null @@ -1,826 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "netlib.h" - -static const char search_request_msg[] = - "M-SEARCH * HTTP/1.1\r\n" - "HOST: 239.255.255.250:1900\r\n" - "MAN: \"ssdp:discover\"\r\n" - "MX: 1\r\n" - "ST: urn:schemas-upnp-org:service:%s\r\n" - "\r\n"; - -static const char xml_get_hdr[] = - "GET %s HTTP/1.1\r\n" - "HOST: %s:%u\r\n" - "ACCEPT-LANGUAGE: *\r\n\r\n"; - -static const char soap_post_hdr[] = - "POST %s HTTP/1.1\r\n" - "HOST: %s:%u\r\n" - "CONTENT-LENGTH: %u\r\n" - "CONTENT-TYPE: text/xml; charset = \"utf-8\"\r\n" - "SOAPACTION: \"%s#%s\"\r\n\r\n" - "%s"; - -static const char soap_post_hdr_m[] = - "M-POST %s URL HTTP/1.1\r\n" - "HOST: %s:%u\r\n" - "CONTENT-LENGTH: %u\r\n" - "CONTENT-TYPE: text/xml; charset = \"utf-8\"\r\n" - "MAN: \"http://schemas.xmlsoap.org/soap/envelope/\"; ns = 01\r\n" - "01-SOAPACTION: \"%s#%s\"\r\n\r\n" - "%s"; - -static const char search_device[] = - "%s"; - -static const char soap_action[] = - "\r\n" - "\r\n" - " \r\n" - " \r\n" - "%s" - " \r\n" - " \r\n" - "\r\n"; - -static const char soap_query[] = - "\r\n" - " \r\n" - " \r\n" - " %s\r\n" - " \r\n" - " \r\n" - "\r\n"; - -static const char add_port_mapping[] = - " \r\n" - " %i\r\n" - " %s\r\n" - " %i\r\n" - " %s\r\n" - " 1\r\n" - " Miranda\r\n" - " 0\r\n"; - -static const char delete_port_mapping[] = - " \r\n" - " %i\r\n" - " %s\r\n"; - -static const char get_port_mapping[] = - " %i\r\n"; - -static bool gatewayFound; -static SOCKADDR_IN locIP; -static time_t lastDiscTime; -static int expireTime = 120; - -static int retryCount; -static SOCKET sock = INVALID_SOCKET; -static char szConnHost[256]; -static unsigned short sConnPort; - -static WORD *portList; -static unsigned numports, numportsAlloc; -static HANDLE portListMutex; - -static char szCtlUrl[256], szDev[256]; - -typedef enum -{ - DeviceGetReq, - ControlAction, - ControlQuery -} ReqType; - -static bool txtParseParam(char* szData, char* presearch, - char* start, char* finish, char* param, size_t size) -{ - char *cp, *cp1; - size_t len; - - *param = 0; - - if (presearch != NULL) { - cp1 = strstr(szData, presearch); - if (cp1 == NULL) return false; - } - else - cp1 = szData; - - cp = strstr(cp1, start); - if (cp == NULL) return false; - cp += mir_strlen(start); - while (*cp == ' ') ++cp; - - cp1 = strstr(cp, finish); - if (cp1 == NULL) return false; - while (*(cp1-1) == ' ' && cp1 > cp) --cp1; - - len = min((size_t)(cp1 - cp), size-1); - strncpy(param, cp, len); - param[len] = 0; - - return true; -} - -void parseURL(char* szUrl, char* szHost, unsigned short* sPort, char* szPath) -{ - char *ppath, *phost, *pport; - int sz; - - phost = strstr(szUrl, "://"); - if (phost == NULL) phost = szUrl; - else phost += 3; - - ppath = strchr(phost, '/'); - if (ppath == NULL) ppath = phost + mir_strlen(phost); - - pport = strchr(phost, ':'); - if (pport == NULL) pport = ppath; - - if (szHost != NULL) { - sz = pport - phost + 1; - if (sz > 256) sz = 256; - strncpy(szHost, phost, sz); - szHost[sz - 1] = 0; - } - - if (sPort != NULL) { - if (pport < ppath) { - long prt = atol(pport + 1); - *sPort = prt != 0 ? (unsigned short)prt : 80; - } - else - *sPort = 80; - } - - if (szPath != NULL) { - strncpy(szPath, ppath, 256); - szPath[255] = 0; - } -} - -static void LongLog(char* szData) -{ - CallService(MS_NETLIB_LOG, 0, (LPARAM)szData); -} - -static void closeRouterConnection(void) -{ - if (sock != INVALID_SOCKET) { - closesocket(sock); - sock = INVALID_SOCKET; - } -} - -static void validateSocket(void) -{ - static const TIMEVAL tv = { 0, 0 }; - fd_set rfd; - char buf[4]; - bool opened; - - if (sock == INVALID_SOCKET) - return; - - FD_ZERO(&rfd); - FD_SET(sock, &rfd); - - switch (select(1, &rfd, NULL, NULL, &tv)) { - case SOCKET_ERROR: - opened = false; - break; - - case 0: - opened = true; - break; - - case 1: - opened = recv(sock, buf, 1, MSG_PEEK) > 0; - break; - } - - if (!opened) - closeRouterConnection(); -} - -static int httpTransact(char* szUrl, char* szResult, int resSize, char* szActionName, ReqType reqtype) -{ - // Parse URL - char szHost[256], szPath[256], szRes[16]; - int sz = 0, res = 0; - unsigned short sPort; - bool needClose = false; - - const char* szPostHdr = soap_post_hdr; - char* szData = (char*)mir_alloc(4096); - char* szReq = NULL; - - parseURL(szUrl, szHost, &sPort, szPath); - - if (sPort != sConnPort || _stricmp(szHost, szConnHost)) - closeRouterConnection(); - else - validateSocket(); - - while (true) { - retryCount = 0; - switch (reqtype) { - case DeviceGetReq: - sz = mir_snprintf(szData, 4096, xml_get_hdr, szPath, szHost, sPort); - break; - - case ControlAction: - { - char szData1[1024]; - - szReq = mir_strdup(szResult); - sz = mir_snprintf(szData1, SIZEOF(szData1), - soap_action, szActionName, szDev, szReq, szActionName); - - sz = mir_snprintf(szData, 4096, - szPostHdr, szPath, szHost, sPort, - sz, szDev, szActionName, szData1); - } - break; - - case ControlQuery: - { - char szData1[1024]; - - sz = mir_snprintf(szData1, SIZEOF(szData1), - soap_query, szActionName); - - sz = mir_snprintf(szData, 4096, - szPostHdr, szPath, szHost, sPort, - sz, "urn:schemas-upnp-org:control-1-0", "QueryStateVariable", szData1); - } - break; - } - szResult[0] = 0; - { - static const TIMEVAL tv = { 6, 0 }; - static unsigned ttl = 4; - static u_long mode = 1; - fd_set rfd, wfd, efd; - SOCKADDR_IN enetaddr; - -retrycon: - if (sock == INVALID_SOCKET) { - sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - - enetaddr.sin_family = AF_INET; - enetaddr.sin_port = htons(sPort); - enetaddr.sin_addr.s_addr = inet_addr(szHost); - - // Resolve host name if needed - if (enetaddr.sin_addr.s_addr == INADDR_NONE) { - PHOSTENT he = gethostbyname(szHost); - if (he) - enetaddr.sin_addr.s_addr = *(unsigned*)he->h_addr_list[0]; - } - - NetlibLogf(NULL, "UPnP HTTP connection Host: %s Port: %u", szHost, sPort); - - FD_ZERO(&rfd); FD_ZERO(&wfd); FD_ZERO(&efd); - FD_SET(sock, &rfd); FD_SET(sock, &wfd); FD_SET(sock, &efd); - - // Limit the scope of the connection (does not work for - setsockopt(sock, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(unsigned)); - - // Put socket into non-blocking mode for timeout on connect - ioctlsocket(sock, FIONBIO, &mode); - - // Connect to the remote host - if (connect(sock, (SOCKADDR*)&enetaddr, sizeof(enetaddr)) == SOCKET_ERROR) { - int err = WSAGetLastError(); - - // Socket connection failed - if (err != WSAEWOULDBLOCK) { - closeRouterConnection(); - NetlibLogf(NULL, "UPnP connect failed %d", err); - break; - } - // Wait for socket to connect - else if (select(1, &rfd, &wfd, &efd, &tv) != 1) { - closeRouterConnection(); - NetlibLogf(NULL, "UPnP connect timeout"); - break; - } - else if (!FD_ISSET(sock, &wfd)) { - closeRouterConnection(); - NetlibLogf(NULL, "UPnP connect failed"); - break; - } - } - strncpy_s(szConnHost, szHost, _TRUNCATE); - sConnPort = sPort; - } - - if (send(sock, szData, sz, 0) != SOCKET_ERROR) { - char *hdrend = NULL; - int acksz = 0, pktsz = 0; - - if (szActionName == NULL) { - int len = sizeof(locIP); - getsockname(sock, (SOCKADDR*)&locIP, &len); - if (locIP.sin_addr.S_un.S_addr == 0x0100007f) { - struct hostent *he; - - gethostname(szPath, sizeof(szPath)); - he = gethostbyname(szPath); - if (he != NULL) - locIP.sin_addr.S_un.S_addr = *(PDWORD)he->h_addr_list[0]; - } - } - - LongLog(szData); - sz = 0; - while (true) { - int bytesRecv; - - FD_ZERO(&rfd); - FD_SET(sock, &rfd); - - // Wait for the next packet - if (select(1, &rfd, NULL, NULL, &tv) != 1) { - closeRouterConnection(); - NetlibLogf(NULL, "UPnP recieve timeout"); - break; - } - - // - bytesRecv = recv(sock, &szResult[sz], resSize - sz, 0); - - // Connection closed or aborted, all data received - if (bytesRecv == 0 || bytesRecv == SOCKET_ERROR) { - closeRouterConnection(); - if ((bytesRecv == SOCKET_ERROR || sz == 0) && retryCount < 2) { - ++retryCount; - goto retrycon; - } - break; - } - - sz += bytesRecv; - - // Insert null terminator to use string functions - if (sz >= (resSize - 1)) { - szResult[resSize - 1] = 0; - break; - } - else - szResult[sz] = 0; - - // HTTP header found? - if (hdrend == NULL) { - // Find HTTP header end - hdrend = strstr(szResult, "\r\n\r\n"); - if (hdrend == NULL) { - hdrend = strstr(szResult, "\n\n"); - if (hdrend) hdrend += 2; - } - - else - hdrend += 4; - - if (hdrend != NULL) { - // Get packet size if provided - if (txtParseParam(szResult, NULL, "Content-Length:", "\n", szRes, sizeof(szRes)) || - txtParseParam(szResult, NULL, "CONTENT-LENGTH:", "\n", szRes, sizeof(szRes))) { - // Add size of HTTP header to the packet size to compute full transmission size - pktsz = atol(ltrimp(szRes)) + (hdrend - szResult); - } - // Get encoding type if provided - else if (txtParseParam(szResult, NULL, "Transfer-Encoding:", "\n", szRes, sizeof(szRes))) { - if (_stricmp(lrtrimp(szRes), "Chunked") == 0) - acksz = hdrend - szResult; - } - if (txtParseParam(szResult, NULL, "Connection:", "\n", szRes, sizeof(szRes))) { - needClose = (_stricmp(lrtrimp(szRes), "close") == 0); - } - } - } - - // Content-Length bytes reached, all data received - if (sz >= pktsz && pktsz != 0) { - szResult[pktsz] = 0; - break; - } - - // Chunked encoding processing - if (sz > acksz && acksz != 0) { -retry: - // Parse out chunk size - char* data = szResult + acksz; - char* peol1 = data == hdrend ? data - 1 : strchr(data, '\n'); - if (peol1 != NULL) { - char *peol2 = strchr(++peol1, '\n'); - if (peol2 != NULL) { - // Get chunk size - int chunkBytes = strtol(peol1, NULL, 16); - acksz += chunkBytes; - peol2++; - - memmove(data, peol2, mir_strlen(peol2) + 1); - sz -= peol2 - data; - - // Last chunk, all data received - if (chunkBytes == 0) break; - if (sz > acksz) goto retry; - } - } - } - } - LongLog(szResult); - } - else { - if (retryCount < 2) { - closeRouterConnection(); - ++retryCount; - goto retrycon; - } - else - NetlibLogf(NULL, "UPnP send failed %d", WSAGetLastError()); - } - } - txtParseParam(szResult, "HTTP", " ", " ", szRes, sizeof(szRes)); - res = atol(szRes); - if (szActionName != NULL && res == 405 && szPostHdr == soap_post_hdr) - szPostHdr = soap_post_hdr_m; - else - break; - } - - if (needClose) - closeRouterConnection(); - - mir_free(szData); - mir_free(szReq); - return res; -} - -static unsigned getExtIP(void) -{ - char szExtIP[30]; - char* szData = (char*)mir_alloc(4096); szData[0] = 0; - - unsigned extip = 0; - int res = httpTransact(szCtlUrl, szData, 4096, "GetExternalIPAddress", ControlAction); - if (res == 200 && txtParseParam(szData, "", "<", szExtIP, sizeof(szExtIP))) - extip = ntohl(inet_addr(szExtIP)); - - mir_free(szData); - return extip; -} - -static bool getUPnPURLs(char* szUrl, size_t sizeUrl) -{ - char* szData = (char*)mir_alloc(8192); - - gatewayFound = httpTransact(szUrl, szData, 8192, NULL, DeviceGetReq) == 200; - if (gatewayFound) { - char szTemp[256], *rpth; - size_t ctlLen; - - txtParseParam(szData, NULL, "", "", szTemp, sizeof(szTemp)); - strncpy(szCtlUrl, szTemp[0] ? szTemp : szUrl, sizeof(szCtlUrl)); - szCtlUrl[sizeof(szCtlUrl) - 1] = 0; - - mir_snprintf(szTemp, search_device, szDev); - txtParseParam(szData, szTemp, "", "", szUrl, sizeUrl); - - // URL combining per RFC 2396 - if (szUrl[0] != 0) { - if (strstr(szUrl, "://") != NULL) // absolute URI - rpth = szCtlUrl; - else if (strncmp(szUrl, "//", 2) == 0) // relative URI net_path - { - rpth = strstr(szCtlUrl, "//"); - if (rpth == NULL) rpth = szCtlUrl; - } - else if (szUrl[0] == '/') // relative URI abs_path - { - rpth = strstr(szCtlUrl, "//"); - rpth = rpth ? rpth + 2 : szCtlUrl; - - rpth = strchr(rpth, '/'); - if (rpth == NULL) rpth = szCtlUrl + mir_strlen(szCtlUrl); - } - else { // relative URI rel_path - size_t ctlCLen = mir_strlen(szCtlUrl); - rpth = szCtlUrl + ctlCLen; - if (ctlCLen != 0 && *(rpth - 1) != '/') - strncpy(rpth++, "/", sizeof(szCtlUrl) - ctlCLen); - } - - ctlLen = sizeof(szCtlUrl) - (rpth - szCtlUrl); - strncpy(rpth, szUrl, ctlLen); - szCtlUrl[sizeof(szCtlUrl) - 1] = 0; - } - else { - szCtlUrl[0] = 0; - gatewayFound = false; - } - } - mir_free(szData); - - return gatewayFound; -} - -static void discoverUPnP(void) -{ - char* buf; - int buflen; - unsigned i, j, nip = 0; - unsigned* ips = NULL; - - static const unsigned any = INADDR_ANY; - static const TIMEVAL tv = { 1, 600000 }; - - char szUrl[256] = ""; - char hostname[256]; - PHOSTENT he; - fd_set readfd; - - SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - - SOCKADDR_IN enetaddr; - enetaddr.sin_family = AF_INET; - enetaddr.sin_port = htons(1900); - enetaddr.sin_addr.s_addr = inet_addr("239.255.255.250"); - - gethostname(hostname, sizeof(hostname)); - he = gethostbyname(hostname); - - if (he) { - while (he->h_addr_list[nip]) ++nip; - - ips = (unsigned*)mir_alloc(nip * sizeof(unsigned)); - - for (j = 0; j < nip; j++) - ips[j] = *(unsigned*)he->h_addr_list[j]; - } - - buf = (char*)mir_alloc(1500); - - for (i = 3; --i && szUrl[0] == 0;) { - for (j = 0; j < nip; j++) { - if (ips) - setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)&ips[j], sizeof(unsigned)); - - buflen = mir_snprintf(buf, 1500, search_request_msg, "WANIPConnection:1"); - sendto(sock, buf, buflen, 0, (SOCKADDR*)&enetaddr, sizeof(enetaddr)); - LongLog(buf); - - buflen = mir_snprintf(buf, 1500, search_request_msg, "WANPPPConnection:1"); - sendto(sock, buf, buflen, 0, (SOCKADDR*)&enetaddr, sizeof(enetaddr)); - LongLog(buf); - } - - if (Miranda_Terminated()) break; - - FD_ZERO(&readfd); - FD_SET(sock, &readfd); - - while (select(1, &readfd, NULL, NULL, &tv) >= 1) { - buflen = recv(sock, buf, 1500, 0); - if (buflen != SOCKET_ERROR) { - buf[buflen] = 0; - LongLog(buf); - - if (txtParseParam(buf, NULL, "LOCATION:", "\n", szUrl, sizeof(szUrl)) || - txtParseParam(buf, NULL, "Location:", "\n", szUrl, sizeof(szUrl))) { - char age[30]; - char szHostNew[256], szHostExist[256]; - - lrtrim(szUrl); - - parseURL(szUrl, szHostNew, NULL, NULL); - parseURL(szCtlUrl, szHostExist, NULL, NULL); - if (mir_strcmp(szHostNew, szHostExist) == 0) { - gatewayFound = true; - break; - } - - txtParseParam(buf, NULL, "ST:", "\n", szDev, sizeof(szDev)); - txtParseParam(buf, "max-age", " = ", "\n", age, sizeof(age)); - expireTime = atoi(lrtrimp(age)); - lrtrim(szDev); - - if (getUPnPURLs(szUrl, sizeof(szUrl))) { - gatewayFound = getExtIP() != 0; - if (gatewayFound) break; - } - } - } - FD_ZERO(&readfd); - FD_SET(sock, &readfd); - } - } - - mir_free(buf); - mir_free(ips); - setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)&any, sizeof(unsigned)); - closesocket(sock); -} - -static bool findUPnPGateway(void) -{ - if ((time(NULL) - lastDiscTime) >= expireTime) { - WaitForSingleObject(portListMutex, INFINITE); - - time_t curTime = time(NULL); - - if ((curTime - lastDiscTime) >= expireTime) { - gatewayFound = false; - - discoverUPnP(); - lastDiscTime = curTime; - - NetlibLogf(NULL, "UPnP Gateway detected %d, Control URL: %s", gatewayFound, szCtlUrl); - } - - ReleaseMutex(portListMutex); - } - - return gatewayFound; -} - -bool NetlibUPnPAddPortMapping(WORD intport, char *proto, WORD *extport, DWORD *extip, bool search) -{ - int res = 0, i = 5; - - if (findUPnPGateway()) { - char* szData = (char*)mir_alloc(4096); - char szExtIP[30]; - - *extport = intport - 1; - *extip = ntohl(locIP.sin_addr.S_un.S_addr); - - WaitForSingleObject(portListMutex, INFINITE); - - do { - ++*extport; - mir_snprintf(szData, 4096, add_port_mapping, - *extport, proto, intport, inet_ntoa(locIP.sin_addr)); - res = httpTransact(szCtlUrl, szData, 4096, "AddPortMapping", ControlAction); - txtParseParam(szData, NULL, "", "", szExtIP, sizeof(szExtIP)); - - } while (search && res == 500 && atol(szExtIP) == 718 && --i); - - mir_free(szData); - - if (res == 200) { - unsigned ip = getExtIP(); - if (ip) *extip = ip; - - if (numports >= numportsAlloc) - mir_realloc(portList, sizeof(WORD)*(numportsAlloc += 10)); - portList[numports++] = *extport; - } - - ReleaseMutex(portListMutex); - } - - return res == 200; -} - -void NetlibUPnPDeletePortMapping(WORD extport, char* proto) -{ - if (extport == 0) - return; - - // findUPnPGateway(); - - if (gatewayFound) { - unsigned i; - char* szData = (char*)mir_alloc(4096); - - WaitForSingleObject(portListMutex, INFINITE); - mir_snprintf(szData, 4096, delete_port_mapping, extport, proto); - httpTransact(szCtlUrl, szData, 4096, "DeletePortMapping", ControlAction); - - for (i = 0; i < numports; i++) - if (portList[i] == extport && --numports > 0) - memmove(&portList[i], &portList[i + 1], (numports - i) * sizeof(WORD)); - - mir_free(szData); - ReleaseMutex(portListMutex); - } -} - -void NetlibUPnPCleanup(void*) -{ - // upnp is disabled globally, no need for a cleanup - if (db_get_b(NULL, "Netlib", "NLEnableUPnP", 1) == 0) - return; - - { - int incoming = 0; - mir_cslock lck(csNetlibUser); - for (int i = 0; i < netlibUser.getCount(); i++) - if (netlibUser[i]->user.flags & NUF_INCOMING) { - incoming = 1; - break; - } - - if (!incoming) - return; - } - - if (findUPnPGateway()) { - char *szData = (char*)alloca(4096); - char buf[50], lip[50]; - unsigned j = 0, k, num = 100; - - strncpy_s(lip, inet_ntoa(locIP.sin_addr), _TRUNCATE); - - WaitForSingleObject(portListMutex, INFINITE); - - if (httpTransact(szCtlUrl, szData, 4096, "PortMappingNumberOfEntries", ControlQuery) == 200 && - txtParseParam(szData, "QueryStateVariableResponse", "", "<", buf, sizeof(buf))) - num = atol(buf); - - WORD ports[30]; - for (unsigned i = 0; i < num && !Miranda_Terminated(); i++) { - mir_snprintf(szData, 4096, get_port_mapping, i); - - ReleaseMutex(portListMutex); - WaitForSingleObject(portListMutex, INFINITE); - - if (httpTransact(szCtlUrl, szData, 4096, "GetGenericPortMappingEntry", ControlAction) != 200) - break; - - if (!txtParseParam(szData, "", "<", buf, sizeof(buf)) || mir_strcmp(buf, "Miranda") != 0) - continue; - - if (!txtParseParam(szData, "", "<", buf, sizeof(buf)) || mir_strcmp(buf, lip) != 0) - continue; - - if (txtParseParam(szData, "", "<", buf, sizeof(buf))) { - WORD mport = (WORD)atol(buf); - - if (j >= SIZEOF(ports)) - break; - - for (k = 0; k < numports; ++k) - if (portList[k] == mport) - break; - - if (k >= numports) - ports[j++] = mport; - } - } - - ReleaseMutex(portListMutex); - - for (unsigned i = 0; i < j && !Miranda_Terminated(); i++) - NetlibUPnPDeletePortMapping(ports[i], "TCP"); - } -} - -void NetlibUPnPInit(void) -{ - numports = 0; - numportsAlloc = 10; - portList = (WORD*)mir_alloc(sizeof(WORD)*numportsAlloc); - - portListMutex = CreateMutex(NULL, FALSE, NULL); -} - -void NetlibUPnPDestroy(void) -{ - mir_free(portList); - CloseHandle(portListMutex); -} diff --git a/src/modules/options/descbutton.cpp b/src/modules/options/descbutton.cpp deleted file mode 100644 index f6b66eb041..0000000000 --- a/src/modules/options/descbutton.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -Copyright (c) 2007 Artem Shpynov -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "m_descbutton.h" - -extern HINSTANCE hInst; - -//////////////////////////////////////////////////////////////////////////////////// -// Internals - -#define DBC_BORDER_SIZE 7 -#define DBC_VSPACING 15 -#define DBC_HSPACING 10 - -static LRESULT CALLBACK MDescButtonWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - -// structure is used for storing list of tab info -struct MDescButtonCtrl -{ - HWND hwnd; - BOOL bSharedIcon; - HICON hIcon; - TCHAR *lpzTitle; - TCHAR *lpzDescription; - - // UI info - BOOL bMouseInside; - RECT rc; - int width, height; - HFONT hfntTitle; - - // control colors - RGBQUAD rgbBkgTop, rgbBkgBottom; - RGBQUAD rgbSelTop, rgbSelBottom; - RGBQUAD rgbHotTop, rgbHotBottom; - COLORREF clText, clBackground; - COLORREF clSelText, clSelBorder; - COLORREF clHotText, clHotBorder; - - // fonts - HFONT hFont; -}; - -int LoadDescButtonModule() -{ - WNDCLASSEX wc; - - memset(&wc, 0, sizeof(wc)); - wc.cbSize = sizeof(wc); - wc.lpszClassName = MIRANDADESCBUTTONCLASS; - wc.lpfnWndProc = MDescButtonWndProc; - wc.hCursor = LoadCursor(NULL, IDC_HAND); - wc.cbWndExtra = sizeof(MDescButtonCtrl *); - wc.hbrBackground = 0; //GetStockObject(WHITE_BRUSH); - wc.style = CS_GLOBALCLASS | CS_SAVEBITS; - RegisterClassEx(&wc); - return 0; -} - -static void MDescButton_SetupColors(MDescButtonCtrl *dat) -{ - COLORREF cl = GetSysColor(COLOR_WINDOW); - dat->rgbBkgBottom.rgbRed = (dat->rgbBkgTop.rgbRed = GetRValue(cl)) * .95; - dat->rgbBkgBottom.rgbGreen = (dat->rgbBkgTop.rgbGreen = GetGValue(cl)) * .95; - dat->rgbBkgBottom.rgbBlue = (dat->rgbBkgTop.rgbBlue = GetBValue(cl)) * .95; - - cl = GetSysColor(COLOR_HIGHLIGHT); - dat->rgbSelTop.rgbRed = (dat->rgbSelBottom.rgbRed = GetRValue(cl)) * .75; - dat->rgbSelTop.rgbGreen = (dat->rgbSelBottom.rgbGreen = GetGValue(cl)) * .75; - dat->rgbSelTop.rgbBlue = (dat->rgbSelBottom.rgbBlue = GetBValue(cl)) * .75; - - dat->rgbHotTop.rgbRed = (dat->rgbSelTop.rgbRed + 255) / 2; - dat->rgbHotTop.rgbGreen = (dat->rgbSelTop.rgbGreen + 255) / 2; - dat->rgbHotTop.rgbBlue = (dat->rgbSelTop.rgbBlue + 255) / 2; - - dat->rgbHotBottom.rgbRed = (dat->rgbSelBottom.rgbRed + 255) / 2; - dat->rgbHotBottom.rgbGreen = (dat->rgbSelBottom.rgbGreen + 255) / 2; - dat->rgbHotBottom.rgbBlue = (dat->rgbSelBottom.rgbBlue + 255) / 2; - - dat->clBackground = GetSysColor(COLOR_3DFACE); - dat->clText = GetSysColor(COLOR_WINDOWTEXT); - dat->clSelText = GetSysColor(COLOR_HIGHLIGHTTEXT); - dat->clSelBorder = RGB(dat->rgbSelTop.rgbRed, dat->rgbSelTop.rgbGreen, dat->rgbSelTop.rgbBlue); - dat->clHotBorder = RGB(dat->rgbHotTop.rgbRed, dat->rgbHotTop.rgbGreen, dat->rgbHotTop.rgbBlue); - - if (!dat->hFont) dat->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); -} - -static void MDescButton_FillRect(HDC hdc, int x, int y, int width, int height, COLORREF cl) -{ - int oldMode = SetBkMode(hdc, OPAQUE); - COLORREF oldColor = SetBkColor(hdc, cl); - - RECT rc; SetRect(&rc, x, y, x + width, y + height); - ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, "", 0, 0); - - SetBkMode(hdc, oldMode); - SetBkColor(hdc, oldColor); -} - -static void MDescButton_DrawGradient(HDC hdc, int x, int y, int width, int height, RGBQUAD *rgb0, RGBQUAD *rgb1) -{ - int oldMode = SetBkMode(hdc, OPAQUE); - COLORREF oldColor = SetBkColor(hdc, 0); - - RECT rc; SetRect(&rc, x, 0, x + width, 0); - for (int i = y + height; --i >= y;) { - COLORREF color = RGB( - ((height - i - 1)*rgb0->rgbRed + i*rgb1->rgbRed) / height, - ((height - i - 1)*rgb0->rgbGreen + i*rgb1->rgbGreen) / height, - ((height - i - 1)*rgb0->rgbBlue + i*rgb1->rgbBlue) / height); - rc.top = rc.bottom = i; - ++rc.bottom; - SetBkColor(hdc, color); - ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, "", 0, 0); - } - - SetBkMode(hdc, oldMode); - SetBkColor(hdc, oldColor); -} - -static LRESULT MDescButton_OnPaint(HWND hwndDlg, MDescButtonCtrl *dat, UINT msg, WPARAM wParam, LPARAM lParam) -{ - PAINTSTRUCT ps; - HDC hdc = BeginPaint(hwndDlg, &ps); - HDC tempDC = CreateCompatibleDC(hdc); - - SIZE titleSize = { 0 }; - - HBITMAP hBmp = CreateCompatibleBitmap(hdc, dat->width, dat->height); - HBITMAP hOldBmp = (HBITMAP)SelectObject(tempDC, hBmp); - - RECT temprc; - temprc.left = 0; - temprc.right = dat->width; - temprc.top = 0; - - // Draw background - if (dat->bMouseInside || (GetFocus() == hwndDlg)) { - MDescButton_FillRect(tempDC, 0, 0, dat->width, dat->height, dat->clSelBorder); - MDescButton_DrawGradient(tempDC, 1, 1, dat->width - 2, dat->height - 2, &dat->rgbSelTop, &dat->rgbSelBottom); - SetTextColor(tempDC, dat->clSelText); - } - else { - MDescButton_FillRect(tempDC, 0, 0, dat->width, dat->height, dat->clBackground); - SetTextColor(tempDC, dat->clText); - } - - if (dat->hIcon) - DrawIcon(tempDC, DBC_BORDER_SIZE, DBC_BORDER_SIZE, dat->hIcon); - - HFONT hfntSave = (HFONT)SelectObject(tempDC, dat->hFont); - SetBkMode(tempDC, TRANSPARENT); - - if (dat->lpzTitle) { - LOGFONT lf; - GetObject(dat->hFont, sizeof(lf), &lf); - lf.lfWeight = FW_BOLD; - lf.lfHeight *= 1.5; - HFONT hfntSave = (HFONT)SelectObject(tempDC, CreateFontIndirect(&lf)); - - RECT textRect; - textRect.left = DBC_BORDER_SIZE + (dat->hIcon ? 32 + DBC_VSPACING : 0); - textRect.right = dat->width - DBC_BORDER_SIZE; - textRect.top = DBC_BORDER_SIZE; - textRect.bottom = dat->height - DBC_BORDER_SIZE; - DrawText(tempDC, dat->lpzTitle, -1, &textRect, DT_TOP | DT_LEFT | DT_END_ELLIPSIS); - GetTextExtentPoint32(tempDC, dat->lpzTitle, (int)mir_tstrlen(dat->lpzTitle), &titleSize); - - DeleteObject(SelectObject(tempDC, hfntSave)); - } - - if (dat->lpzDescription) { - RECT textRect; - textRect.left = DBC_BORDER_SIZE + (dat->hIcon ? 32 + DBC_VSPACING : 0); - textRect.right = dat->width - DBC_BORDER_SIZE; - textRect.top = DBC_BORDER_SIZE + titleSize.cy ? titleSize.cy + DBC_HSPACING : 0; - textRect.bottom = dat->height - DBC_BORDER_SIZE; - DrawText(tempDC, dat->lpzDescription, -1, &textRect, DT_TOP | DT_LEFT | DT_WORDBREAK | DT_END_ELLIPSIS); - GetTextExtentPoint32(tempDC, dat->lpzTitle, (int)mir_tstrlen(dat->lpzTitle), &titleSize); - } - - SelectObject(tempDC, hfntSave); - - //Copy to output - BitBlt(hdc, dat->rc.left, dat->rc.top, dat->width, dat->height, tempDC, 0, 0, SRCCOPY); - SelectObject(tempDC, hOldBmp); - DeleteObject(hBmp); - DeleteDC(tempDC); - EndPaint(hwndDlg, &ps); - - return TRUE; -} - -static LRESULT CALLBACK MDescButtonWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - MDescButtonCtrl *dat = (MDescButtonCtrl *)GetWindowLongPtr(hwndDlg, 0); - switch (msg) { - case WM_NCCREATE: - dat = (MDescButtonCtrl*)mir_alloc(sizeof(MDescButtonCtrl)); - if (dat == NULL) - return FALSE; - - memset(dat, 0, sizeof(MDescButtonCtrl)); - SetWindowLongPtr(hwndDlg, 0, (LONG_PTR)dat); - MDescButton_SetupColors(dat); - return TRUE; - - case WM_SETFONT: - dat->hFont = (HFONT)wParam; - break; - - case WM_SIZE: - GetClientRect(hwndDlg, &dat->rc); - dat->width = dat->rc.right - dat->rc.left; - dat->height = dat->rc.bottom - dat->rc.top; - return TRUE; - - case WM_THEMECHANGED: - case WM_STYLECHANGED: - MDescButton_SetupColors(dat); - return TRUE; - - case WM_MOUSEMOVE: - if (!dat->bMouseInside) { - TRACKMOUSEEVENT tme = { 0 }; - tme.cbSize = sizeof(tme); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = hwndDlg; - _TrackMouseEvent(&tme); - dat->bMouseInside = TRUE; - RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); - } - return 0; - - case WM_MOUSELEAVE: - dat->bMouseInside = FALSE; - RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); - return 0; - - case WM_LBUTTONUP: - SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(hwndDlg, GWL_ID), 0), 0); - return 0; - - case WM_ERASEBKGND: - return 1; - - case WM_NCPAINT: - InvalidateRect(hwndDlg, NULL, FALSE); - break; - - case WM_PAINT: - MDescButton_OnPaint(hwndDlg, dat, msg, wParam, lParam); - break; - - case DBCM_SETTITLE: - if (dat->lpzTitle) - mir_free(dat->lpzTitle); - if (wParam & MDBCF_UNICODE) - dat->lpzTitle = mir_u2t((WCHAR *)lParam); - else - dat->lpzTitle = mir_a2t((char *)lParam); - RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); - return TRUE; - - case DBCM_SETDESCRIPTION: - if (dat->lpzDescription) - mir_free(dat->lpzDescription); - if (wParam & MDBCF_UNICODE) - dat->lpzDescription = mir_u2t((WCHAR *)lParam); - else - dat->lpzDescription = mir_a2t((char *)lParam); - RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); - return TRUE; - - case DBCM_SETICON: - if (dat->hIcon && !dat->bSharedIcon) - DestroyIcon(dat->hIcon); - - if (wParam & MDBCF_SHAREDICON) { - dat->bSharedIcon = TRUE; - dat->hIcon = (HICON)lParam; - } - else { - dat->bSharedIcon = FALSE; - dat->hIcon = CopyIcon((HICON)lParam); - } - RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); - return TRUE; - - case WM_DESTROY: - if (dat->lpzTitle) - mir_free(dat->lpzTitle); - if (dat->lpzDescription) - mir_free(dat->lpzDescription); - if (dat->hIcon && !dat->bSharedIcon) - DestroyIcon(dat->hIcon); - mir_free(dat); - return TRUE; - } - - return DefWindowProc(hwndDlg, msg, wParam, lParam); -} diff --git a/src/modules/options/filter.cpp b/src/modules/options/filter.cpp deleted file mode 100644 index 982fe77399..0000000000 --- a/src/modules/options/filter.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "filter.h" - -CPageList filterStrings(1); - -void AddFilterString(const PageHash key, TCHAR *data) -{ - if (ContainsFilterString(key, data)) return; - - CPageKeywords * values = filterStrings[key]; - if (values == NULL) { - values = new CPageKeywords(key); - filterStrings.insert(values); - } - values->AddKeyWord(data); -} - -void ClearFilterStrings() -{ - filterStrings.destroy(); -} - -BOOL ContainsFilterString(const PageHash key, TCHAR *data) -{ - CPageKeywords* values = filterStrings[key]; - return (values) ? values->ContainsString(data) : FALSE; -} - -void AddTreeViewNodes(HWND hWndDlg, PageHash key, HTREEITEM root) -{ - if (root) { - TCHAR title[2048] = {0}; - - TVITEM item = {0}; - item.mask = TVIF_TEXT; - item.hItem = root; - item.pszText = title; - item.cchTextMax = SIZEOF(title); - - if (TreeView_GetItem(hWndDlg, &item)) - if (mir_tstrlen(title) > 0) - AddFilterString(key, title); - - HTREEITEM child = root; - while (child) { - child = TreeView_GetNextItem(hWndDlg, child, TVGN_CHILD); - AddTreeViewNodes(hWndDlg, key, child); - } - - AddTreeViewNodes(hWndDlg, key, TreeView_GetNextSibling(hWndDlg, root)); - } -} - -void AddDialogString(HWND hWndDlg, const PageHash key) -{ - TCHAR title[2048]; - GetWindowText(hWndDlg, title, SIZEOF(title)); - if (mir_tstrlen(title) > 0) - AddFilterString(key, title); - - TCHAR szClass[64]; - GetClassName(hWndDlg, szClass, SIZEOF(szClass)); - - if (mir_tstrcmpi(szClass, _T("SysTreeView32")) == 0) { - HTREEITEM hItem = TreeView_GetRoot(hWndDlg); - AddTreeViewNodes(hWndDlg, key, hItem); - return; - } - - if (mir_tstrcmpi(szClass, _T("listbox")) == 0) { - if (GetWindowStyle(hWndDlg) & LBS_HASSTRINGS) { - int count = ListBox_GetCount(hWndDlg); - for (int i=0; i < count; i++) { - title[0] = 0; //safety - int res = ListBox_GetText(hWndDlg, i, title); - if (res != LB_ERR) { - title[SIZEOF(title) - 1] = 0; - if (mir_tstrlen(title) > 0) - AddFilterString(key, title); - } - } - } - return; - } - - if (mir_tstrcmpi(szClass, _T("SysListView32")) == 0) { - int count = ListView_GetItemCount(hWndDlg); - for (int i=0; i < count; i++) { - title[0] = 0; //safety - ListView_GetItemText(hWndDlg, i, 0, title, SIZEOF(title)); - - if (mir_tstrlen(title) > 0) - AddFilterString(key, title); - } - return; - } - - if (mir_tstrcmpi(szClass, _T("combobox")) == 0) { - if (GetWindowStyle(hWndDlg) & CBS_HASSTRINGS) { - int count = ComboBox_GetCount(hWndDlg); - for (int i=0; i < count; i++) { - title[0] = 0; //safety - int res = ComboBox_GetLBText(hWndDlg, i, title); - if (res != CB_ERR) { - title[SIZEOF(title) - 1] = 0; - - if (mir_tstrlen(title) > 0) - AddFilterString(key, title); - } - } - } - } -} - -static BOOL CALLBACK GetDialogStringsCallback(HWND hWnd, LPARAM lParam) -{ - AddDialogString(hWnd, lParam); - - return TRUE; -} - -void GetDialogStrings(int enableKeywordFiltering, const PageHash key, TCHAR *pluginName, HWND hWnd, TCHAR *group, TCHAR *title, TCHAR *tab, TCHAR *name) -{ - AddFilterString(key, pluginName); //add the plugin name as keyword - if (group) AddFilterString(key, group); - if (title) AddFilterString(key, title); - if (tab) AddFilterString(key, tab); - if (name) AddFilterString(key, name); - - if ((enableKeywordFiltering) && (hWnd != 0)) { - AddDialogString(hWnd, key); - - EnumChildWindows(hWnd, GetDialogStringsCallback, (LPARAM) key); - } -} diff --git a/src/modules/options/filter.h b/src/modules/options/filter.h deleted file mode 100644 index 9317547726..0000000000 --- a/src/modules/options/filter.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 M_OPTIONS_FILTERING_H -#define M_OPTIONS_FILTERING_H - -extern HANDLE hOptionsInitialize; - -typedef DWORD PageHash; - -void AddFilterString(const PageHash key, const TCHAR *data); -BOOL ContainsFilterString(const PageHash key, TCHAR *data); -void ClearFilterStrings(); -void GetDialogStrings(int enableKeywordFiltering, const PageHash key, TCHAR *pluginName, HWND hWnd, TCHAR *group, TCHAR *title, TCHAR *tab, TCHAR *name); - -_inline TCHAR *_tcslwr_locale(TCHAR *buf) -{ - LCMapString(Langpack_GetDefaultLocale() , LCMAP_LOWERCASE, buf, (int)mir_tstrlen(buf), buf, (int)mir_tstrlen(buf)); - return buf; -} - -typedef LIST KeywordList; -class CPageKeywords -{ - PageHash _pageHashKey; - KeywordList _pageKeyWords; - static int _KeyWordsSortFunc(const TCHAR* p1, const TCHAR* p2) { return mir_tstrcmp(p1, p2); }; - -public: - CPageKeywords(PageHash pageHashKey) : _pageHashKey(pageHashKey), _pageKeyWords(1, _KeyWordsSortFunc) {}; - ~CPageKeywords() - { - for (int j = 0; j < _pageKeyWords.getCount(); j++) - mir_free(_pageKeyWords[j]); - }; - - void AddKeyWord(TCHAR *ptKeyWord) - { - TCHAR *plwrWord = _tcslwr_locale(mir_tstrdup(ptKeyWord)); - if (_pageKeyWords.getIndex(plwrWord) == -1) - _pageKeyWords.insert(plwrWord); - else - mir_free(plwrWord); - }; - - BOOL ContainsString(TCHAR *data) - { - for (int i=0; i < _pageKeyWords.getCount(); i++) - if (_tcsstr(_pageKeyWords[i], data)) - return TRUE; - return FALSE; - } - static int PageSortFunc(const CPageKeywords* p1, const CPageKeywords* p2) - { - if (p1->_pageHashKey < p2->_pageHashKey) { return -1; } - else if (p1->_pageHashKey > p2->_pageHashKey) { return 1; } - return 0; - } -}; - -class CPageList : public OBJLIST -{ - CPageList(); -public: - CPageList( int aincr, FTSortFunc afunc = CPageKeywords::PageSortFunc) : OBJLIST(aincr, afunc) {}; - CPageKeywords * operator[](PageHash key) - { - CPageKeywords keyToSearch(key); - return this->find(&keyToSearch); - } - ~CPageList() {}; -}; - -#endif //M_OPTIONS_FILTERING_H diff --git a/src/modules/options/headerbar.cpp b/src/modules/options/headerbar.cpp deleted file mode 100644 index fe0c0bd2da..0000000000 --- a/src/modules/options/headerbar.cpp +++ /dev/null @@ -1,349 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -Copyright (c) 2007 Artem Shpynov -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "m_iconheader.h" - -extern HINSTANCE hInst; - -static BOOL IsAeroMode() -{ - BOOL result; - return dwmIsCompositionEnabled && (dwmIsCompositionEnabled(&result) == S_OK) && result; -} - -static BOOL IsVSMode() -{ - return IsWinVerVistaPlus() && IsThemeActive(); -} - -//////////////////////////////////////////////////////////////////////////////////// -// Internals - -static LRESULT CALLBACK MHeaderbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - -// structure is used for storing list of tab info -struct MHeaderbarCtrl : public MZeroedObject -{ - MHeaderbarCtrl() {} - ~MHeaderbarCtrl() { mir_free(controlsToRedraw); } - - HWND hwnd; - - // UI info - RECT rc; - int width, height; - HICON hIcon; - - // control colors - RGBQUAD rgbBkgTop, rgbBkgBottom; - COLORREF clText; - - int nControlsToRedraw; - HWND *controlsToRedraw; - - // fonts - HFONT hFont; -}; - -int LoadHeaderbarModule() -{ - WNDCLASSEX wc = { 0 }; - wc.cbSize = sizeof(wc); - wc.lpszClassName = _T("MHeaderbarCtrl"); - wc.lpfnWndProc = MHeaderbarWndProc; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.cbWndExtra = sizeof(MHeaderbarCtrl*); - wc.style = CS_GLOBALCLASS|CS_SAVEBITS; - RegisterClassEx(&wc); - return 0; -} - -static void MHeaderbar_SetupColors(MHeaderbarCtrl *dat) -{ - COLORREF cl = GetSysColor(COLOR_WINDOW); - dat->rgbBkgBottom.rgbRed = (dat->rgbBkgTop.rgbRed = GetRValue(cl)) * .95; - dat->rgbBkgBottom.rgbBlue = (dat->rgbBkgTop.rgbBlue = GetBValue(cl)) * .95; - dat->rgbBkgBottom.rgbGreen = (dat->rgbBkgTop.rgbGreen = GetGValue(cl)) * .95; - - dat->clText = GetSysColor(COLOR_WINDOWTEXT); - if (!dat->hFont) - dat->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); -} - -static void MHeaderbar_FillRect(HDC hdc, int x, int y, int width, int height, COLORREF cl) -{ - int oldMode = SetBkMode(hdc, OPAQUE); - COLORREF oldColor = SetBkColor(hdc, cl); - - RECT rc; SetRect(&rc, x, y, x+width, y+height); - ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, "", 0, 0); - - SetBkMode(hdc, oldMode); - SetBkColor(hdc, oldColor); -} - -static void MHeaderbar_DrawGradient(HDC hdc, int x, int y, int width, int height, RGBQUAD *rgb0, RGBQUAD *rgb1) -{ - int oldMode = SetBkMode(hdc, OPAQUE); - COLORREF oldColor = SetBkColor(hdc, 0); - - RECT rc; SetRect(&rc, x, 0, x + width, 0); - for (int i = y + height; --i >= y;) { - COLORREF color = RGB( - ((height - i - 1)*rgb0->rgbRed + i*rgb1->rgbRed) / height, - ((height - i - 1)*rgb0->rgbGreen + i*rgb1->rgbGreen) / height, - ((height - i - 1)*rgb0->rgbBlue + i*rgb1->rgbBlue) / height); - rc.top = rc.bottom = i; - ++rc.bottom; - SetBkColor(hdc, color); - ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, "", 0, 0); - } - - SetBkMode(hdc, oldMode); - SetBkColor(hdc, oldColor); -} - -static LRESULT MHeaderbar_OnPaint(HWND hwndDlg, MHeaderbarCtrl *mit, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int iTopSpace = IsAeroMode() ? 0 : 3; - PAINTSTRUCT ps; - HBITMAP hBmp, hOldBmp; - - int titleLength = GetWindowTextLength(hwndDlg) + 1; - TCHAR *szTitle = (TCHAR *)mir_alloc(sizeof(TCHAR) * titleLength); - GetWindowText(hwndDlg, szTitle, titleLength); - - TCHAR *szSubTitle = _tcschr(szTitle, _T('\n')); - if (szSubTitle) - *szSubTitle++ = 0; - - HDC hdc = BeginPaint(hwndDlg, &ps); - HDC tempDC = CreateCompatibleDC(hdc); - - BITMAPINFO bmi; - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = mit->width; - bmi.bmiHeader.biHeight = -mit->height; // we need this for DrawThemeTextEx - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - hBmp = CreateDIBSection(tempDC, &bmi, DIB_RGB_COLORS, NULL, NULL, 0); - - hOldBmp = (HBITMAP)SelectObject(tempDC, hBmp); - - if (IsAeroMode()) { - RECT temprc = { 0, 0, mit->width, mit->width }; - FillRect(tempDC, &temprc, (HBRUSH)GetStockObject(BLACK_BRUSH)); - - MARGINS margins = { 0, 0, mit->height, 0 }; - dwmExtendFrameIntoClientArea(GetParent(hwndDlg), &margins); - - WTA_OPTIONS opts; - opts.dwFlags = opts.dwMask = WTNCA_NOSYSMENU | WTNCA_NODRAWICON; - setWindowThemeAttribute(GetParent(hwndDlg), WTA_NONCLIENT, &opts, sizeof(opts)); - } - else { - if (IsVSMode()) - MHeaderbar_FillRect(tempDC, 0, 0, mit->width, mit->height, GetSysColor(COLOR_WINDOW)); - else - MHeaderbar_DrawGradient(tempDC, 0, 0, mit->width, mit->height, &mit->rgbBkgTop, &mit->rgbBkgBottom); - - MHeaderbar_FillRect(tempDC, 0, mit->height-2, mit->width, 1, GetSysColor(COLOR_BTNSHADOW)); - MHeaderbar_FillRect(tempDC, 0, mit->height-1, mit->width, 1, GetSysColor(COLOR_BTNHIGHLIGHT)); - } - - HFONT hFont = mit->hFont; - SetBkMode(tempDC, TRANSPARENT); - SetTextColor(tempDC, mit->clText); - - LOGFONT lf; - GetObject(hFont, sizeof(lf), &lf); - lf.lfWeight = FW_BOLD; - HFONT hFntBold = CreateFontIndirect(&lf), hOldFont; - - if (mit->hIcon) - DrawIcon(tempDC, 10, iTopSpace, mit->hIcon); - else { - HICON hIcon = (HICON)SendMessage(GetParent(hwndDlg), WM_GETICON, ICON_BIG, 0); - if (hIcon == NULL) - hIcon = (HICON)SendMessage(GetParent(hwndDlg), WM_GETICON, ICON_SMALL, 0); - DrawIcon(tempDC, 10, iTopSpace, hIcon); - } - - RECT textRect; - textRect.left = 50; - textRect.right = mit->width; - textRect.top = 2 + iTopSpace; - textRect.bottom = GetSystemMetrics(SM_CYICON) - 2 + iTopSpace; - - if (IsAeroMode()) { - DTTOPTS dto = { 0 }; - dto.dwSize = sizeof(dto); - dto.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE; - dto.iGlowSize = 10; - - HANDLE hTheme = OpenThemeData(hwndDlg, L"Window"); - textRect.left = 50; - hOldFont = (HFONT)SelectObject(tempDC, hFntBold); - - wchar_t *szTitleW = mir_t2u(szTitle); - drawThemeTextEx(hTheme, tempDC, WP_CAPTION, CS_ACTIVE, szTitleW, -1, DT_TOP | DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_END_ELLIPSIS, &textRect, &dto); - mir_free(szTitleW); - - if (szSubTitle) { - textRect.left = 66; - SelectObject(tempDC, hFont); - - wchar_t *szSubTitleW = mir_t2u(szSubTitle); - drawThemeTextEx(hTheme, tempDC, WP_CAPTION, CS_ACTIVE, szSubTitleW, -1, DT_BOTTOM | DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_END_ELLIPSIS, &textRect, &dto); - mir_free(szSubTitleW); - } - CloseThemeData(hTheme); - } - else { - textRect.left = 50; - hOldFont = (HFONT)SelectObject(tempDC, hFntBold); - DrawText(tempDC, szTitle, -1, &textRect, DT_TOP | DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_END_ELLIPSIS); - - if (szSubTitle) { - textRect.left = 66; - SelectObject(tempDC, hFont); - DrawText(tempDC, szSubTitle, -1, &textRect, DT_BOTTOM | DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_END_ELLIPSIS); - } - } - - DeleteObject(hFntBold); - - mir_free(szTitle); - - //Copy to output - if (mit->nControlsToRedraw) { - RECT temprc; - temprc.left = 0; - temprc.right = mit->width; - temprc.top = 0; - temprc.bottom = mit->width; - HRGN hRgn = CreateRectRgnIndirect(&temprc); - - for (int i = 0; i < mit->nControlsToRedraw; i++) { - GetWindowRect(mit->controlsToRedraw[i], &temprc); - MapWindowPoints(NULL, hwndDlg, (LPPOINT)&temprc, 2); - HRGN hRgnTmp = CreateRectRgnIndirect(&temprc); - CombineRgn(hRgn, hRgn, hRgnTmp, RGN_DIFF); - DeleteObject(hRgnTmp); - } - SelectClipRgn(hdc, hRgn); - DeleteObject(hRgn); - } - - BitBlt(hdc, mit->rc.left, mit->rc.top, mit->width, mit->height, tempDC, 0, 0, SRCCOPY); - - SelectClipRgn(hdc, NULL); - - SelectObject(tempDC, hOldBmp); - DeleteObject(hBmp); - SelectObject(tempDC, hOldFont); - DeleteDC(tempDC); - - EndPaint(hwndDlg, &ps); - - return TRUE; -} - -static LRESULT CALLBACK MHeaderbarWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - MHeaderbarCtrl* itc = (MHeaderbarCtrl *)GetWindowLongPtr(hwndDlg, 0); - switch (msg) { - case WM_NCCREATE: - itc = new MHeaderbarCtrl; //(MHeaderbarCtrl*)mir_alloc(sizeof(MHeaderbarCtrl)); - - SetWindowLongPtr(hwndDlg, 0, (LONG_PTR)itc); - MHeaderbar_SetupColors(itc); - - { - HWND hParent = GetParent(hwndDlg); - RECT rcWnd; GetWindowRect(hwndDlg, &rcWnd); - itc->controlsToRedraw = 0; - itc->nControlsToRedraw = 0; - for (HWND hChild = FindWindowEx(hParent, NULL, NULL, NULL); hChild; hChild = FindWindowEx(hParent, hChild, NULL, NULL)) { - if (hChild != hwndDlg) { - RECT rcChild; GetWindowRect(hChild, &rcChild); - RECT rc; - IntersectRect(&rc, &rcChild, &rcWnd); - if (!IsRectEmpty(&rc)) { - ++itc->nControlsToRedraw; - itc->controlsToRedraw = (HWND *)mir_realloc(itc->controlsToRedraw, sizeof(HWND) * itc->nControlsToRedraw); - itc->controlsToRedraw[itc->nControlsToRedraw - 1] = hChild; - } - } - } - } - - break; - - case WM_SETFONT: - itc->hFont = (HFONT)wParam; - break; - - case WM_SIZE: - GetClientRect(hwndDlg, &itc->rc); - itc->width = itc->rc.right - itc->rc.left; - itc->height = itc->rc.bottom - itc->rc.top; - return TRUE; - - case WM_THEMECHANGED: - case WM_STYLECHANGED: - MHeaderbar_SetupColors(itc); - return TRUE; - - case WM_LBUTTONDOWN: - SendMessage(GetParent(hwndDlg), WM_SYSCOMMAND, 0xF012, 0); - return 0; - - case WM_SETICON: - if (wParam < 3) { - itc->hIcon = (HICON)lParam; - InvalidateRect(hwndDlg, NULL, FALSE); - } - break; - - case WM_ERASEBKGND: - return 1; - - case WM_NCPAINT: - InvalidateRect(hwndDlg, NULL, FALSE); - break; - - case WM_PAINT: - MHeaderbar_OnPaint(hwndDlg, itc, msg, wParam, lParam); - break; - - case WM_DESTROY: - delete itc; - break; - } - return DefWindowProc(hwndDlg, msg, wParam, lParam); -} diff --git a/src/modules/options/iconheader.cpp b/src/modules/options/iconheader.cpp deleted file mode 100644 index 42ec5d2fbb..0000000000 --- a/src/modules/options/iconheader.cpp +++ /dev/null @@ -1,534 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -Copyright (c) 2007 Artem Shpynov -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "m_iconheader.h" - -extern HINSTANCE hInst; - -static BOOL IsAeroMode() -{ - BOOL result; - return dwmIsCompositionEnabled && (dwmIsCompositionEnabled(&result) == S_OK) && result; -} - -static BOOL IsVSMode() -{ - return IsWinVerVistaPlus() && IsThemeActive(); -} - -//////////////////////////////////////////////////////////////////////////////////// -// Internals - -#define ITC_BORDER_SIZE 3 - -static LRESULT CALLBACK MIcoTabWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - -// structure is used for storing list of tab info -struct MIcoTabCtrl : public MZeroedObject -{ - MIcoTabCtrl(): pList(1) {} - - HWND hwnd; - int nSelectedIdx, nHotIdx; - LIST pList; - - // UI info - BOOL bMouseInside; - RECT rc; - int width, height; - int itemWidth, itemHeight; - - //background bitmap - HBITMAP hBkgBmp; - HBITMAP hBkgOldBmp; - HDC hBkgDC; - SIZE BkgSize; - - // control colors - RGBQUAD rgbBkgTop, rgbBkgBottom; - RGBQUAD rgbSelTop, rgbSelBottom; - RGBQUAD rgbHotTop, rgbHotBottom; - COLORREF clText; - COLORREF clSelText, clSelBorder; - COLORREF clHotText, clHotBorder; - - // fonts - HFONT hFont; -}; - -typedef void (*ItemDestuctor)(void*); - -static void MITListDestructor(void * adr) -{ - MIcoTab * mit = (MIcoTab *)adr; - mir_free(mit->tcsName); - if (mit->hIcon && !(mit->flag&MITCF_SHAREDICON)) - DestroyIcon(mit->hIcon); - mir_free(adr); -} - -void li_ListDestruct(LIST &pList, ItemDestuctor pItemDestructor) -{ - for (int i=0; irgbBkgBottom.rgbRed = (dat->rgbBkgTop.rgbRed = GetRValue(cl)) * .95; - dat->rgbBkgBottom.rgbGreen = (dat->rgbBkgTop.rgbGreen = GetGValue(cl)) * .95; - dat->rgbBkgBottom.rgbBlue = (dat->rgbBkgTop.rgbBlue = GetBValue(cl)) * .95; - - cl = GetSysColor(COLOR_HIGHLIGHT); - dat->rgbSelTop.rgbRed = (dat->rgbSelBottom.rgbRed = GetRValue(cl)) * .75; - dat->rgbSelTop.rgbGreen = (dat->rgbSelBottom.rgbGreen = GetGValue(cl)) * .75; - dat->rgbSelTop.rgbBlue = (dat->rgbSelBottom.rgbBlue = GetBValue(cl)) * .75; - - dat->rgbHotTop.rgbRed = (dat->rgbSelTop.rgbRed + 255) / 2; - dat->rgbHotTop.rgbGreen = (dat->rgbSelTop.rgbGreen + 255) / 2; - dat->rgbHotTop.rgbBlue = (dat->rgbSelTop.rgbBlue + 255) / 2; - - dat->rgbHotBottom.rgbRed = (dat->rgbSelBottom.rgbRed + 255) / 2; - dat->rgbHotBottom.rgbGreen = (dat->rgbSelBottom.rgbGreen + 255) / 2; - dat->rgbHotBottom.rgbBlue = (dat->rgbSelBottom.rgbBlue + 255) / 2; - - dat->clText = GetSysColor(COLOR_WINDOWTEXT); - dat->clSelText = GetSysColor(COLOR_HIGHLIGHTTEXT); - dat->clSelBorder = RGB(dat->rgbSelTop.rgbRed, dat->rgbSelTop.rgbGreen, dat->rgbSelTop.rgbBlue); - dat->clHotBorder = RGB(dat->rgbHotTop.rgbRed, dat->rgbHotTop.rgbGreen, dat->rgbHotTop.rgbBlue); - - if (!dat->hFont) dat->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); -} - -static void MIcoTab_FillRect(HDC hdc, int x, int y, int width, int height, COLORREF cl) -{ - int oldMode = SetBkMode(hdc, OPAQUE); - COLORREF oldColor = SetBkColor(hdc, cl); - - RECT rc; SetRect(&rc, x, y, x+width, y+height); - ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, "", 0, 0); - - SetBkMode(hdc, oldMode); - SetBkColor(hdc, oldColor); -} - -static void MIcoTab_DrawGradient(HDC hdc, int x, int y, int width, int height, RGBQUAD *rgb0, RGBQUAD *rgb1) -{ - int oldMode = SetBkMode(hdc, OPAQUE); - COLORREF oldColor = SetBkColor(hdc, 0); - - RECT rc; SetRect(&rc, x, 0, x+width, 0); - for (int i = y+height; --i >= y;) { - COLORREF color = RGB( - ((height-i-1)*rgb0->rgbRed + i*rgb1->rgbRed) / height, - ((height-i-1)*rgb0->rgbGreen + i*rgb1->rgbGreen) / height, - ((height-i-1)*rgb0->rgbBlue + i*rgb1->rgbBlue) / height); - rc.top = rc.bottom = i; - ++rc.bottom; - SetBkColor(hdc, color); - ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, "", 0, 0); - } - - SetBkMode(hdc, oldMode); - SetBkColor(hdc, oldColor); -} - -static void MIcoTab_DrawItem(HWND hwnd, HDC hdc, MIcoTabCtrl *dat, MIcoTab *tab, int i) -{ - int iTopSpace = IsAeroMode() ? 0 : ITC_BORDER_SIZE; - int itemX = ITC_BORDER_SIZE + dat->itemWidth * i; - int iconTop = iTopSpace + 5; - int textTop = iconTop + 32 + 3; - - HFONT hFntSave = NULL; - - if (dat->nSelectedIdx == i) { - LOGFONT lf; - GetObject(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf); - lf.lfWeight = FW_BOLD; - hFntSave = (HFONT)SelectObject(hdc, CreateFontIndirect(&lf)); - - if (IsVSMode()) { - RECT rc; - rc.left = itemX; - rc.top = iTopSpace; - rc.right = itemX + dat->itemWidth; - rc.bottom = iTopSpace + dat->itemHeight; - HANDLE hTheme = OpenThemeData(hwnd, L"ListView"); - if (dat->nHotIdx == i || GetFocus() == hwnd) - DrawThemeBackground(hTheme, hdc, LVP_LISTITEM, LISS_HOTSELECTED, &rc, NULL); - else - DrawThemeBackground(hTheme, hdc, LVP_LISTITEM, LISS_SELECTED, &rc, NULL); - - CloseThemeData(hTheme); - } - else { - MIcoTab_FillRect(hdc, itemX, ITC_BORDER_SIZE, dat->itemWidth, dat->itemHeight, dat->clSelBorder); - MIcoTab_DrawGradient(hdc, itemX+1, ITC_BORDER_SIZE+1, dat->itemWidth-2, dat->itemHeight-2, &dat->rgbSelTop, &dat->rgbSelBottom); - } - SetTextColor(hdc, dat->clSelText); - } - else if (dat->nHotIdx == i) { - if (IsVSMode()) { - RECT rc; - rc.left = itemX; - rc.top = iTopSpace; - rc.right = itemX + dat->itemWidth; - rc.bottom = iTopSpace + dat->itemHeight; - SetWindowTheme(hwnd, L"explorer", NULL); - HANDLE hTheme = OpenThemeData(hwnd, L"ListView"); - DrawThemeBackground(hTheme, hdc, LVP_LISTITEM, LISS_HOT, &rc, NULL); - CloseThemeData(hTheme); - } - else { - MIcoTab_FillRect(hdc, itemX, ITC_BORDER_SIZE, dat->itemWidth, dat->itemHeight, dat->clHotBorder); - MIcoTab_DrawGradient(hdc, itemX+1, ITC_BORDER_SIZE+1, dat->itemWidth-2, dat->itemHeight-2, &dat->rgbHotTop, &dat->rgbHotBottom); - } - SetTextColor(hdc, dat->clHotText); - } - else SetTextColor(hdc, dat->clText); - - RECT textRect; - textRect.left = itemX; - textRect.right = itemX+dat->itemWidth; - textRect.top = textTop; - textRect.bottom = iconTop+dat->itemHeight; - DrawIcon(hdc, itemX+dat->itemWidth/2-16, iconTop, tab->hIcon); - - if (IsVSMode()) { - DTTOPTS dto = {0}; - dto.dwSize = sizeof(dto); - dto.dwFlags = DTT_COMPOSITED|DTT_GLOWSIZE; - dto.iGlowSize = 10; - HANDLE hTheme = OpenThemeData(hwnd, L"Window"); - wchar_t *tcsNameW = mir_t2u(tab->tcsName); - drawThemeTextEx(hTheme, hdc, WP_CAPTION, CS_ACTIVE, tcsNameW, -1, DT_VCENTER|DT_CENTER|DT_END_ELLIPSIS, &textRect, &dto); - mir_free(tcsNameW); - CloseThemeData(hTheme); - } - else DrawText(hdc, tab->tcsName, -1, &textRect, DT_VCENTER|DT_CENTER|DT_END_ELLIPSIS); - - if (hFntSave) - DeleteObject(SelectObject(hdc, hFntSave)); -} - -static LRESULT MIcoTab_OnPaint(HWND hwndDlg, MIcoTabCtrl *mit, UINT msg, WPARAM wParam, LPARAM lParam) -{ - PAINTSTRUCT ps; - - HDC hdc = BeginPaint(hwndDlg, &ps); - HDC tempDC = CreateCompatibleDC(hdc); - - BITMAPINFO bmi; - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = mit->width; - bmi.bmiHeader.biHeight = -mit->height; // we need this for DrawThemeTextEx - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - HBITMAP hBmp = CreateDIBSection(tempDC, &bmi, DIB_RGB_COLORS, NULL, NULL, 0); - - HBITMAP hOldBmp = (HBITMAP)SelectObject(tempDC, hBmp); - - if (IsAeroMode()) { - RECT temprc; - temprc.left = 0; - temprc.right = mit->width; - temprc.top = 0; - temprc.bottom = mit->width; - FillRect(tempDC, &temprc, (HBRUSH)GetStockObject(BLACK_BRUSH)); - } - else { - if (mit->hBkgBmp) - StretchBlt(tempDC, 0, 0, mit->width, mit->height, mit->hBkgDC, 0, 0, mit->BkgSize.cx, mit->BkgSize.cy, SRCCOPY); - else { - if (IsVSMode()) - MIcoTab_FillRect(tempDC, 0, 0, mit->width, mit->height, GetSysColor(COLOR_WINDOW)); - else - MIcoTab_DrawGradient(tempDC, 0, 0, mit->width, mit->height, &mit->rgbBkgTop, &mit->rgbBkgBottom); - - MIcoTab_FillRect(tempDC, 0, mit->height-2, mit->width, 1, GetSysColor(COLOR_BTNSHADOW)); - MIcoTab_FillRect(tempDC, 0, mit->height-1, mit->width, 1, GetSysColor(COLOR_BTNHIGHLIGHT)); - } - } - - //Draw Items - HFONT hFont = mit->hFont; - HFONT hOldFont = (HFONT)SelectObject(tempDC, hFont); - SetBkMode(tempDC, TRANSPARENT); - - for (int i=0; ipList.getCount(); i++) { - MIcoTab *tab = (MIcoTab *)mit->pList[i]; - MIcoTab_DrawItem(hwndDlg, tempDC, mit, tab, i); - } - - //Copy to output - BitBlt(hdc, mit->rc.left, mit->rc.top, mit->width, mit->height, tempDC, 0, 0, SRCCOPY); - SelectObject(tempDC, hOldBmp); - DeleteObject(hBmp); - SelectObject(tempDC,hOldFont); - DeleteDC(tempDC); - - EndPaint(hwndDlg, &ps); - - return TRUE; -} - -static LRESULT CALLBACK MIcoTabWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - MIcoTabCtrl* itc = (MIcoTabCtrl *)GetWindowLongPtr(hwndDlg, 0); - switch(msg) { - case WM_NCCREATE: - itc = new MIcoTabCtrl; //(MIcoTabCtrl*)mir_alloc(sizeof(MIcoTabCtrl)); - itc->nSelectedIdx = -1; - itc->nHotIdx = -1; - itc->bMouseInside = FALSE; - SetWindowLongPtr(hwndDlg, 0, (LONG_PTR)itc); - MIcoTab_SetupColors(itc); - - if (IsAeroMode()) { - RECT rc; GetWindowRect(hwndDlg, &rc); - MARGINS margins = {0, 0, rc.bottom-rc.top, 0}; - dwmExtendFrameIntoClientArea(GetParent(hwndDlg), &margins); - } - - return TRUE; - - case WM_SETFONT: - itc->hFont = (HFONT)wParam; - break; - - case WM_SIZE: - GetClientRect(hwndDlg, &itc->rc); - itc->width = itc->rc.right-itc->rc.left; - itc->height = itc->rc.bottom-itc->rc.top; - - if (itc->pList.getCount()) { - itc->itemWidth = (itc->width-2*ITC_BORDER_SIZE)/itc->pList.getCount(); - itc->itemHeight = itc->height-2*ITC_BORDER_SIZE-2; - } - else itc->itemWidth = itc->itemHeight = 0; - return TRUE; - - case WM_THEMECHANGED: - case WM_STYLECHANGED: - MIcoTab_SetupColors(itc); - return TRUE; - - case WM_MOUSEMOVE: - if (!itc->bMouseInside) { - TRACKMOUSEEVENT tme = {0}; - tme.cbSize = sizeof(tme); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = hwndDlg; - _TrackMouseEvent(&tme); - itc->bMouseInside = TRUE; - } - - itc->nHotIdx = (LOWORD(lParam) - ITC_BORDER_SIZE) / itc->itemWidth; - if (itc->nHotIdx >= itc->pList.getCount()) - itc->nHotIdx = -1; - RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); - return 0; - - case WM_MOUSELEAVE: - itc->bMouseInside = FALSE; - itc->nHotIdx = -1; - RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); - return 0; - - case WM_LBUTTONUP: - if ((itc->nHotIdx >= 0) && (itc->nHotIdx != itc->nSelectedIdx)) - { - itc->nSelectedIdx = itc->nHotIdx; - SetWindowText(hwndDlg, itc->pList[itc->nSelectedIdx]->tcsName); - RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); - SendMessage(GetParent(hwndDlg), WM_COMMAND, - MAKEWPARAM(GetWindowLongPtr(hwndDlg, GWL_ID), ITCN_SELCHANGED), - itc->nSelectedIdx); - } - return 0; - - case WM_SETFOCUS: - case WM_KILLFOCUS: - RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); - break; - - case WM_MOUSEACTIVATE: - SetFocus(hwndDlg); - return MA_ACTIVATE; - - case WM_GETDLGCODE: - { - if (lParam) - { - MSG *msg = (MSG *) lParam; - if (msg->message == WM_KEYDOWN) - { - if (msg->wParam == VK_TAB) - return 0; - if (msg->wParam == VK_ESCAPE) - return 0; - } else - if (msg->message == WM_CHAR) - { - if (msg->wParam == '\t') - return 0; - if (msg->wParam == 27) - return 0; - } - } - return DLGC_WANTMESSAGE; - } - - case WM_KEYDOWN: - { - int newIdx = itc->nSelectedIdx; - switch (wParam) - { - case VK_NEXT: - case VK_RIGHT: - newIdx++; - break; - case VK_PRIOR: - case VK_LEFT: - newIdx--; - break; - } - if ((newIdx >= 0) && (newIdx < itc->pList.getCount()) && (newIdx != itc->nSelectedIdx)) - { - itc->nSelectedIdx = newIdx; - SetWindowText(hwndDlg, itc->pList[itc->nSelectedIdx]->tcsName); - RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); - SendMessage(GetParent(hwndDlg), WM_COMMAND, - MAKEWPARAM(GetWindowLongPtr(hwndDlg, GWL_ID), ITCN_SELCHANGEDKBD), - itc->nSelectedIdx); - } - return 0; - } - - case WM_ERASEBKGND: - return 1; - - case WM_NCPAINT: - InvalidateRect(hwndDlg, NULL, FALSE); - break; - - case WM_PAINT: - MIcoTab_OnPaint(hwndDlg, itc, msg, wParam, lParam); - break; - - case ITCM_SETBACKGROUND: - itc->hBkgBmp = (HBITMAP)lParam; - if (!itc->hBkgDC) - itc->hBkgDC = CreateCompatibleDC(NULL); - itc->hBkgOldBmp = (HBITMAP)SelectObject(itc->hBkgDC, itc->hBkgBmp); - { - BITMAPINFO bmp; - GetObject(itc->hBkgBmp, sizeof(bmp), &bmp); - itc->BkgSize.cx = bmp.bmiHeader.biWidth; - itc->BkgSize.cy = bmp.bmiHeader.biHeight; - } - return TRUE; - - case ITCM_ADDITEM: - { - MIcoTab* pMit = (MIcoTab *)wParam; - if (!pMit) - return FALSE; - - MIcoTab* pListMit = (MIcoTab *)mir_calloc(sizeof(MIcoTab)); - pListMit->flag = pMit->flag; - pListMit->data = pMit->data; - if (pMit->flag & MITCF_UNICODE) - pListMit->tcsName = mir_u2t(pMit->lpwzName); - else - pListMit->tcsName = mir_a2t(pMit->lpzName); - if (pMit->hIcon) { - if (pListMit->flag&MITCF_SHAREDICON) - pListMit->hIcon = pMit->hIcon; - else - pListMit->hIcon = CopyIcon(pMit->hIcon); - } - itc->pList.insert(pListMit); - - itc->itemWidth = (itc->width-2*ITC_BORDER_SIZE)/itc->pList.getCount(); - itc->itemHeight = itc->height-2*ITC_BORDER_SIZE-2; - - RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); - return TRUE; - } - - case ITCM_SETSEL: - if ((int)wParam >= 0 && (int)wParam < itc->pList.getCount()) { - itc->nSelectedIdx = wParam; - SetWindowText(hwndDlg, itc->pList[itc->nSelectedIdx]->tcsName); - RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); - SendMessage(GetParent(hwndDlg), WM_COMMAND, - MAKEWPARAM(GetWindowLongPtr(hwndDlg, GWL_ID), ITCN_SELCHANGED), - itc->nSelectedIdx); - } - return TRUE; - - case ITCM_GETSEL: - return itc->nSelectedIdx; - - case ITCM_GETITEMDATA: - if ((int)wParam >= 0 && (int)wParam < itc->pList.getCount()) - return ((MIcoTab *)itc->pList[wParam])->data; - return 0; - - case WM_DESTROY: - if (itc->hBkgDC) { - SelectObject(itc->hBkgDC, itc->hBkgOldBmp); - DeleteDC(itc->hBkgDC); - } - li_ListDestruct(itc->pList, MITListDestructor); - delete itc; - return TRUE; - } - return DefWindowProc(hwndDlg, msg, wParam, lParam); -} diff --git a/src/modules/options/options.cpp b/src/modules/options/options.cpp deleted file mode 100644 index 61e3f3775f..0000000000 --- a/src/modules/options/options.cpp +++ /dev/null @@ -1,1327 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -Copyright (c) 2007 Artem Shpynov -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "filter.h" - -#define FILTER_TIMEOUT_TIMER 10012 - -#define ALL_MODULES_FILTER LPGEN("") -#define CORE_MODULES_FILTER LPGEN("") - -int LangpackOptionsInit(WPARAM, LPARAM); - -static HANDLE hOptionsInitEvent; -static HWND hwndOptions = NULL; -static HWND hFilterSearchWnd = NULL; - -// Thread for search keywords in dialogs -static BYTE bSearchState = 0; // 0 - not executed; 1 - in progress; 2 - completed; -static int FilterPage = 0; -static int FilterLoadProgress = 100; -static int FilterTimerId = 0; - -struct OptionsPageInit -{ - int pageCount; - OPTIONSDIALOGPAGE *odp; -}; - -///////////////////////////////////////////////////////////////////////////////////////// - -class COptionPageDialog : public CDlgBase -{ - DLGPROC m_wndProc; - LPARAM m_lParam; - -public: - COptionPageDialog(HINSTANCE hInst, int idDialog, DLGPROC pProc, LPARAM lParam) : - CDlgBase(hInst, idDialog), - m_wndProc(pProc), - m_lParam(lParam) - { - } - - virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) - { - if (msg == WM_INITDIALOG) - lParam = m_lParam; - - LRESULT res = m_wndProc(m_hwnd, msg, wParam, lParam); - - if (msg == WM_DESTROY) - m_hwnd = NULL; - - return res; - } -}; - -struct OptionsPageData : public MZeroedObject -{ - OptionsPageData(OPTIONSDIALOGPAGE *src) - { - if (src->hInstance != NULL && src->pszTemplate != NULL) - pDialog = new COptionPageDialog(src->hInstance, (int)src->pszTemplate, src->pfnDlgProc, src->dwInitParam); - else - pDialog = src->pDialog; - assert(pDialog != NULL); - - flags = src->flags; - hLangpack = src->hLangpack; - - if (src->flags & ODPF_UNICODE) - ptszTitle = mir_tstrdup(src->ptszTitle); - else - ptszTitle = mir_a2t(src->pszTitle); - - if (src->flags & ODPF_UNICODE) - ptszGroup = mir_tstrdup(src->ptszGroup); - else - ptszGroup = mir_a2t(src->pszGroup); - - if (src->flags & ODPF_UNICODE) - ptszTab = mir_tstrdup(src->ptszTab); - else - ptszTab = mir_a2t(src->pszTab); - } - - ~OptionsPageData() - { - if (pDialog && getHwnd() != NULL) - DestroyWindow(getHwnd()); - } - - CDlgBase *pDialog; - int hLangpack; - ptrT ptszTitle, ptszGroup, ptszTab; - HTREEITEM hTreeItem; - int changed; - int height; - int width; - DWORD flags; - BOOL insideTab; - - __forceinline HWND getHwnd() const { return pDialog->GetHwnd(); } - __forceinline HINSTANCE getInst() const { return pDialog->GetInst(); } - - __forceinline TCHAR* getString(TCHAR *ptszStr) - { - if (flags & ODPF_DONTTRANSLATE) - return ptszStr; - return TranslateTH(hLangpack, ptszStr); - } -}; - -struct OptionsDlgData : public MZeroedObject -{ - OptionsDlgData() : - arOpd(10) - {} - - int currentPage; - HTREEITEM hCurrentPage; - LIST arOpd; - RECT rcDisplay; - RECT rcTab; - HFONT hBoldFont; - TCHAR szFilterString[1024]; - HANDLE hPluginLoad, hPluginUnload; - - OptionsPageData* getCurrent() const - { return (currentPage == -1) ? NULL : arOpd[currentPage]; - } -}; - -HTREEITEM FindNamedTreeItemAtRoot(HWND hwndTree, const TCHAR* name) -{ - TCHAR str[128]; - TVITEM tvi; - tvi.mask = TVIF_TEXT; - tvi.pszText = str; - tvi.cchTextMax = SIZEOF(str); - tvi.hItem = TreeView_GetRoot(hwndTree); - while (tvi.hItem != NULL) { - SendMessage(hwndTree, TVM_GETITEM, 0, (LPARAM)&tvi); - if (!mir_tstrcmpi(str, name)) - return tvi.hItem; - - tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); - } - return NULL; -} - -static HTREEITEM FindNamedTreeItemAtChildren(HWND hwndTree, HTREEITEM hItem, const TCHAR* name) -{ - TCHAR str[128]; - TVITEM tvi; - tvi.mask = TVIF_TEXT; - tvi.pszText = str; - tvi.cchTextMax = SIZEOF(str); - tvi.hItem = TreeView_GetChild(hwndTree, hItem); - while (tvi.hItem != NULL) { - SendMessage(hwndTree, TVM_GETITEM, 0, (LPARAM)&tvi); - if (!mir_tstrcmpi(str, name)) - return tvi.hItem; - - tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); - } - return NULL; -} - -static BOOL CALLBACK BoldGroupTitlesEnumChildren(HWND hwnd, LPARAM lParam) -{ - TCHAR szClass[64]; - GetClassName(hwnd, szClass, SIZEOF(szClass)); - - if (!mir_tstrcmp(szClass, _T("Button")) && (GetWindowLongPtr(hwnd, GWL_STYLE) & 0x0F) == BS_GROUPBOX) - SendMessage(hwnd, WM_SETFONT, lParam, 0); - return TRUE; -} - -#define OPTSTATE_PREFIX "s_" - -static void SaveOptionsTreeState(HWND hdlg) -{ - TVITEMA tvi; - char buf[130], str[128]; - tvi.mask = TVIF_TEXT | TVIF_STATE; - tvi.pszText = str; - tvi.cchTextMax = SIZEOF(str); - tvi.hItem = TreeView_GetRoot(GetDlgItem(hdlg, IDC_PAGETREE)); - while (tvi.hItem != NULL) { - if (SendDlgItemMessageA(hdlg, IDC_PAGETREE, TVM_GETITEMA, 0, (LPARAM)&tvi)) { - mir_snprintf(buf, "%s%s", OPTSTATE_PREFIX, str); - db_set_b(NULL, "Options", buf, (BYTE)((tvi.state & TVIS_EXPANDED) ? 1 : 0)); - } - tvi.hItem = TreeView_GetNextSibling(GetDlgItem(hdlg, IDC_PAGETREE), tvi.hItem); - } -} - -#define DM_FOCUSPAGE (WM_USER+10) -#define DM_REBUILDPAGETREE (WM_USER+11) - -#define HM_MODULELOAD (WM_USER+12) -#define HM_MODULEUNLOAD (WM_USER+13) - -static void ThemeDialogBackground(HWND hwnd, BOOL tabbed) -{ - EnableThemeDialogTexture(hwnd, (tabbed ? ETDT_ENABLE : ETDT_DISABLE) | ETDT_USETABTEXTURE); -} - -static TCHAR* GetPluginName(HINSTANCE hInstance, TCHAR *buffer, int size) -{ - TCHAR tszModuleName[MAX_PATH]; - GetModuleFileName(hInstance, tszModuleName, SIZEOF(tszModuleName)); - TCHAR *dllName = _tcsrchr(tszModuleName, '\\'); - if (!dllName) - dllName = tszModuleName; - else - dllName++; - - _tcsncpy_s(buffer, size, dllName, _TRUNCATE); - return buffer; -} - -PageHash GetPluginPageHash(const OptionsPageData *page) -{ - return mir_hashstrT(page->ptszGroup) + mir_hashstrT(page->ptszTitle) + mir_hashstrT(page->ptszTab); -} - -static HWND CreateOptionWindow(const OptionsPageData *opd, HWND hWndParent) -{ - opd->pDialog->SetParent(hWndParent); - opd->pDialog->Create(); - return opd->pDialog->GetHwnd(); -} - -static void FindFilterStrings(int enableKeywordFiltering, int current, HWND hWndParent, const OptionsPageData *page) -{ - HWND hWnd = 0; - if (enableKeywordFiltering) { - if (current) - hWnd = page->getHwnd(); - else { - hWnd = CreateOptionWindow(page, hWndParent); - ShowWindow(hWnd, SW_HIDE); // make sure it's hidden - } - } - - DWORD key = GetPluginPageHash(page); // get the plugin page hash - - TCHAR pluginName[MAX_PATH]; - char *temp = GetPluginNameByInstance(page->getInst()); - GetDialogStrings(enableKeywordFiltering, key, GetPluginName(page->getInst(), pluginName, SIZEOF(pluginName)), hWnd, page->ptszGroup, page->ptszTitle, page->ptszTab, _A2T(temp)); - - if (enableKeywordFiltering && !current) - DestroyWindow(hWnd); // destroy the page, we're done with it -} - -static int MatchesFilter(const OptionsPageData *page, TCHAR *szFilterString) -{ - return ContainsFilterString(GetPluginPageHash(page), szFilterString); -} - -static LRESULT CALLBACK OptionsFilterSubclassProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - if (message != WM_PAINT && message != WM_PRINT) - return mir_callNextSubclass(hWnd, OptionsFilterSubclassProc, message, wParam, lParam); - - if (GetFocus() == hWnd || GetWindowTextLength(hWnd)) - return mir_callNextSubclass(hWnd, OptionsFilterSubclassProc, message, wParam, lParam); - - RECT rc; - GetClientRect(hWnd, &rc); - - PAINTSTRUCT paint; - HDC hdc = (message == WM_PAINT) ? BeginPaint(hWnd, &paint) : (HDC)wParam; - - TCHAR buf[255]; - if (bSearchState == 1 && FilterLoadProgress < 100 && FilterLoadProgress > 0) - mir_sntprintf(buf, TranslateT("Loading... %d%%"), FilterLoadProgress); - else - mir_sntprintf(buf, TranslateT("Search")); - - bool bDrawnByTheme = false; - - int oldMode = SetBkMode(hdc, TRANSPARENT); - - HTHEME hTheme = OpenThemeData(hWnd, L"EDIT"); - if (hTheme) { - if (IsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL)) - DrawThemeParentBackground(hWnd, hdc, &rc); - - RECT rc2; - GetThemeBackgroundContentRect(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &rc, &rc2); - rc2.top = 2 * rc.top - rc2.top; - rc2.left = 2 * rc.left - rc2.left; - rc2.bottom = 2 * rc.bottom - rc2.bottom; - rc2.right = 2 * rc.right - rc2.right; - - DrawThemeBackground(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &rc2, &rc); - HFONT hFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0); - HFONT oldFont = (HFONT)SelectObject(hdc, hFont); - - wchar_t *bufW = mir_t2u(buf); - DrawThemeText(hTheme, hdc, EP_EDITTEXT, ETS_DISABLED, bufW, -1, 0, 0, &rc); - mir_free(bufW); - - SelectObject(hdc, oldFont); - CloseThemeData(hTheme); - bDrawnByTheme = true; - } - - SetBkMode(hdc, oldMode); - - if (!bDrawnByTheme) { - HFONT hFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0); - HFONT oldFont = (HFONT)SelectObject(hdc, hFont); - SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT)); - FillRect(hdc, &rc, GetSysColorBrush(COLOR_WINDOW)); - int oldMode = SetBkMode(hdc, TRANSPARENT); - DrawText(hdc, buf, -1, &rc, 0); - SetBkMode(hdc, oldMode); - SelectObject(hdc, oldFont); - } - - if (message == WM_PAINT) - EndPaint(hWnd, &paint); - - return 0; -} - -static bool CheckPageShow(HWND hdlg, OptionsDlgData *dat, int i) -{ - OptionsPageData *opd = dat->arOpd[i]; - if (dat->szFilterString[0] && !MatchesFilter(opd, dat->szFilterString)) - return false; - return true; -} - -static BOOL IsAeroMode() -{ - BOOL result; - return dwmIsCompositionEnabled && (dwmIsCompositionEnabled(&result) == S_OK) && result; -} - -static void FreeOptionsData(OptionsPageInit* popi) -{ - for (int i = 0; i < popi->pageCount; i++) { - mir_free((char*)popi->odp[i].pszTitle); - mir_free(popi->odp[i].pszGroup); - mir_free(popi->odp[i].pszTab); - if ((DWORD_PTR)popi->odp[i].pszTemplate & 0xFFFF0000) - mir_free((char*)popi->odp[i].pszTemplate); - } - mir_free(popi->odp); -} - -static LRESULT CALLBACK AeroPaintSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - -static void AeroPaintControl(HWND hwnd, HDC hdc, UINT msg, LPARAM lpFlags) -{ - RECT rc; - GetClientRect(hwnd, &rc); - - HDC tempDC = CreateCompatibleDC(hdc); - - BITMAPINFO bmi; - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = rc.right; - bmi.bmiHeader.biHeight = -rc.bottom; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - - BYTE *pBits; - HBITMAP hBmp = CreateDIBSection(tempDC, &bmi, DIB_RGB_COLORS, (void **)&pBits, NULL, 0); - HBITMAP hOldBmp = (HBITMAP)SelectObject(tempDC, hBmp); - - // paint - SetPropA(hwnd, "Miranda.AeroRender.Active", (HANDLE)TRUE); - mir_callNextSubclass(hwnd, AeroPaintSubclassProc, msg, (WPARAM)tempDC, lpFlags); - SetPropA(hwnd, "Miranda.AeroRender.Active", (HANDLE)FALSE); - - // Fix alpha channel - GdiFlush(); - for (int i = 0; i < rc.right*rc.bottom; i++, pBits += 4) - if (!pBits[3]) - pBits[3] = 255; - - // Copy to output - BitBlt(hdc, 0, 0, rc.right, rc.bottom, tempDC, 0, 0, SRCCOPY); - SelectObject(tempDC, hOldBmp); - DeleteObject(hBmp); - DeleteDC(tempDC); -} - -static LRESULT CALLBACK AeroPaintSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_CTLCOLOREDIT: - if (!GetPropA((HWND)lParam, "Miranda.AeroRender.Active")) - RedrawWindow((HWND)lParam, NULL, NULL, RDW_INVALIDATE); - break; - - case WM_ERASEBKGND: - return TRUE; - - case WM_PRINT: - case WM_PRINTCLIENT: - AeroPaintControl(hwnd, (HDC)wParam, msg, lParam); - return TRUE; - - case WM_DESTROY: - RemovePropA(hwnd, "Miranda.AeroRender.Active"); - break; - - case WM_PAINT: - PAINTSTRUCT ps; - HDC hdc = BeginPaint(hwnd, &ps); - AeroPaintControl(hwnd, hdc, WM_PRINT, PRF_CLIENT | PRF_NONCLIENT); - EndPaint(hwnd, &ps); - return TRUE; - } - return mir_callNextSubclass(hwnd, AeroPaintSubclassProc, msg, wParam, lParam); -} - -static void CALLBACK FilterSearchTimerFunc(HWND hwnd, UINT, UINT_PTR, DWORD) -{ - OptionsDlgData *dat = (OptionsDlgData*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - if (!dat) - return; - - if (hFilterSearchWnd == NULL) - hFilterSearchWnd = CreateWindowA("STATIC", "Test", WS_OVERLAPPED | WS_DISABLED, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, GetModuleHandle(NULL), 0); // Fake window to keep option page focused - - if (FilterPage < dat->arOpd.getCount()) - FindFilterStrings(TRUE, dat->currentPage == FilterPage, hFilterSearchWnd, dat->arOpd[FilterPage]); - - FilterPage++; - FilterLoadProgress = FilterPage * 100 / ((dat->arOpd.getCount()) ? dat->arOpd.getCount() : FilterPage); - if (FilterPage >= dat->arOpd.getCount()) { - KillTimer(hwnd, FilterTimerId); - FilterTimerId = 0; - bSearchState = 2; - FilterLoadProgress = 100; - DestroyWindow(hFilterSearchWnd); - hFilterSearchWnd = NULL; - } - RedrawWindow(GetDlgItem(hwnd, IDC_KEYWORD_FILTER), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE); -} - -static void ExecuteFindFilterStringsTimer(HWND hdlg) -{ - bSearchState = 1; - FilterPage = 0; - if (FilterTimerId) KillTimer(hdlg, FilterTimerId); - FilterTimerId = SetTimer(hdlg, NULL, 1, FilterSearchTimerFunc); -} - -static void FillFilterCombo(HWND hDlg, OptionsDlgData* dat) -{ - HINSTANCE *KnownInstances = (HINSTANCE*)alloca(sizeof(HINSTANCE)*dat->arOpd.getCount()); - int countKnownInst = 0; - SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_RESETCONTENT, 0, 0); - int index = SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_ADDSTRING, 0, (LPARAM)TranslateT(ALL_MODULES_FILTER)); - SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_SETITEMDATA, (WPARAM)index, 0); - index = SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_ADDSTRING, 0, (LPARAM)TranslateT(CORE_MODULES_FILTER)); - SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_SETITEMDATA, (WPARAM)index, (LPARAM)hInst); - - for (int i = 0; i < dat->arOpd.getCount(); i++) { - OptionsPageData *opd = dat->arOpd[i]; - FindFilterStrings(FALSE, FALSE, hDlg, opd); // only modules name (fast enougth) - - HINSTANCE inst = opd->getInst(); - if (inst == hInst) - continue; - - int j; - for (j = 0; j < countKnownInst; j++) - if (KnownInstances[j] == inst) - break; - if (j != countKnownInst) - continue; - - KnownInstances[countKnownInst] = inst; - countKnownInst++; - - TCHAR tszModuleName[MAX_PATH]; - GetModuleFileName(inst, tszModuleName, SIZEOF(tszModuleName)); - - TCHAR *dllName = mir_a2t(GetPluginNameByInstance(inst)); - if (!dllName) dllName = mir_tstrdup(_tcsrchr(tszModuleName, _T('\\'))); - if (!dllName) dllName = mir_tstrdup(tszModuleName); - if (dllName) { - index = SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_ADDSTRING, 0, (LPARAM)dllName); - SendDlgItemMessage(hDlg, IDC_KEYWORD_FILTER, (UINT)CB_SETITEMDATA, (WPARAM)index, (LPARAM)inst); - mir_free(dllName); - } - } - - FilterLoadProgress = 100; -} - -static void RebuildPageTree(HWND hdlg, OptionsDlgData *dat) -{ - LPARAM oldSel = SendDlgItemMessage(hdlg, IDC_KEYWORD_FILTER, CB_GETEDITSEL, 0, 0); - GetDlgItemText(hdlg, IDC_KEYWORD_FILTER, dat->szFilterString, SIZEOF(dat->szFilterString)); - - // if filter string is set to all modules then make the filter string empty (this will return all modules) - BOOL bRemoveFocusFromFilter = FALSE; - if (mir_tstrcmp(dat->szFilterString, TranslateT(ALL_MODULES_FILTER)) == 0) { - dat->szFilterString[0] = 0; - bRemoveFocusFromFilter = TRUE; - } - // if filter string is set to core modules replace it with the name of the executable (this will return all core modules) - else if (mir_tstrcmp(dat->szFilterString, TranslateT(CORE_MODULES_FILTER)) == 0) { - // replace string with process name - that will show core settings - TCHAR szFileName[300]; - GetModuleFileName(NULL, szFileName, SIZEOF(szFileName)); - TCHAR *pos = _tcsrchr(szFileName, _T('\\')); - if (pos) - pos++; - else - pos = szFileName; - - _tcsncpy_s(dat->szFilterString, pos, _TRUNCATE); - } - else { - int sel = SendDlgItemMessage(hdlg, IDC_KEYWORD_FILTER, (UINT)CB_GETCURSEL, 0, 0); - if (sel != -1) { - HINSTANCE hinst = (HINSTANCE)SendDlgItemMessage(hdlg, IDC_KEYWORD_FILTER, (UINT)CB_GETITEMDATA, sel, 0); - TCHAR szFileName[300]; - GetModuleFileName(hinst, szFileName, SIZEOF(szFileName)); - TCHAR *pos = _tcsrchr(szFileName, _T('\\')); - if (pos) pos++; - else pos = szFileName; - _tcsncpy_s(dat->szFilterString, pos, _TRUNCATE); - } - } - - _tcslwr_locale(dat->szFilterString); //all strings are stored as lowercase ... make sure filter string is lowercase too - - HWND hwndTree = GetDlgItem(hdlg, IDC_PAGETREE); - SendMessage(hwndTree, WM_SETREDRAW, FALSE, 0); - - HWND oldWnd = NULL; - HWND oldTab = NULL; - CMString fullTitle; - - OptionsPageData *opd = dat->getCurrent(); - if (opd != NULL) { - oldWnd = opd->getHwnd(); - if (opd->insideTab) - oldTab = GetDlgItem(hdlg, IDC_TAB); - } - - dat->hCurrentPage = NULL; - - TreeView_SelectItem(hwndTree, NULL); - TreeView_DeleteAllItems(hwndTree); - - TVINSERTSTRUCT tvis; - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_SORT; - tvis.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM; - tvis.item.state = tvis.item.stateMask = TVIS_EXPANDED; - for (int i = 0; i < dat->arOpd.getCount(); i++) { - if (!CheckPageShow(hdlg, dat, i)) - continue; - - opd = dat->arOpd[i]; - TCHAR *ptszGroup = TranslateTH(opd->hLangpack, opd->ptszGroup); - TCHAR *ptszTitle = opd->getString(opd->ptszTitle), *useTitle; - TCHAR *ptszTab = TranslateTH(opd->hLangpack, opd->ptszTab); - - tvis.hParent = NULL; - useTitle = ptszTitle; - - if (ptszGroup != NULL) { - tvis.hParent = FindNamedTreeItemAtRoot(hwndTree, ptszGroup); - if (tvis.hParent == NULL) { - tvis.item.lParam = -1; - tvis.item.pszText = ptszGroup; - tvis.hParent = TreeView_InsertItem(hwndTree, &tvis); - } - } - else { - TVITEM tvi; - tvi.hItem = FindNamedTreeItemAtRoot(hwndTree, useTitle); - if (tvi.hItem != NULL) { - if (i == dat->currentPage) dat->hCurrentPage = tvi.hItem; - tvi.mask = TVIF_PARAM; - TreeView_GetItem(hwndTree, &tvi); - if (tvi.lParam == -1) { - tvi.lParam = i; - TreeView_SetItem(hwndTree, &tvi); - continue; - } - } - } - - if (ptszTab != NULL) { - HTREEITEM hItem; - if (tvis.hParent == NULL) - hItem = FindNamedTreeItemAtRoot(hwndTree, useTitle); - else - hItem = FindNamedTreeItemAtChildren(hwndTree, tvis.hParent, useTitle); - if (hItem != NULL) { - if (i == dat->currentPage) { - TVITEM tvi; - tvi.hItem = hItem; - tvi.mask = TVIF_PARAM; - tvi.lParam = dat->currentPage; - TreeView_SetItem(hwndTree, &tvi); - dat->hCurrentPage = hItem; - } - continue; - } - } - - tvis.item.pszText = useTitle; - tvis.item.lParam = i; - opd->hTreeItem = TreeView_InsertItem(hwndTree, &tvis); - if (i == dat->currentPage) - dat->hCurrentPage = opd->hTreeItem; - } - - char str[128]; - TVITEMA tvi; - tvi.mask = TVIF_TEXT | TVIF_STATE; - tvi.pszText = str; - tvi.cchTextMax = SIZEOF(str); - tvi.hItem = TreeView_GetRoot(hwndTree); - while (tvi.hItem != NULL) { - if (SendMessageA(hwndTree, TVM_GETITEMA, 0, (LPARAM)&tvi)) { - char buf[130]; - mir_snprintf(buf, "%s%s", OPTSTATE_PREFIX, str); - if (!db_get_b(NULL, "Options", buf, 1)) - TreeView_Expand(hwndTree, tvi.hItem, TVE_COLLAPSE); - } - tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); - } - - if (dat->hCurrentPage == NULL) { - dat->hCurrentPage = TreeView_GetRoot(hwndTree); - dat->currentPage = -1; - } - TreeView_SelectItem(hwndTree, dat->hCurrentPage); - - if (oldWnd) { - opd = dat->getCurrent(); - if (opd && oldWnd != opd->getHwnd()) { - ShowWindow(oldWnd, SW_HIDE); - if (oldTab && (opd == NULL || !opd->insideTab)) - ShowWindow(oldTab, SW_HIDE); - } - } - - if (dat->szFilterString[0] == 0) // Clear the keyword combo box - SetDlgItemText(hdlg, IDC_KEYWORD_FILTER, _T("")); - if (!bRemoveFocusFromFilter) - SetFocus(GetDlgItem(hdlg, IDC_KEYWORD_FILTER)); //set the focus back to the combo box - - SendDlgItemMessage(hdlg, IDC_KEYWORD_FILTER, CB_SETEDITSEL, 0, oldSel); //but don't select any of the text - - SendMessage(hwndTree, WM_SETREDRAW, TRUE, 0); - TreeView_EnsureVisible(hwndTree, dat->hCurrentPage); -} - -static BOOL IsInsideTab(HWND hdlg, OptionsDlgData *dat, int i) -{ - OptionsPageData *opd = dat->arOpd[i]; - int pages = 0; - if (opd->ptszTab != NULL) { - // Count tabs to calc position - for (int j = 0; j < dat->arOpd.getCount() && pages < 2; j++) { - OptionsPageData* opd2 = dat->arOpd[j]; - if (!CheckPageShow(hdlg, dat, j)) continue; - if (mir_tstrcmp(opd2->ptszTitle, opd->ptszTitle) || mir_tstrcmp(opd2->ptszGroup, opd->ptszGroup)) - continue; - pages++; - } - } - return (pages > 1); -} - -static void LoadOptionsModule(HWND hdlg, OptionsDlgData *dat, HINSTANCE hInst) -{ - OptionsPageInit opi = { 0 }; - CallPluginEventHook(hInst, hOptionsInitEvent, (WPARAM)&opi, 0); - if (opi.pageCount == 0) - return; - - for (int i = 0; i < opi.pageCount; i++) { - OptionsPageData *opd = new OptionsPageData(&opi.odp[i]); - if (opd->pDialog == NULL) // smth went wrong - delete opd; - else - dat->arOpd.insert(opd); - } - - FreeOptionsData(&opi); - PostMessage(hdlg, DM_REBUILDPAGETREE, 0, 0); -} - -static void UnloadOptionsModule(HWND hdlg, OptionsDlgData *dat, HINSTANCE hInst) -{ - bool bToRebuildTree = false; - - for (int i = dat->arOpd.getCount() - 1; i >= 0; i--) { - OptionsPageData *opd = dat->arOpd[i]; - if (opd->getInst() != hInst) - continue; - - if (dat->currentPage > i) - dat->currentPage--; - - dat->arOpd.remove(i); - delete opd; - bToRebuildTree = true; - } - - if (bToRebuildTree) - PostMessage(hdlg, DM_REBUILDPAGETREE, 0, 0); -} - -static INT_PTR CALLBACK OptionsDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - OptionsPageData *opd; - OptionsDlgData *dat = (OptionsDlgData*)GetWindowLongPtr(hdlg, GWLP_USERDATA); - HWND hwndTree = GetDlgItem(hdlg, IDC_PAGETREE); - - switch (message) { - case WM_CTLCOLORSTATIC: - switch (GetDlgCtrlID((HWND)lParam)) { - case IDC_WHITERECT: - case IDC_KEYWORD_FILTER: - SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); - return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); - } - break; - - case WM_INITDIALOG: - TranslateDialogDefault(hdlg); - - if (!ServiceExists(MS_MODERNOPT_SHOW)) - ShowWindow(GetDlgItem(hdlg, IDC_MODERN), FALSE); - - dat = new OptionsDlgData; - SetWindowLongPtr(hdlg, GWLP_USERDATA, (LONG_PTR)dat); - - Utils_RestoreWindowPositionNoSize(hdlg, NULL, "Options", ""); - Window_SetIcon_IcoLib(hdlg, SKINICON_OTHER_OPTIONS); - EnableWindow(GetDlgItem(hdlg, IDC_APPLY), FALSE); - { - COMBOBOXINFO cbi; - cbi.cbSize = sizeof(COMBOBOXINFO); - GetComboBoxInfo(GetDlgItem(hdlg, IDC_KEYWORD_FILTER), &cbi); - mir_subclassWindow(cbi.hwndItem, OptionsFilterSubclassProc); - - if (IsAeroMode()) { - mir_subclassWindow(cbi.hwndCombo, AeroPaintSubclassProc); - mir_subclassWindow(cbi.hwndItem, AeroPaintSubclassProc); - } - - PROPSHEETHEADER *psh = (PROPSHEETHEADER*)lParam; - SetWindowText(hdlg, psh->pszCaption); - - LOGFONT lf; - dat->hBoldFont = (HFONT)SendDlgItemMessage(hdlg, IDC_APPLY, WM_GETFONT, 0, 0); - GetObject(dat->hBoldFont, sizeof(lf), &lf); - lf.lfWeight = FW_BOLD; - dat->hBoldFont = CreateFontIndirect(&lf); - - dat->hPluginLoad = HookEventMessage(ME_SYSTEM_MODULELOAD, hdlg, HM_MODULELOAD); - dat->hPluginUnload = HookEventMessage(ME_SYSTEM_MODULEUNLOAD, hdlg, HM_MODULEUNLOAD); - dat->currentPage = -1; - - ptrT lastPage, lastGroup, lastTab; - OPENOPTIONSDIALOG *ood = (OPENOPTIONSDIALOG*)psh->pStartPage; - if (ood->pszPage == NULL) { - lastPage = db_get_tsa(NULL, "Options", "LastPage"); - - if (ood->pszGroup == NULL) - lastGroup = db_get_tsa(NULL, "Options", "LastGroup"); - else - lastGroup = mir_a2t(ood->pszGroup); - } - else { - lastPage = mir_a2t(ood->pszPage); - lastGroup = mir_a2t(ood->pszGroup); - } - - if (ood->pszTab == NULL) - lastTab = db_get_tsa(NULL, "Options", "LastTab"); - else - lastTab = mir_a2t(ood->pszTab); - - OPTIONSDIALOGPAGE *odp = (OPTIONSDIALOGPAGE*)psh->ppsp; - for (UINT i = 0; i < psh->nPages; i++, odp++) { - OptionsPageData *opd = new OptionsPageData(odp); - if (opd->pDialog == NULL) // smth went wrong - delete opd; - else - dat->arOpd.insert(opd); - - if (!mir_tstrcmp(lastPage, odp->ptszTitle) && !mir_tstrcmp(lastGroup, odp->ptszGroup)) - if ((ood->pszTab == NULL && dat->currentPage == -1) || !mir_tstrcmp(lastTab, odp->ptszTab)) - dat->currentPage = (int)i; - } - - GetWindowRect(GetDlgItem(hdlg, IDC_STNOPAGE), &dat->rcDisplay); - MapWindowPoints(NULL, hdlg, (LPPOINT)&dat->rcDisplay, 2); - - // Add an item to count in height - TCITEM tie; - tie.mask = TCIF_TEXT | TCIF_IMAGE; - tie.iImage = -1; - tie.pszText = _T("X"); - TabCtrl_InsertItem(GetDlgItem(hdlg, IDC_TAB), 0, &tie); - - GetWindowRect(GetDlgItem(hdlg, IDC_TAB), &dat->rcTab); - MapWindowPoints(NULL, hdlg, (LPPOINT)&dat->rcTab, 2); - TabCtrl_AdjustRect(GetDlgItem(hdlg, IDC_TAB), FALSE, &dat->rcTab); - - FillFilterCombo(hdlg, dat); - PostMessage(hdlg, DM_REBUILDPAGETREE, 0, 0); - } - return TRUE; - - case DM_REBUILDPAGETREE: - RebuildPageTree(hdlg, dat); - break; - - case HM_MODULELOAD: - LoadOptionsModule(hdlg, dat, (HINSTANCE)lParam); - break; - - case HM_MODULEUNLOAD: - UnloadOptionsModule(hdlg, dat, (HINSTANCE)lParam); - break; - - case PSM_CHANGED: - EnableWindow(GetDlgItem(hdlg, IDC_APPLY), TRUE); - - opd = dat->getCurrent(); - if (opd) - opd->changed = 1; - - return TRUE; - - case PSM_GETBOLDFONT: - SetWindowLongPtr(hdlg, DWLP_MSGRESULT, (LONG_PTR)dat->hBoldFont); - return TRUE; - - case WM_NOTIFY: - switch (wParam) { - case IDC_TAB: - case IDC_PAGETREE: - switch (((LPNMHDR)lParam)->code) { - case TVN_ITEMEXPANDING: - SetWindowLongPtr(hdlg, DWLP_MSGRESULT, FALSE); - return TRUE; - - case TCN_SELCHANGING: - case TVN_SELCHANGING: - opd = dat->getCurrent(); - if (opd && opd->getHwnd() != NULL) { - PSHNOTIFY pshn; - pshn.hdr.code = PSN_KILLACTIVE; - pshn.hdr.hwndFrom = dat->arOpd[dat->currentPage]->getHwnd(); - pshn.hdr.idFrom = 0; - pshn.lParam = 0; - if (SendMessage(dat->arOpd[dat->currentPage]->getHwnd(), WM_NOTIFY, 0, (LPARAM)&pshn)) { - SetWindowLongPtr(hdlg, DWLP_MSGRESULT, TRUE); - return TRUE; - } - } - break; - - case TCN_SELCHANGE: - case TVN_SELCHANGED: - ShowWindow(GetDlgItem(hdlg, IDC_STNOPAGE), SW_HIDE); - - opd = dat->getCurrent(); - if (opd && opd->getHwnd() != NULL) - ShowWindow(opd->getHwnd(), SW_HIDE); - - if (wParam != IDC_TAB) { - TVITEM tvi; - tvi.hItem = dat->hCurrentPage = TreeView_GetSelection(hwndTree); - if (tvi.hItem == NULL) { - ShowWindow(GetDlgItem(hdlg, IDC_TAB), SW_HIDE); - break; - } - - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - TreeView_GetItem(hwndTree, &tvi); - dat->currentPage = tvi.lParam; - ShowWindow(GetDlgItem(hdlg, IDC_TAB), SW_HIDE); - } - else { - TCITEM tie; - tie.mask = TCIF_PARAM; - TabCtrl_GetItem(GetDlgItem(hdlg, IDC_TAB), TabCtrl_GetCurSel(GetDlgItem(hdlg, IDC_TAB)), &tie); - dat->currentPage = tie.lParam; - - TVITEM tvi; - tvi.hItem = dat->hCurrentPage; - tvi.mask = TVIF_PARAM; - tvi.lParam = dat->currentPage; - TreeView_SetItem(hwndTree, &tvi); - } - - opd = dat->getCurrent(); - if (opd == NULL) { - ShowWindow(GetDlgItem(hdlg, IDC_STNOPAGE), SW_SHOW); - break; - } - if (opd->getHwnd() == NULL) { - CreateOptionWindow(opd, hdlg); - if (opd->flags & ODPF_BOLDGROUPS) - EnumChildWindows(opd->getHwnd(), BoldGroupTitlesEnumChildren, (LPARAM)dat->hBoldFont); - - RECT rcPage; - GetClientRect(opd->getHwnd(), &rcPage); - int w = opd->width = rcPage.right; - int h = opd->height = rcPage.bottom; - - RECT rc; - GetWindowRect(opd->getHwnd(), &rc); - - opd->insideTab = IsInsideTab(hdlg, dat, dat->currentPage); - if (opd->insideTab) { - SetWindowPos(opd->getHwnd(), HWND_TOP, (dat->rcTab.left + dat->rcTab.right - w) >> 1, dat->rcTab.top, w, h, 0); - ThemeDialogBackground(opd->getHwnd(), TRUE); - } - else { - SetWindowPos(opd->getHwnd(), HWND_TOP, (dat->rcDisplay.left + dat->rcDisplay.right - w) >> 1, (dat->rcDisplay.top + dat->rcDisplay.bottom - h) >> 1, w, h, 0); - ThemeDialogBackground(opd->getHwnd(), FALSE); - } - } - - if (wParam != IDC_TAB) { - opd->insideTab = IsInsideTab(hdlg, dat, dat->currentPage); - if (opd->insideTab) { - // Make tabbed pane - int pages = 0, sel = 0; - HWND hwndTab = GetDlgItem(hdlg, IDC_TAB); - TabCtrl_DeleteAllItems(hwndTab); - - TCITEM tie; - tie.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM; - tie.iImage = -1; - for (int i = 0; i < dat->arOpd.getCount(); i++) { - if (!CheckPageShow(hdlg, dat, i)) - continue; - - OptionsPageData *p = dat->arOpd[i]; - if (mir_tstrcmp(opd->ptszTitle, p->ptszTitle) || mir_tstrcmp(opd->ptszGroup, p->ptszGroup)) - continue; - - tie.pszText = TranslateTH(p->hLangpack, p->ptszTab); - tie.lParam = i; - TabCtrl_InsertItem(hwndTab, pages, &tie); - if (!mir_tstrcmp(opd->ptszTab, p->ptszTab)) - sel = pages; - pages++; - } - TabCtrl_SetCurSel(hwndTab, sel); - ShowWindow(hwndTab, opd->insideTab ? SW_SHOW : SW_HIDE); - } - - ThemeDialogBackground(opd->getHwnd(), opd->insideTab); - } - - ShowWindow(opd->getHwnd(), SW_SHOW); - if (((LPNMTREEVIEW)lParam)->action == TVC_BYMOUSE) - PostMessage(hdlg, DM_FOCUSPAGE, 0, 0); - else - SetFocus(hwndTree); - } - } - break; - - case DM_FOCUSPAGE: - if (dat->currentPage != -1) - SetFocus(dat->arOpd[dat->currentPage]->getHwnd()); - break; - - case WM_TIMER: - if (wParam == FILTER_TIMEOUT_TIMER) { - SaveOptionsTreeState(hdlg); - SendMessage(hdlg, DM_REBUILDPAGETREE, 0, 0); - - KillTimer(hdlg, FILTER_TIMEOUT_TIMER); - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_KEYWORD_FILTER: - // add a timer - when the timer elapses filter the option pages - if ((HIWORD(wParam) == CBN_SELCHANGE) || (HIWORD(wParam) == CBN_EDITCHANGE)) - if (!SetTimer(hdlg, FILTER_TIMEOUT_TIMER, 400, NULL)) - MessageBeep(MB_ICONSTOP); - break; - - case IDC_MODERN: - db_set_b(NULL, "Options", "Expert", 0); - SaveOptionsTreeState(hdlg); - PostMessage(hdlg, WM_CLOSE, 0, 0); - CallService(MS_MODERNOPT_SHOW, 0, 0); - break; - - case IDCANCEL: - { - PSHNOTIFY pshn; - pshn.hdr.idFrom = 0; - pshn.lParam = 0; - pshn.hdr.code = PSN_RESET; - for (int i = 0; i < dat->arOpd.getCount(); i++) { - OptionsPageData *p = dat->arOpd[i]; - if (p->getHwnd() == NULL || !p->changed) - continue; - pshn.hdr.hwndFrom = p->getHwnd(); - SendMessage(p->getHwnd(), WM_NOTIFY, 0, (LPARAM)&pshn); - } - DestroyWindow(hdlg); - } - break; - - case IDOK: - case IDC_APPLY: - if (LOWORD(wParam) == IDOK && GetParent(GetFocus()) == GetDlgItem(hdlg, IDC_KEYWORD_FILTER)) - return TRUE; - - PSHNOTIFY pshn; - EnableWindow(GetDlgItem(hdlg, IDC_APPLY), FALSE); - SetFocus(hwndTree); - - opd = dat->getCurrent(); - if (opd != NULL) { - pshn.hdr.idFrom = 0; - pshn.lParam = LOWORD(wParam); - pshn.hdr.code = PSN_KILLACTIVE; - pshn.hdr.hwndFrom = opd->getHwnd(); - if (SendMessage(opd->getHwnd(), WM_NOTIFY, 0, (LPARAM)&pshn)) - break; - } - - pshn.hdr.code = PSN_APPLY; - for (int i = 0; i < dat->arOpd.getCount(); i++) { - OptionsPageData *p = dat->arOpd[i]; - if (p->getHwnd() == NULL || !p->changed) continue; - p->changed = 0; - pshn.hdr.hwndFrom = p->getHwnd(); - if (SendMessage(p->getHwnd(), WM_NOTIFY, 0, (LPARAM)&pshn) == PSNRET_INVALID_NOCHANGEPAGE) { - dat->hCurrentPage = p->hTreeItem; - TreeView_SelectItem(hwndTree, dat->hCurrentPage); - if (opd) - opd->pDialog->Show(SW_HIDE); - dat->currentPage = i; - if (opd) - opd->pDialog->Show(); - return 0; - } - } - - if (LOWORD(wParam) == IDOK) - DestroyWindow(hdlg); - } - break; - - case WM_DESTROY: - if (FilterTimerId) - KillTimer(hdlg, FilterTimerId); - DestroyWindow(hFilterSearchWnd); - ClearFilterStrings(); - dat->szFilterString[0] = 0; - - UnhookEvent(dat->hPluginLoad); - UnhookEvent(dat->hPluginUnload); - - SaveOptionsTreeState(hdlg); - Window_FreeIcon_IcoLib(hdlg); - - opd = dat->getCurrent(); - if (opd) { - if (opd->ptszTab) - db_set_ts(NULL, "Options", "LastTab", opd->ptszTab); - else - db_unset(NULL, "Options", "LastTab"); - if (opd->ptszGroup) - db_set_ts(NULL, "Options", "LastGroup", opd->ptszGroup); - else - db_unset(NULL, "Options", "LastGroup"); - db_set_ts(NULL, "Options", "LastPage", opd->ptszTitle); - } - else { - db_unset(NULL, "Options", "LastTab"); - db_unset(NULL, "Options", "LastGroup"); - db_unset(NULL, "Options", "LastPage"); - } - - Utils_SaveWindowPosition(hdlg, NULL, "Options", ""); - - for (int i = 0; i < dat->arOpd.getCount(); i++) - delete dat->arOpd[i]; - - DeleteObject(dat->hBoldFont); - delete dat; - hwndOptions = NULL; - - CallService(MS_MODERNOPT_RESTORE, 0, 0); - break; - } - return FALSE; -} - -void OpenAccountOptions(PROTOACCOUNT *pa) -{ - if (pa->ppro == NULL) - return; - - OptionsPageInit opi = { 0 }; - pa->ppro->OnEvent(EV_PROTO_ONOPTIONS, (WPARAM)&opi, 0); - if (opi.pageCount == 0) - return; - - TCHAR tszTitle[100]; - mir_sntprintf(tszTitle, SIZEOF(tszTitle), TranslateT("%s options"), pa->tszAccountName); - - OPENOPTIONSDIALOG ood = { sizeof(ood) }; - ood.pszGroup = LPGEN("Network"); - ood.pszPage = mir_t2a(pa->tszAccountName); - - PROPSHEETHEADER psh = { sizeof(psh) }; - psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW; - psh.hwndParent = NULL; - psh.nPages = opi.pageCount; - psh.pStartPage = (LPCTSTR)&ood; - psh.pszCaption = tszTitle; - psh.ppsp = (PROPSHEETPAGE*)opi.odp; - hwndOptions = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_OPTIONSPAGE), NULL, OptionsDlgProc, (LPARAM)&psh); - mir_free((void*)ood.pszPage); - FreeOptionsData(&opi); -} - -static void OpenOptionsNow(int hLangpack, const char *pszGroup, const char *pszPage, const char *pszTab, bool bSinglePage = false) -{ - if (IsWindow(hwndOptions)) { - ShowWindow(hwndOptions, SW_RESTORE); - SetForegroundWindow(hwndOptions); - if (pszPage != NULL) { - ptrT ptszPage(mir_a2t(pszPage)); - HTREEITEM hItem = NULL; - if (pszGroup != NULL) { - ptrT ptszGroup(mir_a2t(pszGroup)); - hItem = FindNamedTreeItemAtRoot(GetDlgItem(hwndOptions, IDC_PAGETREE), TranslateTH(hLangpack, ptszGroup)); - if (hItem != NULL) - hItem = FindNamedTreeItemAtChildren(GetDlgItem(hwndOptions, IDC_PAGETREE), hItem, TranslateTH(hLangpack, ptszPage)); - } - else hItem = FindNamedTreeItemAtRoot(GetDlgItem(hwndOptions, IDC_PAGETREE), TranslateTH(hLangpack, ptszPage)); - - if (hItem != NULL) - TreeView_SelectItem(GetDlgItem(hwndOptions, IDC_PAGETREE), hItem); - } - } - else { - OptionsPageInit opi = { 0 }; - NotifyEventHooks(hOptionsInitEvent, (WPARAM)&opi, 0); - if (opi.pageCount == 0) - return; - - OPENOPTIONSDIALOG ood = { 0 }; - ood.cbSize = sizeof(ood); - ood.pszGroup = pszGroup; - ood.pszPage = pszPage; - ood.pszTab = pszTab; - - PROPSHEETHEADER psh = { 0 }; - psh.dwSize = sizeof(psh); - psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW; - psh.nPages = opi.pageCount; - psh.pStartPage = (LPCTSTR)&ood; // more structure misuse - psh.pszCaption = TranslateT("Miranda NG options"); - psh.ppsp = (PROPSHEETPAGE*)opi.odp; // blatent misuse of the structure, but what the hell - - hwndOptions = CreateDialogParam(hInst, - MAKEINTRESOURCE(bSinglePage ? IDD_OPTIONSPAGE : IDD_OPTIONS), - NULL, OptionsDlgProc, (LPARAM)&psh); - - FreeOptionsData(&opi); - } -} - -static INT_PTR OpenOptions(WPARAM wParam, LPARAM lParam) -{ - OPENOPTIONSDIALOG *ood = (OPENOPTIONSDIALOG*)lParam; - if (ood == NULL || ood->cbSize != sizeof(OPENOPTIONSDIALOG)) - return 1; - - OpenOptionsNow((int)wParam, ood->pszGroup, ood->pszPage, ood->pszTab); - return 0; -} - -static INT_PTR OpenOptionsPage(WPARAM wParam, LPARAM lParam) -{ - OPENOPTIONSDIALOG *ood = (OPENOPTIONSDIALOG*)lParam; - if (ood == NULL || ood->cbSize != sizeof(OPENOPTIONSDIALOG)) - return 1; - - OpenOptionsNow((int)wParam, ood->pszGroup, ood->pszPage, ood->pszTab, true); - return (INT_PTR)hwndOptions; -} - -static INT_PTR OpenOptionsDialog(WPARAM, LPARAM) -{ - if (hwndOptions || !ServiceExists(MS_MODERNOPT_SHOW)) - OpenOptionsNow(NULL, NULL, NULL, NULL); - else - CallService(MS_MODERNOPT_SHOW, 0, 0); - return 0; -} - -static INT_PTR AddOptionsPage(WPARAM wParam, LPARAM lParam) -{ - OPTIONSDIALOGPAGE *odp = (OPTIONSDIALOGPAGE*)lParam, *dst; - OptionsPageInit *opi = (OptionsPageInit*)wParam; - if (odp == NULL || opi == NULL) - return 1; - - opi->odp = (OPTIONSDIALOGPAGE*)mir_realloc(opi->odp, sizeof(OPTIONSDIALOGPAGE)*(opi->pageCount + 1)); - dst = opi->odp + opi->pageCount; - memcpy(dst, odp, sizeof(OPTIONSDIALOGPAGE)); - - if (odp->ptszTitle != NULL) { - if (odp->flags & ODPF_UNICODE) - dst->ptszTitle = mir_wstrdup(odp->ptszTitle); - else { - dst->ptszTitle = mir_a2u(odp->pszTitle); - dst->flags |= ODPF_UNICODE; - } - } - - if (odp->ptszGroup != NULL) { - if (odp->flags & ODPF_UNICODE) - dst->ptszGroup = mir_wstrdup(odp->ptszGroup); - else { - dst->ptszGroup = mir_a2t(odp->pszGroup); - dst->flags |= ODPF_UNICODE; - } - } - - if (odp->ptszTab != NULL) { - if (odp->flags & ODPF_UNICODE) - dst->ptszTab = mir_wstrdup(odp->ptszTab); - else { - dst->ptszTab = mir_a2t(odp->pszTab); - dst->flags |= ODPF_UNICODE; - } - } - - if ((DWORD_PTR)odp->pszTemplate & 0xFFFF0000) - dst->pszTemplate = mir_strdup(odp->pszTemplate); - - opi->pageCount++; - return 0; -} - -static int OptModulesLoaded(WPARAM, LPARAM) -{ - CLISTMENUITEM mi = { sizeof(mi) }; - mi.icolibItem = GetSkinIconHandle(SKINICON_OTHER_OPTIONS); - mi.position = 1900000000; - mi.pszName = LPGEN("&Options..."); - mi.pszService = "Options/OptionsCommand"; - Menu_AddMainMenuItem(&mi); - return 0; -} - -int ShutdownOptionsModule(WPARAM, LPARAM) -{ - if (IsWindow(hwndOptions)) { - DestroyWindow(hwndOptions); - hwndOptions = NULL; - } - return 0; -} - -int LoadOptionsModule(void) -{ - hwndOptions = NULL; - hOptionsInitEvent = CreateHookableEvent(ME_OPT_INITIALISE); - HookEvent(ME_OPT_INITIALISE, LangpackOptionsInit); - - CreateServiceFunction("Opt/AddPage", AddOptionsPage); - CreateServiceFunction("Opt/OpenOptions", OpenOptions); - CreateServiceFunction("Opt/OpenOptionsPage", OpenOptionsPage); - CreateServiceFunction("Options/OptionsCommand", OpenOptionsDialog); - HookEvent(ME_SYSTEM_MODULESLOADED, OptModulesLoaded); - HookEvent(ME_SYSTEM_PRESHUTDOWN, ShutdownOptionsModule); - return 0; -} diff --git a/src/modules/plugins/dll_sniffer.cpp b/src/modules/plugins/dll_sniffer.cpp deleted file mode 100644 index 31a566346c..0000000000 --- a/src/modules/plugins/dll_sniffer.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "plugins.h" - -static IMAGE_SECTION_HEADER *getSectionByRVA(IMAGE_SECTION_HEADER *pISH, int nSections, IMAGE_DATA_DIRECTORY *pIDD) -{ - for (int i=0; i < nSections; i++, pISH++) - if (pIDD->VirtualAddress >= pISH->VirtualAddress && pIDD->VirtualAddress + pIDD->Size <= pISH->VirtualAddress + pISH->SizeOfRawData ) - return pISH; - - return NULL; -} - -MUUID* GetPluginInterfaces(const TCHAR* ptszFileName, bool& bIsPlugin) -{ - bIsPlugin = false; - - HANDLE hFile = CreateFile( ptszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); - if (hFile == INVALID_HANDLE_VALUE) - return NULL; - - MUUID* pResult = NULL; - BYTE* ptr = NULL; - HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL ); - - __try { - __try { - if (!hMap ) - __leave; - - DWORD dwHSize = 0, filesize = GetFileSize( hFile, &dwHSize ); - if (!filesize || filesize == INVALID_FILE_SIZE || dwHSize) - __leave; - - if ( filesize < sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) ) - __leave; - - ptr = (BYTE*)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0); - if (ptr == NULL) - __leave; - - PIMAGE_NT_HEADERS pINTH = { 0 }; - PIMAGE_DOS_HEADER pIDH = (PIMAGE_DOS_HEADER)ptr; - if ( pIDH->e_magic == IMAGE_DOS_SIGNATURE ) - pINTH = (PIMAGE_NT_HEADERS)(ptr + pIDH->e_lfanew); - else - __leave; - - if ((PBYTE)pINTH + sizeof(IMAGE_NT_HEADERS) >= ptr + filesize ) - __leave; - if ( pINTH->Signature != IMAGE_NT_SIGNATURE ) - __leave; - - int nSections = pINTH->FileHeader.NumberOfSections; - if (!nSections ) - __leave; - - INT_PTR base; - PIMAGE_DATA_DIRECTORY pIDD; - if ( pINTH->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 && - pINTH->FileHeader.SizeOfOptionalHeader >= sizeof(IMAGE_OPTIONAL_HEADER32) && - pINTH->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) - { - pIDD = (PIMAGE_DATA_DIRECTORY)( (PBYTE)pINTH + offsetof( IMAGE_NT_HEADERS32, OptionalHeader.DataDirectory )); - base = *(DWORD*)((PBYTE)pINTH + offsetof(IMAGE_NT_HEADERS32, OptionalHeader.ImageBase)); - } - else if ( pINTH->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 && - pINTH->FileHeader.SizeOfOptionalHeader >= sizeof(IMAGE_OPTIONAL_HEADER64) && - pINTH->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) - { - pIDD = (PIMAGE_DATA_DIRECTORY)( (PBYTE)pINTH + offsetof( IMAGE_NT_HEADERS64, OptionalHeader.DataDirectory )); - base = *(ULONGLONG*)((PBYTE)pINTH + offsetof(IMAGE_NT_HEADERS64, OptionalHeader.ImageBase )); - } - else __leave; - - // Export information entry - DWORD expvaddr = pIDD[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - DWORD expsize = pIDD[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; - if (expsize < sizeof(IMAGE_EXPORT_DIRECTORY)) __leave; - - BYTE* pImage = ptr + pIDH->e_lfanew + pINTH->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_NT_HEADERS) - sizeof(IMAGE_OPTIONAL_HEADER); - IMAGE_SECTION_HEADER *pExp = getSectionByRVA((IMAGE_SECTION_HEADER *)pImage, nSections, pIDD); - if (!pExp) __leave; - - BYTE *pSecStart = ptr + pExp->PointerToRawData - pExp->VirtualAddress; - IMAGE_EXPORT_DIRECTORY *pED = (PIMAGE_EXPORT_DIRECTORY)&pSecStart[expvaddr]; - DWORD *ptrRVA = (DWORD*)&pSecStart[pED->AddressOfNames]; - WORD *ptrOrdRVA = (WORD*)&pSecStart[pED->AddressOfNameOrdinals]; - DWORD *ptrFuncList = (DWORD*)&pSecStart[pED->AddressOfFunctions]; - - MUUID* pIds; - bool bHasLoad = false, bHasUnload = false, bHasInfo = false, bHasMuuids = false; - for (size_t i=0; i < pED->NumberOfNames; i++, ptrRVA++, ptrOrdRVA++) { - char *szName = (char*)&pSecStart[*ptrRVA]; - if (!mir_strcmp(szName, "Load")) - bHasLoad = true; - if (!mir_strcmp(szName, "MirandaPluginInfoEx")) - bHasInfo = true; - else if (!mir_strcmp(szName, "Unload")) - bHasUnload = true; - else if (!mir_strcmp(szName, "MirandaInterfaces")) { - bHasMuuids = true; - pIds = (MUUID*)&pSecStart[ ptrFuncList[*ptrOrdRVA]]; - } - // old plugin, skip it - else if (!mir_strcmp(szName, "MirandaPluginInterfaces")) - __leave; - } - - // a plugin might have no interfaces - if (bHasLoad && bHasUnload && bHasInfo) - bIsPlugin = true; - - if (!bHasLoad || !bHasMuuids || !bHasUnload) - __leave; - - int nLength = 1; // one for MIID_LAST - for (MUUID* p = pIds; !equalUUID(*p, miid_last); p++) - nLength++; - - pResult = (MUUID*)mir_alloc( sizeof(MUUID)*nLength); - if (pResult) - memcpy(pResult, pIds, sizeof(MUUID)*nLength); - } - __except(EXCEPTION_EXECUTE_HANDLER) - {}; - } - __finally - { - if (ptr) UnmapViewOfFile(ptr); - if (hMap) CloseHandle(hMap); - CloseHandle(hFile); - }; - - return pResult; -} diff --git a/src/modules/plugins/newplugins.cpp b/src/modules/plugins/newplugins.cpp deleted file mode 100644 index 6eccaa8059..0000000000 --- a/src/modules/plugins/newplugins.cpp +++ /dev/null @@ -1,898 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#include "plugins.h" -#include "..\database\profilemanager.h" -#include "..\langpack\langpack.h" - -void LoadExtraIconsModule(); - -extern bool bModulesLoadedFired; - -static int sttComparePluginsByName(const pluginEntry* p1, const pluginEntry* p2) -{ - return mir_tstrcmpi(p1->pluginname, p2->pluginname); -} - -LIST - pluginList(10, sttComparePluginsByName), - servicePlugins(5, sttComparePluginsByName), - clistPlugins(5, sttComparePluginsByName); - -///////////////////////////////////////////////////////////////////////////////////////// - -#define MAX_MIR_VER ULONG_MAX - -static BOOL bModuleInitialized = FALSE; - -TCHAR mirandabootini[MAX_PATH]; -static DWORD mirandaVersion; -static int sttFakeID = -100; -static HANDLE hPluginListHeap = NULL; -static int askAboutIgnoredPlugins; - -static pluginEntry *plugin_freeimg, *plugin_crshdmp, *serviceModePlugin, *plugin_ssl; - -#define PLUGINDISABLELIST "PluginDisable" - -///////////////////////////////////////////////////////////////////////////////////////// -// basic functions - -int equalUUID(const MUUID& u1, const MUUID& u2) -{ - return memcmp(&u1, &u2, sizeof(MUUID)) ? 0 : 1; -} - -bool hasMuuid(const MUUID* p, const MUUID& uuid) -{ - if (p == NULL) - return false; - - for (int i = 0; !equalUUID(miid_last, p[i]); i++) - if (equalUUID(uuid, p[i])) - return true; - - return false; -} - -bool hasMuuid(const BASIC_PLUGIN_INFO& bpi, const MUUID& uuid) -{ - if (bpi.Interfaces) - return hasMuuid(bpi.Interfaces, uuid); - - return false; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// banned plugins - -static const MUUID pluginBannedList[] = -{ - { 0x9d6c3213, 0x02b4, 0x4fe1, { 0x92, 0xe6, 0x52, 0x6d, 0xe2, 0x4f, 0x8d, 0x65 } }, // old chat - { 0x240a91dc, 0x9464, 0x457a, { 0x97, 0x87, 0xff, 0x1e, 0xa8, 0x8e, 0x77, 0xe3 } }, // old clist - { 0x657fe89b, 0xd121, 0x40c2, { 0x8a, 0xc9, 0xb9, 0xfa, 0x57, 0x55, 0xb3, 0x0c } }, // old srmm - { 0x112f7d30, 0xcd19, 0x4c74, { 0xa0, 0x3b, 0xbf, 0xbb, 0x76, 0xb7, 0x5b, 0xc4 } }, // extraicons - { 0x72765a6f, 0xb017, 0x42f1, { 0xb3, 0x0f, 0x5e, 0x09, 0x41, 0x27, 0x3a, 0x3f } }, // flashavatars - { 0x1394a3ab, 0x2585, 0x4196, { 0x8f, 0x72, 0x0e, 0xae, 0xc2, 0x45, 0x0e, 0x11 } }, // db3x - { 0x28ff9b91, 0x3e4d, 0x4f1c, { 0xb4, 0x7c, 0xc6, 0x41, 0xb0, 0x37, 0xff, 0x40 } }, // dbx_mmap_sa - { 0x28f45248, 0x8c9c, 0x4bee, { 0x93, 0x07, 0x7b, 0xcf, 0x3e, 0x12, 0xbf, 0x99 } }, // dbx_tree - { 0x4c4a27cf, 0x5e64, 0x4242, { 0xa3, 0x32, 0xb9, 0x8b, 0x08, 0x24, 0x3e, 0x89 } }, // metacontacts - { 0x9c448c61, 0xfc3f, 0x42f9, { 0xb9, 0xf0, 0x4a, 0x30, 0xe1, 0xcf, 0x86, 0x71 } }, // skypekit based skype - { 0x49c2cf54, 0x7898, 0x44de, { 0xbe, 0x3a, 0x6d, 0x2e, 0x4e, 0xf9, 0x00, 0x79 } } // firstrun -}; - -static bool isPluginBanned(const MUUID& u1) -{ - for (int i = 0; i < SIZEOF(pluginBannedList); i++) - if (equalUUID(pluginBannedList[i], u1)) - return true; - - return false; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// default plugins - -static MuuidReplacement pluginDefault[] = -{ - { MIID_UIUSERINFO, _T("stduserinfo"), NULL }, // 0 - { MIID_SRURL, _T("stdurl"), NULL }, // 1 - { MIID_SREMAIL, _T("stdemail"), NULL }, // 2 - { MIID_SRAUTH, _T("stdauth"), NULL }, // 3 - { MIID_SRFILE, _T("stdfile"), NULL }, // 4 - { MIID_UIHELP, _T("stdhelp"), NULL }, // 5 - { MIID_UIHISTORY, _T("stduihist"), NULL }, // 6 - { MIID_IDLE, _T("stdidle"), NULL }, // 7 - { MIID_AUTOAWAY, _T("stdautoaway"), NULL }, // 8 - { MIID_USERONLINE, _T("stduseronline"), NULL }, // 9 - { MIID_SRAWAY, _T("stdaway"), NULL }, // 10 - { MIID_CLIST, _T("stdclist"), NULL }, // 11 - { MIID_CHAT, _T("stdchat"), NULL }, // 12 - { MIID_SRMM, _T("stdmsg"), NULL } // 13 -}; - -int getDefaultPluginIdx(const MUUID &muuid) -{ - for (int i = 0; i < SIZEOF(pluginDefault); i++) - if (equalUUID(muuid, pluginDefault[i].uuid)) - return i; - - return -1; -} - -int LoadStdPlugins() -{ - for (int i = 0; i < SIZEOF(pluginDefault); i++) { - if (pluginDefault[i].pImpl) - continue; - - if (!LoadCorePlugin(pluginDefault[i])) - return 1; - } - - if (pluginDefault[13].pImpl == NULL) - MessageBox(NULL, TranslateT("No messaging plugins loaded. Please install/enable one of the messaging plugins, for instance, \"StdMsg.dll\""), _T("Miranda NG"), MB_OK | MB_ICONWARNING); - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// global functions - -char* GetPluginNameByInstance(HINSTANCE hInstance) -{ - if (pluginList.getCount() == 0) - return NULL; - - for (int i = 0; i < pluginList.getCount(); i++) { - pluginEntry *p = pluginList[i]; - if (p->bpi.pluginInfo && p->bpi.hInst == hInstance) - return p->bpi.pluginInfo->shortName; - } - return NULL; -} - -int GetPluginLangByInstance(HINSTANCE hInstance) -{ - if (pluginList.getCount() == 0) - return NULL; - - for (int i = 0; i < pluginList.getCount(); i++) { - pluginEntry *p = pluginList[i]; - if (p->bpi.pluginInfo && p->bpi.hInst == hInstance) - return p->hLangpack; - } - return NULL; -} - -int GetPluginFakeId(const MUUID &uuid, int hLangpack) -{ - for (int i = 0; i < pluginList.getCount(); i++) { - pluginEntry *p = pluginList[i]; - if (!p->bpi.hInst) - continue; - - if (equalUUID(p->bpi.pluginInfo->uuid, uuid)) - return p->hLangpack = (hLangpack) ? hLangpack : --sttFakeID; - } - - return 0; -} - -MUUID miid_last = MIID_LAST; -MUUID miid_chat = MIID_CHAT; -MUUID miid_srmm = MIID_SRMM; -MUUID miid_clist = MIID_CLIST; -MUUID miid_database = MIID_DATABASE; -MUUID miid_protocol = MIID_PROTOCOL; -MUUID miid_servicemode = MIID_SERVICEMODE; -MUUID miid_crypto = MIID_CRYPTO; -MUUID miid_ssl = MIID_SSL; - -static bool validInterfaceList(MUUID *piface) -{ - if (piface == NULL) - return true; - - if (equalUUID(miid_last, piface[0])) - return false; - - return true; -} - -static int checkPI(BASIC_PLUGIN_INFO* bpi, PLUGININFOEX* pi) -{ - if (pi == NULL) - return FALSE; - - if (bpi->InfoEx == NULL || pi->cbSize != sizeof(PLUGININFOEX)) - return FALSE; - - if (!validInterfaceList(bpi->Interfaces) || isPluginBanned(pi->uuid)) - return FALSE; - - if (pi->shortName == NULL || pi->description == NULL || pi->author == NULL || - pi->authorEmail == NULL || pi->copyright == NULL || pi->homepage == NULL) - return FALSE; - - return TRUE; -} - -int checkAPI(TCHAR* plugin, BASIC_PLUGIN_INFO* bpi, DWORD mirandaVersion, int checkTypeAPI) -{ - HINSTANCE h = LoadLibrary(plugin); - if (h == NULL) - return 0; - - // loaded, check for exports - bpi->Load = (Miranda_Plugin_Load)GetProcAddress(h, "Load"); - bpi->Unload = (Miranda_Plugin_Unload)GetProcAddress(h, "Unload"); - bpi->InfoEx = (Miranda_Plugin_InfoEx)GetProcAddress(h, "MirandaPluginInfoEx"); - - // if they were present - if (!bpi->Load || !bpi->Unload || !bpi->InfoEx) { -LBL_Error: - FreeLibrary(h); - return 0; - } - - bpi->Interfaces = (MUUID*)GetProcAddress(h, "MirandaInterfaces"); - if (bpi->Interfaces == NULL) { - typedef MUUID * (__cdecl * Miranda_Plugin_Interfaces) (void); - Miranda_Plugin_Interfaces pFunc = (Miranda_Plugin_Interfaces)GetProcAddress(h, "MirandaPluginInterfaces"); - if (pFunc) - bpi->Interfaces = pFunc(); - } - - PLUGININFOEX* pi = bpi->InfoEx(mirandaVersion); - if (!checkPI(bpi, pi)) - goto LBL_Error; - - bpi->pluginInfo = pi; - // basic API is present - if (checkTypeAPI == CHECKAPI_NONE) { -LBL_Ok: - bpi->hInst = h; - return 1; - } - // check clist ? - if (checkTypeAPI == CHECKAPI_CLIST) { - bpi->clistlink = (CList_Initialise)GetProcAddress(h, "CListInitialise"); - if ((pi->flags & UNICODE_AWARE) && bpi->clistlink) - goto LBL_Ok; - } - goto LBL_Error; -} - -// perform any API related tasks to freeing -void Plugin_Uninit(pluginEntry *p) -{ - // if the basic API check had passed, call Unload if Load(void) was ever called - if (p->pclass & PCLASS_LOADED) { - p->bpi.Unload(); - p->pclass &= ~PCLASS_LOADED; - } - - // release the library - HINSTANCE hInst = p->bpi.hInst; - if (hInst != NULL) { - // we need to kill all resources which belong to that DLL before calling FreeLibrary - KillModuleEventHooks(hInst); - KillModuleServices(hInst); - UnregisterModule(hInst); - - FreeLibrary(hInst); - memset(&p->bpi, 0, sizeof(p->bpi)); - } - - if (p == plugin_crshdmp) - plugin_crshdmp = NULL; - pluginList.remove(p); -} - -int Plugin_UnloadDyn(pluginEntry *p) -{ - if (p->bpi.hInst) { - if (CallPluginEventHook(p->bpi.hInst, hOkToExitEvent, 0, 0) != 0) - return FALSE; - - KillModuleSubclassing(p->bpi.hInst); - - CallPluginEventHook(p->bpi.hInst, hPreShutdownEvent, 0, 0); - CallPluginEventHook(p->bpi.hInst, hShutdownEvent, 0, 0); - - KillModuleEventHooks(p->bpi.hInst); - KillModuleServices(p->bpi.hInst); - } - - int hLangpack = p->hLangpack; - if (hLangpack != 0) { - KillModuleMenus(hLangpack); - KillModuleFonts(hLangpack); - KillModuleColours(hLangpack); - KillModuleEffects(hLangpack); - KillModuleIcons(hLangpack); - KillModuleHotkeys(hLangpack); - KillModuleSounds(hLangpack); - KillModuleExtraIcons(hLangpack); - KillModuleSrmmIcons(hLangpack); - } - - NotifyFastHook(hevUnloadModule, (WPARAM)p->bpi.pluginInfo, (LPARAM)p->bpi.hInst); - - Plugin_Uninit(p); - - // mark default plugins to be loaded - if (!(p->pclass & PCLASS_CORE)) - for (int i = 0; i < SIZEOF(pluginDefault); i++) - if (pluginDefault[i].pImpl == p) - pluginDefault[i].pImpl = NULL; - - return TRUE; -} - -// returns true if the given file is .dll exactly -static int valid_library_name(TCHAR *name) -{ - TCHAR *dot = _tcsrchr(name, '.'); - if (dot != NULL && mir_tstrcmpi(dot + 1, _T("dll")) == 0) - if (dot[4] == 0) - return 1; - - return 0; -} - -void enumPlugins(SCAN_PLUGINS_CALLBACK cb, WPARAM wParam, LPARAM lParam) -{ - // get miranda's exe path - TCHAR exe[MAX_PATH]; - GetModuleFileName(NULL, exe, SIZEOF(exe)); - TCHAR *p = _tcsrchr(exe, '\\'); if (p) *p = 0; - - // create the search filter - TCHAR search[MAX_PATH]; - mir_sntprintf(search, SIZEOF(search), _T("%s\\Plugins\\*.dll"), exe); - - // FFFN will return filenames for things like dot dll+ or dot dllx - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile(search, &ffd); - if (hFind == INVALID_HANDLE_VALUE) - return; - - do { - if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && valid_library_name(ffd.cFileName)) - cb(&ffd, exe, wParam, lParam); - } while (FindNextFile(hFind, &ffd)); - FindClose(hFind); -} - -pluginEntry* OpenPlugin(TCHAR *tszFileName, TCHAR *dir, TCHAR *path) -{ - pluginEntry *p = (pluginEntry*)HeapAlloc(hPluginListHeap, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, sizeof(pluginEntry)); - _tcsncpy_s(p->pluginname, tszFileName, _TRUNCATE); - - // add it to the list anyway - pluginList.insert(p); - - TCHAR tszFullPath[MAX_PATH]; - mir_sntprintf(tszFullPath, SIZEOF(tszFullPath), _T("%s\\%s\\%s"), path, dir, tszFileName); - - // map dll into the memory and check its exports - bool bIsPlugin = false; - mir_ptr pIds(GetPluginInterfaces(tszFullPath, bIsPlugin)); - if (!bIsPlugin) { - p->pclass |= PCLASS_FAILED; // piece of shit - return p; - } - - // plugin declared that it's a database or a cryptor. load it asap! - bool bIsDb = hasMuuid(pIds, miid_database); - if (bIsDb || hasMuuid(pIds, miid_crypto)) { - BASIC_PLUGIN_INFO bpi; - if (checkAPI(tszFullPath, &bpi, mirandaVersion, CHECKAPI_NONE)) { - // plugin is valid - p->pclass |= ((bIsDb ? PCLASS_DB : PCLASS_CRYPT) | PCLASS_BASICAPI); - // copy the dblink stuff - p->bpi = bpi; - - RegisterModule(p->bpi.hInst); - if (bpi.Load() != 0) - p->pclass |= PCLASS_FAILED; - else - p->pclass |= PCLASS_LOADED; - } - else p->pclass |= PCLASS_FAILED; - } - // plugin declared that it's a contact list. mark it for the future load - else if (hasMuuid(pIds, miid_clist)) { - // keep a note of this plugin for later - clistPlugins.insert(p); - p->pclass |= PCLASS_CLIST; - } - // plugin declared that it's a ssl provider. mark it for the future load - else if (hasMuuid(pIds, miid_ssl)) { - plugin_ssl = p; - p->pclass |= PCLASS_LAST; - } - // plugin declared that it's a service mode plugin. - // load it for a profile manager's window - else if (hasMuuid(pIds, miid_servicemode)) { - BASIC_PLUGIN_INFO bpi; - if (checkAPI(tszFullPath, &bpi, mirandaVersion, CHECKAPI_NONE)) { - p->pclass |= (PCLASS_OK | PCLASS_BASICAPI); - p->bpi = bpi; - if (hasMuuid(bpi, miid_servicemode)) { - p->pclass |= (PCLASS_SERVICE); - servicePlugins.insert(p); - } - } - else - // didn't have basic APIs or DB exports - failed. - p->pclass |= PCLASS_FAILED; - } - return p; -} - -void SetPluginOnWhiteList(const TCHAR* pluginname, int allow) -{ - db_set_b(NULL, PLUGINDISABLELIST, _strlwr(_T2A(pluginname)), allow == 0); -} - -// returns 1 if the plugin should be enabled within this profile, filename is always lower case -int isPluginOnWhiteList(const TCHAR* pluginname) -{ - int rc = db_get_b(NULL, PLUGINDISABLELIST, _strlwr(_T2A(pluginname)), 0); - if (rc != 0 && askAboutIgnoredPlugins) { - TCHAR buf[256]; - mir_sntprintf(buf, TranslateT("'%s' is disabled, re-enable?"), pluginname); - if (MessageBox(NULL, buf, TranslateT("Re-enable Miranda plugin?"), MB_YESNO | MB_ICONQUESTION) == IDYES) { - SetPluginOnWhiteList(pluginname, 1); - rc = 0; - } - } - - return rc == 0; -} - -bool TryLoadPlugin(pluginEntry *p, bool bDynamic) -{ - TCHAR exe[MAX_PATH], tszFullPath[MAX_PATH]; - GetModuleFileName(NULL, exe, SIZEOF(exe)); - TCHAR* slice = _tcsrchr(exe, '\\'); - if (slice) - *slice = 0; - - if (!(p->pclass & (PCLASS_LOADED | PCLASS_DB | PCLASS_CLIST))) { - if (!bDynamic && !isPluginOnWhiteList(p->pluginname)) - return false; - - if (!(p->pclass & PCLASS_BASICAPI)) { - BASIC_PLUGIN_INFO bpi; - mir_sntprintf(tszFullPath, SIZEOF(tszFullPath), _T("%s\\%s\\%s"), exe, (p->pclass & PCLASS_CORE) ? _T("Core") : _T("Plugins"), p->pluginname); - if (!checkAPI(tszFullPath, &bpi, mirandaVersion, CHECKAPI_NONE)) { - p->pclass |= PCLASS_FAILED; - return false; - } - - p->bpi = bpi; - p->pclass |= PCLASS_OK | PCLASS_BASICAPI; - } - - if (p->bpi.Interfaces) { - MUUID *piface = p->bpi.Interfaces; - for (int i = 0; !equalUUID(miid_last, piface[i]); i++) { - int idx = getDefaultPluginIdx(piface[i]); - if (idx != -1 && pluginDefault[idx].pImpl) { - if (!bDynamic) { // this place is already occupied, skip & disable - SetPluginOnWhiteList(p->pluginname, 0); - return false; - } - - // we're loading new implementation dynamically, let the old one die - if (!(p->pclass & PCLASS_CORE)) - Plugin_UnloadDyn(pluginDefault[idx].pImpl); - } - } - } - - RegisterModule(p->bpi.hInst); - if (p->bpi.Load() != 0) - return false; - - p->pclass |= PCLASS_LOADED; - if (p->bpi.Interfaces) { - MUUID *piface = p->bpi.Interfaces; - for (int i = 0; !equalUUID(miid_last, piface[i]); i++) { - int idx = getDefaultPluginIdx(piface[i]); - if (idx != -1) - pluginDefault[idx].pImpl = p; - } - } - } - else if (p->bpi.hInst != NULL) { - RegisterModule(p->bpi.hInst); - p->pclass |= PCLASS_LOADED; - } - return true; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Core plugins support - -static TCHAR tszCoreErr[] = LPGENT("Core plugin '%s' cannot be loaded or missing. Miranda will exit now"); - -bool LoadCorePlugin(MuuidReplacement& mr) -{ - TCHAR exe[MAX_PATH], tszPlugName[MAX_PATH]; - GetModuleFileName(NULL, exe, SIZEOF(exe)); - TCHAR *p = _tcsrchr(exe, '\\'); if (p) *p = 0; - - mir_sntprintf(tszPlugName, SIZEOF(tszPlugName), _T("%s.dll"), mr.stdplugname); - pluginEntry* pPlug = OpenPlugin(tszPlugName, _T("Core"), exe); - if (pPlug->pclass & PCLASS_FAILED) { -LBL_Error: - MessageBox(NULL, CMString(FORMAT, TranslateTS(tszCoreErr), mr.stdplugname), TranslateT("Fatal error"), MB_OK | MB_ICONSTOP); - - Plugin_UnloadDyn(pPlug); - mr.pImpl = NULL; - return false; - } - - pPlug->pclass |= PCLASS_CORE; - - if (!TryLoadPlugin(pPlug, true)) - goto LBL_Error; - - if (bModulesLoadedFired) { - if (CallPluginEventHook(pPlug->bpi.hInst, hModulesLoadedEvent, 0, 0) != 0) - goto LBL_Error; - - NotifyEventHooks(hevLoadModule, (WPARAM)pPlug->bpi.pluginInfo, (LPARAM)pPlug->bpi.hInst); - } - mr.pImpl = pPlug; - return true; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Contact list plugins support - -static bool loadClistModule(TCHAR* exe, pluginEntry *p) -{ - BASIC_PLUGIN_INFO bpi; - if (checkAPI(exe, &bpi, mirandaVersion, CHECKAPI_CLIST)) { - p->bpi = bpi; - p->pclass |= PCLASS_LAST | PCLASS_OK | PCLASS_BASICAPI; - RegisterModule(p->bpi.hInst); - if (bpi.clistlink() == 0) { - p->bpi = bpi; - p->pclass |= PCLASS_LOADED; - pluginDefault[11].pImpl = p; - - LoadExtraIconsModule(); - return true; - } - Plugin_Uninit(p); - } - return false; -} - -static pluginEntry* getCListModule(TCHAR *exe) -{ - TCHAR tszFullPath[MAX_PATH]; - - for (int i = 0; i < clistPlugins.getCount(); i++) { - pluginEntry *p = clistPlugins[i]; - if (!isPluginOnWhiteList(p->pluginname)) - continue; - - mir_sntprintf(tszFullPath, SIZEOF(tszFullPath), _T("%s\\Plugins\\%s"), exe, p->pluginname); - if (loadClistModule(tszFullPath, p)) - return p; - } - - MuuidReplacement& stdClist = pluginDefault[11]; - if (LoadCorePlugin(stdClist)) { - mir_sntprintf(tszFullPath, SIZEOF(tszFullPath), _T("%s\\Core\\%s.dll"), exe, stdClist.stdplugname); - if (loadClistModule(tszFullPath, stdClist.pImpl)) - return stdClist.pImpl; - } - - return NULL; -} - -int UnloadPlugin(TCHAR* buf, int bufLen) -{ - for (int i = pluginList.getCount() - 1; i >= 0; i--) { - pluginEntry *p = pluginList[i]; - if (!mir_tstrcmpi(p->pluginname, buf)) { - GetModuleFileName(p->bpi.hInst, buf, bufLen); - Plugin_Uninit(p); - return TRUE; - } - } - - return FALSE; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Service plugins functions - -void SetServiceModePlugin(pluginEntry *p) -{ - serviceModePlugin = p; -} - -static int LaunchServicePlugin(pluginEntry *p) -{ - // plugin load failed - terminating Miranda - if (!(p->pclass & PCLASS_LOADED)) { - if (p->bpi.Load() != ERROR_SUCCESS) { - Plugin_Uninit(p); - return SERVICE_FAILED; - } - p->pclass |= PCLASS_LOADED; - } - - INT_PTR res = CallService(MS_SERVICEMODE_LAUNCH, 0, 0); - if (res != CALLSERVICE_NOTFOUND) - return res; - - MessageBox(NULL, TranslateT("Unable to load plugin in service mode!"), p->pluginname, MB_ICONSTOP); - Plugin_Uninit(p); - return SERVICE_FAILED; -} - -int LoadDefaultServiceModePlugin() -{ - LPCTSTR param = CmdLine_GetOption(_T("svc")); - if (param == NULL || *param == 0) - return SERVICE_CONTINUE; - - size_t cbLen = mir_tstrlen(param); - for (int i = 0; i < servicePlugins.getCount(); i++) { - pluginEntry *p = servicePlugins[i]; - if (!_tcsnicmp(p->pluginname, param, cbLen)) { - int res = LaunchServicePlugin(p); - if (res == SERVICE_ONLYDB) // load it later - serviceModePlugin = p; - return res; - } - } - - return SERVICE_CONTINUE; -} - -int LoadServiceModePlugin() -{ - return (serviceModePlugin == NULL) ? SERVICE_CONTINUE : LaunchServicePlugin(serviceModePlugin); -} - -void EnsureCheckerLoaded(bool bEnable) -{ - for (int i = 0; i < pluginList.getCount(); i++) { - pluginEntry *p = pluginList[i]; - if (mir_tstrcmpi(p->pluginname, _T("dbchecker.dll"))) - continue; - - if (bEnable) { - if (!(p->pclass & PCLASS_LOADED)) { - if (p->bpi.Load() != ERROR_SUCCESS) - Plugin_Uninit(p); - else { - p->pclass |= PCLASS_LOADED; - servicePlugins.remove(p); - } - } - } - else Plugin_Uninit(p); - break; - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - -int LoadSslModule(void) -{ - if (plugin_ssl != NULL) { - if (!TryLoadPlugin(plugin_ssl, false)) { - Plugin_Uninit(plugin_ssl); - return 1; - } - } - else { - MuuidReplacement stdSsl = { MIID_SSL, _T("stdssl"), NULL }; - if (!LoadCorePlugin(stdSsl)) - return 1; - } - - mir_getSI(&si); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Event hook to unload all non-core plugins -// hooked very late, after all the internal plugins, blah - -void UnloadNewPlugins(void) -{ - // unload everything but the special db/clist plugins - for (int i = pluginList.getCount() - 1; i >= 0; i--) { - pluginEntry *p = pluginList[i]; - if (!(p->pclass & PCLASS_LAST) && (p->pclass & PCLASS_OK)) - Plugin_Uninit(p); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Loads all plugins - -int LoadNewPluginsModule(void) -{ - int i; - - // make full path to the plugin - TCHAR exe[MAX_PATH], fullPath[MAX_PATH]; - GetModuleFileName(NULL, exe, SIZEOF(exe)); - TCHAR *slice = _tcsrchr(exe, '\\'); - if (slice) - *slice = 0; - - // remember some useful options - askAboutIgnoredPlugins = (UINT)GetPrivateProfileInt(_T("PluginLoader"), _T("AskAboutIgnoredPlugins"), 0, mirandabootini); - - // if Crash Dumper is present, load it to provide Crash Reports - if (plugin_crshdmp != NULL && isPluginOnWhiteList(plugin_crshdmp->pluginname)) - if (!TryLoadPlugin(plugin_crshdmp, false)) - Plugin_Uninit(plugin_crshdmp); - - // if freeimage is present, load it to provide the basic core functions - if (plugin_freeimg != NULL) { - BASIC_PLUGIN_INFO bpi; - mir_sntprintf(fullPath, SIZEOF(fullPath), _T("%s\\Plugins\\%s"), exe, plugin_freeimg->pluginname); - if (checkAPI(fullPath, &bpi, mirandaVersion, CHECKAPI_NONE)) { - plugin_freeimg->bpi = bpi; - plugin_freeimg->pclass |= PCLASS_OK | PCLASS_BASICAPI; - if (bpi.Load() == 0) - plugin_freeimg->pclass |= PCLASS_LOADED; - else - Plugin_Uninit(plugin_freeimg); - } - } - - // first load the clist cos alot of plugins need that to be present at Load(void) - pluginEntry* clist = getCListModule(exe); - - /* the loop above will try and get one clist DLL to work, if all fail then just bail now */ - if (clist == NULL) { - // result = 0, no clist_* can be found - if (clistPlugins.getCount()) - MessageBox(NULL, TranslateT("Unable to start any of the installed contact list plugins, I even ignored your preferences for which contact list couldn't load any."), _T("Miranda NG"), MB_OK | MB_ICONERROR); - else - MessageBox(NULL, TranslateT("Can't find a contact list plugin! You need StdClist or any other contact list plugin."), _T("Miranda NG"), MB_OK | MB_ICONERROR); - return 1; - } - - /* enable and disable as needed */ - for (i = 0; i < clistPlugins.getCount(); i++) - SetPluginOnWhiteList(clistPlugins[i]->pluginname, clist != clistPlugins[i] ? 0 : 1); - - /* now loop thru and load all the other plugins, do this in one pass */ - for (i = 0; i < pluginList.getCount(); i++) { - pluginEntry *p = pluginList[i]; - if (!TryLoadPlugin(p, false)) { - Plugin_Uninit(p); - i--; - } - } - - HookEvent(ME_OPT_INITIALISE, PluginOptionsInit); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Plugins module initialization -// called before anything real is loaded, incl. database - -static BOOL scanPluginsDir(WIN32_FIND_DATA *fd, TCHAR *path, WPARAM, LPARAM) -{ - pluginEntry *p = OpenPlugin(fd->cFileName, _T("Plugins"), path); - if (!(p->pclass & PCLASS_FAILED)) { - if (plugin_freeimg == NULL && mir_tstrcmpi(fd->cFileName, _T("advaimg.dll")) == 0) { - plugin_freeimg = p; - p->pclass |= PCLASS_LAST; - } - - if (plugin_crshdmp == NULL && mir_tstrcmpi(fd->cFileName, _T("crashdumper.dll")) == 0) { - plugin_crshdmp = p; - p->pclass |= PCLASS_LAST; - } - } - - return TRUE; -} - -int LoadNewPluginsModuleInfos(void) -{ - bModuleInitialized = TRUE; - - LoadPluginOptions(); - - hPluginListHeap = HeapCreate(HEAP_NO_SERIALIZE, 0, 0); - mirandaVersion = (DWORD)CallService(MS_SYSTEM_GETVERSION, 0, 0); - - // remember where the mirandaboot.ini goes - PathToAbsoluteT(_T("mirandaboot.ini"), mirandabootini); - - // look for all *.dll's - enumPlugins(scanPluginsDir, 0, 0); - - MuuidReplacement stdCrypt = { MIID_CRYPTO, _T("stdcrypt"), NULL }; - return !LoadCorePlugin(stdCrypt); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Plugins module unloading -// called at the end of module chain unloading, just modular engine left at this point - -void UnloadDatabase(void) -{ - if (currDb != NULL) { - db_setCurrent(NULL); - currDblink->Unload(currDb); - currDb = NULL; - currDblink = NULL; - } - - UninitIni(); -} - -void UnloadNewPluginsModule(void) -{ - if (!bModuleInitialized) - return; - - UnloadPluginOptions(); - - // unload everything but the DB - for (int i = pluginList.getCount() - 1; i >= 0; i--) { - pluginEntry *p = pluginList[i]; - if (!(p->pclass & (PCLASS_DB | PCLASS_CRYPT)) && p != plugin_crshdmp) - Plugin_Uninit(p); - } - - if (plugin_crshdmp) - Plugin_Uninit(plugin_crshdmp); - - UnloadDatabase(); - - for (int k = pluginList.getCount() - 1; k >= 0; k--) { - pluginEntry *p = pluginList[k]; - Plugin_Uninit(p); - } - - if (hPluginListHeap) HeapDestroy(hPluginListHeap); - hPluginListHeap = 0; -} diff --git a/src/modules/plugins/pluginopts.cpp b/src/modules/plugins/pluginopts.cpp deleted file mode 100644 index 9200d04bd1..0000000000 --- a/src/modules/plugins/pluginopts.cpp +++ /dev/null @@ -1,575 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#include - -#include "plugins.h" - -extern MUUID miid_clist, miid_database, miid_protocol; -HANDLE hevLoadModule, hevUnloadModule; - -static bool bOldMode = false; -static CMString szFilter; -static UINT_PTR timerID; - -///////////////////////////////////////////////////////////////////////////////////////// -// Plugins options page dialog - -struct PluginListItemData -{ - TCHAR fileName[MAX_PATH]; - HINSTANCE hInst; - int flags, stdPlugin; - char* author; - char* authorEmail; - char* description; - char* copyright; - char* homepage; - MUUID uuid; -}; - -static int sttSortPlugins(const PluginListItemData *p1, const PluginListItemData *p2) -{ - return mir_tstrcmp(p1->fileName, p2->fileName); -} - -static LIST arPluginList(10, sttSortPlugins); - -static BOOL dialogListPlugins(WIN32_FIND_DATA *fd, TCHAR *path, WPARAM, LPARAM lParam) -{ - TCHAR buf[MAX_PATH]; - mir_sntprintf(buf, _T("%s\\Plugins\\%s"), path, fd->cFileName); - HINSTANCE hInst = GetModuleHandle(buf); - - BASIC_PLUGIN_INFO pi; - if (checkAPI(buf, &pi, MIRANDA_VERSION_CORE, CHECKAPI_NONE) == 0) - return TRUE; - - PluginListItemData *dat = (PluginListItemData*)mir_alloc(sizeof(PluginListItemData)); - dat->hInst = hInst; - dat->flags = pi.pluginInfo->flags; - - dat->stdPlugin = 0; - if (pi.Interfaces) { - MUUID *piface = pi.Interfaces; - for (int i=0; !equalUUID(miid_last, piface[i]); i++) { - int idx = getDefaultPluginIdx( piface[i] ); - if (idx != -1 ) { - dat->stdPlugin |= (1 << idx); - break; - } - } - } - - CharLower(fd->cFileName); - _tcsncpy_s(dat->fileName, fd->cFileName, _TRUNCATE); - - HWND hwndList = (HWND)lParam; - - LVITEM it = { 0 }; - // column 1: Checkbox + Enable/disabled icons - it.mask = LVIF_PARAM | LVIF_IMAGE; - it.iImage = (hInst != NULL) ? 2 : 3; - bool bNoCheckbox = (dat->flags & STATIC_PLUGIN) != 0; - if (bNoCheckbox|| hasMuuid(pi, miid_clist) || hasMuuid(pi, miid_protocol)) - it.iImage += 2; - it.lParam = (LPARAM)dat; - int iRow = ListView_InsertItem(hwndList, &it); - - if (isPluginOnWhiteList(fd->cFileName)) - ListView_SetItemState(hwndList, iRow, bNoCheckbox ? 0x3000 : 0x2000, LVIS_STATEIMAGEMASK); - - if (iRow != -1) { - // column 2: Unicode/ANSI icon + filename - it.mask = LVIF_IMAGE | LVIF_TEXT; - it.iItem = iRow; - it.iSubItem = 1; - it.iImage = (dat->flags & UNICODE_AWARE) ? 0 : 1; - it.pszText = fd->cFileName; - ListView_SetItem(hwndList, &it); - - dat->author = mir_strdup(pi.pluginInfo->author); - dat->authorEmail = mir_strdup(pi.pluginInfo->authorEmail); - dat->copyright = mir_strdup(pi.pluginInfo->copyright); - dat->description = mir_strdup(pi.pluginInfo->description); - dat->homepage = mir_strdup(pi.pluginInfo->homepage); - if (pi.pluginInfo->cbSize == sizeof(PLUGININFOEX)) - dat->uuid = pi.pluginInfo->uuid; - else - memset(&dat->uuid, 0, sizeof(dat->uuid)); - - TCHAR *shortNameT = mir_a2t(pi.pluginInfo->shortName); - // column 3: plugin short name - if (shortNameT) { - ListView_SetItemText(hwndList, iRow, 2, shortNameT); - mir_free(shortNameT); - } - - // column4: version number - DWORD unused, verInfoSize = GetFileVersionInfoSize(buf, &unused); - if (verInfoSize != 0) { - UINT blockSize; - VS_FIXEDFILEINFO *fi; - void *pVerInfo = mir_alloc(verInfoSize); - GetFileVersionInfo(buf, 0, verInfoSize, pVerInfo); - VerQueryValue(pVerInfo, _T("\\"), (LPVOID*)&fi, &blockSize); - mir_sntprintf(buf, _T("%d.%d.%d.%d"), HIWORD(fi->dwProductVersionMS), - LOWORD(fi->dwProductVersionMS), HIWORD(fi->dwProductVersionLS), LOWORD(fi->dwProductVersionLS)); - mir_free(pVerInfo); - } - else - mir_sntprintf(buf, _T("%d.%d.%d.%d"), HIBYTE(HIWORD(pi.pluginInfo->version)), - LOBYTE(HIWORD(pi.pluginInfo->version)), HIBYTE(LOWORD(pi.pluginInfo->version)), - LOBYTE(LOWORD(pi.pluginInfo->version))); - - ListView_SetItemText(hwndList, iRow, 3, buf); - arPluginList.insert(dat); - } - else - mir_free(dat); - FreeLibrary(pi.hInst); - return TRUE; -} - -static int uuidToString(const MUUID uuid, char *szStr, int cbLen) -{ - if (cbLen < 1 || !szStr) - return 0; - - mir_snprintf(szStr, cbLen, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", - uuid.a, uuid.b, uuid.c, uuid.d[0], uuid.d[1], uuid.d[2], uuid.d[3], uuid.d[4], uuid.d[5], uuid.d[6], uuid.d[7]); - return 1; -} - -static void RemoveAllItems(HWND hwnd) -{ - LVITEM lvi; - lvi.mask = LVIF_PARAM; - lvi.iItem = 0; - while (ListView_GetItem(hwnd, &lvi)) { - PluginListItemData *dat = (PluginListItemData*)lvi.lParam; - mir_free(dat->author); - mir_free(dat->authorEmail); - mir_free(dat->copyright); - mir_free(dat->description); - mir_free(dat->homepage); - mir_free(dat); - lvi.iItem ++; - } -} - -static bool LoadPluginDynamically(PluginListItemData *dat) -{ - TCHAR exe[MAX_PATH]; - GetModuleFileName(NULL, exe, SIZEOF(exe)); - TCHAR *p = _tcsrchr(exe, '\\'); if (p) *p = 0; - - pluginEntry* pPlug = OpenPlugin(dat->fileName, _T("Plugins"), exe); - if (pPlug->pclass & PCLASS_FAILED) { -LBL_Error: - Plugin_UnloadDyn(pPlug); - return false; - } - - if (!TryLoadPlugin(pPlug, true)) - goto LBL_Error; - - if (CallPluginEventHook(pPlug->bpi.hInst, hModulesLoadedEvent, 0, 0) != 0) - goto LBL_Error; - - dat->hInst = pPlug->bpi.hInst; - NotifyFastHook(hevLoadModule, (WPARAM)pPlug->bpi.pluginInfo, (LPARAM)pPlug->bpi.hInst); - return true; -} - -static bool UnloadPluginDynamically(PluginListItemData *dat) -{ - pluginEntry *p = pluginList.find((pluginEntry*)dat->fileName); - if (p) { - if (!Plugin_UnloadDyn(p)) - return false; - - dat->hInst = NULL; - } - return true; -} - -static LRESULT CALLBACK PluginListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) { - case WM_CHAR: - if (wParam == '\b') { - if (szFilter.GetLength() > 0) - szFilter.Truncate(szFilter.GetLength() - 1); - } - else { - szFilter.AppendChar(wParam); - - for (int i = 0; i < arPluginList.getCount(); i++) { - PluginListItemData *p = arPluginList[i]; - if (!_tcsnicmp(szFilter, p->fileName, szFilter.GetLength())) { - LVFINDINFO lvfi; - lvfi.flags = LVFI_PARAM; - lvfi.lParam = (LPARAM)p; - int idx = ListView_FindItem(hwnd, 0, &lvfi); - if (idx != -1) { - ListView_SetItemState(hwnd, idx, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); - ListView_EnsureVisible(hwnd, idx, FALSE); - if (timerID != 0) - KillTimer(hwnd, timerID); - timerID = SetTimer(hwnd, 1, 1500, 0); - return TRUE; - } - } - } - - szFilter.Truncate(szFilter.GetLength() - 1); - MessageBeep((UINT)-1); - } - return TRUE; - - case WM_TIMER: - if (wParam == 1) { - KillTimer(hwnd, timerID); - timerID = 0; - szFilter.Empty(); - } - break; - - case WM_LBUTTONDOWN: - LVHITTESTINFO hi; - hi.pt.x = LOWORD(lParam); - hi.pt.y = HIWORD(lParam); - ListView_SubItemHitTest(hwnd, &hi); - // Dynamically load/unload a plugin - if ((hi.iSubItem == 0) && (hi.flags & LVHT_ONITEMICON)) { - LVITEM lvi = {0}; - lvi.mask = LVIF_IMAGE | LVIF_PARAM; - lvi.stateMask = -1; - lvi.iItem = hi.iItem; - lvi.iSubItem = 0; - if (ListView_GetItem(hwnd, &lvi)) { - lvi.mask = LVIF_IMAGE; - PluginListItemData *dat = (PluginListItemData*)lvi.lParam; - if (lvi.iImage == 3) { - // load plugin - if (LoadPluginDynamically(dat)) { - lvi.iImage = 2; - ListView_SetItem(hwnd, &lvi); - } - } - else if (lvi.iImage == 2) { - // unload plugin - if (UnloadPluginDynamically(dat)) { - lvi.iImage = 3; - ListView_SetItem(hwnd, &lvi); - } - } - LoadStdPlugins(); - } - } - } - - return mir_callNextSubclass(hwnd, PluginListWndProc, msg, wParam, lParam); -} - -static int CALLBACK SortPlugins(WPARAM i1, LPARAM i2, LPARAM) -{ - PluginListItemData *p1 = (PluginListItemData*)i1, *p2 = (PluginListItemData*)i2; - return mir_tstrcmp(p1->fileName, p2->fileName); -} - -static TCHAR *latin2t(const char *p) -{ - if (p == NULL) - return mir_tstrdup( _T("")); - - return mir_a2t_cp(p, 1250); -} - -INT_PTR CALLBACK DlgPluginOpt(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - timerID = 0; - { - HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); - mir_subclassWindow(hwndList, PluginListWndProc); - - HIMAGELIST hIml = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 4, 0); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_UNICODE); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_ANSI); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_LOADED); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_NOTLOADED); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_LOADEDGRAY); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_NOTLOADEDGRAY); - ListView_SetImageList(hwndList, hIml, LVSIL_SMALL); - - LVCOLUMN col; - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.pszText = _T(""); - col.cx = 40; - ListView_InsertColumn(hwndList, 0, &col); - - col.pszText = TranslateT("Plugin"); - col.cx = 180; - ListView_InsertColumn(hwndList, 1, &col); - - col.pszText = TranslateT("Name"); - col.cx = 180;//max = 220; - ListView_InsertColumn(hwndList, 2, &col); - - col.pszText = TranslateT("Version"); - col.cx = 75; - ListView_InsertColumn(hwndList, 3, &col); - - ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_SUBITEMIMAGES | LVS_EX_CHECKBOXES | LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT); - // scan the plugin dir for plugins, cos - arPluginList.destroy(); - szFilter.Empty(); - enumPlugins(dialogListPlugins, (WPARAM)hwndDlg, (LPARAM)hwndList); - // sort out the headers - - ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); // dll name - int w = ListView_GetColumnWidth(hwndList, 1); - if (w > 110) { - ListView_SetColumnWidth(hwndList, 1, w = 110); - } - int max = w < 110 ? 189 + 110 - w : 189; - ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); // short name - w = ListView_GetColumnWidth(hwndList, 2); - if (w > max) - ListView_SetColumnWidth(hwndList, 2, max); - - ListView_SortItems(hwndList, SortPlugins, (LPARAM)hwndDlg); - } - return TRUE; - - case WM_NOTIFY: - if (lParam) { - NMLISTVIEW *hdr = (NMLISTVIEW *)lParam; - if (hdr->hdr.code == LVN_ITEMCHANGED && IsWindowVisible(hdr->hdr.hwndFrom)) { - if (hdr->uOldState != 0 && (hdr->uNewState == 0x1000 || hdr->uNewState == 0x2000)) { - HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); - - LVITEM it; - it.mask = LVIF_PARAM | LVIF_STATE; - it.iItem = hdr->iItem; - if (!ListView_GetItem(hwndList, &it)) - break; - - PluginListItemData *dat = (PluginListItemData*)it.lParam; - if (dat->flags & STATIC_PLUGIN) { - ListView_SetItemState(hwndList, hdr->iItem, 0x3000, LVIS_STATEIMAGEMASK); - return FALSE; - } - // find all another standard plugins by mask and disable them - if ((hdr->uNewState == 0x2000) && dat->stdPlugin != 0) { - for (int iRow = 0; iRow != -1; iRow = ListView_GetNextItem(hwndList, iRow, LVNI_ALL)) { - if (iRow != hdr->iItem) { // skip the plugin we're standing on - LVITEM dt; - dt.mask = LVIF_PARAM; - dt.iItem = iRow; - if (ListView_GetItem(hwndList, &dt)) { - PluginListItemData *dat2 = (PluginListItemData*)dt.lParam; - if (dat2->stdPlugin & dat->stdPlugin) {// mask differs - // the lParam is unset, so when the check is unset the clist block doesnt trigger - int lParam = dat2->stdPlugin; - dat2->stdPlugin = 0; - ListView_SetItemState(hwndList, iRow, 0x1000, LVIS_STATEIMAGEMASK); - dat2->stdPlugin = lParam; - } - } - } - } - } - - if (bOldMode) - ShowWindow(GetDlgItem(hwndDlg, IDC_RESTART), TRUE); // this here only in "ghazan mode" - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - } - - if (hdr->iItem != -1) { - int sel = hdr->uNewState & LVIS_SELECTED; - HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); - LVITEM lvi = { 0 }; - lvi.mask = LVIF_PARAM; - lvi.iItem = hdr->iItem; - if (ListView_GetItem(hwndList, &lvi)) { - PluginListItemData *dat = (PluginListItemData*)lvi.lParam; - - TCHAR buf[1024]; - ListView_GetItemText(hwndList, hdr->iItem, 2, buf, SIZEOF(buf)); - SetDlgItemText(hwndDlg, IDC_PLUGININFOFRAME, sel ? buf : _T("")); - - ptrT tszAuthor(latin2t(sel ? dat->author : NULL)); - SetDlgItemText(hwndDlg, IDC_PLUGINAUTHOR, tszAuthor); - - ptrT tszEmail(latin2t(sel ? dat->authorEmail : NULL)); - SetDlgItemText(hwndDlg, IDC_PLUGINEMAIL, tszEmail); - - ptrT p(Langpack_PcharToTchar(dat->description)); - SetDlgItemText(hwndDlg, IDC_PLUGINLONGINFO, sel ? p : _T("")); - - ptrT tszCopyright(latin2t(sel ? dat->copyright : NULL)); - SetDlgItemText(hwndDlg, IDC_PLUGINCPYR, tszCopyright); - - ptrT tszUrl(latin2t(sel ? dat->homepage : NULL)); - SetDlgItemText(hwndDlg, IDC_PLUGINURL, tszUrl); - - if (!equalUUID(miid_last, dat->uuid)) { - char szUID[128]; - uuidToString(dat->uuid, szUID, sizeof(szUID)); - SetDlgItemTextA(hwndDlg, IDC_PLUGINPID, sel ? szUID : ""); - } - else - SetDlgItemText(hwndDlg, IDC_PLUGINPID, sel ? TranslateT("") : _T("")); - } - } - } - - if (hdr->hdr.code == PSN_APPLY) { - bool needRestart = false; - TCHAR bufRestart[1024]; - int bufLen = mir_sntprintf(bufRestart, SIZEOF(bufRestart), _T("%s\n"), TranslateT("Miranda NG must be restarted to apply changes for these plugins:")); - - HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); - for (int iRow = 0; iRow != -1;) { - TCHAR buf[1024]; - ListView_GetItemText(hwndList, iRow, 1, buf, SIZEOF(buf)); - int iState = ListView_GetItemState(hwndList, iRow, LVIS_STATEIMAGEMASK); - SetPluginOnWhiteList(buf, (iState & 0x2000) ? 1 : 0); - - if (!bOldMode && iState != 0x3000) { - LVITEM lvi = { 0 }; - lvi.mask = LVIF_IMAGE | LVIF_PARAM; - lvi.stateMask = -1; - lvi.iItem = iRow; - lvi.iSubItem = 0; - if (ListView_GetItem(hwndList, &lvi)) { - lvi.mask = LVIF_IMAGE; - - PluginListItemData *dat = (PluginListItemData*)lvi.lParam; - if (iState == 0x2000) { - // enabling plugin - if (lvi.iImage == 3 || lvi.iImage == 5) { - if (lvi.iImage == 3 && LoadPluginDynamically(dat)) { - lvi.iImage = 2; - ListView_SetItem(hwndList, &lvi); - } - else { - bufLen += mir_sntprintf(bufRestart + bufLen, SIZEOF(bufRestart) - bufLen, _T(" - %s\n"), buf); - needRestart = true; - } - } - } - else { - // disabling plugin - if (lvi.iImage == 2 || lvi.iImage == 4) { - if (lvi.iImage == 2 && UnloadPluginDynamically(dat)) { - lvi.iImage = 3; - ListView_SetItem(hwndList, &lvi); - } - else { - bufLen += mir_sntprintf(bufRestart + bufLen, SIZEOF(bufRestart) - bufLen, _T(" - %s\n"), buf); - needRestart = true; - } - } - } - } - } - - iRow = ListView_GetNextItem(hwndList, iRow, LVNI_ALL); - } - LoadStdPlugins(); - - ShowWindow(GetDlgItem(hwndDlg, IDC_RESTART), needRestart); - if (needRestart) { - mir_sntprintf(bufRestart + bufLen, SIZEOF(bufRestart) - bufLen, _T("\n%s"), TranslateT("Do you want to restart it now?")); - if (MessageBox(NULL, bufRestart, _T("Miranda NG"), MB_ICONWARNING | MB_YESNO) == IDYES) - CallService(MS_SYSTEM_RESTART, 1, 0); - } - } - } - break; - - case WM_COMMAND: - if (HIWORD(wParam) == STN_CLICKED) { - switch (LOWORD(wParam)) { - case IDC_GETMOREPLUGINS: - CallService(MS_UTILS_OPENURL, 0, (LPARAM) "http://miranda-ng.org/downloads/"); - break; - - case IDC_PLUGINEMAIL: - case IDC_PLUGINURL: - char buf[512]; - char *p = &buf[7]; - mir_strcpy(buf, "mailto:"); - if (GetDlgItemTextA(hwndDlg, LOWORD(wParam), p, SIZEOF(buf) - 7)) - CallService(MS_UTILS_OPENURL, 0, (LPARAM)(LOWORD(wParam) == IDC_PLUGINEMAIL ? buf : p)); - break; - } - } - break; - - case WM_DESTROY: - arPluginList.destroy(); - RemoveAllItems(GetDlgItem(hwndDlg, IDC_PLUGLIST)); - break; - } - return FALSE; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -int PluginOptionsInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.hInstance = hInst; - odp.pfnDlgProc = DlgPluginOpt; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_PLUGINS); - odp.position = 1300000000; - odp.pszTitle = LPGEN("Plugins"); - odp.flags = ODPF_BOLDGROUPS; - Options_AddPage(wParam, &odp); - return 0; -} - -void LoadPluginOptions() -{ - bOldMode = db_get_b(NULL, "Options", "OldPluginSettings", false) != 0; - - hevLoadModule = CreateHookableEvent(ME_SYSTEM_MODULELOAD); - hevUnloadModule = CreateHookableEvent(ME_SYSTEM_MODULEUNLOAD); -} - -void UnloadPluginOptions() -{ - DestroyHookableEvent(hevLoadModule); - DestroyHookableEvent(hevUnloadModule); -} diff --git a/src/modules/plugins/plugins.h b/src/modules/plugins/plugins.h deleted file mode 100644 index 35ae742b60..0000000000 --- a/src/modules/plugins/plugins.h +++ /dev/null @@ -1,84 +0,0 @@ - -// returns true if the API exports were good, otherwise, passed in data is returned -#define CHECKAPI_NONE 0 -#define CHECKAPI_CLIST 1 - -// block these plugins -#define DEFMOD_REMOVED_UIPLUGINOPTS 21 -#define DEFMOD_REMOVED_PROTOCOLNETLIB 22 - -// basic export prototypes -typedef int (__cdecl * Miranda_Plugin_Load) (void); -typedef int (__cdecl * Miranda_Plugin_Unload) (void); -// version control -typedef PLUGININFOEX * (__cdecl * Miranda_Plugin_InfoEx) (DWORD mirandaVersion); -// prototype for clists -typedef int (__cdecl * CList_Initialise) (void); - -// can all be NULL -struct BASIC_PLUGIN_INFO -{ - HINSTANCE hInst; - Miranda_Plugin_Load Load; - Miranda_Plugin_Unload Unload; - Miranda_Plugin_InfoEx InfoEx; - CList_Initialise clistlink; - PLUGININFOEX * pluginInfo; // must be freed if hInst = = NULL then its a copy - MUUID *Interfaces; // array of supported interfaces -}; - -#define PCLASS_FAILED 0x1 // not a valid plugin, or API is invalid, pluginname is valid -#define PCLASS_BASICAPI 0x2 // has Load, Unload, MirandaPluginInfo() -> PLUGININFO seems valid, this dll is in memory. -#define PCLASS_DB 0x4 // has DatabasePluginInfo() and is valid as can be, and PCLASS_BASICAPI has to be set too -#define PCLASS_LAST 0x8 // this plugin should be unloaded after everything else -#define PCLASS_OK 0x10 // plugin should be loaded, if DB means nothing -#define PCLASS_LOADED 0x20 // Load(void) has been called, Unload() should be called. -#define PCLASS_STOPPED 0x40 // wasn't loaded cos plugin name not on white list -#define PCLASS_CLIST 0x80 // a CList implementation -#define PCLASS_SERVICE 0x100 // has Service Mode implementation -#define PCLASS_CORE 0x200 // a plugin from the /Core directory -#define PCLASS_CRYPT 0x400 // crypto provider - -struct pluginEntry -{ - TCHAR pluginname[64]; - unsigned int pclass; // PCLASS_* - int hLangpack; - BASIC_PLUGIN_INFO bpi; -}; - -extern LIST pluginList, servicePlugins, clistPlugins; -extern MUUID miid_last; - -int PluginOptionsInit(WPARAM, LPARAM); -void LoadPluginOptions(); -void UnloadPluginOptions(); - -int isPluginOnWhiteList(const TCHAR* pluginname); -void SetPluginOnWhiteList(const TCHAR* pluginname, int allow); - -int getDefaultPluginIdx(const MUUID& muuid); -bool hasMuuid(const BASIC_PLUGIN_INFO&, const MUUID&); -bool hasMuuid(const MUUID* pFirst, const MUUID&); -int equalUUID(const MUUID& u1, const MUUID& u2); -int checkAPI(TCHAR* plugin, BASIC_PLUGIN_INFO* bpi, DWORD mirandaVersion, int checkTypeAPI); - -pluginEntry* OpenPlugin(TCHAR *tszFileName, TCHAR *dir, TCHAR *path); - -bool TryLoadPlugin(pluginEntry *p, bool bDynamic); -void Plugin_Uninit(pluginEntry *p); -int Plugin_UnloadDyn(pluginEntry *p); - -typedef BOOL (*SCAN_PLUGINS_CALLBACK) (WIN32_FIND_DATA * fd, TCHAR *path, WPARAM wParam, LPARAM lParam); -void enumPlugins(SCAN_PLUGINS_CALLBACK cb, WPARAM wParam, LPARAM lParam); - -struct MuuidReplacement -{ - MUUID uuid; // default interface plugin - TCHAR* stdplugname; - pluginEntry* pImpl; // replacement plugin -}; - -bool LoadCorePlugin( MuuidReplacement& ); - -MUUID* GetPluginInterfaces(const TCHAR* ptszFileName, bool& bIsPlugin); \ No newline at end of file diff --git a/src/modules/protocols/protoaccs.cpp b/src/modules/protocols/protoaccs.cpp deleted file mode 100644 index 1e92cb637c..0000000000 --- a/src/modules/protocols/protoaccs.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#include "../clist/clc.h" - -bool CheckProtocolOrder(void); -void BuildProtoMenus(); - -HICON Proto_GetIcon(PROTO_INTERFACE *ppro, int iconIndex); - -static BOOL bModuleInitialized = FALSE; -static HANDLE hHooks[4]; - -static int CompareAccounts(const PROTOACCOUNT* p1, const PROTOACCOUNT* p2) -{ - return mir_strcmp(p1->szModuleName, p2->szModuleName); -} - -LIST accounts(10, CompareAccounts); - -///////////////////////////////////////////////////////////////////////////////////////// - -static int EnumDbModules(const char *szModuleName, DWORD ofsModuleName, LPARAM lParam) -{ - DBVARIANT dbv; - if (!db_get_s(NULL, szModuleName, "AM_BaseProto", &dbv)) { - if (!Proto_GetAccount(szModuleName)) { - PROTOACCOUNT *pa = (PROTOACCOUNT*)mir_calloc(sizeof(PROTOACCOUNT)); - pa->cbSize = sizeof(*pa); - pa->szModuleName = mir_strdup(szModuleName); - pa->szProtoName = mir_strdup(dbv.pszVal); - pa->tszAccountName = mir_a2t(szModuleName); - pa->bIsVisible = TRUE; - pa->bIsEnabled = FALSE; - pa->iOrder = accounts.getCount(); - accounts.insert(pa); - } - db_free(&dbv); - } - return 0; -} - -void LoadDbAccounts(void) -{ - DBVARIANT dbv; - int ver = db_get_dw(NULL, "Protocols", "PrVer", -1); - int count = db_get_dw(NULL, "Protocols", "ProtoCount", 0); - - for (int i = 0; i < count; i++) { - char buf[10]; - _itoa(i, buf, 10); - if (db_get_s(NULL, "Protocols", buf, &dbv)) - continue; - - PROTOACCOUNT *pa = (PROTOACCOUNT*)mir_calloc(sizeof(PROTOACCOUNT)); - if (pa == NULL) { - db_free(&dbv); - continue; - } - pa->cbSize = sizeof(*pa); - pa->szModuleName = mir_strdup(dbv.pszVal); - db_free(&dbv); - - _itoa(OFFSET_VISIBLE + i, buf, 10); - pa->bIsVisible = db_get_dw(NULL, "Protocols", buf, 1) != 0; - - _itoa(OFFSET_PROTOPOS + i, buf, 10); - pa->iOrder = db_get_dw(NULL, "Protocols", buf, 1); - - if (ver >= 4) { - db_free(&dbv); - _itoa(OFFSET_NAME + i, buf, 10); - if (!db_get_ts(NULL, "Protocols", buf, &dbv)) { - pa->tszAccountName = mir_tstrdup(dbv.ptszVal); - db_free(&dbv); - } - - _itoa(OFFSET_ENABLED + i, buf, 10); - pa->bIsEnabled = db_get_dw(NULL, "Protocols", buf, 1) != 0; - - if (!db_get_s(NULL, pa->szModuleName, "AM_BaseProto", &dbv)) { - pa->szProtoName = mir_strdup(dbv.pszVal); - db_free(&dbv); - } - } - else pa->bIsEnabled = true; - - if (!pa->szProtoName) { - pa->szProtoName = mir_strdup(pa->szModuleName); - db_set_s(NULL, pa->szModuleName, "AM_BaseProto", pa->szProtoName); - } - - if (!pa->tszAccountName) - pa->tszAccountName = mir_a2t(pa->szModuleName); - - accounts.insert(pa); - } - - if (CheckProtocolOrder()) - WriteDbAccounts(); - - int anum = accounts.getCount(); - CallService(MS_DB_MODULES_ENUM, 0, (LPARAM)EnumDbModules); - if (anum != accounts.getCount()) - WriteDbAccounts(); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - int arrlen; - char **pszSettingName; -} -enumDB_ProtoProcParam; - -static int enumDB_ProtoProc(const char* szSetting, LPARAM lParam) -{ - if (szSetting) { - enumDB_ProtoProcParam* p = (enumDB_ProtoProcParam*)lParam; - - p->arrlen++; - p->pszSettingName = (char**)mir_realloc(p->pszSettingName, p->arrlen*sizeof(char*)); - p->pszSettingName[p->arrlen - 1] = mir_strdup(szSetting); - } - return 0; -} - -void WriteDbAccounts() -{ - // enum all old settings to delete - enumDB_ProtoProcParam param = { 0, NULL }; - - DBCONTACTENUMSETTINGS dbces; - dbces.pfnEnumProc = enumDB_ProtoProc; - dbces.szModule = "Protocols"; - dbces.ofsSettings = 0; - dbces.lParam = (LPARAM)¶m; - CallService(MS_DB_CONTACT_ENUMSETTINGS, 0, (LPARAM)&dbces); - - // delete all settings - if (param.arrlen) { - for (int i = 0; i < param.arrlen; i++) { - db_unset(0, "Protocols", param.pszSettingName[i]); - mir_free(param.pszSettingName[i]); - } - mir_free(param.pszSettingName); - } - - // write new data - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - - char buf[20]; - _itoa(i, buf, 10); - db_set_s(NULL, "Protocols", buf, pa->szModuleName); - - _itoa(OFFSET_PROTOPOS + i, buf, 10); - db_set_dw(NULL, "Protocols", buf, pa->iOrder); - - _itoa(OFFSET_VISIBLE + i, buf, 10); - db_set_dw(NULL, "Protocols", buf, pa->bIsVisible); - - _itoa(OFFSET_ENABLED + i, buf, 10); - db_set_dw(NULL, "Protocols", buf, pa->bIsEnabled); - - _itoa(OFFSET_NAME + i, buf, 10); - db_set_ts(NULL, "Protocols", buf, pa->tszAccountName); - } - - db_unset(0, "Protocols", "ProtoCount"); - db_set_dw(0, "Protocols", "ProtoCount", accounts.getCount()); - db_set_dw(0, "Protocols", "PrVer", 4); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static int OnContactDeleted(WPARAM hContact, LPARAM lParam) -{ - if (hContact) { - PROTOACCOUNT *pa = Proto_GetAccount(hContact); - if (Proto_IsAccountEnabled(pa) && pa->ppro) - pa->ppro->OnEvent(EV_PROTO_ONCONTACTDELETED, hContact, lParam); - } - return 0; -} - -static int OnDbSettingsChanged(WPARAM hContact, LPARAM lParam) -{ - if (hContact) { - PROTOACCOUNT *pa = Proto_GetAccount(hContact); - if (Proto_IsAccountEnabled(pa) && pa->ppro) - pa->ppro->OnEvent(EV_PROTO_DBSETTINGSCHANGED, hContact, lParam); - } - return 0; -} - -static int InitializeStaticAccounts(WPARAM, LPARAM) -{ - int count = 0; - - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (!pa->ppro || !Proto_IsAccountEnabled(pa)) - continue; - - pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); - - if (!pa->bOldProto) - count++; - } - - BuildProtoMenus(); - - if (count == 0 && !db_get_b(NULL, "FirstRun", "AccManager", 0)) { - db_set_b(NULL, "FirstRun", "AccManager", 1); - CallService(MS_PROTO_SHOWACCMGR, 0, 0); - } - // This is for pack creators with a profile with predefined accounts - else if (db_get_b(NULL, "FirstRun", "ForceShowAccManager", 0)) { - CallService(MS_PROTO_SHOWACCMGR, 0, 0); - db_unset(NULL, "FirstRun", "ForceShowAccManager"); - } - return 0; -} - -static int UninitializeStaticAccounts(WPARAM, LPARAM) -{ - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (pa->ppro && Proto_IsAccountEnabled(pa)) - if (pa->ppro->OnEvent(EV_PROTO_ONREADYTOEXIT, 0, 0) != TRUE) - return 1; - } - - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (pa->ppro && Proto_IsAccountEnabled(pa)) - pa->ppro->OnEvent(EV_PROTO_ONEXIT, 0, 0); - } - - return 0; -} - -int LoadAccountsModule(void) -{ - bModuleInitialized = TRUE; - - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - pa->bDynDisabled = !Proto_IsProtocolLoaded(pa->szProtoName); - if (pa->ppro) - continue; - - if (!Proto_IsAccountEnabled(pa)) - continue; - - if (!ActivateAccount(pa)) - pa->bDynDisabled = TRUE; - } - - hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED, InitializeStaticAccounts); - hHooks[1] = HookEvent(ME_SYSTEM_PRESHUTDOWN, UninitializeStaticAccounts); - hHooks[2] = HookEvent(ME_DB_CONTACT_DELETED, OnContactDeleted); - hHooks[3] = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, OnDbSettingsChanged); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static HANDLE CreateProtoServiceEx(const char* szModule, const char* szService, MIRANDASERVICEOBJ pFunc, void* param) -{ - char tmp[100]; - mir_snprintf(tmp, "%s%s", szModule, szService); - return CreateServiceFunctionObj(tmp, pFunc, param); -} - -BOOL ActivateAccount(PROTOACCOUNT *pa) -{ - PROTOCOLDESCRIPTOR* ppd = Proto_IsProtocolLoaded(pa->szProtoName); - if (ppd == NULL) - return FALSE; - - if (ppd->fnInit == NULL) - return FALSE; - - PROTO_INTERFACE *ppi = ppd->fnInit(pa->szModuleName, pa->tszAccountName); - if (ppi == NULL) - return FALSE; - - pa->ppro = ppi; - ppi->m_iDesiredStatus = ppi->m_iStatus = ID_STATUS_OFFLINE; - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -struct DeactivationThreadParam -{ - PROTO_INTERFACE *ppro; - pfnUninitProto fnUninit; - bool bIsDynamic, bErase; -}; - -pfnUninitProto GetProtocolDestructor(char *szProto); - -static int DeactivationThread(DeactivationThreadParam* param) -{ - PROTO_INTERFACE *p = (PROTO_INTERFACE*)param->ppro; - p->SetStatus(ID_STATUS_OFFLINE); - - char *szModuleName = NEWSTR_ALLOCA(p->m_szModuleName); - - if (param->bIsDynamic) { - while (p->OnEvent(EV_PROTO_ONREADYTOEXIT, 0, 0) != TRUE) - SleepEx(100, TRUE); - - p->OnEvent(EV_PROTO_ONEXIT, 0, 0); - } - - KillObjectThreads(p); // waits for them before terminating - KillObjectEventHooks(p); // untie an object from the outside world - - if (param->bErase) - p->OnEvent(EV_PROTO_ONERASE, 0, 0); - - if (param->fnUninit) - param->fnUninit(p); - - KillObjectServices(p); - - if (param->bErase) - EraseAccount(szModuleName); - - delete param; - return 0; -} - -void DeactivateAccount(PROTOACCOUNT *pa, bool bIsDynamic, bool bErase) -{ - if (pa->ppro == NULL) { - if (bErase) - EraseAccount(pa->szModuleName); - return; - } - - if (pa->hwndAccMgrUI) { - DestroyWindow(pa->hwndAccMgrUI); - pa->hwndAccMgrUI = NULL; - pa->bAccMgrUIChanged = FALSE; - } - - DeactivationThreadParam *param = new DeactivationThreadParam; - param->ppro = pa->ppro; - param->fnUninit = GetProtocolDestructor(pa->szProtoName); - param->bIsDynamic = bIsDynamic; - param->bErase = bErase; - pa->ppro = NULL; - if (bIsDynamic) - mir_forkthread((pThreadFunc)DeactivationThread, param); - else - DeactivationThread(param); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void EraseAccount(const char* pszModuleName) -{ - // remove protocol contacts first - for (MCONTACT hContact = db_find_first(pszModuleName); hContact != NULL;) { - MCONTACT hNext = db_find_next(hContact, pszModuleName); - CallService(MS_DB_CONTACT_DELETE, hContact, 0); - hContact = hNext; - } - - // remove all protocol settings - CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)pszModuleName); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void UnloadAccount(PROTOACCOUNT *pa, bool bIsDynamic, bool bErase) -{ - DeactivateAccount(pa, bIsDynamic, bErase); - - mir_free(pa->tszAccountName); - mir_free(pa->szProtoName); - // szModuleName should be freed only on a program's exit. - // otherwise many plugins dependand on static protocol names will crash! - // do NOT fix this 'leak', please - if (!bIsDynamic) { - mir_free(pa->szModuleName); - mir_free(pa); - } -} - -void UnloadAccountsModule() -{ - if (!bModuleInitialized) return; - - for (int i = accounts.getCount() - 1; i >= 0; i--) { - PROTOACCOUNT *pa = accounts[i]; - UnloadAccount(pa, false, false); - accounts.remove(i); - } - accounts.destroy(); - - for (int i = 0; i < SIZEOF(hHooks); i++) - UnhookEvent(hHooks[i]); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void BuildProtoMenus() -{ - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (cli.pfnGetProtocolVisibility(pa->szModuleName) == 0) - continue; - - if (pa->ppro) - pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); - } -} - -void RebuildProtoMenus(int iNewValue) -{ - RebuildMenuOrder(); - BuildProtoMenus(); -} diff --git a/src/modules/protocols/protochains.cpp b/src/modules/protocols/protochains.cpp deleted file mode 100644 index be760d9877..0000000000 --- a/src/modules/protocols/protochains.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include - -extern LIST filters; - -static int GetProtocolP(MCONTACT hContact, char *szBuf, int cbLen) -{ - if (currDb == NULL) - return 1; - - DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact); - if (cc && cc->szProto != NULL) { - strncpy(szBuf, cc->szProto, cbLen); - szBuf[cbLen - 1] = 0; - return 0; - } - - DBVARIANT dbv; - dbv.type = DBVT_ASCIIZ; - dbv.pszVal = szBuf; - dbv.cchVal = cbLen; - - int res = currDb->GetContactSettingStatic(hContact, "Protocol", "p", &dbv); - if (res == 0) { - if (cc == NULL) - cc = currDb->m_cache->AddContactToCache(hContact); - - cc->szProto = currDb->m_cache->GetCachedSetting(NULL, szBuf, 0, (int)mir_strlen(szBuf)); - } - return res; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -INT_PTR CallContactService(MCONTACT hContact, const char *szProtoService, WPARAM wParam, LPARAM lParam) -{ - INT_PTR ret; - CCSDATA ccs = { hContact, szProtoService, wParam, lParam }; - - for (int i = 0; i < filters.getCount(); i++) { - if ((ret = CallProtoServiceInt(hContact, filters[i]->szName, szProtoService, i + 1, (LPARAM)&ccs)) != CALLSERVICE_NOTFOUND) { - //chain was started, exit - return ret; - } - } - - char szProto[40]; - if (GetProtocolP((MCONTACT)hContact, szProto, sizeof(szProto))) - return 1; - - PROTOACCOUNT *pa = Proto_GetAccount(szProto); - if (pa == NULL || pa->ppro == NULL) - return 1; - - if (pa->bOldProto) - ret = CallProtoServiceInt(hContact, szProto, szProtoService, (WPARAM)(-1), (LPARAM)&ccs); - else - ret = CallProtoServiceInt(hContact, szProto, szProtoService, wParam, lParam); - if (ret == CALLSERVICE_NOTFOUND) - ret = 1; - - return ret; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -INT_PTR Proto_CallContactService(WPARAM wParam, LPARAM lParam) -{ - CCSDATA *ccs = (CCSDATA*)lParam; - INT_PTR ret; - - if (wParam == (WPARAM)(-1)) - return 1; - - for (int i = wParam; i < filters.getCount(); i++) { - if ((ret = CallProtoServiceInt(NULL, filters[i]->szName, ccs->szProtoService, i + 1, lParam)) != CALLSERVICE_NOTFOUND) { - //chain was started, exit - return ret; - } - } - - char szProto[40]; - if (GetProtocolP((MCONTACT)ccs->hContact, szProto, sizeof(szProto))) - return 1; - - PROTOACCOUNT *pa = Proto_GetAccount(szProto); - if (pa == NULL || pa->ppro == NULL) - return 1; - - if (pa->bOldProto) - ret = CallProtoServiceInt(ccs->hContact, szProto, ccs->szProtoService, (WPARAM)(-1), (LPARAM)ccs); - else - ret = CallProtoServiceInt(ccs->hContact, szProto, ccs->szProtoService, ccs->wParam, ccs->lParam); - if (ret == CALLSERVICE_NOTFOUND) - ret = 1; - - return ret; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR Proto_RecvChain(WPARAM wParam, LPARAM lParam) -{ - CCSDATA *ccs = (CCSDATA*)lParam; - INT_PTR ret; - - if (wParam == (WPARAM)(-1)) return 1; //shouldn't happen - sanity check - if (wParam == 0) { //begin processing by finding end of chain - if (GetCurrentThreadId() != hMainThreadId) // restart this function in the main thread - return CallServiceSync(MS_PROTO_CHAINRECV, wParam, lParam); - - wParam = filters.getCount(); - } - else wParam--; - - for (int i = wParam - 1; i >= 0; i--) - if ((ret = CallProtoServiceInt(NULL, filters[i]->szName, ccs->szProtoService, i + 1, lParam)) != CALLSERVICE_NOTFOUND) - //chain was started, exit - return ret; - - //end of chain, call network protocol again - char szProto[40]; - if (GetProtocolP((MCONTACT)ccs->hContact, szProto, sizeof(szProto))) - return 1; - - PROTOACCOUNT *pa = Proto_GetAccount(szProto); - if (pa == NULL || pa->ppro == NULL) - return 1; - - if (pa->bOldProto) - ret = CallProtoServiceInt(ccs->hContact, szProto, ccs->szProtoService, (WPARAM)(-1), (LPARAM)ccs); - else - ret = CallProtoServiceInt(ccs->hContact, szProto, ccs->szProtoService, ccs->wParam, ccs->lParam); - if (ret == CALLSERVICE_NOTFOUND) - ret = 1; - - return ret; -} - -PROTOACCOUNT* __fastcall Proto_GetAccount(MCONTACT hContact) -{ - if (hContact == NULL) - return NULL; - - char szProto[40]; - if (GetProtocolP((MCONTACT)hContact, szProto, sizeof(szProto))) - return NULL; - - return Proto_GetAccount(szProto); -} - -static INT_PTR Proto_GetContactBaseProto(WPARAM wParam, LPARAM) -{ - PROTOACCOUNT *pa = Proto_GetAccount(wParam); - return (INT_PTR)(Proto_IsAccountEnabled(pa) ? pa->szModuleName : NULL); -} - -static INT_PTR Proto_GetContactBaseAccount(WPARAM wParam, LPARAM) -{ - PROTOACCOUNT *pa = Proto_GetAccount(wParam); - return (INT_PTR)(pa ? pa->szModuleName : NULL); -} - -static INT_PTR Proto_IsProtoOnContact(WPARAM wParam, LPARAM lParam) -{ - char *szProto = (char*)lParam; - if (szProto == NULL) - return 0; - - char szContactProto[40]; - if (!GetProtocolP(wParam, szContactProto, sizeof(szContactProto))) - if (!_stricmp(szProto, szContactProto)) - return -1; - - for (int i = 0; i < filters.getCount(); i++) - if (!mir_strcmp(szProto, filters[i]->szName)) - return i + 1; - - return 0; -} - -static INT_PTR Proto_AddToContact(WPARAM wParam, LPARAM lParam) -{ - char *szProto = (char*)lParam; - PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(szProto); - if (pd == NULL) { - PROTOACCOUNT *pa = Proto_GetAccount(szProto); - if (pa) { - db_set_s(wParam, "Protocol", "p", szProto); - return 0; - } - return 1; - } - - if (pd->type == PROTOTYPE_PROTOCOL || pd->type == PROTOTYPE_VIRTUAL) - db_set_s(wParam, "Protocol", "p", szProto); - - return 0; -} - -static INT_PTR Proto_RemoveFromContact(WPARAM wParam, LPARAM lParam) -{ - switch (Proto_IsProtoOnContact(wParam, lParam)) { - case 0: - return 1; - case -1: - db_unset(wParam, "Protocol", "p"); - } - - return 0; -} - -int LoadProtoChains(void) -{ - if (!db_get_b(NULL, "Compatibility", "Filters", 0)) { - CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)"_Filters"); - db_set_b(NULL, "Compatibility", "Filters", 1); - } - - CreateServiceFunction(MS_PROTO_CALLCONTACTSERVICE, Proto_CallContactService); - CreateServiceFunction(MS_PROTO_CHAINSEND, Proto_CallContactService); - CreateServiceFunction(MS_PROTO_CHAINRECV, Proto_RecvChain); - CreateServiceFunction(MS_PROTO_GETCONTACTBASEPROTO, Proto_GetContactBaseProto); - CreateServiceFunction(MS_PROTO_GETCONTACTBASEACCOUNT, Proto_GetContactBaseAccount); - CreateServiceFunction(MS_PROTO_ISPROTOONCONTACT, Proto_IsProtoOnContact); - CreateServiceFunction(MS_PROTO_ADDTOCONTACT, Proto_AddToContact); - CreateServiceFunction(MS_PROTO_REMOVEFROMCONTACT, Proto_RemoveFromContact); - return 0; -} diff --git a/src/modules/protocols/protocols.cpp b/src/modules/protocols/protocols.cpp deleted file mode 100644 index 273fb85dd9..0000000000 --- a/src/modules/protocols/protocols.cpp +++ /dev/null @@ -1,511 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -int LoadProtoChains(void); -int LoadProtoOptions(void); - -HANDLE hAccListChanged; -static HANDLE hTypeEvent; -static BOOL bModuleInitialized = FALSE; - -struct TServiceListItem -{ - const char *name; - int id; -}; - -static int __cdecl CompareServiceItems(const void *p1, const void *p2) -{ return strcmp(((TServiceListItem*)p1)->name, ((TServiceListItem*)p2)->name); -} - -static TServiceListItem serviceItems[] = -{ - { PS_ADDTOLIST, 1 }, - { PS_ADDTOLISTBYEVENT, 2 }, - { PS_AUTHALLOW, 3 }, - { PS_AUTHDENY, 4 }, - { PSR_AUTH, 5 }, - { PSS_AUTHREQUEST, 6 }, - { PSS_FILEALLOW, 8 }, - { PSS_FILECANCEL, 9 }, - { PSS_FILEDENY, 10 }, - { PS_FILERESUME, 11 }, - { PS_GETCAPS, 12 }, - { PS_LOADICON, 13 }, - { PSS_GETINFO, 14 }, - { PS_BASICSEARCH, 15 }, - { PS_SEARCHBYEMAIL, 16 }, - { PS_SEARCHBYNAME, 17 }, - { PS_SEARCHBYADVANCED, 18 }, - { PS_CREATEADVSEARCHUI, 19 }, - { PSR_CONTACTS, 20 }, - { PSR_FILE, 21 }, - { PSR_MESSAGE, 22 }, - { PSR_URL, 23 }, - { PSS_CONTACTS, 24 }, - { PSS_FILE, 25 }, - { PSS_MESSAGE, 26 }, - { PSS_URL, 27 }, - { PSS_SETAPPARENTMODE, 28 }, - { PS_SETSTATUS, 29 }, - { PSS_GETAWAYMSG, 30 }, - { PSR_AWAYMSG, 31 }, - { PS_SETAWAYMSG, 33 }, - { PSS_USERISTYPING, 34 }, - { PS_GETNAME, 35 }, - { PS_GETSTATUS, 36 } -}; - -//------------------------------------------------------------------------------------ - -static int CompareProtos(const PROTOCOLDESCRIPTOR *p1, const PROTOCOLDESCRIPTOR *p2) -{ - if (p1->type != p2->type) - return p1->type - p2->type; - - return mir_strcmp(p1->szName, p2->szName); -} - -LIST filters(10, CompareProtos); - -//------------------------------------------------------------------------------------ - -void FreeFilesMatrix(TCHAR ***files); - -INT_PTR srvProto_IsLoaded(WPARAM, LPARAM lParam) -{ - return (INT_PTR)Proto_IsProtocolLoaded((char*)lParam); -} - -static PROTO_INTERFACE* defInitProto(const char* szModule, const TCHAR*) -{ - return AddDefaultAccount(szModule); -} - -static INT_PTR srvProto_RegisterModule(WPARAM, LPARAM lParam) -{ - PROTOCOLDESCRIPTOR *pd = (PROTOCOLDESCRIPTOR*)lParam; - if (pd->cbSize != sizeof(PROTOCOLDESCRIPTOR) && pd->cbSize != PROTOCOLDESCRIPTOR_V3_SIZE) - return 1; - - PROTOCOLDESCRIPTOR *p = Proto_RegisterModule(pd); - if (p == NULL) - return 2; - - if (p->fnInit == NULL && (p->type == PROTOTYPE_PROTOCOL || p->type == PROTOTYPE_VIRTUAL)) { - // let's create a new container - PROTO_INTERFACE* ppi = AddDefaultAccount(pd->szName); - if (ppi) { - ppi->m_iVersion = (pd->cbSize == PROTOCOLDESCRIPTOR_V3_SIZE) ? 1 : 2; - PROTOACCOUNT *pa = Proto_GetAccount(pd->szName); - if (pa == NULL) { - pa = (PROTOACCOUNT*)mir_calloc(sizeof(PROTOACCOUNT)); - pa->cbSize = sizeof(PROTOACCOUNT); - pa->szModuleName = mir_strdup(pd->szName); - pa->szProtoName = mir_strdup(pd->szName); - pa->tszAccountName = mir_a2t(pd->szName); - pa->bIsVisible = pa->bIsEnabled = true; - pa->iOrder = accounts.getCount(); - accounts.insert(pa); - } - pa->bOldProto = true; - pa->bIsVirtual = (p->type == PROTOTYPE_VIRTUAL); - pa->ppro = ppi; - p->fnInit = defInitProto; - p->fnUninit = FreeDefaultAccount; - } - } - - if (p->type != PROTOTYPE_PROTOCOL && p->type != PROTOTYPE_VIRTUAL) - filters.insert(p); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Basic core services - -static INT_PTR Proto_RecvMessage(WPARAM, LPARAM lParam) -{ - CCSDATA *ccs = (CCSDATA*)lParam; - PROTORECVEVENT *pre = (PROTORECVEVENT*)ccs->lParam; - if (pre->szMessage == NULL) - return NULL; - - ptrA pszTemp; - mir_ptr pszBlob; - - DBEVENTINFO dbei = { 0 }; - dbei.cbSize = sizeof(dbei); - dbei.flags = DBEF_UTF; - dbei.szModule = GetContactProto(ccs->hContact); - dbei.timestamp = pre->timestamp; - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.cbBlob = (DWORD)mir_strlen(pre->szMessage) + 1; - dbei.pBlob = (PBYTE)pre->szMessage; - - if (pre->cbCustomDataSize != 0) { - pszBlob = (PBYTE)mir_alloc(dbei.cbBlob + pre->cbCustomDataSize); - memcpy(pszBlob, dbei.pBlob, dbei.cbBlob); - memcpy((PBYTE)pszBlob + dbei.cbBlob, pre->pCustomData, pre->cbCustomDataSize); - dbei.pBlob = pszBlob; - dbei.cbBlob += pre->cbCustomDataSize; - } - - if (pre->flags & PREF_CREATEREAD) - dbei.flags |= DBEF_READ; - if (pre->flags & PREF_SENT) - dbei.flags |= DBEF_SENT; - - return (INT_PTR)db_event_add(ccs->hContact, &dbei); -} - -static INT_PTR Proto_AuthRecv(WPARAM wParam, LPARAM lParam) -{ - PROTORECVEVENT* pre = (PROTORECVEVENT*)lParam; - - DBEVENTINFO dbei = { sizeof(dbei) }; - dbei.szModule = (char*)wParam; - dbei.timestamp = pre->timestamp; - dbei.flags = DBEF_UTF | pre->flags & (PREF_CREATEREAD ? DBEF_READ : 0); - dbei.eventType = EVENTTYPE_AUTHREQUEST; - dbei.cbBlob = pre->lParam; - dbei.pBlob = (PBYTE)pre->szMessage; - return (INT_PTR)db_event_add(NULL, &dbei); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// User Typing Notification services - -static int Proto_ValidTypingContact(MCONTACT hContact, char *szProto) -{ - if (!hContact || !szProto) - return 0; - - return (CallProtoServiceInt(NULL, szProto, PS_GETCAPS, PFLAGNUM_4, 0) & PF4_SUPPORTTYPING) ? 1 : 0; -} - -static INT_PTR Proto_SelfIsTyping(WPARAM wParam, LPARAM lParam) -{ - if (lParam == PROTOTYPE_SELFTYPING_OFF || lParam == PROTOTYPE_SELFTYPING_ON) { - char *szProto = GetContactProto(wParam); - if (!szProto) - return 0; - - if (Proto_ValidTypingContact(wParam, szProto)) - CallProtoServiceInt(NULL, szProto, PSS_USERISTYPING, wParam, lParam); - } - - return 0; -} - -static INT_PTR Proto_ContactIsTyping(WPARAM wParam, LPARAM lParam) -{ - int type = (int)lParam; - char *szProto = GetContactProto(wParam); - if (!szProto) - return 0; - - if (CallService(MS_IGNORE_ISIGNORED, wParam, IGNOREEVENT_TYPINGNOTIFY)) - return 0; - - if (type < PROTOTYPE_CONTACTTYPING_OFF) - return 0; - - if (Proto_ValidTypingContact(wParam, szProto)) - NotifyEventHooks(hTypeEvent, wParam, lParam); - - return 0; -} - -void Proto_SetStatus(const char *szProto, unsigned status) -{ - if (CallProtoServiceInt(NULL, szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND) { - ptrT tszAwayMsg((TCHAR*)CallService(MS_AWAYMSG_GETSTATUSMSGT, status, (LPARAM)szProto)); - CallProtoServiceInt(NULL, szProto, PS_SETAWAYMSG, status, tszAwayMsg); - } - CallProtoServiceInt(NULL, szProto, PS_SETSTATUS, status, 0); -} - -char** __fastcall Proto_FilesMatrixA(wchar_t **files) -{ - if (files == NULL) return NULL; - - int count = 0; - while (files[count++]); - - char** filesA = (char**)mir_alloc(count * sizeof(char*)); - for (int i = 0; i < count; i++) - filesA[i] = mir_u2a(files[i]); - - return filesA; -} - -static wchar_t** __fastcall Proto_FilesMatrixU(char **files) -{ - if (files == NULL) return NULL; - - int count = 0; - while (files[count++]); - - wchar_t** filesU = (wchar_t**)mir_alloc(count * sizeof(wchar_t*)); - for (int i = 0; i < count; i++) - filesU[i] = mir_a2u(files[i]); - - return filesU; -} - -HICON Proto_GetIcon(PROTO_INTERFACE *ppro, int iconIndex) -{ - if (LOWORD(iconIndex) != PLI_PROTOCOL) - return NULL; - - if (iconIndex & PLIF_ICOLIBHANDLE) - return (HICON)ppro->m_hProtoIcon; - - bool big = (iconIndex & PLIF_SMALL) == 0; - HICON hIcon = Skin_GetIconByHandle(ppro->m_hProtoIcon, big); - if (iconIndex & PLIF_ICOLIB) - return hIcon; - - HICON hIcon2 = CopyIcon(hIcon); - Skin_ReleaseIcon(hIcon); - return hIcon2; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// 0.8.0+ - accounts - -PROTOACCOUNT* __fastcall Proto_GetAccount(const char* accName) -{ - if (accName == NULL) - return NULL; - - int idx; - PROTOACCOUNT temp; - temp.szModuleName = (char*)accName; - if ((idx = accounts.getIndex(&temp)) == -1) - return NULL; - - return accounts[idx]; -} - -static INT_PTR srvProto_CreateAccount(WPARAM, LPARAM lParam) -{ - ACC_CREATE *p = (ACC_CREATE*)lParam; - if (p == NULL) - return NULL; - - PROTOACCOUNT *pa = Proto_CreateAccount(p->pszInternal, p->pszBaseProto, p->ptszAccountName); - if (pa) { - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, PRAC_ADDED, (LPARAM)pa); - } - return (INT_PTR)pa; -} - -static INT_PTR srvProto_GetAccount(WPARAM, LPARAM lParam) -{ - return (INT_PTR)Proto_GetAccount((char*)lParam); -} - -static INT_PTR Proto_EnumAccounts(WPARAM wParam, LPARAM lParam) -{ - *(int*)wParam = accounts.getCount(); - *(PROTOACCOUNT***)lParam = accounts.getArray(); - return 0; -} - -bool __fastcall Proto_IsAccountEnabled(PROTOACCOUNT *pa) -{ - return pa && ((pa->bIsEnabled && !pa->bDynDisabled) || pa->bOldProto); -} - -static INT_PTR srvProto_IsAccountEnabled(WPARAM, LPARAM lParam) -{ - return (INT_PTR)Proto_IsAccountEnabled((PROTOACCOUNT*)lParam); -} - -bool __fastcall Proto_IsAccountLocked(PROTOACCOUNT *pa) -{ - return pa && db_get_b(NULL, pa->szModuleName, "LockMainStatus", 0) != 0; -} - -static INT_PTR srvProto_IsAccountLocked(WPARAM, LPARAM lParam) -{ - return (INT_PTR)Proto_IsAccountLocked(Proto_GetAccount((char*)lParam)); -} - -static INT_PTR Proto_BroadcastAck(WPARAM, LPARAM lParam) -{ - ACKDATA *ack = (ACKDATA*)lParam; - return ProtoBroadcastAck(ack->szModule, ack->hContact, ack->type, ack->result, ack->hProcess, ack->lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -int ProtoServiceExists(const char *szModule, const char *szService) -{ - if (szModule == NULL || szService == NULL) - return false; - - TServiceListItem *item = (TServiceListItem*)bsearch(&szService, serviceItems, _countof(serviceItems), sizeof(serviceItems[0]), CompareServiceItems); - if (item != NULL) - return true; - - char str[MAXMODULELABELLENGTH * 2]; - strncpy_s(str, szModule, _TRUNCATE); - strncat_s(str, szService, _TRUNCATE); - return ServiceExists(str); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -INT_PTR CallProtoService(const char* szModule, const char* szService, WPARAM wParam, LPARAM lParam) -{ - return CallProtoServiceInt(NULL, szModule, szService, wParam, lParam); -} - -INT_PTR CallProtoServiceInt(MCONTACT hContact, const char *szModule, const char *szService, WPARAM wParam, LPARAM lParam) -{ - PROTOACCOUNT *pa = Proto_GetAccount(szModule); - if (pa && !pa->bOldProto) { - PROTO_INTERFACE *ppi = pa->ppro; - if (ppi != NULL && ppi->m_iVersion > 1) { - TServiceListItem *item = (TServiceListItem*)bsearch(&szService, serviceItems, _countof(serviceItems), sizeof(serviceItems[0]), CompareServiceItems); - if (item) { - switch (item->id) { - case 1: return (INT_PTR)ppi->AddToList(wParam, (PROTOSEARCHRESULT*)lParam); - case 2: return (INT_PTR)ppi->AddToListByEvent(LOWORD(wParam), HIWORD(wParam), (MEVENT)lParam); - case 3: return (INT_PTR)ppi->Authorize((MEVENT)wParam); - case 4: return (INT_PTR)ppi->AuthDeny((MEVENT)wParam, (TCHAR*)lParam); - case 5: return (INT_PTR)ppi->AuthRecv(hContact, (PROTORECVEVENT*)lParam); - case 6: return (INT_PTR)ppi->AuthRequest(hContact, (TCHAR*)lParam); - case 8: return (INT_PTR)ppi->FileAllow(hContact, (HANDLE)wParam, (TCHAR*)lParam); - case 9: return (INT_PTR)ppi->FileCancel(hContact, (HANDLE)wParam); - case 10: return (INT_PTR)ppi->FileDeny(hContact, (HANDLE)wParam, (TCHAR*)lParam); - case 11: { - PROTOFILERESUME *pfr = (PROTOFILERESUME*)lParam; - return (INT_PTR)ppi->FileResume((HANDLE)wParam, &pfr->action, (const TCHAR**)&pfr->szFilename); - } - - case 12: return (INT_PTR)ppi->GetCaps(wParam, lParam); - case 13: return (INT_PTR)Proto_GetIcon(ppi, wParam); - case 14: return (INT_PTR)ppi->GetInfo(hContact, wParam); - case 15: return (INT_PTR)ppi->SearchBasic((TCHAR*)lParam); - case 16: return (INT_PTR)ppi->SearchByEmail((TCHAR*)lParam); - case 17: { - PROTOSEARCHBYNAME* psbn = (PROTOSEARCHBYNAME*)lParam; - return (INT_PTR)ppi->SearchByName(psbn->pszNick, psbn->pszFirstName, psbn->pszLastName); - } - case 18: return (INT_PTR)ppi->SearchAdvanced((HWND)lParam); - case 19: return (INT_PTR)ppi->CreateExtendedSearchUI((HWND)lParam); - case 20: return (INT_PTR)ppi->RecvContacts(hContact, (PROTORECVEVENT*)lParam); - case 21: return (INT_PTR)ppi->RecvFile(hContact, (PROTORECVFILET*)lParam); - case 22: return (INT_PTR)ppi->RecvMsg(hContact, (PROTORECVEVENT*)lParam); - case 23: return (INT_PTR)ppi->RecvUrl(hContact, (PROTORECVEVENT*)lParam); - case 24: return (INT_PTR)ppi->SendContacts(hContact, LOWORD(wParam), HIWORD(wParam), (MCONTACT*)lParam); - case 25: return (INT_PTR)ppi->SendFile(hContact, (TCHAR*)wParam, (TCHAR**)lParam); - case 26: return (INT_PTR)ppi->SendMsg(hContact, wParam, (const char*)lParam); - case 27: return (INT_PTR)ppi->SendUrl(hContact, wParam, (const char*)lParam); - case 28: return (INT_PTR)ppi->SetApparentMode(hContact, wParam); - case 29: return (INT_PTR)ppi->SetStatus(wParam); - case 30: return (INT_PTR)ppi->GetAwayMsg(hContact); - case 31: return (INT_PTR)ppi->RecvAwayMsg(hContact, wParam, (PROTORECVEVENT*)lParam); - case 33: return (INT_PTR)ppi->SetAwayMsg(wParam, (TCHAR*)lParam); - case 34: return (INT_PTR)ppi->UserIsTyping(wParam, lParam); - case 35: mir_strncpy((char*)lParam, ppi->m_szModuleName, wParam); return 0; - case 36: - return ppi->m_iStatus; - } - } - } - } - - return ProtoCallService(szModule, szService, wParam, lParam); -} - -INT_PTR ProtoCallService(const char *szModule, const char *szService, WPARAM wParam, LPARAM lParam) -{ - if (szModule == NULL || szService == NULL) - return false; - - char str[MAXMODULELABELLENGTH * 2]; - strncpy_s(str, szModule, _TRUNCATE); - strncat_s(str, szService, _TRUNCATE); - return CallService(str, wParam, lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -int LoadProtocolsModule(void) -{ - bModuleInitialized = TRUE; - - if (LoadProtoChains()) - return 1; - - qsort(serviceItems, _countof(serviceItems), sizeof(serviceItems[0]), CompareServiceItems); - - hTypeEvent = CreateHookableEvent(ME_PROTO_CONTACTISTYPING); - hAccListChanged = CreateHookableEvent(ME_PROTO_ACCLISTCHANGED); - - CreateServiceFunction(MS_PROTO_BROADCASTACK, Proto_BroadcastAck); - CreateServiceFunction(MS_PROTO_ISPROTOCOLLOADED, srvProto_IsLoaded); - CreateServiceFunction(MS_PROTO_REGISTERMODULE, srvProto_RegisterModule); - CreateServiceFunction(MS_PROTO_SELFISTYPING, Proto_SelfIsTyping); - CreateServiceFunction(MS_PROTO_CONTACTISTYPING, Proto_ContactIsTyping); - - CreateServiceFunction(MS_PROTO_RECVMSG, Proto_RecvMessage); - CreateServiceFunction(MS_PROTO_AUTHRECV, Proto_AuthRecv); - - CreateServiceFunction("Proto/EnumProtocols", Proto_EnumAccounts); - CreateServiceFunction(MS_PROTO_ENUMACCOUNTS, Proto_EnumAccounts); - CreateServiceFunction(MS_PROTO_CREATEACCOUNT, srvProto_CreateAccount); - CreateServiceFunction(MS_PROTO_GETACCOUNT, srvProto_GetAccount); - - CreateServiceFunction(MS_PROTO_ISACCOUNTENABLED, srvProto_IsAccountEnabled); - CreateServiceFunction(MS_PROTO_ISACCOUNTLOCKED, srvProto_IsAccountLocked); - - return LoadProtoOptions(); -} - -void UnloadProtocolsModule() -{ - if (!bModuleInitialized) return; - - if (hAccListChanged) { - DestroyHookableEvent(hAccListChanged); - hAccListChanged = NULL; - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - -pfnUninitProto GetProtocolDestructor(char *szProto) -{ - PROTOCOLDESCRIPTOR *p = Proto_IsProtocolLoaded(szProto); - return (p == NULL) ? NULL : p->fnUninit; -} diff --git a/src/modules/protocols/protodir.cpp b/src/modules/protocols/protodir.cpp deleted file mode 100644 index 672fb7f007..0000000000 --- a/src/modules/protocols/protodir.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#if 0 - -extern HANDLE hCacheHeap; - -/* - - the id cache has id/proto against hContact to lookup ID's fast to resolve to hContact, - the protoBaseCache has hContact's sorted, so can lookup hContact->proto fast, these two caches - share the same data, they're indexes, each entry might not have an "id" set. - - There is a small cache which maintains a protocol list - -*/ - -/* - - The information we need to cache is not readily available, data has to be gathered at startup - when a new contact is created/deleted, when a new proto registers and so on. - - The information we get at startup includes walking the contact chain and reading Protocol/p which - will give us the protocol the contact is on, all this info is stored in contactEntry's within - protoCache ONLY - contactCache is EMPTY at this point. - - We can not fetch the id of the contact because this information is only in SOME protocol plugins, - this is a problem but we'll hook all proto registrations and ask each proto if it supports the - returning this ID name, if not - it won't even use our id <-> contact look so no biggie! - -*/ - -typedef struct { - char * proto; // within proto cache - char * id; // optional - HANDLE hContact; -} contactEntry; - -typedef struct { - mir_cs csLock; - SortedList contactCache; // index for id/proto -> hContact - SortedList protoCache; // index for hContact -> proto/id - SortedList protoNameCache; // index of protocol names -} contactDir; - -static contactDir condir; - -// compare's id/proto and return's hContact's -int contactCacheCompare(void * a, void * b) -{ - contactEntry * x = (contactEntry *) a; - contactEntry * y = (contactEntry *) b; - int rc=0; - // same protocol? - rc = mir_strcmp(x->proto, y->proto); - if ( rc == 0 ) { - // same id? id's might be missing - if ( x->id && y->id ) rc = mir_strcmp(x->id, y->id); - } - return rc; -} - -// compares hContact's and returns associated data -int protoCacheCompare(void * a, void * b) -{ - contactEntry * x = (contactEntry *) a; - contactEntry * y = (contactEntry *) b; - if ( x->hContact < y->hContact ) return -1; - if ( x->hContact > y->hContact ) return 1; - return 0; -} - -// keeps a list of protocol names -int protoNameCacheCompare(void * a, void * b) -{ - return mir_strcmp( (char *)a, (char*)b ); -} - -// cache the protocol string so that its not allocated per contact but shared -char * contactDir_Proto_Add(contactDir * cd, char * proto) -{ - int index = 0 ; - char * szCache = 0; - mir_cslock lck(cd->csLock); - if ( List_GetIndex(&cd->protoNameCache, proto, &index) ) szCache = cd->protoNameCache.items[index]; - else { - szCache = HeapAlloc(hCacheHeap, HEAP_NO_SERIALIZE, mir_strlen(proto)+1); - mir_strcpy(szCache, proto); - List_Insert(&cd->protoNameCache, szCache, index); - } - return szCache; -} - -// thread safe -char * contactDir_Proto_Get(contactDir * cd, HANDLE hContact) -{ - char * szCache = 0; - int index = 0; - contactEntry e; - e.hContact=hContact; - e.proto=""; - e.id=""; - mir_cslock lck(cd->csLock); - if ( List_GetIndex(&cd->protoCache, &e, &index) ) { - contactEntry * p = cd->protoCache.items[index]; - szCache = p->proto; - } - return szCache; -} - -// thread tolerant, if updating id dont pass proto, if updating proto dont pass id -void contactDir_Contact_Add(contactDir * cd, HANDLE hContact, char * proto, char * id) -{ - // if a contact is gonna exist anywhere it's going to be in the ->protoCache which has a key of hContact - // if id is not null then the contact should be indexed via the ->contactCache instead - if ( id == NULL ) { - int index = 0; - contactEntry e; - e.hContact=hContact; - e.proto = proto; - e.id = ""; - mir_cslock lck(cd->csLock); - if ( List_GetIndex(&cd->protoCache, &e, &index) ) { - contactEntry * p = cd->protoCache.items[index]; - // this hContact is in the cache, protcol changing? - p->proto = contactDir_Proto_Add(cd, proto); // just replace the old pointer - } else { - contactEntry * p = 0; - // this hContact isn't in the cache, add it - p = HeapAlloc(hCacheHeap, HEAP_NO_SERIALIZE, sizeof(contactEntry)); - p->proto = contactDir_Proto_Add(cd, proto); - p->id = 0; - p->hContact = hContact; - // add it - List_Insert(&cd->protoCache, p, index); - } - } else { - // this contact HAS to be in ->protoCache since it was added during startup - // need to find the contactEntry* that should already exist for it - } //if -} - -// only expected to be called at startup. -void contactDir_Proto_Walk(contactDir * cd) -{ - HANDLE hContact; - char buf[128]; - DBCONTACTGETSETTING gsProto; - DBVARIANT dbvProto; - // setup the read structure - gsProto.szModule="Protocol"; - gsProto.szSetting="p"; - gsProto.pValue = &dbvProto; - // this might not work - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while ( hContact ) { - // and how we'll get the reset - dbvProto.type=DBVT_ASCIIZ; - dbvProto.pszVal = (char *) &buf; - dbvProto.cchVal = SIZEOF(buf); - // figure out what hContact/Protocol/p is - if ( CallService(MS_DB_CONTACT_GETSETTINGSTATIC,(WPARAM)hContact, (LPARAM)&gsProto) == 0 ) { - contactDir_Contact_Add(cd, hContact, buf, NULL); - } - // find next - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); - } -} - -// ctor/dtor - -void contactDir_Init(contactDir * cd) -{ - cd->contactCache.increment=50; - cd->contactCache.sortFunc=contactCacheCompare; - cd->protoCache.increment=50; - cd->protoCache.sortFunc=protoCacheCompare; - cd->protoNameCache.increment=5; - cd->protoNameCache.sortFunc=protoNameCacheCompare; - // build a list of all hContact's and what proto's they are on - contactDir_Proto_Walk(cd); -} - -void contactDir_Deinit(contactDir * cd) -{ - List_Destroy(&cd->contactCache); - List_Destroy(&cd->protoCache); - List_Destroy(&cd->protoNameCache); -} - -static int contactDirGetProto(WPARAM wParam, LPARAM lParam) -{ - return (int) contactDir_Proto_Get(&condir,(HANDLE)wParam); -} - -#endif - -void InitContactDir(void) -{ - return; - //contactDir_Init(&condir); - //CreateServiceFunction(MS_PROTODIR_PROTOFROMCONTACT, contactDirGetProto); -} - -void UninitContactDir(void) -{ - return; -#if 0 - { - int j; - for ( j = 0; j< condir.protoCache.realCount; j++) { - char buf[128]; - contactEntry * p = condir.protoCache.items[j]; - mir_snprintf(buf,SIZEOF(buf)," [%s] %s @ %x \n", p->proto, p->id ? p->id : "", p->hContact); - OutputDebugString(buf); - } - } - contactDir_Deinit(&condir); -#endif -} diff --git a/src/modules/protocols/protoint.cpp b/src/modules/protocols/protoint.cpp deleted file mode 100644 index 2fadfa4e89..0000000000 --- a/src/modules/protocols/protoint.cpp +++ /dev/null @@ -1,304 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -char** __fastcall Proto_FilesMatrixA(TCHAR **files); - -void FreeFilesMatrix(TCHAR ***files) -{ - if (*files == NULL) - return; - - // Free each filename in the pointer array - TCHAR **pFile = *files; - while (*pFile != NULL) { - mir_free(*pFile); - *pFile = NULL; - pFile++; - } - - // Free the array itself - mir_free(*files); - *files = NULL; -} - -struct DEFAULT_PROTO_INTERFACE : public PROTO_INTERFACE -{ - MCONTACT __cdecl AddToList(int flags, PROTOSEARCHRESULT *psr) - { - return (MCONTACT)ProtoCallService(m_szModuleName, PS_ADDTOLIST, flags, (LPARAM)psr); - } - - MCONTACT __cdecl AddToListByEvent(int flags, int iContact, MEVENT hDbEvent) - { - return (MCONTACT)ProtoCallService(m_szModuleName, PS_ADDTOLISTBYEVENT, MAKELONG(flags, iContact), hDbEvent); - } - - int __cdecl Authorize(MEVENT hDbEvent) - { - return (int)ProtoCallService(m_szModuleName, PS_AUTHALLOW, (WPARAM)hDbEvent, 0); - } - - int __cdecl AuthDeny(MEVENT hDbEvent, const TCHAR *szReason) - { - if (m_iVersion > 1) - return (int)ProtoCallService(m_szModuleName, PS_AUTHDENY, hDbEvent, (LPARAM)szReason); - - return (int)ProtoCallService(m_szModuleName, PS_AUTHDENY, hDbEvent, _T2A(szReason)); - } - - int __cdecl AuthRecv(MCONTACT hContact, PROTORECVEVENT *evt) - { - CCSDATA ccs = { hContact, PSR_AUTH, 0, (LPARAM)evt }; - return (int)ProtoCallService(m_szModuleName, PSR_AUTH, 0, (LPARAM)&ccs); - } - - int __cdecl AuthRequest(MCONTACT hContact, const TCHAR *szMessage) - { - CCSDATA ccs = { hContact, PSS_AUTHREQUEST, 0, (LPARAM)szMessage }; - if (m_iVersion > 1) - return (int)ProtoCallService(m_szModuleName, PSS_AUTHREQUEST, 0, (LPARAM)&ccs); - - ccs.lParam = (LPARAM)mir_t2a(szMessage); - int res = (int)ProtoCallService(m_szModuleName, PSS_AUTHREQUEST, 0, (LPARAM)&ccs); - mir_free((char*)ccs.lParam); - return res; - } - - HANDLE __cdecl FileAllow(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szPath) - { - CCSDATA ccs = { hContact, PSS_FILEALLOW, (WPARAM)hTransfer, (LPARAM)szPath }; - if (m_iVersion > 1) - return (HANDLE)ProtoCallService(m_szModuleName, PSS_FILEALLOW, 0, (LPARAM)&ccs); - - ccs.lParam = (LPARAM)mir_t2a(szPath); - HANDLE res = (HANDLE)ProtoCallService(m_szModuleName, PSS_FILEALLOW, 0, (LPARAM)&ccs); - mir_free((char*)ccs.lParam); - return res; - } - - int __cdecl FileCancel(MCONTACT hContact, HANDLE hTransfer) - { - CCSDATA ccs = { hContact, PSS_FILECANCEL, (WPARAM)hTransfer, 0 }; - return (int)ProtoCallService(m_szModuleName, PSS_FILECANCEL, 0, (LPARAM)&ccs); - } - - int __cdecl FileDeny(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szReason) - { - CCSDATA ccs = { hContact, PSS_FILEDENY, (WPARAM)hTransfer, (LPARAM)szReason }; - if (m_iVersion > 1) - return (int)ProtoCallService(m_szModuleName, PSS_FILEDENY, 0, (LPARAM)&ccs); - - ccs.lParam = (LPARAM)mir_t2a(szReason); - int res = (int)ProtoCallService(m_szModuleName, PSS_FILEDENY, 0, (LPARAM)&ccs); - mir_free((char*)ccs.lParam); - return res; - } - - int __cdecl FileResume(HANDLE hTransfer, int* action, const TCHAR** szFilename) - { - PROTOFILERESUME pfr = { *action, *szFilename }; - if (m_iVersion > 1) - return (int)ProtoCallService(m_szModuleName, PS_FILERESUME, (WPARAM)hTransfer, (LPARAM)&pfr); - - pfr.szFilename = (TCHAR*)mir_t2a(pfr.szFilename); - int res = (int)ProtoCallService(m_szModuleName, PS_FILERESUME, (WPARAM)hTransfer, (LPARAM)&pfr); - mir_free((TCHAR*)*szFilename); - *action = pfr.action; *szFilename = (TCHAR*)pfr.szFilename; - - return res; - } - - DWORD_PTR __cdecl GetCaps(int type, MCONTACT hContact) - { - return (DWORD_PTR)ProtoCallService(m_szModuleName, PS_GETCAPS, type, hContact); - } - - HICON __cdecl GetIcon(int iconIndex) - { - return (HICON)ProtoCallService(m_szModuleName, PS_LOADICON, iconIndex, 0); - } - - int __cdecl GetInfo(MCONTACT hContact, int flags) - { - CCSDATA ccs = { hContact, PSS_GETINFO, flags, 0 }; - return ProtoCallService(m_szModuleName, PSS_GETINFO, 0, (LPARAM)&ccs); - } - - HANDLE __cdecl SearchBasic(const TCHAR* id) - { - if (m_iVersion > 1) - return (HANDLE)ProtoCallService(m_szModuleName, PS_BASICSEARCH, 0, (LPARAM)id); - - return (HANDLE)ProtoCallService(m_szModuleName, PS_BASICSEARCH, 0, _T2A(id)); - } - - HANDLE __cdecl SearchByEmail(const TCHAR* email) - { - if (m_iVersion > 1) - return (HANDLE)ProtoCallService(m_szModuleName, PS_SEARCHBYEMAIL, 0, (LPARAM)email); - return (HANDLE)ProtoCallService(m_szModuleName, PS_SEARCHBYEMAIL, 0, _T2A(email)); - } - - HANDLE __cdecl SearchByName(const TCHAR* nick, const TCHAR* firstName, const TCHAR* lastName) - { - PROTOSEARCHBYNAME psn; - psn.pszNick = (TCHAR*)mir_t2a(nick); - psn.pszFirstName = (TCHAR*)mir_t2a(firstName); - psn.pszLastName = (TCHAR*)mir_t2a(lastName); - HANDLE res = (HANDLE)ProtoCallService(m_szModuleName, PS_SEARCHBYNAME, 0, (LPARAM)&psn); - mir_free(psn.pszNick); - mir_free(psn.pszFirstName); - mir_free(psn.pszLastName); - return res; - - } - - HWND __cdecl SearchAdvanced(HWND owner) - { - return (HWND)ProtoCallService(m_szModuleName, PS_SEARCHBYADVANCED, 0, (LPARAM)owner); - } - - HWND __cdecl CreateExtendedSearchUI(HWND owner) - { - return (HWND)ProtoCallService(m_szModuleName, PS_CREATEADVSEARCHUI, 0, (LPARAM)owner); - } - - int __cdecl RecvContacts(MCONTACT hContact, PROTORECVEVENT* evt) - { - CCSDATA ccs = { hContact, PSR_CONTACTS, 0, (LPARAM)evt }; - return (int)ProtoCallService(m_szModuleName, PSR_CONTACTS, 0, (LPARAM)&ccs); - } - - int __cdecl RecvFile(MCONTACT hContact, PROTORECVFILET* evt) - { - CCSDATA ccs = { hContact, PSR_FILE, 0, (LPARAM)evt }; - return ProtoCallService(m_szModuleName, PSR_FILE, 0, (LPARAM)&ccs); - } - - int __cdecl RecvMsg(MCONTACT hContact, PROTORECVEVENT* evt) - { - CCSDATA ccs = { hContact, PSR_MESSAGE, 0, (LPARAM)evt }; - return (int)ProtoCallService(m_szModuleName, PSR_MESSAGE, 0, (LPARAM)&ccs); - } - - int __cdecl RecvUrl(MCONTACT hContact, PROTORECVEVENT* evt) - { - CCSDATA ccs = { hContact, PSR_URL, 0, (LPARAM)evt }; - return (int)ProtoCallService(m_szModuleName, PSR_URL, 0, (LPARAM)&ccs); - } - - int __cdecl SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList) - { - CCSDATA ccs = { hContact, PSS_CONTACTS, MAKEWPARAM(flags, nContacts), (LPARAM)hContactsList }; - return (int)ProtoCallService(m_szModuleName, PSS_CONTACTS, 0, (LPARAM)&ccs); - } - - HANDLE __cdecl SendFile(MCONTACT hContact, const TCHAR* szDescription, TCHAR** ppszFiles) - { - CCSDATA ccs = { hContact, PSS_FILE, (WPARAM)szDescription, (LPARAM)ppszFiles }; - - if (m_iVersion > 1) - return (HANDLE)ProtoCallService(m_szModuleName, PSS_FILE, 0, (LPARAM)&ccs); - - ccs.wParam = (WPARAM)mir_t2a(szDescription); - ccs.lParam = (LPARAM)Proto_FilesMatrixA(ppszFiles); - HANDLE res = (HANDLE)ProtoCallService(m_szModuleName, PSS_FILE, 0, (LPARAM)&ccs); - if (res == 0) FreeFilesMatrix((TCHAR***)&ccs.lParam); - mir_free((char*)ccs.wParam); - return res; - } - - int __cdecl SendMsg(MCONTACT hContact, const char* msg) - { - CCSDATA ccs = { hContact, PSS_MESSAGE, 0, (LPARAM)msg }; - return (int)ProtoCallService(m_szModuleName, PSS_MESSAGE, 0, (LPARAM)&ccs); - } - - int __cdecl SendUrl(MCONTACT hContact, int flags, const char* url) - { - CCSDATA ccs = { hContact, PSS_URL, flags, (LPARAM)url }; - return (int)ProtoCallService(m_szModuleName, PSS_URL, 0, (LPARAM)&ccs); - } - - int __cdecl SetApparentMode(MCONTACT hContact, int mode) - { - CCSDATA ccs = { hContact, PSS_SETAPPARENTMODE, mode, 0 }; - return (int)ProtoCallService(m_szModuleName, PSS_SETAPPARENTMODE, 0, (LPARAM)&ccs); - } - - int __cdecl SetStatus(int iNewStatus) - { - return (int)ProtoCallService(m_szModuleName, PS_SETSTATUS, iNewStatus, 0); - } - - HANDLE __cdecl GetAwayMsg(MCONTACT hContact) - { - CCSDATA ccs = { hContact, PSS_GETAWAYMSG, 0, 0 }; - return (HANDLE)ProtoCallService(m_szModuleName, PSS_GETAWAYMSG, 0, (LPARAM)&ccs); - } - - int __cdecl RecvAwayMsg(MCONTACT hContact, int statusMode, PROTORECVEVENT* evt) - { - CCSDATA ccs = { hContact, PSR_AWAYMSG, statusMode, (LPARAM)evt }; - return (int)ProtoCallService(m_szModuleName, PSR_AWAYMSG, 0, (LPARAM)&ccs); - } - - int __cdecl SetAwayMsg(int iStatus, const TCHAR *msg) - { - if (m_iVersion > 1) - return (int)ProtoCallService(m_szModuleName, PS_SETAWAYMSG, iStatus, (LPARAM)msg); - return (int)ProtoCallService(m_szModuleName, PS_SETAWAYMSG, iStatus, _T2A(msg)); - } - - int __cdecl UserIsTyping(MCONTACT hContact, int type) - { - CCSDATA ccs = { hContact, PSS_USERISTYPING, hContact, type }; - return ProtoCallService(m_szModuleName, PSS_USERISTYPING, 0, (LPARAM)&ccs); - } - - int __cdecl OnEvent(PROTOEVENTTYPE, WPARAM, LPARAM) - { - return 1; - } -}; - -// creates the default protocol container for compatibility with the old plugins - -PROTO_INTERFACE* AddDefaultAccount(const char *szProtoName) -{ - PROTO_INTERFACE* ppi = new DEFAULT_PROTO_INTERFACE; - ppi->m_szModuleName = mir_strdup(szProtoName); - ppi->m_tszUserName = mir_a2t(szProtoName); - return ppi; -} - -int FreeDefaultAccount(PROTO_INTERFACE* ppi) -{ - mir_free(ppi->m_szModuleName); - mir_free(ppi->m_tszUserName); - delete ppi; - return 0; -} diff --git a/src/modules/protocols/protoopts.cpp b/src/modules/protocols/protoopts.cpp deleted file mode 100644 index 35b59d11bb..0000000000 --- a/src/modules/protocols/protoopts.cpp +++ /dev/null @@ -1,1062 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#define LBN_MY_CHECK 0x1000 -#define LBN_MY_RENAME 0x1001 - -#define WM_MY_REFRESH (WM_USER+0x1000) -#define WM_MY_RENAME (WM_USER+0x1001) - -bool CheckProtocolOrder(void); - -#define errMsg \ -TranslateT("WARNING! The account is going to be deleted. It means that all its \ -settings, contacts and histories will be also erased.\n\n\ -Are you absolutely sure?") - -#define upgradeMsg \ -TranslateT("Your account was successfully upgraded. \ -To activate it, restart of Miranda is needed.\n\n\ -If you want to restart Miranda now, press Yes, if you want to upgrade another account, press No") -// is upgradeMsg in use in any place? -#define legacyMsg \ -TranslateT("This account uses legacy protocol plugin. \ -Use Miranda NG options dialogs to change its preferences.") - -#define welcomeMsg \ -TranslateT("Welcome to Miranda NG's account manager!\n\ -Here you can set up your IM accounts.\n\n\ -Select an account from the list on the left to see the available options. \ -Alternatively, just click on the Plus sign underneath the list to set up a new IM account.") - -static HWND hAccMgr = NULL; - -extern HANDLE hAccListChanged; - -int UnloadPlugin(TCHAR* buf, int bufLen); - -PROTOACCOUNT* Proto_CreateAccount(const char *szModuleName, const char *szBaseProto, const TCHAR *tszAccountName) -{ - PROTOACCOUNT *pa = (PROTOACCOUNT*)mir_calloc(sizeof(PROTOACCOUNT)); - if (pa == NULL) - return NULL; - - pa->cbSize = sizeof(PROTOACCOUNT); - pa->bIsEnabled = pa->bIsVisible = true; - pa->iOrder = accounts.getCount(); - pa->szProtoName = mir_strdup(szBaseProto); - - // if the internal name is empty, generate new one - if (mir_strlen(szModuleName) == 0) { - char buf[100]; - int count = 1; - while (true) { - mir_snprintf(buf, "%s_%d", szBaseProto, count++); - if (ptrA(db_get_sa(NULL, buf, "AM_BaseProto")) == NULL) - break; - } - pa->szModuleName = mir_strdup(buf); - } - else pa->szModuleName = mir_strdup(szModuleName); - - pa->tszAccountName = mir_tstrdup(tszAccountName); - - db_set_s(NULL, pa->szModuleName, "AM_BaseProto", szBaseProto); - accounts.insert(pa); - - if (ActivateAccount(pa)) { - pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); - if (!db_get_b(NULL, "CList", "MoveProtoMenus", true)) - pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); - } - - return pa; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Account edit form -// Gets PROTOACCOUNT* as a parameter, or NULL to edit a new one - -struct AccFormDlgParam -{ - int action; - PROTOACCOUNT *pa; -}; - -static bool FindAccountByName(const char *szModuleName) -{ - if (!mir_strlen(szModuleName)) - return false; - - for (int i = 0; i < accounts.getCount(); i++) - if (_stricmp(szModuleName, accounts[i]->szModuleName) == 0) - return true; - - return false; -} - -static bool OnCreateAccount(HWND hwndDlg) -{ - AccFormDlgParam* param = (AccFormDlgParam*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - PROTOACCOUNT *pa = param->pa; - - TCHAR tszAccName[256]; - GetDlgItemText(hwndDlg, IDC_ACCNAME, tszAccName, SIZEOF(tszAccName)); - rtrimt(tszAccName); - if (tszAccName[0] == 0) { - MessageBox(hwndDlg, TranslateT("Account name must be filled."), TranslateT("Account error"), MB_ICONERROR | MB_OK); - return false; - } - - if (param->action == PRAC_ADDED) { - char buf[200]; - GetDlgItemTextA(hwndDlg, IDC_ACCINTERNALNAME, buf, SIZEOF(buf)); - if (FindAccountByName(rtrim(buf))) { - MessageBox(hwndDlg, TranslateT("Account name has to be unique. Please enter unique name."), TranslateT("Account error"), MB_ICONERROR | MB_OK); - return false; - } - } - - if (param->action == PRAC_UPGRADED) { - BOOL oldProto = pa->bOldProto; - TCHAR szPlugin[MAX_PATH]; - mir_sntprintf(szPlugin, SIZEOF(szPlugin), _T("%s.dll"), _A2T(pa->szProtoName)); - int idx = accounts.getIndex(pa); - UnloadAccount(pa, false, false); - accounts.remove(idx); - if (oldProto && UnloadPlugin(szPlugin, SIZEOF(szPlugin))) { - TCHAR szNewName[MAX_PATH]; - mir_sntprintf(szNewName, SIZEOF(szNewName), _T("%s~"), szPlugin); - MoveFile(szPlugin, szNewName); - } - param->action = PRAC_ADDED; - } - - if (param->action == PRAC_ADDED) { - char buf[200]; - GetDlgItemTextA(hwndDlg, IDC_PROTOTYPECOMBO, buf, SIZEOF(buf)); - char *szBaseProto = NEWSTR_ALLOCA(buf); - - GetDlgItemTextA(hwndDlg, IDC_ACCINTERNALNAME, buf, SIZEOF(buf)); - rtrim(buf); - - pa = Proto_CreateAccount(buf, szBaseProto, tszAccName); - } - else replaceStrT(pa->tszAccountName, tszAccName); - - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, param->action, (LPARAM)pa); - - SendMessage(GetParent(hwndDlg), WM_MY_REFRESH, 0, 0); - return true; -} - -static INT_PTR CALLBACK AccFormDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - { - PROTOCOLDESCRIPTOR **proto; - int protoCount, i, cnt = 0; - CallService(MS_PROTO_ENUMPROTOS, (WPARAM)&protoCount, (LPARAM)&proto); - for (i = 0; i < protoCount; i++) { - PROTOCOLDESCRIPTOR* pd = proto[i]; - if (pd->type == PROTOTYPE_PROTOCOL && pd->cbSize == sizeof(*pd)) { - SendDlgItemMessageA(hwndDlg, IDC_PROTOTYPECOMBO, CB_ADDSTRING, 0, (LPARAM)proto[i]->szName); - ++cnt; - } - } - SendDlgItemMessage(hwndDlg, IDC_PROTOTYPECOMBO, CB_SETCURSEL, 0, 0); - EnableWindow(GetDlgItem(hwndDlg, IDOK), cnt != 0); - - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - AccFormDlgParam* param = (AccFormDlgParam*)lParam; - - if (param->action == PRAC_ADDED) // new account - SetWindowText(hwndDlg, TranslateT("Create new account")); - else { - TCHAR str[200]; - if (param->action == PRAC_CHANGED) { // update - EnableWindow(GetDlgItem(hwndDlg, IDC_PROTOTYPECOMBO), FALSE); - mir_sntprintf(str, SIZEOF(str), _T("%s: %s"), TranslateT("Editing account"), param->pa->tszAccountName); - } - else mir_sntprintf(str, SIZEOF(str), _T("%s: %s"), TranslateT("Upgrading account"), param->pa->tszAccountName); - - SetWindowText(hwndDlg, str); - SetDlgItemText(hwndDlg, IDC_ACCNAME, param->pa->tszAccountName); - SetDlgItemTextA(hwndDlg, IDC_ACCINTERNALNAME, param->pa->szModuleName); - SendDlgItemMessageA(hwndDlg, IDC_PROTOTYPECOMBO, CB_SELECTSTRING, -1, (LPARAM)param->pa->szProtoName); - - EnableWindow(GetDlgItem(hwndDlg, IDC_ACCINTERNALNAME), FALSE); - } - SendDlgItemMessage(hwndDlg, IDC_ACCINTERNALNAME, EM_LIMITTEXT, 40, 0); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - if (OnCreateAccount(hwndDlg)) - EndDialog(hwndDlg, TRUE); - break; - - case IDCANCEL: - EndDialog(hwndDlg, FALSE); - break; - } - } - - return FALSE; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Accounts manager - -struct TAccMgrData -{ - HFONT hfntTitle, hfntText; - int titleHeight, textHeight; - int selectedHeight, normalHeight; - int iSelected; -}; - -struct TAccListData -{ - int iItem; - RECT rcCheck; - HWND hwndEdit; -}; - -static void sttClickButton(HWND hwndDlg, int idcButton) -{ - if (IsWindowEnabled(GetDlgItem(hwndDlg, idcButton))) - PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(idcButton, BN_CLICKED), (LPARAM)GetDlgItem(hwndDlg, idcButton)); -} - -static LRESULT CALLBACK sttEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_KEYDOWN: - switch (wParam) { - case VK_RETURN: - DestroyWindow(hwnd); - return 0; - - case VK_ESCAPE: - SetWindowLongPtr(hwnd, GWLP_WNDPROC, GetWindowLongPtr(hwnd, GWLP_USERDATA)); - DestroyWindow(hwnd); - return 0; - } - break; - - case WM_GETDLGCODE: - if (wParam == VK_RETURN || wParam == VK_ESCAPE) - return DLGC_WANTMESSAGE; - break; - - case WM_KILLFOCUS: - int length = GetWindowTextLength(hwnd) + 1; - TCHAR *str = (TCHAR*)mir_alloc(sizeof(TCHAR) * length); - GetWindowText(hwnd, str, length); - SendMessage(GetParent(GetParent(hwnd)), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(GetParent(hwnd), GWL_ID), LBN_MY_RENAME), (LPARAM)str); - DestroyWindow(hwnd); - return 0; - } - return mir_callNextSubclass(hwnd, sttEditSubclassProc, msg, wParam, lParam); -} - -static LRESULT CALLBACK AccListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - struct TAccListData *dat = (struct TAccListData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); - if (!dat) - return DefWindowProc(hwnd, msg, wParam, lParam); - - switch (msg) { - case WM_LBUTTONDOWN: - { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - int iItem = LOWORD(SendMessage(hwnd, LB_ITEMFROMPOINT, 0, lParam)); - ListBox_GetItemRect(hwnd, iItem, &dat->rcCheck); - - dat->rcCheck.right = dat->rcCheck.left + GetSystemMetrics(SM_CXSMICON) + 4; - dat->rcCheck.bottom = dat->rcCheck.top + GetSystemMetrics(SM_CYSMICON) + 4; - if (PtInRect(&dat->rcCheck, pt)) - dat->iItem = iItem; - else - dat->iItem = -1; - } - break; - - case WM_LBUTTONUP: - { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - if ((dat->iItem >= 0) && PtInRect(&dat->rcCheck, pt)) - PostMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(hwnd, GWL_ID), LBN_MY_CHECK), (LPARAM)dat->iItem); - dat->iItem = -1; - } - break; - - case WM_CHAR: - if (wParam == ' ') { - int iItem = ListBox_GetCurSel(hwnd); - if (iItem >= 0) - PostMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(hwnd, GWL_ID), LBN_MY_CHECK), (LPARAM)iItem); - return 0; - } - - if (wParam == 10 /* enter */) - return 0; - - break; - - case WM_GETDLGCODE: - if (wParam == VK_RETURN) - return DLGC_WANTMESSAGE; - break; - - case WM_MY_RENAME: - RECT rc; - { - struct TAccMgrData *parentDat = (struct TAccMgrData *)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); - PROTOACCOUNT *pa = (PROTOACCOUNT *)ListBox_GetItemData(hwnd, ListBox_GetCurSel(hwnd)); - if (!pa || pa->bOldProto || pa->bDynDisabled) - return 0; - - ListBox_GetItemRect(hwnd, ListBox_GetCurSel(hwnd), &rc); - rc.left += 2 * GetSystemMetrics(SM_CXSMICON) + 4; - rc.bottom = rc.top + max(GetSystemMetrics(SM_CXSMICON), parentDat->titleHeight) + 4 - 1; - ++rc.top; --rc.right; - - dat->hwndEdit = CreateWindow(_T("EDIT"), pa->tszAccountName, WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hwnd, NULL, hInst, NULL); - mir_subclassWindow(dat->hwndEdit, sttEditSubclassProc); - SendMessage(dat->hwndEdit, WM_SETFONT, (WPARAM)parentDat->hfntTitle, 0); - SendMessage(dat->hwndEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN | EC_USEFONTINFO, 0); - SendMessage(dat->hwndEdit, EM_SETSEL, 0, -1); - ShowWindow(dat->hwndEdit, SW_SHOW); - } - SetFocus(dat->hwndEdit); - break; - - case WM_KEYDOWN: - switch (wParam) { - case VK_F2: - PostMessage(hwnd, WM_MY_RENAME, 0, 0); - return 0; - - case VK_INSERT: - sttClickButton(GetParent(hwnd), IDC_ADD); - return 0; - - case VK_DELETE: - sttClickButton(GetParent(hwnd), IDC_REMOVE); - return 0; - - case VK_RETURN: - if (GetAsyncKeyState(VK_CONTROL)) - sttClickButton(GetParent(hwnd), IDC_EDIT); - else - sttClickButton(GetParent(hwnd), IDOK); - return 0; - } - break; - } - - return mir_callNextSubclass(hwnd, AccListWndProc, msg, wParam, lParam); -} - -static void sttSubclassAccList(HWND hwnd, BOOL subclass) -{ - if (subclass) { - struct TAccListData *dat = (struct TAccListData *)mir_alloc(sizeof(struct TAccListData)); - dat->iItem = -1; - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat); - mir_subclassWindow(hwnd, AccListWndProc); - } - else { - struct TAccListData *dat = (struct TAccListData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); - SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); - mir_free(dat); - } -} - -static void sttSelectItem(struct TAccMgrData *dat, HWND hwndList, int iItem) -{ - if ((dat->iSelected != iItem) && (dat->iSelected >= 0)) - ListBox_SetItemHeight(hwndList, dat->iSelected, dat->normalHeight); - - dat->iSelected = iItem; - ListBox_SetItemHeight(hwndList, dat->iSelected, dat->selectedHeight); - RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); -} - -static void sttUpdateAccountInfo(HWND hwndDlg, struct TAccMgrData *dat) -{ - HWND hwndList = GetDlgItem(hwndDlg, IDC_ACCLIST); - int curSel = ListBox_GetCurSel(hwndList); - if (curSel != LB_ERR) { - PROTOACCOUNT *pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, curSel); - if (pa) { - EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), pa->bOldProto || pa->bDynDisabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), !pa->bOldProto && !pa->bDynDisabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), pa->ppro != 0); - - if (dat->iSelected >= 0) { - PROTOACCOUNT *pa_old = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, dat->iSelected); - if (pa_old && pa_old != pa && pa_old->hwndAccMgrUI) - ShowWindow(pa_old->hwndAccMgrUI, SW_HIDE); - } - - if (pa->hwndAccMgrUI) { - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_HIDE); - ShowWindow(pa->hwndAccMgrUI, SW_SHOW); - } - else if (!pa->ppro) { - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW); - SetDlgItemText(hwndDlg, IDC_TXT_INFO, TranslateT("Account is disabled. Please activate it to access options.")); - } - else { - HWND hwnd = (HWND)CallProtoService(pa->szModuleName, PS_CREATEACCMGRUI, 0, (LPARAM)hwndDlg); - if (hwnd && (hwnd != (HWND)CALLSERVICE_NOTFOUND)) { - RECT rc; - - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_HIDE); - - GetWindowRect(GetDlgItem(hwndDlg, IDC_TXT_INFO), &rc); - MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rc, 2); - SetWindowPos(hwnd, hwndList, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); - - pa->hwndAccMgrUI = hwnd; - } - else { - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW); - SetDlgItemText(hwndDlg, IDC_TXT_INFO, legacyMsg); - } - } - return; - } - } - - EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), FALSE); - - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW); - SetDlgItemText(hwndDlg, IDC_TXT_INFO, welcomeMsg); -} - -INT_PTR CALLBACK AccMgrDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - struct TAccMgrData *dat = (struct TAccMgrData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - HWND hwndList = GetDlgItem(hwndDlg, IDC_ACCLIST); - PROTOACCOUNT *pa; - int idx; - PSHNOTIFY pshn; - - switch (message) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - Window_SetIcon_IcoLib(hwndDlg, SKINICON_OTHER_ACCMGR); - - dat = (TAccMgrData *)mir_alloc(sizeof(TAccMgrData)); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); - - Button_SetIcon_IcoLib(hwndDlg, IDC_ADD, SKINICON_OTHER_ADDCONTACT, LPGEN("New account")); - Button_SetIcon_IcoLib(hwndDlg, IDC_EDIT, SKINICON_OTHER_RENAME, LPGEN("Edit")); - Button_SetIcon_IcoLib(hwndDlg, IDC_REMOVE, SKINICON_OTHER_DELETE, LPGEN("Remove account")); - Button_SetIcon_IcoLib(hwndDlg, IDC_OPTIONS, SKINICON_OTHER_OPTIONS, LPGEN("Configure...")); - Button_SetIcon_IcoLib(hwndDlg, IDC_UPGRADE, SKINICON_OTHER_ACCMGR, LPGEN("Upgrade account")); - - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), FALSE); - { - LOGFONT lf; - GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf); - dat->hfntText = CreateFontIndirect(&lf); - - GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf); - lf.lfWeight = FW_BOLD; - dat->hfntTitle = CreateFontIndirect(&lf); - - HDC hdc = GetDC(hwndDlg); - HFONT hfnt = (HFONT)SelectObject(hdc, dat->hfntTitle); - - TEXTMETRIC tm; - GetTextMetrics(hdc, &tm); - dat->titleHeight = tm.tmHeight; - SelectObject(hdc, dat->hfntText); - - GetTextMetrics(hdc, &tm); - dat->textHeight = tm.tmHeight; - SelectObject(hdc, hfnt); - ReleaseDC(hwndDlg, hdc); - - dat->normalHeight = 4 + max(dat->titleHeight, GetSystemMetrics(SM_CYSMICON)); - dat->selectedHeight = dat->normalHeight + 4 + 2 * dat->textHeight; - } - - SendDlgItemMessage(hwndDlg, IDC_NAME, WM_SETFONT, (WPARAM)dat->hfntTitle, 0); - SendDlgItemMessage(hwndDlg, IDC_TXT_ACCOUNT, WM_SETFONT, (WPARAM)dat->hfntTitle, 0); - SendDlgItemMessage(hwndDlg, IDC_TXT_ADDITIONAL, WM_SETFONT, (WPARAM)dat->hfntTitle, 0); - - dat->iSelected = -1; - sttSubclassAccList(GetDlgItem(hwndDlg, IDC_ACCLIST), TRUE); - SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); - - Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "AccMgr", ""); - return TRUE; - - case WM_CTLCOLORSTATIC: - switch (GetDlgCtrlID((HWND)lParam)) { - case IDC_WHITERECT: - case IDC_NAME: - SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); - return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); - } - break; - - case WM_MEASUREITEM: - { - LPMEASUREITEMSTRUCT lps = (LPMEASUREITEMSTRUCT)lParam; - PROTOACCOUNT *acc = (PROTOACCOUNT *)lps->itemData; - - if ((lps->CtlID != IDC_ACCLIST) || !acc) - break; - - lps->itemWidth = 10; - lps->itemHeight = dat->normalHeight; - } - return TRUE; - - case WM_DRAWITEM: - HBRUSH hbrBack; - SIZE sz; - { - int cxIcon = GetSystemMetrics(SM_CXSMICON); - int cyIcon = GetSystemMetrics(SM_CYSMICON); - - LPDRAWITEMSTRUCT lps = (LPDRAWITEMSTRUCT)lParam; - PROTOACCOUNT *acc = (PROTOACCOUNT *)lps->itemData; - if ((lps->CtlID != IDC_ACCLIST) || (lps->itemID == -1) || !acc) - break; - - SetBkMode(lps->hDC, TRANSPARENT); - if (lps->itemState & ODS_SELECTED) { - hbrBack = GetSysColorBrush(COLOR_HIGHLIGHT); - SetTextColor(lps->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); - } - else { - hbrBack = GetSysColorBrush(COLOR_WINDOW); - SetTextColor(lps->hDC, GetSysColor(COLOR_WINDOWTEXT)); - } - FillRect(lps->hDC, &lps->rcItem, hbrBack); - - lps->rcItem.left += 2; - lps->rcItem.top += 2; - lps->rcItem.bottom -= 2; - - int tmp; - if (acc->bOldProto) - tmp = SKINICON_OTHER_ON; - else if (acc->bDynDisabled) - tmp = SKINICON_OTHER_OFF; - else - tmp = acc->bIsEnabled ? SKINICON_OTHER_TICK : SKINICON_OTHER_NOTICK; - - HICON hIcon = LoadSkinnedIcon(tmp); - DrawIconEx(lps->hDC, lps->rcItem.left, lps->rcItem.top, hIcon, cxIcon, cyIcon, 0, hbrBack, DI_NORMAL); - IcoLib_ReleaseIcon(hIcon, 0); - - lps->rcItem.left += cxIcon + 2; - - if (acc->ppro) { - hIcon = Skin_GetIconByHandle(acc->ppro->m_hProtoIcon); - DrawIconEx(lps->hDC, lps->rcItem.left, lps->rcItem.top, hIcon, cxIcon, cyIcon, 0, hbrBack, DI_NORMAL); - Skin_ReleaseIcon(hIcon); - } - lps->rcItem.left += cxIcon + 2; - - int length = SendDlgItemMessage(hwndDlg, IDC_ACCLIST, LB_GETTEXTLEN, lps->itemID, 0); - int size = max(length + 1, 256); - TCHAR *text = (TCHAR *)_alloca(sizeof(TCHAR) * size); - SendDlgItemMessage(hwndDlg, IDC_ACCLIST, LB_GETTEXT, lps->itemID, (LPARAM)text); - - SelectObject(lps->hDC, dat->hfntTitle); - tmp = lps->rcItem.bottom; - lps->rcItem.bottom = lps->rcItem.top + max(cyIcon, dat->titleHeight); - DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS | DT_VCENTER); - lps->rcItem.bottom = tmp; - GetTextExtentPoint32(lps->hDC, text, length, &sz); - lps->rcItem.top += max(cxIcon, sz.cy) + 2; - - if (lps->itemID == (unsigned)dat->iSelected) { - SelectObject(lps->hDC, dat->hfntText); - mir_sntprintf(text, size, _T("%s: %S"), TranslateT("Protocol"), acc->szProtoName); - length = (int)mir_tstrlen(text); - DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS); - GetTextExtentPoint32(lps->hDC, text, length, &sz); - lps->rcItem.top += sz.cy + 2; - - if (acc->ppro && Proto_IsProtocolLoaded(acc->szProtoName)) { - char *szIdName = (char *)acc->ppro->GetCaps(PFLAG_UNIQUEIDTEXT, 0); - TCHAR *tszIdName = szIdName ? mir_a2t(szIdName) : mir_tstrdup(TranslateT("Account ID")); - - CONTACTINFO ci = { 0 }; - ci.cbSize = sizeof(ci); - ci.hContact = NULL; - ci.szProto = acc->szModuleName; - ci.dwFlag = CNF_UNIQUEID | CNF_TCHAR; - if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)& ci)) { - switch (ci.type) { - case CNFT_ASCIIZ: - mir_sntprintf(text, size, _T("%s: %s"), tszIdName, ci.pszVal); - mir_free(ci.pszVal); - break; - case CNFT_DWORD: - mir_sntprintf(text, size, _T("%s: %d"), tszIdName, ci.dVal); - break; - } - } - else mir_sntprintf(text, size, _T("%s: %s"), tszIdName, TranslateT("")); - mir_free(tszIdName); - } - else mir_sntprintf(text, size, TranslateT("Protocol is not loaded.")); - - length = (int)mir_tstrlen(text); - DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS); - GetTextExtentPoint32(lps->hDC, text, length, &sz); - lps->rcItem.top += sz.cy + 2; - } - } - return TRUE; - - case WM_MY_REFRESH: - dat->iSelected = -1; - { - int i = ListBox_GetCurSel(hwndList); - PROTOACCOUNT *acc = (i == LB_ERR) ? NULL : (PROTOACCOUNT *)ListBox_GetItemData(hwndList, i); - - SendMessage(hwndList, LB_RESETCONTENT, 0, 0); - for (i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *p = accounts[i]; - PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(p->szProtoName); - if (pd != NULL && pd->type != PROTOTYPE_PROTOCOL) - continue; - - int iItem = SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)p->tszAccountName); - SendMessage(hwndList, LB_SETITEMDATA, iItem, (LPARAM)p); - - if (p == acc) - ListBox_SetCurSel(hwndList, iItem); - } - - dat->iSelected = ListBox_GetCurSel(hwndList); // -1 if error = > nothing selected in our case - if (dat->iSelected >= 0) - sttSelectItem(dat, hwndList, dat->iSelected); - else if (acc && acc->hwndAccMgrUI) - ShowWindow(acc->hwndAccMgrUI, SW_HIDE); - } - sttUpdateAccountInfo(hwndDlg, dat); - break; - - case WM_CONTEXTMENU: - if (GetWindowLongPtr((HWND)wParam, GWL_ID) == IDC_ACCLIST) { - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - int iItem = ListBox_GetCurSel(hwndList); - - if (pt.x == -1 && pt.y == -1) { - if (iItem != LB_ERR) { - RECT rc; - ListBox_GetItemRect(hwndList, iItem, &rc); - pt.x = rc.left + GetSystemMetrics(SM_CXSMICON) + 4; - pt.y = rc.top + 4 + max(GetSystemMetrics(SM_CXSMICON), dat->titleHeight); - ClientToScreen(hwndList, &pt); - } - } - else { - // menu was activated with mouse = > find item under cursor & set focus to our control. - POINT ptItem = pt; - ScreenToClient(hwndList, &ptItem); - iItem = (short)LOWORD(SendMessage(hwndList, LB_ITEMFROMPOINT, 0, MAKELPARAM(ptItem.x, ptItem.y))); - if (iItem != LB_ERR) { - ListBox_SetCurSel(hwndList, iItem); - sttUpdateAccountInfo(hwndDlg, dat); - sttSelectItem(dat, hwndList, iItem); - SetFocus(hwndList); - } - } - - if (iItem != LB_ERR) { - pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, iItem); - HMENU hMenu = CreatePopupMenu(); - if (!pa->bOldProto && !pa->bDynDisabled) - AppendMenu(hMenu, MF_STRING, 1, TranslateT("Rename")); - - AppendMenu(hMenu, MF_STRING, 3, TranslateT("Delete")); - - if (Proto_IsAccountEnabled(pa)) - AppendMenu(hMenu, MF_STRING, 4, TranslateT("Configure")); - - if (pa->bOldProto || pa->bDynDisabled) - AppendMenu(hMenu, MF_STRING, 5, TranslateT("Upgrade")); - - switch (TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) { - case 1: - PostMessage(hwndList, WM_MY_RENAME, 0, 0); - break; - - case 2: - sttClickButton(hwndDlg, IDC_EDIT); - break; - - case 3: - sttClickButton(hwndDlg, IDC_REMOVE); - break; - - case 4: - sttClickButton(hwndDlg, IDC_OPTIONS); - break; - - case 5: - sttClickButton(hwndDlg, IDC_UPGRADE); - break; - } - DestroyMenu(hMenu); - } - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_ACCLIST: - switch (HIWORD(wParam)) { - case LBN_SELCHANGE: - sttUpdateAccountInfo(hwndDlg, dat); - sttSelectItem(dat, hwndList, ListBox_GetCurSel(hwndList)); - SetFocus(hwndList); - break; - - case LBN_DBLCLK: - PostMessage(hwndList, WM_MY_RENAME, 0, 0); - break; - - case LBN_MY_CHECK: - pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, lParam); - if (pa) { - if (pa->bOldProto || pa->bDynDisabled) - break; - - pa->bIsEnabled = !pa->bIsEnabled; - if (pa->bIsEnabled) { - if (ActivateAccount(pa)) { - pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); - if (!db_get_b(NULL, "CList", "MoveProtoMenus", TRUE)) - pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); - } - } - else { - DWORD dwStatus = CallProtoServiceInt(NULL, pa->szModuleName, PS_GETSTATUS, 0, 0); - if (dwStatus >= ID_STATUS_ONLINE) { - TCHAR buf[200]; - mir_sntprintf(buf, TranslateT("Account %s is being disabled"), pa->tszAccountName); - if (IDNO == ::MessageBox(hwndDlg, - TranslateT("Account is online. Disable account?"), - buf, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO)) { - pa->bIsEnabled = 1; //stay enabled - } - } - - if (!pa->bIsEnabled) - DeactivateAccount(pa, true, false); - } - - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, PRAC_CHECKED, (LPARAM)pa); - sttUpdateAccountInfo(hwndDlg, dat); - RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); - } - break; - - case LBN_MY_RENAME: - int iItem = ListBox_GetCurSel(hwndList); - pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, iItem); - if (pa) { - mir_free(pa->tszAccountName); - pa->tszAccountName = (TCHAR*)lParam; - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, PRAC_CHANGED, (LPARAM)pa); - - ListBox_DeleteString(hwndList, iItem); - iItem = ListBox_AddString(hwndList, pa->tszAccountName); - ListBox_SetItemData(hwndList, iItem, (LPARAM)pa); - ListBox_SetCurSel(hwndList, iItem); - - sttSelectItem(dat, hwndList, iItem); - - RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); - } - else mir_free((TCHAR*)lParam); - } - break; - - case IDC_ADD: - { - AccFormDlgParam param = { PRAC_ADDED, NULL }; - if (IDOK == DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ACCFORM), hwndDlg, AccFormDlgProc, (LPARAM)¶m)) - SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); - } - break; - - case IDC_EDIT: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) - PostMessage(hwndList, WM_MY_RENAME, 0, 0); - break; - - case IDC_REMOVE: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) { - pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, idx); - TCHAR buf[200]; - mir_sntprintf(buf, TranslateT("Account %s is being deleted"), pa->tszAccountName); - if (pa->bOldProto) { - MessageBox(hwndDlg, TranslateT("You need to disable plugin to delete this account"), buf, MB_ICONERROR | MB_OK); - break; - } - if (IDYES == MessageBox(hwndDlg, errMsg, buf, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO)) { - // lock controls to avoid changes during remove process - ListBox_SetCurSel(hwndList, -1); - sttUpdateAccountInfo(hwndDlg, dat); - EnableWindow(hwndList, FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); - - ListBox_SetItemData(hwndList, idx, 0); - - accounts.remove(pa); - - CheckProtocolOrder(); - - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, PRAC_REMOVED, (LPARAM)pa); - - UnloadAccount(pa, true, true); - SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); - - EnableWindow(hwndList, TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), TRUE); - } - } - break; - - case IDC_OPTIONS: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) { - pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, idx); - if (pa->bOldProto) { - OPENOPTIONSDIALOG ood; - ood.cbSize = sizeof(ood); - ood.pszGroup = "Network"; - ood.pszPage = pa->szModuleName; - ood.pszTab = NULL; - Options_Open(&ood); - } - else OpenAccountOptions(pa); - } - break; - - case IDC_UPGRADE: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) { - AccFormDlgParam param = { PRAC_UPGRADED, (PROTOACCOUNT*)ListBox_GetItemData(hwndList, idx) }; - DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ACCFORM), hwndDlg, AccFormDlgProc, (LPARAM)¶m); - } - break; - - case IDC_LNK_NETWORK: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_APPLY; - pshn.hdr.hwndFrom = hwndDlg; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn); - { - OPENOPTIONSDIALOG ood = { 0 }; - ood.cbSize = sizeof(ood); - ood.pszPage = "Network"; - Options_Open(&ood); - } - break; - - case IDC_LNK_ADDONS: - CallService(MS_UTILS_OPENURL, OUF_NEWWINDOW, (LPARAM)"http://miranda-ng.org/"); - break; - - case IDOK: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_APPLY; - pshn.hdr.hwndFrom = hwndDlg; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn); - DestroyWindow(hwndDlg); - break; - - case IDCANCEL: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_RESET; - pshn.hdr.hwndFrom = hwndDlg; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn); - DestroyWindow(hwndDlg); - break; - } - break; - - case PSM_CHANGED: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) { - pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, idx); - if (pa) { - pa->bAccMgrUIChanged = TRUE; - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->idFrom == 0) { - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_APPLY; - for (int i = 0; i < accounts.getCount(); i++) { - pa = accounts[i]; - if (pa->hwndAccMgrUI && pa->bAccMgrUIChanged) { - pshn.hdr.hwndFrom = pa->hwndAccMgrUI; - SendMessage(pa->hwndAccMgrUI, WM_NOTIFY, 0, (LPARAM)&pshn); - pa->bAccMgrUIChanged = FALSE; - } - } - return TRUE; - - case PSN_RESET: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_RESET; - for (int i = 0; i < accounts.getCount(); i++) { - pa = accounts[i]; - if (pa->hwndAccMgrUI && pa->bAccMgrUIChanged) { - pshn.hdr.hwndFrom = pa->hwndAccMgrUI; - SendMessage(pa->hwndAccMgrUI, WM_NOTIFY, 0, (LPARAM)&pshn); - pa->bAccMgrUIChanged = FALSE; - } - } - return TRUE; - } - } - break; - - case WM_DESTROY: - for (int i = 0; i < accounts.getCount(); i++) { - pa = accounts[i]; - pa->bAccMgrUIChanged = FALSE; - if (pa->hwndAccMgrUI) { - DestroyWindow(pa->hwndAccMgrUI); - pa->hwndAccMgrUI = NULL; - } - } - - Window_FreeIcon_IcoLib(hwndDlg); - Button_FreeIcon_IcoLib(hwndDlg, IDC_ADD); - Button_FreeIcon_IcoLib(hwndDlg, IDC_EDIT); - Button_FreeIcon_IcoLib(hwndDlg, IDC_REMOVE); - Button_FreeIcon_IcoLib(hwndDlg, IDC_OPTIONS); - Button_FreeIcon_IcoLib(hwndDlg, IDC_UPGRADE); - Utils_SaveWindowPosition(hwndDlg, NULL, "AccMgr", ""); - sttSubclassAccList(GetDlgItem(hwndDlg, IDC_ACCLIST), FALSE); - DeleteObject(dat->hfntTitle); - DeleteObject(dat->hfntText); - mir_free(dat); - hAccMgr = NULL; - break; - } - - return FALSE; -} - -static INT_PTR OptProtosShow(WPARAM, LPARAM) -{ - if (!hAccMgr) - hAccMgr = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ACCMGR), NULL, AccMgrDlgProc, 0); - - ShowWindow(hAccMgr, SW_RESTORE); - SetForegroundWindow(hAccMgr); - SetActiveWindow(hAccMgr); - return 0; -} - -int OptProtosLoaded(WPARAM, LPARAM) -{ - CLISTMENUITEM mi = { sizeof(mi) }; - mi.icolibItem = GetSkinIconHandle(SKINICON_OTHER_ACCMGR); - mi.position = 1900000000; - mi.pszName = LPGEN("&Accounts..."); - mi.pszService = MS_PROTO_SHOWACCMGR; - Menu_AddMainMenuItem(&mi); - return 0; -} - -static int OnAccListChanged(WPARAM eventCode, LPARAM lParam) -{ - PROTOACCOUNT *pa = (PROTOACCOUNT*)lParam; - - switch (eventCode) { - case PRAC_CHANGED: - if (pa->ppro) { - mir_free(pa->ppro->m_tszUserName); - pa->ppro->m_tszUserName = mir_tstrdup(pa->tszAccountName); - pa->ppro->OnEvent(EV_PROTO_ONRENAME, 0, lParam); - } - } - - return 0; -} - -static int ShutdownAccMgr(WPARAM, LPARAM) -{ - if (IsWindow(hAccMgr)) - DestroyWindow(hAccMgr); - hAccMgr = NULL; - return 0; -} - -int LoadProtoOptions(void) -{ - CreateServiceFunction(MS_PROTO_SHOWACCMGR, OptProtosShow); - - HookEvent(ME_SYSTEM_MODULESLOADED, OptProtosLoaded); - HookEvent(ME_PROTO_ACCLISTCHANGED, OnAccListChanged); - HookEvent(ME_SYSTEM_PRESHUTDOWN, ShutdownAccMgr); - return 0; -} diff --git a/src/modules/skin/hotkey_opts.cpp b/src/modules/skin/hotkey_opts.cpp deleted file mode 100644 index c385293210..0000000000 --- a/src/modules/skin/hotkey_opts.cpp +++ /dev/null @@ -1,1048 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#include -#include "skin.h" - -static TCHAR* sttHokeyVkToName(WORD vkKey) -{ - static TCHAR buf[256] = { 0 }; - DWORD code = MapVirtualKey(vkKey, 0) << 16; - - switch (vkKey) { - case 0: - case VK_CONTROL: - case VK_SHIFT: - case VK_MENU: - case VK_LWIN: - case VK_RWIN: - case VK_PAUSE: - case VK_CANCEL: - case VK_NUMLOCK: - case VK_CAPITAL: - case VK_SCROLL: - return _T(""); - case VK_BROWSER_BACK: - return TranslateT("Browser: Back"); - case VK_BROWSER_FORWARD: - return TranslateT("Browser: Forward"); - case VK_BROWSER_REFRESH: - return TranslateT("Browser: Refresh"); - case VK_BROWSER_STOP: - return TranslateT("Browser: Stop"); - case VK_BROWSER_SEARCH: - return TranslateT("Browser: Search"); - case VK_BROWSER_FAVORITES: - return TranslateT("Browser: Fav"); - case VK_BROWSER_HOME: - return TranslateT("Browser: Home"); - case VK_VOLUME_MUTE: - return TranslateT("Mute"); - case VK_VOLUME_DOWN: - return TranslateT("Vol-"); - case VK_VOLUME_UP: - return TranslateT("Vol+"); - case VK_MEDIA_NEXT_TRACK: - return TranslateT("Media: Next Track"); - case VK_MEDIA_PREV_TRACK: - return TranslateT("Media: Prev. Track"); - case VK_MEDIA_STOP: - return TranslateT("Media: Stop"); - case VK_MEDIA_PLAY_PAUSE: - return TranslateT("Media: Play/Pause"); - case VK_LAUNCH_MAIL: - return TranslateT("Mail"); - case VK_LAUNCH_MEDIA_SELECT: - return TranslateT("Media: Select"); - case VK_LAUNCH_APP1: - return TranslateT("App 1"); - case VK_LAUNCH_APP2: - return TranslateT("App 2"); - - case VK_DIVIDE: - case VK_INSERT: - case VK_HOME: - case VK_PRIOR: - case VK_DELETE: - case VK_END: - case VK_NEXT: - case VK_LEFT: - case VK_RIGHT: - case VK_UP: - case VK_DOWN: - code |= (1UL << 24); - } - - GetKeyNameText(code, buf, 256); - return buf; -} - -void HotkeyToName(TCHAR *buf, int size, BYTE shift, BYTE key) -{ - mir_sntprintf(buf, size, _T("%s%s%s%s%s"), - (shift & HOTKEYF_CONTROL) ? TranslateT("Ctrl + ") : _T(""), - (shift & HOTKEYF_ALT) ? TranslateT("Alt + ") : _T(""), - (shift & HOTKEYF_SHIFT) ? TranslateT("Shift + ") : _T(""), - (shift & HOTKEYF_EXT) ? TranslateT("Win + ") : _T(""), - sttHokeyVkToName(key)); -} - -/////////////////////////////////////////////////////////////////////////////// -// Hotkey control - -static LRESULT CALLBACK sttHotkeyEditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - THotkeyBoxData *data = (THotkeyBoxData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); - BOOL bKeyDown = FALSE; - if (!data) return 0; - - switch (msg) { - case HKM_GETHOTKEY: - return data->key ? MAKEWORD(data->key, data->shift) : 0; - - case HKM_SETHOTKEY: - { - TCHAR buf[256] = { 0 }; - data->key = (BYTE)LOWORD(wParam); - data->shift = (BYTE)HIWORD(wParam); - HotkeyToName(buf, SIZEOF(buf), data->shift, data->key); - SetWindowText(hwnd, buf); - } - return 0; - - case WM_GETDLGCODE: - return DLGC_WANTALLKEYS; - - case WM_KILLFOCUS: - break; - - case WM_CHAR: - case WM_SYSCHAR: - case WM_PASTE: - case WM_CONTEXTMENU: - return TRUE; - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - bKeyDown = TRUE; - - case WM_KEYUP: - case WM_SYSKEYUP: - { - TCHAR buf[256] = { 0 }; - - BYTE shift = 0; - BYTE key = wParam; - TCHAR *name = sttHokeyVkToName(key); - if (!*name || !bKeyDown) - key = 0; - - if (GetAsyncKeyState(VK_CONTROL)) shift |= HOTKEYF_CONTROL; - if (GetAsyncKeyState(VK_MENU)) shift |= HOTKEYF_ALT; - if (GetAsyncKeyState(VK_SHIFT)) shift |= HOTKEYF_SHIFT; - if (GetAsyncKeyState(VK_LWIN) || GetAsyncKeyState(VK_RWIN)) shift |= HOTKEYF_EXT; - - if (bKeyDown || !data->key) { - data->shift = shift; - data->key = key; - } - - HotkeyToName(buf, SIZEOF(buf), data->shift, data->key); - SetWindowText(hwnd, buf); - - if (bKeyDown && data->key) - SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG(GetWindowLongPtr(hwnd, GWL_ID), 0), (LPARAM)hwnd); - } - return TRUE; - - case WM_DESTROY: - SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); - mir_free(data); - } - - return mir_callNextSubclass(hwnd, sttHotkeyEditProc, msg, wParam, lParam); -} - -void HotkeyEditCreate(HWND hwnd) -{ - THotkeyBoxData *data = (THotkeyBoxData *)mir_alloc(sizeof(THotkeyBoxData)); - SetWindowLongPtr(hwnd, GWLP_USERDATA, (ULONG_PTR)data); - mir_subclassWindow(hwnd, sttHotkeyEditProc); -} - -void HotkeyEditDestroy(HWND hwnd) -{ - THotkeyBoxData *data = (THotkeyBoxData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); - SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); - mir_free(data); -} - -/////////////////////////////////////////////////////////////////////////////// -// Options - -enum { COL_NAME, COL_TYPE, COL_KEY, COL_RESET, COL_ADDREMOVE }; - -static void sttOptionsSetupItem(HWND hwndList, int idx, THotkeyItem *item) -{ - TCHAR buf[256]; - LVITEM lvi = { 0 }; - lvi.iItem = idx; - - if (!item->rootHotkey) { - lvi.mask = LVIF_TEXT | LVIF_IMAGE; - lvi.iSubItem = COL_NAME; - lvi.pszText = item->getDescr(); - lvi.iImage = item->OptType; - ListView_SetItem(hwndList, &lvi); - - ListView_SetCheckState(hwndList, lvi.iItem, item->Enabled); - } - - lvi.mask = LVIF_TEXT; - lvi.iSubItem = COL_KEY; - HotkeyToName(buf, SIZEOF(buf), HIBYTE(item->OptHotkey), LOBYTE(item->OptHotkey)); - lvi.pszText = buf; - ListView_SetItem(hwndList, &lvi); - - if (item->rootHotkey) { - lvi.mask = LVIF_IMAGE; - lvi.iSubItem = COL_TYPE; - lvi.iImage = item->OptType; - ListView_SetItem(hwndList, &lvi); - } - - lvi.mask = LVIF_IMAGE; - lvi.iSubItem = COL_RESET; - lvi.iImage = (item->Hotkey != item->OptHotkey) ? 5 : -1; - ListView_SetItem(hwndList, &lvi); - - lvi.mask = LVIF_IMAGE | LVIF_TEXT; - lvi.iSubItem = COL_ADDREMOVE; - if (item->rootHotkey) { - lvi.iImage = 4; - lvi.pszText = TranslateT("Remove shortcut"); - } - else { - lvi.iImage = 3; - lvi.pszText = TranslateT("Add another shortcut"); - } - ListView_SetItem(hwndList, &lvi); -} - -static void sttOptionsDeleteHotkey(HWND hwndList, int idx, THotkeyItem *item) -{ - item->OptDeleted = TRUE; - ListView_DeleteItem(hwndList, idx); - if (item->rootHotkey) - item->rootHotkey->OptChanged = TRUE; -} - -static int CALLBACK sttOptionsSortList(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) -{ - TCHAR title1[256] = { 0 }, title2[256] = { 0 }; - THotkeyItem *item1 = NULL, *item2 = NULL; - LVITEM lvi = { 0 }; - int res; - - lvi.mask = LVIF_TEXT | LVIF_PARAM; - lvi.iItem = lParam1; - lvi.pszText = title1; - lvi.cchTextMax = SIZEOF(title1); - if (ListView_GetItem((HWND)lParamSort, &lvi)) - item1 = (THotkeyItem *)lvi.lParam; - - lvi.mask = LVIF_TEXT | LVIF_PARAM; - lvi.iItem = lParam2; - lvi.pszText = title2; - lvi.cchTextMax = SIZEOF(title2); - if (ListView_GetItem((HWND)lParamSort, &lvi)) - item2 = (THotkeyItem *)lvi.lParam; - - if (!item1 && !item2) - return mir_tstrcmp(title1, title2); - - if (!item1 && item2) { - if (res = mir_tstrcmp(title1, item2->getSection())) - return res; - return -1; - } - - if (!item2 && item1) { - if (res = mir_tstrcmp(item1->getSection(), title2)) - return res; - return 1; - } - /* item1 != NULL && item2 != NULL */ - - if (res = mir_tstrcmp(item1->getSection(), item2->getSection())) return res; - if (res = mir_tstrcmp(item1->getDescr(), item2->getDescr())) return res; - if (!item1->rootHotkey && item2->rootHotkey) return -1; - if (item1->rootHotkey && !item2->rootHotkey) return 1; - return 0; -} - -static void sttOptionsAddHotkey(HWND hwndList, THotkeyItem *item) -{ - char buf[256]; - mir_snprintf(buf, "mir_hotkey_%d_%d", g_pid, g_hkid++); - - THotkeyItem *newItem = (THotkeyItem *)mir_alloc(sizeof(THotkeyItem)); - newItem->pszName = NULL; - newItem->pszService = item->pszService ? mir_strdup(item->pszService) : NULL; - newItem->ptszSection = mir_tstrdup(item->ptszSection); - newItem->ptszDescription = mir_tstrdup(item->ptszDescription); - newItem->lParam = item->lParam; - newItem->idHotkey = GlobalAddAtomA(buf); - newItem->rootHotkey = item; - newItem->Hotkey = newItem->DefHotkey = newItem->OptHotkey = 0; - newItem->type = newItem->OptType = item->OptType; - newItem->Enabled = newItem->OptEnabled = TRUE; - newItem->OptChanged = newItem->OptDeleted = FALSE; - newItem->OptNew = TRUE; - hotkeys.insert(newItem); - - SendMessage(hwndList, WM_SETREDRAW, FALSE, 0); - - LVITEM lvi = { 0 }; - lvi.mask |= LVIF_PARAM; - lvi.lParam = (LPARAM)newItem; - sttOptionsSetupItem(hwndList, ListView_InsertItem(hwndList, &lvi), newItem); - ListView_SortItemsEx(hwndList, sttOptionsSortList, (LPARAM)hwndList); - - SendMessage(hwndList, WM_SETREDRAW, TRUE, 0); - RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); - - item->OptChanged = TRUE; -} - -static void sttOptionsSetChanged(THotkeyItem *item) -{ - item->OptChanged = TRUE; - if (item->rootHotkey) - item->rootHotkey->OptChanged = TRUE; -} - -static void sttOptionsSaveItem(THotkeyItem *item) -{ - int i; - char buf[MAXMODULELABELLENGTH]; - - if (item->rootHotkey) return; - if (!item->OptChanged) return; - - item->Hotkey = item->OptHotkey; - item->type = item->OptType; - item->Enabled = item->OptEnabled; - - db_set_w(NULL, DBMODULENAME, item->pszName, item->Hotkey); - db_set_b(NULL, DBMODULENAME "Off", item->pszName, (BYTE)!item->Enabled); - if (item->type != HKT_MANUAL) - db_set_b(NULL, DBMODULENAME "Types", item->pszName, (BYTE)item->type); - - item->nSubHotkeys = 0; - for (i = 0; i < hotkeys.getCount(); i++) { - THotkeyItem *subItem = hotkeys[i]; - if (subItem->rootHotkey == item) { - subItem->Hotkey = subItem->OptHotkey; - subItem->type = subItem->OptType; - - mir_snprintf(buf, "%s$%d", item->pszName, item->nSubHotkeys); - db_set_w(NULL, DBMODULENAME, buf, subItem->Hotkey); - if (subItem->type != HKT_MANUAL) - db_set_b(NULL, DBMODULENAME "Types", buf, (BYTE)subItem->type); - - ++item->nSubHotkeys; - } - } - - mir_snprintf(buf, "%s$count", item->pszName); - db_set_dw(NULL, DBMODULENAME, buf, item->nSubHotkeys); -} - -static void sttBuildHotkeyList(HWND hwndList) -{ - int i, nItems = 0; - ListView_DeleteAllItems(hwndList); - - for (i = 0; i < hotkeys.getCount(); i++) { - LVITEM lvi = { 0 }; - THotkeyItem *item = hotkeys[i]; - - if (item->OptDeleted) - continue; - - if (!i || mir_tstrcmp(item->ptszSection, hotkeys[i - 1]->ptszSection)) { - lvi.mask = LVIF_TEXT | LVIF_PARAM; - lvi.iItem = nItems++; - lvi.iSubItem = 0; - lvi.lParam = 0; - lvi.pszText = item->getSection(); - ListView_InsertItem(hwndList, &lvi); - ListView_SetCheckState(hwndList, lvi.iItem, TRUE); - - lvi.mask = LVIF_TEXT; - lvi.iSubItem = 1; - lvi.pszText = item->ptszSection; - ListView_SetItem(hwndList, &lvi); - - lvi.iSubItem = 0; - } - - lvi.mask = LVIF_PARAM | LVIF_INDENT; - lvi.iIndent = 1; - lvi.iItem = nItems++; - lvi.lParam = (LPARAM)item; - ListView_InsertItem(hwndList, &lvi); - sttOptionsSetupItem(hwndList, nItems - 1, item); - } - - ListView_SortItemsEx(hwndList, sttOptionsSortList, (LPARAM)hwndList); -} - -static void sttOptionsStartEdit(HWND hwndDlg, HWND hwndHotkey) -{ - LVITEM lvi; - THotkeyItem *item; - int iItem = ListView_GetNextItem(hwndHotkey, -1, LVNI_SELECTED); - if (iItem < 0) return; - - lvi.mask = LVIF_PARAM; - lvi.iItem = iItem; - ListView_GetItem(hwndHotkey, &lvi); - - if (item = (THotkeyItem *)lvi.lParam) { - RECT rc; - ListView_GetSubItemRect(hwndHotkey, iItem, COL_KEY, LVIR_BOUNDS, &rc); - MapWindowPoints(hwndHotkey, hwndDlg, (LPPOINT)&rc, 2); - SendDlgItemMessage(hwndDlg, IDC_HOTKEY, HKM_SETHOTKEY, MAKELONG(LOBYTE(item->OptHotkey), HIBYTE(item->OptHotkey)), 0); - - SetWindowPos(hwndHotkey, HWND_BOTTOM, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); - SetWindowPos(GetDlgItem(hwndDlg, IDC_HOTKEY), HWND_TOP, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_SHOWWINDOW); - RedrawWindow(GetDlgItem(hwndDlg, IDC_HOTKEY), NULL, NULL, RDW_INVALIDATE); - - SetFocus(GetDlgItem(hwndDlg, IDC_HOTKEY)); - RedrawWindow(GetDlgItem(hwndDlg, IDC_HOTKEY), NULL, NULL, RDW_INVALIDATE); - } -} - -static void sttOptionsDrawTextChunk(HDC hdc, TCHAR *text, RECT *rc) -{ - DrawText(hdc, text, -1, rc, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS); - - SIZE sz; - GetTextExtentPoint32(hdc, text, (int)mir_tstrlen(text), &sz); - rc->left += sz.cx; -} - -static INT_PTR CALLBACK sttOptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static BOOL initialized = FALSE; - static int colWidth = 0; - static WORD currentLanguage = 0; - - HWND hwndHotkey = GetDlgItem(hwndDlg, IDC_LV_HOTKEYS); - - switch (msg) { - case WM_INITDIALOG: - initialized = FALSE; - - TranslateDialogDefault(hwndDlg); - - HotkeyEditCreate(GetDlgItem(hwndDlg, IDC_HOTKEY)); - { - HIMAGELIST hIml = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 3, 1); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_WINDOWS); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_MIRANDA); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_WINDOW); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_ADDCONTACT); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_DELETE); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_UNDO); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_GROUPOPEN); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_GROUPSHUT); - ListView_SetImageList(hwndHotkey, hIml, LVSIL_SMALL); - } - ListView_SetExtendedListViewStyle(hwndHotkey, LVS_EX_CHECKBOXES | LVS_EX_SUBITEMIMAGES | LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP); - { - RECT rc; - GetClientRect(hwndHotkey, &rc); - colWidth = rc.right - GetSystemMetrics(SM_CXHTHUMB) - 3 * GetSystemMetrics(SM_CXSMICON) - 5; - - LVCOLUMN lvc; - lvc.mask = LVCF_WIDTH; - lvc.cx = colWidth * 2 / 3; - ListView_InsertColumn(hwndHotkey, COL_NAME, &lvc); - lvc.cx = GetSystemMetrics(SM_CXSMICON); - ListView_InsertColumn(hwndHotkey, COL_TYPE, &lvc); - lvc.cx = colWidth / 3; - ListView_InsertColumn(hwndHotkey, COL_KEY, &lvc); - lvc.cx = GetSystemMetrics(SM_CXSMICON); - ListView_InsertColumn(hwndHotkey, COL_RESET, &lvc); - lvc.cx = GetSystemMetrics(SM_CXSMICON); - ListView_InsertColumn(hwndHotkey, COL_ADDREMOVE, &lvc); - - for (int i = 0; i < hotkeys.getCount(); i++) { - THotkeyItem *item = hotkeys[i]; - - item->OptChanged = FALSE; - item->OptDeleted = item->OptNew = FALSE; - item->OptEnabled = item->Enabled; - item->OptHotkey = item->Hotkey; - item->OptType = item->type; - } - - currentLanguage = LOWORD(GetKeyboardLayout(0)); - sttBuildHotkeyList(hwndHotkey); - } - SetTimer(hwndDlg, 1024, 1000, NULL); - initialized = TRUE; - { - /* load group states */ - int count = ListView_GetItemCount(hwndHotkey); - TCHAR buf[128]; - LVITEM lvi = { 0 }; - lvi.pszText = buf; - lvi.cchTextMax = SIZEOF(buf); - for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) { - char *szSetting; - - lvi.mask = LVIF_PARAM; - lvi.iSubItem = 0; - ListView_GetItem(hwndHotkey, &lvi); - if (lvi.lParam) continue; - - lvi.mask = LVIF_TEXT; - lvi.iSubItem = 1; - ListView_GetItem(hwndHotkey, &lvi); - - szSetting = mir_t2a(lvi.pszText); - - ListView_SetCheckState(hwndHotkey, lvi.iItem, - db_get_b(NULL, DBMODULENAME "UI", szSetting, TRUE)); - - mir_free(szSetting); - } - } - - g_hwndHkOptions = hwndDlg; - break; - - case WM_TIMER: - if (initialized) { - WORD newLanguage = LOWORD(GetKeyboardLayout(0)); - if (newLanguage == currentLanguage) - break; - - int count = ListView_GetItemCount(hwndHotkey); - - LVITEM lvi = { 0 }; - lvi.mask = LVIF_PARAM; - for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) { - ListView_GetItem(hwndHotkey, &lvi); - if (lvi.lParam) - sttOptionsSetupItem(hwndHotkey, lvi.iItem, (THotkeyItem *)lvi.lParam); - } - currentLanguage = newLanguage; - } - break; - - case WM_HOTKEYUNREGISTERED: - { - int count = ListView_GetItemCount(hwndHotkey); - - LVITEM lvi = { 0 }; - lvi.mask = LVIF_PARAM; - for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) { - ListView_GetItem(hwndHotkey, &lvi); - if (!lvi.lParam) continue; - - if (((THotkeyItem *)lvi.lParam)->UnregisterHotkey) { - ListView_DeleteItem(hwndHotkey, lvi.iItem); - --lvi.iItem; - --count; - } - } - } - break; - - case WM_DRAWITEM: - { - LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam; - RECT rc = lpdis->rcItem; - int prefix = 65; - int width = (lpdis->rcItem.right - lpdis->rcItem.left - prefix) / 3; - rc.left += 5; - - HIMAGELIST hIml = ListView_GetImageList(hwndHotkey, LVSIL_SMALL); - if (lpdis->CtlID == IDC_CANVAS2) { - sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Scope:"), &rc); - - rc.left = prefix; - ImageList_Draw(hIml, 0, lpdis->hDC, rc.left, (rc.top + rc.bottom - 16) / 2, ILD_TRANSPARENT); - rc.left += 20; - sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("System"), &rc); - - rc.left = prefix + width; - ImageList_Draw(hIml, 1, lpdis->hDC, rc.left, (rc.top + rc.bottom - 16) / 2, ILD_TRANSPARENT); - rc.left += 20; - sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Miranda"), &rc); - - rc.left = prefix + width * 2; - ImageList_Draw(hIml, 2, lpdis->hDC, rc.left, (rc.top + rc.bottom - 16) / 2, ILD_TRANSPARENT); - rc.left += 20; - sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Window"), &rc); - return TRUE; - } - - if (lpdis->CtlID == IDC_CANVAS) { - sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Actions:"), &rc); - - rc.left = prefix; - ImageList_Draw(hIml, 5, lpdis->hDC, rc.left, (rc.top + rc.bottom - 16) / 2, ILD_TRANSPARENT); - rc.left += 20; - sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Undo"), &rc); - - rc.left = prefix + width * 1; - ImageList_Draw(hIml, 3, lpdis->hDC, rc.left, (rc.top + rc.bottom - 16) / 2, ILD_TRANSPARENT); - rc.left += 20; - sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Add binding"), &rc); - - rc.left = prefix + width * 2; - ImageList_Draw(hIml, 4, lpdis->hDC, rc.left, (rc.top + rc.bottom - 16) / 2, ILD_TRANSPARENT); - rc.left += 20; - sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Remove"), &rc); - return TRUE; - } - } - break; - - case WM_COMMAND: - if ((LOWORD(wParam) == IDC_HOTKEY) && ((HIWORD(wParam) == EN_KILLFOCUS) || (HIWORD(wParam) == 0))) { - LVITEM lvi; - THotkeyItem *item; - WORD wHotkey = (WORD)SendDlgItemMessage(hwndDlg, IDC_HOTKEY, HKM_GETHOTKEY, 0, 0); - - ShowWindow(GetDlgItem(hwndDlg, IDC_HOTKEY), SW_HIDE); - SetFocus(hwndHotkey); - if (!wHotkey || (wHotkey == VK_ESCAPE) || (HIWORD(wParam) != 0)) - break; - - lvi.mask = LVIF_PARAM; - lvi.iItem = ListView_GetNextItem(hwndHotkey, -1, LVNI_SELECTED); - if (lvi.iItem >= 0) { - ListView_GetItem(hwndHotkey, &lvi); - if (item = (THotkeyItem *)lvi.lParam) { - item->OptHotkey = wHotkey; - - sttOptionsSetupItem(hwndHotkey, lvi.iItem, item); - sttOptionsSetChanged(item); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - } - break; - - case WM_CONTEXTMENU: - if (GetWindowLongPtr((HWND)wParam, GWL_ID) == IDC_LV_HOTKEYS) { - HWND hwndList = (HWND)wParam; - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - LVITEM lvi = { 0 }; - THotkeyItem *item = NULL; - - lvi.iItem = ListView_GetNextItem(hwndHotkey, -1, LVNI_SELECTED); - if (lvi.iItem < 0) return FALSE; - - lvi.mask = LVIF_PARAM; - ListView_GetItem(hwndList, &lvi); - if (!(item = (THotkeyItem *)lvi.lParam)) return FALSE; - - if ((pt.x == -1) && (pt.y == -1)) { - RECT rc; - ListView_GetItemRect(hwndList, lvi.iItem, &rc, LVIR_LABEL); - pt.x = rc.left; - pt.y = rc.bottom; - ClientToScreen(hwndList, &pt); - } - - enum { MI_CANCEL, MI_CHANGE, MI_SYSTEM, MI_LOCAL, MI_ADD, MI_REMOVE, MI_REVERT }; - - MENUITEMINFO mii = { 0 }; - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STATE; - mii.fState = MFS_DEFAULT; - - HMENU hMenu = CreatePopupMenu(); - AppendMenu(hMenu, MF_STRING, (UINT_PTR)MI_CHANGE, TranslateT("Modify")); - SetMenuItemInfo(hMenu, (UINT_PTR)MI_CHANGE, FALSE, &mii); - if (item->type != HKT_MANUAL) { - AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); - AppendMenu(hMenu, MF_STRING | - ((item->OptType == HKT_GLOBAL) ? MF_CHECKED : 0), - (UINT_PTR)MI_SYSTEM, TranslateT("System scope")); - AppendMenu(hMenu, MF_STRING | - ((item->OptType == HKT_LOCAL) ? MF_CHECKED : 0), - (UINT_PTR)MI_LOCAL, TranslateT("Miranda scope")); - } - AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); - if (!item->rootHotkey) - AppendMenu(hMenu, MF_STRING, (UINT_PTR)MI_ADD, TranslateT("Add binding")); - else - AppendMenu(hMenu, MF_STRING, (UINT_PTR)MI_REMOVE, TranslateT("Remove")); - if (item->Hotkey != item->OptHotkey) { - AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); - AppendMenu(hMenu, MF_STRING, (UINT_PTR)MI_REVERT, TranslateT("Undo")); - } - - switch (TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) { - case MI_CHANGE: - sttOptionsStartEdit(hwndDlg, hwndHotkey); - break; - case MI_SYSTEM: - item->OptType = HKT_GLOBAL; - sttOptionsSetupItem(hwndList, lvi.iItem, item); - sttOptionsSetChanged(item); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case MI_LOCAL: - item->OptType = HKT_LOCAL; - sttOptionsSetupItem(hwndList, lvi.iItem, item); - sttOptionsSetChanged(item); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case MI_ADD: - initialized = FALSE; - sttOptionsAddHotkey(hwndList, item); - initialized = FALSE; - break; - case MI_REMOVE: - sttOptionsDeleteHotkey(hwndList, lvi.iItem, item); - break; - case MI_REVERT: - item->OptHotkey = item->Hotkey; - sttOptionsSetupItem(hwndList, lvi.iItem, item); - break; - } - DestroyMenu(hMenu); - break; - } - break; - - case WM_NOTIFY: - { - LPNMHDR lpnmhdr = (LPNMHDR)lParam; - switch (lpnmhdr->idFrom) { - case 0: - { - int i; - - if ((lpnmhdr->code != PSN_APPLY) && (lpnmhdr->code != PSN_RESET)) - break; - - UnregisterHotkeys(); - - for (i = 0; i < hotkeys.getCount(); i++) { - THotkeyItem *item = hotkeys[i]; - if (item->OptNew && item->OptDeleted || - item->rootHotkey && !item->OptHotkey || - (lpnmhdr->code == PSN_APPLY) && item->OptDeleted || - (lpnmhdr->code == PSN_RESET) && item->OptNew) { - FreeHotkey(item); - hotkeys.remove(i--); - } - } - - if (lpnmhdr->code == PSN_APPLY) { - LVITEM lvi = { 0 }; - int count = ListView_GetItemCount(hwndHotkey); - - for (i = 0; i < hotkeys.getCount(); i++) - sttOptionsSaveItem(hotkeys[i]); - - lvi.mask = LVIF_IMAGE; - lvi.iSubItem = COL_RESET; - lvi.iImage = -1; - for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) - ListView_SetItem(hwndHotkey, &lvi); - } - - RegisterHotkeys(); - - NotifyEventHooks(hEvChanged, 0, 0); - } - break; - - case IDC_LV_HOTKEYS: - switch (lpnmhdr->code) { - case NM_CLICK: - { - THotkeyItem *item = NULL; - LPNMITEMACTIVATE lpnmia = (LPNMITEMACTIVATE)lParam; - LVHITTESTINFO lvhti = { 0 }; - LVITEM lvi = { 0 }; - - lvi.mask = LVIF_PARAM | LVIF_IMAGE; - lvi.iItem = lpnmia->iItem; - ListView_GetItem(lpnmia->hdr.hwndFrom, &lvi); - item = (THotkeyItem *)lvi.lParam; - - lvhti.pt = lpnmia->ptAction; - lvhti.iItem = lpnmia->iItem; - lvhti.iSubItem = lpnmia->iSubItem; - ListView_HitTest(lpnmia->hdr.hwndFrom, &lvhti); - - if (item && - (!item->rootHotkey && (lpnmia->iSubItem == COL_NAME) && ((lvhti.flags & LVHT_ONITEM) == LVHT_ONITEMICON) || - item->rootHotkey && (lpnmia->iSubItem == COL_TYPE)) && - ((item->OptType == HKT_GLOBAL) || (item->OptType == HKT_LOCAL))) { - item->OptType = (item->OptType == HKT_GLOBAL) ? HKT_LOCAL : HKT_GLOBAL; - sttOptionsSetupItem(lpnmia->hdr.hwndFrom, lpnmia->iItem, item); - sttOptionsSetChanged(item); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - else if (item && (lpnmia->iSubItem == COL_RESET)) { - item->OptHotkey = item->Hotkey; - sttOptionsSetupItem(lpnmia->hdr.hwndFrom, lpnmia->iItem, item); - } - else if (item && (lpnmia->iSubItem == COL_ADDREMOVE)) { - if (item->rootHotkey) - sttOptionsDeleteHotkey(lpnmia->hdr.hwndFrom, lpnmia->iItem, item); - else { - initialized = FALSE; - sttOptionsAddHotkey(lpnmia->hdr.hwndFrom, item); - initialized = TRUE; - } - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - break; - - case LVN_KEYDOWN: - { - LPNMLVKEYDOWN param = (LPNMLVKEYDOWN)lParam; - if (param->wVKey == VK_SUBTRACT || param->wVKey == VK_LEFT || param->wVKey == VK_ADD || param->wVKey == VK_RIGHT) { - LVITEM lvi = { 0 }; - lvi.mask = LVIF_PARAM; - lvi.iItem = ListView_GetNextItem(lpnmhdr->hwndFrom, -1, LVNI_SELECTED); - if (lvi.iItem < 0) - break; - - ListView_GetItem(lpnmhdr->hwndFrom, &lvi); - if (lvi.lParam) - break; - - if (param->wVKey == VK_ADD || param->wVKey == VK_RIGHT) { - ListView_SetCheckState(lpnmhdr->hwndFrom, lvi.iItem, TRUE); - } - else { - ListView_SetCheckState(lpnmhdr->hwndFrom, lvi.iItem, FALSE); - } - } - else if (param->wVKey == VK_F2) - sttOptionsStartEdit(hwndDlg, hwndHotkey); - } - break; - - case LVN_ITEMACTIVATE: - { - LVITEM lvi = { 0 }; - lvi.mask = LVIF_PARAM; - lvi.iItem = ListView_GetNextItem(lpnmhdr->hwndFrom, -1, LVNI_SELECTED); - if (lvi.iItem < 0) break; - ListView_GetItem(lpnmhdr->hwndFrom, &lvi); - - if (lvi.lParam) - sttOptionsStartEdit(hwndDlg, hwndHotkey); - else - ListView_SetCheckState(lpnmhdr->hwndFrom, lvi.iItem, !ListView_GetCheckState(lpnmhdr->hwndFrom, lvi.iItem)); - } - break; - - case LVN_ITEMCHANGED: - { - LPNMLISTVIEW param = (LPNMLISTVIEW)lParam; - THotkeyItem *item = (THotkeyItem *)param->lParam; - if (!initialized || (param->uNewState >> 12 == param->uOldState >> 12)) - break; - - if (item && !item->rootHotkey) { - item->OptEnabled = ListView_GetCheckState(lpnmhdr->hwndFrom, param->iItem) ? 1 : 0; - sttOptionsSetChanged(item); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - else if (!item) { - TCHAR buf[256]; - LVITEM lvi = { 0 }; - lvi.mask = LVIF_TEXT; - lvi.iItem = param->iItem; - lvi.pszText = buf; - lvi.cchTextMax = SIZEOF(buf); - ListView_GetItem(lpnmhdr->hwndFrom, &lvi); - - if (param->uNewState >> 12 == 1) { - int count = ListView_GetItemCount(lpnmhdr->hwndFrom); - LVITEM lvi = { 0 }; - lvi.mask = LVIF_PARAM; - for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) { - THotkeyItem *item; - ListView_GetItem(lpnmhdr->hwndFrom, &lvi); - item = (THotkeyItem *)lvi.lParam; - if (!item) continue; - if (!mir_tstrcmp(item->getSection(), buf)) { - ListView_DeleteItem(lpnmhdr->hwndFrom, lvi.iItem); - --lvi.iItem; - --count; - } - } - } - else if (param->uNewState >> 12 == 2) { - int i, nItems = ListView_GetItemCount(lpnmhdr->hwndFrom); - initialized = FALSE; - for (i = 0; i < hotkeys.getCount(); i++) { - LVITEM lvi = { 0 }; - THotkeyItem *item = hotkeys[i]; - - if (item->OptDeleted) - continue; - if (mir_tstrcmp(buf, item->getSection())) - continue; - - lvi.mask = LVIF_PARAM | LVIF_INDENT; - lvi.iIndent = 1; - lvi.iItem = nItems++; - lvi.lParam = (LPARAM)item; - ListView_InsertItem(lpnmhdr->hwndFrom, &lvi); - sttOptionsSetupItem(lpnmhdr->hwndFrom, nItems - 1, item); - } - ListView_SortItemsEx(lpnmhdr->hwndFrom, sttOptionsSortList, (LPARAM)lpnmhdr->hwndFrom); - initialized = TRUE; - } - } - break; - } - case NM_CUSTOMDRAW: - { - NMLVCUSTOMDRAW *param = (NMLVCUSTOMDRAW *)lParam; - switch (param->nmcd.dwDrawStage) { - case CDDS_PREPAINT: - case CDDS_ITEMPREPAINT: - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_NOTIFYSUBITEMDRAW); - return TRUE; - - case CDDS_SUBITEM | CDDS_ITEMPREPAINT: - { - THotkeyItem *item; - TCHAR buf[256]; - LVITEM lvi = { 0 }; - lvi.mask = LVIF_TEXT | LVIF_PARAM; - lvi.iItem = param->nmcd.dwItemSpec; - lvi.pszText = buf; - lvi.cchTextMax = SIZEOF(buf); - ListView_GetItem(lpnmhdr->hwndFrom, &lvi); - - item = (THotkeyItem *)lvi.lParam; - if (!item) { - RECT rc; - HFONT hfnt; - - ListView_GetSubItemRect(lpnmhdr->hwndFrom, param->nmcd.dwItemSpec, param->iSubItem, LVIR_BOUNDS, &rc); - FillRect(param->nmcd.hdc, &rc, GetSysColorBrush(param->nmcd.uItemState&CDIS_SELECTED ? COLOR_HIGHLIGHT : COLOR_WINDOW)); - SetTextColor(param->nmcd.hdc, GetSysColor(param->nmcd.uItemState&CDIS_SELECTED ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT)); - - if (param->iSubItem == 0) { - rc.left += 3; - HIMAGELIST hIml = ListView_GetImageList(hwndHotkey, LVSIL_SMALL); - ImageList_Draw(hIml, - ListView_GetCheckState(hwndHotkey, lvi.iItem) ? 6 : 7, - param->nmcd.hdc, rc.left, (rc.top + rc.bottom - 16) / 2, ILD_TRANSPARENT); - rc.left += 18; - hfnt = (HFONT)SelectObject(param->nmcd.hdc, (HFONT)SendMessage(GetParent(hwndDlg), PSM_GETBOLDFONT, 0, 0)); - DrawText(param->nmcd.hdc, buf, -1, &rc, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER); - SelectObject(param->nmcd.hdc, hfnt); - } - - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT); - return TRUE; - } - - if (item->rootHotkey && (param->iSubItem == 0)) { - RECT rc; - ListView_GetSubItemRect(lpnmhdr->hwndFrom, param->nmcd.dwItemSpec, param->iSubItem, LVIR_BOUNDS, &rc); - FillRect(param->nmcd.hdc, &rc, GetSysColorBrush(COLOR_WINDOW)); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT); - return TRUE; - } - break; - } - } - break; - } - break; - } - } - } - break; - - case WM_DESTROY: - { - int count = ListView_GetItemCount(hwndHotkey); - - g_hwndHkOptions = NULL; - - KillTimer(hwndDlg, 1024); - - TCHAR buf[128]; - LVITEM lvi = { 0 }; - lvi.pszText = buf; - lvi.cchTextMax = SIZEOF(buf); - for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) { - lvi.mask = LVIF_PARAM; - lvi.iSubItem = 0; - ListView_GetItem(hwndHotkey, &lvi); - if (lvi.lParam) continue; - - lvi.mask = LVIF_TEXT; - lvi.iSubItem = 1; - ListView_GetItem(hwndHotkey, &lvi); - - db_set_b(NULL, DBMODULENAME "UI", _T2A(lvi.pszText), ListView_GetCheckState(hwndHotkey, lvi.iItem)); - } - } - } - - return FALSE; -} - -int HotkeyOptionsInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.hInstance = hInst; - odp.flags = ODPF_BOLDGROUPS; - odp.position = -180000000; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_HOTKEYS); - odp.pszTitle = LPGEN("Hotkeys"); - odp.pszGroup = LPGEN("Customize"); - odp.pfnDlgProc = sttOptionsDlgProc; - Options_AddPage(wParam, &odp); - return 0; -} diff --git a/src/modules/skin/hotkeys.cpp b/src/modules/skin/hotkeys.cpp deleted file mode 100644 index f74f91f4b9..0000000000 --- a/src/modules/skin/hotkeys.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#include -#include "skin.h" - -static int sttCompareHotkeys(const THotkeyItem *p1, const THotkeyItem *p2) -{ - int res; - if (res = mir_tstrcmp(p1->ptszSection, p2->ptszSection)) - return res; - if (res = mir_tstrcmp(p1->ptszDescription, p2->ptszDescription)) - return res; - if (!p1->rootHotkey && p2->rootHotkey) - return -1; - if (p1->rootHotkey && !p2->rootHotkey) - return 1; - return 0; -} - -LIST hotkeys(10, sttCompareHotkeys); -DWORD g_pid = 0, g_hkid = 1; -HWND g_hwndHotkeyHost = NULL, g_hwndHkOptions = NULL; -HANDLE hEvChanged = 0; - -static BOOL bModuleInitialized = FALSE; -static HHOOK hhkKeyboard = NULL; - -WORD GetHotkeyValue(INT_PTR idHotkey) -{ - for (int i = 0; i < hotkeys.getCount(); i++) - if (hotkeys[i]->idHotkey == idHotkey) - return hotkeys[i]->Enabled ? hotkeys[i]->Hotkey : 0; - - return 0; -} - -static void sttWordToModAndVk(WORD w, BYTE *mod, BYTE *vk) -{ - *mod = 0; - if (HIBYTE(w) & HOTKEYF_CONTROL) *mod |= MOD_CONTROL; - if (HIBYTE(w) & HOTKEYF_SHIFT) *mod |= MOD_SHIFT; - if (HIBYTE(w) & HOTKEYF_ALT) *mod |= MOD_ALT; - if (HIBYTE(w) & HOTKEYF_EXT) *mod |= MOD_WIN; - *vk = LOBYTE(w); -} - -static LRESULT CALLBACK sttHotkeyHostWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (msg == WM_HOTKEY) { - for (int i = 0; i < hotkeys.getCount(); i++) { - THotkeyItem *item = hotkeys[i]; - if (item->type != HKT_GLOBAL || !item->Enabled) - continue; - - if (item->pszService && (wParam == item->idHotkey)) { - CallService(item->pszService, 0, item->lParam); - break; - } - } - - return FALSE; - } - - return DefWindowProc(hwnd, msg, wParam, lParam); -} - -static LRESULT CALLBACK sttKeyboardProc(int code, WPARAM wParam, LPARAM lParam) -{ - if (code == HC_ACTION && !(HIWORD(lParam) & KF_UP)) { - BYTE mod = 0, vk = wParam; - - if (vk) { - if (GetAsyncKeyState(VK_CONTROL)) mod |= MOD_CONTROL; - if (GetAsyncKeyState(VK_MENU)) mod |= MOD_ALT; - if (GetAsyncKeyState(VK_SHIFT)) mod |= MOD_SHIFT; - if (GetAsyncKeyState(VK_LWIN) || GetAsyncKeyState(VK_RWIN)) mod |= MOD_WIN; - - for (int i = 0; i < hotkeys.getCount(); i++) { - THotkeyItem *item = hotkeys[i]; - if (item->type != HKT_LOCAL || !item->Enabled) - continue; - - BYTE hkMod, hkVk; - sttWordToModAndVk(item->Hotkey, &hkMod, &hkVk); - if (!hkVk) continue; - if (item->pszService && vk == hkVk && mod == hkMod) { - CallService(item->pszService, 0, item->lParam); - return TRUE; - } - } - } - } - - return CallNextHookEx(hhkKeyboard, code, wParam, lParam); -} - -static INT_PTR svcHotkeySubclass(WPARAM wParam, LPARAM) -{ - HotkeyEditCreate((HWND)wParam); - return 0; -} - -static INT_PTR svcHotkeyUnsubclass(WPARAM wParam, LPARAM) -{ - HotkeyEditDestroy((HWND)wParam); - return 0; -} - -static INT_PTR svcHotkeyRegister(WPARAM wParam, LPARAM lParam) -{ - HOTKEYDESC *desc = (HOTKEYDESC *)lParam; - if (desc->cbSize != sizeof(HOTKEYDESC)) - return 0; - - THotkeyItem *item = (THotkeyItem*)mir_alloc(sizeof(THotkeyItem)); - DWORD dwFlags = (desc->cbSize >= sizeof(HOTKEYDESC)) ? desc->dwFlags : 0; - if (dwFlags & HKD_UNICODE) { - item->ptszSection = mir_tstrdup(desc->ptszSection); - item->ptszDescription = mir_tstrdup(desc->ptszDescription); - } - else { - item->ptszSection = mir_a2u(desc->pszSection); - item->ptszDescription = mir_a2u(desc->pszDescription); - } - - item->hLangpack = (int)wParam; - item->allowSubHotkeys = TRUE; - item->rootHotkey = NULL; - item->nSubHotkeys = 0; - - if (item->rootHotkey = hotkeys.find(item)) { - if (item->rootHotkey->allowSubHotkeys) { - char nameBuf[MAXMODULELABELLENGTH]; - mir_snprintf(nameBuf, SIZEOF(nameBuf), "%s$%d", item->rootHotkey->pszName, item->rootHotkey->nSubHotkeys); - item->pszName = mir_strdup(nameBuf); - item->Enabled = TRUE; - - item->rootHotkey->nSubHotkeys++; - } - else { - mir_free(item->ptszSection); - mir_free(item->ptszDescription); - mir_free(item); - return 0; - } - } - else { - item->pszName = mir_strdup(desc->pszName); - item->Enabled = !db_get_b(NULL, DBMODULENAME "Off", item->pszName, 0); - } - - item->pszService = desc->pszService ? mir_strdup(desc->pszService) : 0; - item->DefHotkey = desc->DefHotKey & ~HKF_MIRANDA_LOCAL; - item->Hotkey = db_get_w(NULL, DBMODULENAME, item->pszName, item->DefHotkey); - item->type = item->pszService ? - (THotkeyType)db_get_b(NULL, DBMODULENAME "Types", item->pszName, - (desc->DefHotKey & HKF_MIRANDA_LOCAL) ? HKT_LOCAL : HKT_GLOBAL) : HKT_MANUAL; - item->lParam = desc->lParam; - - char buf[256]; - mir_snprintf(buf, "mir_hotkey_%d_%d", g_pid, g_hkid++); - item->idHotkey = GlobalAddAtomA(buf); - if (item->type == HKT_GLOBAL) { - if (item->Enabled) { - BYTE mod, vk; - sttWordToModAndVk(item->Hotkey, &mod, &vk); - if (vk) RegisterHotKey(g_hwndHotkeyHost, item->idHotkey, mod, vk); - } - } - - hotkeys.insert(item); - - if (!item->rootHotkey) { - /* try to load alternatives from db */ - int count, i; - mir_snprintf(buf, "%s$count", item->pszName); - count = (int)db_get_dw(NULL, DBMODULENAME, buf, -1); - for (i = 0; i < count; i++) { - mir_snprintf(buf, "%s$%d", item->pszName, i); - if (!db_get_w(NULL, DBMODULENAME, buf, 0)) - continue; - - svcHotkeyRegister(wParam, lParam); - } - item->allowSubHotkeys = count < 0; - } - else { - mir_free(item->pszName); - item->pszName = NULL; - } - - return item->idHotkey; -} - -static INT_PTR svcHotkeyUnregister(WPARAM, LPARAM lParam) -{ - int i; - char *pszName = (char *)lParam; - char pszNamePrefix[MAXMODULELABELLENGTH]; - size_t cbNamePrefix; - mir_snprintf(pszNamePrefix, SIZEOF(pszNamePrefix), "%s$", pszName); - cbNamePrefix = mir_strlen(pszNamePrefix); - - for (i = 0; i < hotkeys.getCount(); i++) { - char *pszCurrentName = hotkeys[i]->rootHotkey ? - hotkeys[i]->rootHotkey->pszName : - hotkeys[i]->pszName; - if (!pszCurrentName) continue; - - hotkeys[i]->UnregisterHotkey = - !mir_strcmp(pszCurrentName, pszName) || - !strncmp(pszCurrentName, pszNamePrefix, cbNamePrefix); - } - - if (g_hwndHkOptions) - SendMessage(g_hwndHkOptions, WM_HOTKEYUNREGISTERED, 0, 0); - - for (i = 0; i < hotkeys.getCount(); i++) - if (hotkeys[i]->UnregisterHotkey) { - FreeHotkey(hotkeys[i]); - List_Remove((SortedList *)&hotkeys, i); - --i; - } - - return 0; -} - -static INT_PTR svcHotkeyCheck(WPARAM wParam, LPARAM lParam) -{ - MSG *msg = (MSG *)wParam; - TCHAR *pszSection = mir_a2t((char *)lParam); - - if ((msg->message == WM_KEYDOWN) || (msg->message == WM_SYSKEYDOWN)) { - int i; - BYTE mod = 0, vk = msg->wParam; - - if (vk) { - if (GetAsyncKeyState(VK_CONTROL)) mod |= MOD_CONTROL; - if (GetAsyncKeyState(VK_MENU)) mod |= MOD_ALT; - if (GetAsyncKeyState(VK_SHIFT)) mod |= MOD_SHIFT; - if (GetAsyncKeyState(VK_LWIN) || GetAsyncKeyState(VK_RWIN)) mod |= MOD_WIN; - - for (i = 0; i < hotkeys.getCount(); i++) { - THotkeyItem *item = hotkeys[i]; - BYTE hkMod, hkVk; - if ((item->type != HKT_MANUAL) || mir_tstrcmp(pszSection, item->ptszSection)) continue; - sttWordToModAndVk(item->Hotkey, &hkMod, &hkVk); - if (!hkVk) continue; - if (!item->Enabled) continue; - if ((vk == hkVk) && (mod == hkMod)) { - mir_free(pszSection); - return item->lParam; - } - } - } - } - - mir_free(pszSection); - return 0; -} - -void FreeHotkey(THotkeyItem *item) -{ - if (item->type == HKT_GLOBAL && item->Enabled) - UnregisterHotKey(g_hwndHotkeyHost, item->idHotkey); - GlobalDeleteAtom(item->idHotkey); - mir_free(item->pszName); - mir_free(item->pszService); - mir_free(item->ptszDescription); - mir_free(item->ptszSection); - mir_free(item); -} - -void RegisterHotkeys() -{ - for (int i = 0; i < hotkeys.getCount(); i++) { - THotkeyItem *item = hotkeys[i]; - UnregisterHotKey(g_hwndHotkeyHost, item->idHotkey); - if (item->type != HKT_GLOBAL) continue; - if (item->Enabled) { - BYTE mod, vk; - sttWordToModAndVk(item->Hotkey, &mod, &vk); - if (vk) RegisterHotKey(g_hwndHotkeyHost, item->idHotkey, mod, vk); - } - } -} - -void KillModuleHotkeys(int hLangpack) -{ - for (int i = hotkeys.getCount() - 1; i >= 0; i--) { - THotkeyItem *item = hotkeys[i]; - if (item->hLangpack == hLangpack) { - FreeHotkey(item); - hotkeys.remove(i); - } - } -} - -void UnregisterHotkeys() -{ - for (int i = 0; i < hotkeys.getCount(); i++) { - THotkeyItem *item = hotkeys[i]; - if (item->type == HKT_GLOBAL && item->Enabled) - UnregisterHotKey(g_hwndHotkeyHost, item->idHotkey); - } -} - -static int sttModulesLoaded(WPARAM, LPARAM) -{ - HookEvent(ME_OPT_INITIALISE, HotkeyOptionsInit); - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Hotkey manager - -static const char* oldSettings[] = { "ShowHide", "ReadMsg", "NetSearch", "ShowOptions" }; -static const char* newSettings[] = { "ShowHide", "ReadMessage", "SearchInWeb", "ShowOptions" }; - -int LoadSkinHotkeys(void) -{ - WNDCLASSEX wcl = { 0 }; - - bModuleInitialized = TRUE; - - wcl.cbSize = sizeof(wcl); - wcl.lpfnWndProc = sttHotkeyHostWndProc; - wcl.style = 0; - wcl.cbClsExtra = 0; - wcl.cbWndExtra = 0; - wcl.hInstance = hInst; - wcl.hIcon = NULL; - wcl.hCursor = LoadCursor(NULL, IDC_ARROW); - wcl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); - wcl.lpszMenuName = NULL; - wcl.lpszClassName = _T("MirandaHotkeyHostWnd"); - wcl.hIconSm = NULL; - RegisterClassEx(&wcl); - - g_pid = GetCurrentProcessId(); - - g_hwndHotkeyHost = CreateWindow(_T("MirandaHotkeyHostWnd"), NULL, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInst, NULL); - SetWindowPos(g_hwndHotkeyHost, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_DEFERERASE | SWP_NOSENDCHANGING | SWP_HIDEWINDOW); - - hhkKeyboard = SetWindowsHookEx(WH_KEYBOARD, sttKeyboardProc, NULL, hMainThreadId); - - hEvChanged = CreateHookableEvent(ME_HOTKEYS_CHANGED); - - CreateServiceFunction("CoreHotkeys/Register", svcHotkeyRegister); - CreateServiceFunction(MS_HOTKEY_UNREGISTER, svcHotkeyUnregister); - CreateServiceFunction(MS_HOTKEY_SUBCLASS, svcHotkeySubclass); - CreateServiceFunction(MS_HOTKEY_UNSUBCLASS, svcHotkeyUnsubclass); - CreateServiceFunction(MS_HOTKEY_CHECK, svcHotkeyCheck); - - HookEvent(ME_SYSTEM_MODULESLOADED, sttModulesLoaded); - - for (int i = 0; i < SIZEOF(oldSettings); i++) { - char szSetting[100]; - mir_snprintf(szSetting, "HK%s", oldSettings[i]); - - WORD key; - if ((key = db_get_w(NULL, "Clist", szSetting, 0))) { - db_unset(NULL, "Clist", szSetting); - db_set_w(NULL, DBMODULENAME, newSettings[i], key); - } - - mir_snprintf(szSetting, "HKEn%s", oldSettings[i]); - if ((key = db_get_b(NULL, "Clist", szSetting, 0))) { - db_unset(NULL, "Clist", szSetting); - db_set_b(NULL, DBMODULENAME "Off", newSettings[i], (BYTE)(key == 0)); - } - } - - return 0; -} - -void UnloadSkinHotkeys(void) -{ - if (!bModuleInitialized) - return; - - DestroyHookableEvent(hEvChanged); - UnhookWindowsHookEx(hhkKeyboard); - - for (int i = 0; i < hotkeys.getCount(); i++) - FreeHotkey(hotkeys[i]); - - DestroyWindow(g_hwndHotkeyHost); -} diff --git a/src/modules/skin/skin.h b/src/modules/skin/skin.h deleted file mode 100644 index d0e6eae726..0000000000 --- a/src/modules/skin/skin.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 DBMODULENAME "SkinHotKeys" - -#define WM_HOTKEYUNREGISTERED (WM_USER+721) - -typedef enum { HKT_GLOBAL, HKT_LOCAL, HKT_MANUAL, HKT_COUNT } THotkeyType; - -struct THotkeyBoxData -{ - BYTE shift; - BYTE key; -}; - -struct THotkeyItem -{ - THotkeyType type; - char *pszService, *pszName; // pszName is valid _only_ for "root" hotkeys - TCHAR *ptszSection, *ptszDescription; - LPARAM lParam; - WORD DefHotkey, Hotkey; - bool Enabled; - int hLangpack; - ATOM idHotkey; - - THotkeyItem *rootHotkey; - int nSubHotkeys; - bool allowSubHotkeys; - - bool OptChanged, OptDeleted, OptNew; - WORD OptHotkey; - THotkeyType OptType; - bool OptEnabled; - - bool UnregisterHotkey; // valid only during WM_APP message in options UI, used to remove unregistered hotkeys from options - - __inline TCHAR* getSection() const { return TranslateTH(hLangpack, ptszSection); } - __inline TCHAR* getDescr() const { return TranslateTH(hLangpack, ptszDescription); } -}; - -extern LIST hotkeys; -extern HWND g_hwndHkOptions, g_hwndHotkeyHost; -extern DWORD g_pid, g_hkid; -extern HANDLE hEvChanged; - -int HotkeyOptionsInit(WPARAM, LPARAM); - -void FreeHotkey(THotkeyItem *item); -void RegisterHotkeys(); -void UnregisterHotkeys(); - -void HotkeyEditCreate(HWND hwnd); -void HotkeyEditDestroy(HWND hwnd); diff --git a/src/modules/skin/skinicons.cpp b/src/modules/skin/skinicons.cpp deleted file mode 100644 index 1b8b9de3be..0000000000 --- a/src/modules/skin/skinicons.cpp +++ /dev/null @@ -1,505 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include - -struct StandardIconDescription -{ - int id; - LPCSTR description; - int resource_id; - int pf2; - LPCSTR section; - HANDLE hIcolib; -}; - -static struct StandardIconDescription mainIcons[] = -{ - { SKINICON_OTHER_MIRANDA, LPGEN("Miranda NG"), -IDI_MIRANDA }, // 0 - { SKINICON_EVENT_MESSAGE, LPGEN("Message"), -IDI_RECVMSG }, // 1 - { SKINICON_EVENT_URL, LPGEN("URL"), -IDI_URL }, // 2 - { SKINICON_EVENT_FILE, LPGEN("File"), -IDI_FILE }, // 3 - { SKINICON_OTHER_USERONLINE, LPGEN("User online"), -IDI_USERONLINE }, // 4 - { SKINICON_OTHER_GROUPOPEN, LPGEN("Group (open)"), -IDI_GROUPOPEN }, // 5 - { SKINICON_OTHER_GROUPSHUT, LPGEN("Group (closed)"), -IDI_GROUPSHUT }, // 6 - { SKINICON_OTHER_CONNECTING, LPGEN("Connecting"), -IDI_LOAD }, // 7 - { SKINICON_OTHER_ADDCONTACT, LPGEN("Add contact"), -IDI_ADDCONTACT }, // 8 - { SKINICON_OTHER_USERDETAILS, LPGEN("User details"), -IDI_USERDETAILS }, // 9 - { SKINICON_OTHER_HISTORY, LPGEN("History"), -IDI_HISTORY }, // 10 - { SKINICON_OTHER_DOWNARROW, LPGEN("Down arrow"), -IDI_DOWNARROW }, // 11 - { SKINICON_OTHER_FINDUSER, LPGEN("Find user"), -IDI_FINDUSER }, // 12 - { SKINICON_OTHER_OPTIONS, LPGEN("Options"), -IDI_OPTIONS }, // 13 - { SKINICON_OTHER_SENDEMAIL, LPGEN("Send e-mail"), -IDI_SENDEMAIL }, // 14 - { SKINICON_OTHER_DELETE, LPGEN("Delete"), -IDI_DELETE }, // 15 - { SKINICON_OTHER_RENAME, LPGEN("Rename"), -IDI_RENAME }, // 16 - { SKINICON_OTHER_SMS, LPGEN("SMS"), -IDI_SMS }, // 17 - { SKINICON_OTHER_SEARCHALL, LPGEN("Search all"), -IDI_SEARCHALL }, // 18 - { SKINICON_OTHER_TICK, LPGEN("Tick"), -IDI_TICK }, // 19 - { SKINICON_OTHER_NOTICK, LPGEN("No tick"), -IDI_NOTICK }, // 20 - { SKINICON_OTHER_HELP, LPGEN("Help"), -IDI_HELP }, // 21 - { SKINICON_OTHER_MIRANDAWEB, LPGEN("Miranda website"), -IDI_MIRANDAWEBSITE }, // 22 - { SKINICON_OTHER_TYPING, LPGEN("Typing"), -IDI_TYPING }, // 23 - { SKINICON_OTHER_SMALLDOT, LPGEN("Small dot"), -IDI_SMALLDOT }, // 24 - { SKINICON_OTHER_FILLEDBLOB, LPGEN("Filled blob"), -IDI_FILLEDBLOB }, // 25 - { SKINICON_OTHER_EMPTYBLOB, LPGEN("Empty blob"), -IDI_EMPTYBLOB }, // 26 - { SKINICON_OTHER_UNICODE, LPGEN("Unicode plugin"), -IDI_UNICODE }, // 27 - { SKINICON_OTHER_ANSI, LPGEN("ANSI plugin"), -IDI_ANSI }, // 28 - { SKINICON_OTHER_LOADED, LPGEN("Running plugin"), -IDI_LOADED }, // 29 - { SKINICON_OTHER_NOTLOADED, LPGEN("Unloaded plugin"), -IDI_NOTLOADED }, // 30 - { SKINICON_OTHER_UNDO, LPGEN("Undo"), -IDI_UNDO }, // 31 - { SKINICON_OTHER_WINDOW, LPGEN("Window"), -IDI_WINDOW }, // 32 - { SKINICON_OTHER_WINDOWS, LPGEN("System"), -IDI_WINDOWS }, // 33 - { SKINICON_OTHER_ACCMGR, LPGEN("Accounts"), -IDI_ACCMGR }, // 34 - { SKINICON_OTHER_SHOWHIDE, LPGEN("Show/Hide"), -IDI_SHOWHIDE }, // 35 - { SKINICON_OTHER_EXIT, LPGEN("Exit"), -IDI_EXIT }, // 36 - { SKINICON_OTHER_MAINMENU, LPGEN("Main menu"), -IDI_MAINMENU }, // 37 - { SKINICON_OTHER_STATUS, LPGEN("Status"), -IDI_ONLINE }, // 38 - { SKINICON_CHAT_JOIN, LPGEN("Join chat"), -IDI_JOINCHAT }, // 39 - { SKINICON_CHAT_LEAVE, LPGEN("Leave chat"), -IDI_LEAVECHAT }, // 40 - { SKINICON_OTHER_GROUP, LPGEN("Move to group"), -IDI_MOVETOGROUP }, // 41 - { SKINICON_OTHER_ON, LPGEN("On"), -IDI_ON }, // 42 - { SKINICON_OTHER_OFF, LPGEN("Off"), -IDI_OFF }, // 43 - { SKINICON_OTHER_LOADEDGRAY, LPGEN("Running core plugin"), -IDI_LOADED_GRAY }, // 44 - { SKINICON_OTHER_NOTLOADEDGRAY, LPGEN("Non-loadable plugin"), -IDI_NOTLOADED_GRAY }, // 45 - { SKINICON_OTHER_FRAME, LPGEN("Frames"), -IDI_FRAME }, // 46 - { SKINICON_AUTH_ADD, LPGEN("Add to list"), -IDI_AUTH_ADD }, // 47 - { SKINICON_AUTH_REQUEST, LPGEN("Request authorization"), -IDI_AUTH_REQUEST }, // 48 - { SKINICON_AUTH_GRANT, LPGEN("Grant authorization"), -IDI_AUTH_GRANT }, // 49 - { SKINICON_AUTH_REVOKE, LPGEN("Revoke authorization"), -IDI_AUTH_REVOKE }, // 50 - { SKINICON_FATAL, LPGEN("Fatal error"), -IDI_MFATAL }, - { SKINICON_ERROR, LPGEN("Error"), -IDI_MERROR }, - { SKINICON_WARNING, LPGEN("Warning"), -IDI_MWARNING }, - { SKINICON_INFORMATION, LPGEN("Information"), -IDI_MINFO }, - - { SKINICON_OTHER_VISIBLE_ALL, LPGEN("Always visible"), -IDI_ALWAYSVIS, 0, LPGEN("Contact list") }, - { SKINICON_OTHER_INVISIBLE_ALL, LPGEN("Always invisible"), -IDI_NEVERVIS, 0, LPGEN("Contact list") }, - { SKINICON_OTHER_STATUS_LOCKED, LPGEN("Locked status"), -IDI_STATUS_LOCKED, 0, LPGEN("Status icons") }, -}; - -static struct StandardIconDescription statusIcons[] = -{ - { ID_STATUS_OFFLINE, LPGEN("Offline"), -IDI_OFFLINE, 0xFFFFFFFF }, - { ID_STATUS_ONLINE, LPGEN("Online"), -IDI_ONLINE, PF2_ONLINE }, - { ID_STATUS_AWAY, LPGEN("Away"), -IDI_AWAY, PF2_SHORTAWAY }, - { ID_STATUS_NA, LPGEN("NA"), -IDI_NA, PF2_LONGAWAY }, - { ID_STATUS_OCCUPIED, LPGEN("Occupied"), -IDI_OCCUPIED, PF2_LIGHTDND }, - { ID_STATUS_DND, LPGEN("DND"), -IDI_DND, PF2_HEAVYDND }, - { ID_STATUS_FREECHAT, LPGEN("Free for chat"), -IDI_FREE4CHAT, PF2_FREECHAT }, - { ID_STATUS_INVISIBLE, LPGEN("Invisible"), -IDI_INVISIBLE, PF2_INVISIBLE }, - { ID_STATUS_ONTHEPHONE, LPGEN("On the phone"), -IDI_ONTHEPHONE, PF2_ONTHEPHONE }, - { ID_STATUS_OUTTOLUNCH, LPGEN("Out to lunch"), -IDI_OUTTOLUNCH, PF2_OUTTOLUNCH } -}; - -const char mainIconsFmt[] = "core_main_"; -const char statusIconsFmt[] = "core_status_"; -const char protoIconsFmt[] = LPGEN("%s icons"); - -#define PROTOCOLS_PREFIX LPGEN("Status icons") -#define GLOBAL_PROTO_NAME "*" - -// load small icon (shared) it's not need to be destroyed - -static HICON LoadSmallIconShared(HINSTANCE hInstance, LPCTSTR lpIconName) -{ - int cx = GetSystemMetrics(SM_CXSMICON); - return (HICON)LoadImage(hInstance, lpIconName, IMAGE_ICON, cx, cx, LR_DEFAULTCOLOR | LR_SHARED); -} - -// load small icon (not shared) it IS NEED to be destroyed -static HICON LoadSmallIcon(HINSTANCE hInstance, LPCTSTR lpIconName) -{ - HICON hIcon = NULL; // icon handle - int index = -(int)lpIconName; - TCHAR filename[MAX_PATH] = {0}; - GetModuleFileName(hInstance, filename, MAX_PATH); - ExtractIconEx(filename, index, NULL, &hIcon, 1); - return hIcon; -} - -// load small icon from hInstance -HICON LoadIconEx(HINSTANCE hInstance, LPCTSTR lpIconName, BOOL bShared) -{ - HICON hResIcon = bShared ? LoadSmallIcon(hInstance, lpIconName) : LoadSmallIconShared(hInstance, lpIconName); - if (!hResIcon) { //Icon not found in hInstance lets try to load it from core - HINSTANCE hCoreInstance = hInst; - if (hCoreInstance != hInstance) - hResIcon = bShared ? LoadSmallIcon(hCoreInstance, lpIconName) : LoadSmallIconShared(hCoreInstance, lpIconName); - } - return hResIcon; -} - -int ImageList_AddIcon_NotShared(HIMAGELIST hIml, LPCTSTR szResource) -{ - HICON hTempIcon = LoadIconEx(hInst, szResource, 0); - int res = ImageList_AddIcon(hIml, hTempIcon); - Safe_DestroyIcon(hTempIcon); - return res; -} - -int ImageList_AddIcon_IconLibLoaded(HIMAGELIST hIml, int iconId) -{ - HICON hIcon = LoadSkinIcon(iconId); - int res = ImageList_AddIcon(hIml, hIcon); - IcoLib_ReleaseIcon(hIcon, 0); - return res; -} - -int ImageList_AddIcon_ProtoIconLibLoaded(HIMAGELIST hIml, const char *szProto, int iconId) -{ - HICON hIcon = LoadSkinProtoIcon(szProto, iconId); - int res = ImageList_AddIcon(hIml, hIcon); - IcoLib_ReleaseIcon(hIcon, 0); - return res; -} - -int ImageList_ReplaceIcon_NotShared(HIMAGELIST hIml, int iIndex, HINSTANCE hInstance, LPCTSTR szResource) -{ - HICON hTempIcon = LoadIconEx(hInstance, szResource, 0); - int res = ImageList_ReplaceIcon(hIml, iIndex, hTempIcon); - Safe_DestroyIcon(hTempIcon); - return res; -} - -int ImageList_ReplaceIcon_IconLibLoaded(HIMAGELIST hIml, int nIndex, HICON hIcon) -{ - int res = ImageList_ReplaceIcon(hIml, nIndex, hIcon); - IcoLib_ReleaseIcon(hIcon, 0); - return res; -} - -void Window_SetIcon_IcoLib(HWND hWnd, int iconId) -{ - SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinIcon(iconId, true)); - SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadSkinIcon(iconId)); -} - -void Window_SetProtoIcon_IcoLib(HWND hWnd, const char *szProto, int iconId) -{ - SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinProtoIcon(szProto, iconId, true)); - SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadSkinProtoIcon(szProto, iconId)); -} - -void Window_FreeIcon_IcoLib(HWND hWnd) -{ - IcoLib_ReleaseIcon((HICON)SendMessage(hWnd, WM_SETICON, ICON_BIG, 0), NULL); - IcoLib_ReleaseIcon((HICON)SendMessage(hWnd, WM_SETICON, ICON_SMALL, 0), NULL); -} - -void Button_SetIcon_IcoLib(HWND hwndDlg, int itemId, int iconId, const char* tooltip) -{ - HWND hWnd = GetDlgItem(hwndDlg, itemId); - SendMessage(hWnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinIcon(iconId)); - SendMessage(hWnd, BUTTONSETASFLATBTN, TRUE, 0); - SendMessage(hWnd, BUTTONADDTOOLTIP, (WPARAM)tooltip, 0); -} - -void Button_FreeIcon_IcoLib(HWND hwndDlg, int itemId) -{ - HICON hIcon = (HICON)SendDlgItemMessage(hwndDlg, itemId, BM_SETIMAGE, IMAGE_ICON, 0); - IcoLib_ReleaseIcon(hIcon, 0); -} - -// -// wParam = szProto -// lParam = status -// -HICON LoadSkinProtoIcon(const char *szProto, int status, bool big) -{ - char iconName[MAX_PATH]; - INT_PTR caps2; - if (szProto == NULL) - caps2 = -1; - else if ((caps2 = CallProtoServiceInt(NULL,szProto, PS_GETCAPS, PFLAGNUM_2, 0)) == CALLSERVICE_NOTFOUND) - caps2 = 0; - - if (IsStatusConnecting(status)) { - mir_snprintf(iconName, SIZEOF(iconName), "%s%d", mainIconsFmt, 7); - return IcoLib_GetIcon(iconName, big); - } - - int statusIndx = -1; - for (int i=0; i < SIZEOF(statusIcons); i++) { - if (statusIcons[i].id == status) { - statusIndx = i; - break; - } } - - if (statusIndx == -1) - return NULL; - - if (!szProto) { - // Only return a protocol specific icon if there is only one protocol - // Otherwise return the global icon. This affects the global status menu mainly. - if (accounts.getCount() == 1) { - // format: core_status_%proto%statusindex - mir_snprintf(iconName, SIZEOF(iconName), "%s%s%d", statusIconsFmt, szProto, statusIndx); - - HICON hIcon = IcoLib_GetIcon(iconName, big); - if (hIcon) - return hIcon; - } - - // format: core_status_%s%d - mir_snprintf(iconName, SIZEOF(iconName), "%s%s%d", statusIconsFmt, GLOBAL_PROTO_NAME, statusIndx); - return IcoLib_GetIcon(iconName, big); - } - - // format: core_status_%s%d - mir_snprintf(iconName, SIZEOF(iconName), "%s%s%d", statusIconsFmt, szProto, statusIndx); - HICON hIcon = IcoLib_GetIcon(iconName, big); - if (hIcon == NULL && (caps2 == 0 || (caps2 & statusIcons[statusIndx].pf2))) { - PROTOACCOUNT *pa = Proto_GetAccount(szProto); - if (pa) { - TCHAR szPath[MAX_PATH], szFullPath[MAX_PATH], *str; - GetModuleFileName(hInst, szPath, MAX_PATH); - - // - // Queried protocol isn't in list, adding - // - TCHAR tszSection[MAX_PATH]; - mir_sntprintf(tszSection, SIZEOF(tszSection), _T(PROTOCOLS_PREFIX)_T("/%s"), pa->tszAccountName); - - SKINICONDESC sid = { 0 }; - sid.section.t = tszSection; - sid.flags = SIDF_ALL_TCHAR; - - str = _tcsrchr(szPath, '\\'); - if (str != NULL) - *str = 0; - mir_sntprintf(szFullPath, SIZEOF(szFullPath), _T("%s\\Icons\\proto_%S.dll"), szPath, pa->szProtoName); - if (GetFileAttributes(szFullPath) != INVALID_FILE_ATTRIBUTES) - sid.defaultFile.t = szFullPath; - else { - mir_sntprintf(szFullPath, SIZEOF(szFullPath), _T("%s\\Plugins\\%S.dll"), szPath, szProto); - if (int(ExtractIconEx(szFullPath, statusIcons[statusIndx].resource_id, NULL, &hIcon, 1)) > 0) { - DestroyIcon(hIcon); - sid.defaultFile.t = szFullPath; - hIcon = NULL; - } - - if (sid.defaultFile.a == NULL) { - if (str != NULL) - *str = '\\'; - sid.defaultFile.t = szPath; - } } - - // - // Add global icons to list - // - - int lowidx, highidx; - if (caps2 == 0) - lowidx = statusIndx, highidx = statusIndx+1; - else - lowidx = 0, highidx = SIZEOF(statusIcons); - - for (int i = lowidx; i < highidx; i++) - if (caps2 == 0 || (caps2 & statusIcons[i].pf2)) { - // format: core_%s%d - mir_snprintf(iconName, SIZEOF(iconName), "%s%s%d", statusIconsFmt, szProto, i); - sid.pszName = iconName; - sid.description.t = cli.pfnGetStatusModeDescription(statusIcons[i].id, 0); - sid.iDefaultIndex = statusIcons[i].resource_id; - IcoLib_AddNewIcon(0, &sid); - } - } - - // format: core_status_%s%d - mir_snprintf(iconName, SIZEOF(iconName), "%s%s%d", statusIconsFmt, szProto, statusIndx); - hIcon = IcoLib_GetIcon(iconName, big); - if (hIcon) - return hIcon; - } - - if (hIcon == NULL) { - mir_snprintf(iconName, SIZEOF(iconName), "%s%s%d", statusIconsFmt, GLOBAL_PROTO_NAME, statusIndx); - hIcon = IcoLib_GetIcon(iconName, big); - } - - return hIcon; -} - -HANDLE GetSkinIconHandle(int idx) -{ - for (int i=0; i < SIZEOF(mainIcons); i++) - if (idx == mainIcons[i].id) - return mainIcons[i].hIcolib; - - return NULL; -} - -char* GetSkinIconName(int idx) -{ - static char szIconName[100]; - - for (int i=0; i < SIZEOF(mainIcons); i++) { - if (idx != mainIcons[i].id) - continue; - - mir_snprintf(szIconName, SIZEOF(szIconName), "%s%d", mainIconsFmt, i); - return szIconName; - } - return NULL; -} - -HICON LoadSkinIcon(int idx, bool big) -{ - // - // Query for global status icons - // - if (idx < SKINICON_EVENT_MESSAGE) { - if (idx >= SIZEOF(statusIcons)) - return NULL; - - return LoadSkinProtoIcon(NULL, statusIcons[ idx ].id, big); - } - - return IcoLib_GetIconByHandle(GetSkinIconHandle(idx), big); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Initializes the icon skin module - -static void convertOneProtocol(char *moduleName, char *iconName) -{ - char *pm = moduleName + mir_strlen(moduleName); - char *pi = iconName + mir_strlen(iconName); - - for (int i=0; i < SIZEOF(statusIcons); i++) { - _itoa(statusIcons[i].id, pm, 10); - - DBVARIANT dbv; - if (!db_get_ts(NULL, "Icons", moduleName, &dbv)) { - _itoa(i, pi, 10); - - db_set_ts(NULL, "SkinIcons", iconName, dbv.ptszVal); - db_free(&dbv); - - db_unset(NULL, "Icons", moduleName); -} } } - -static INT_PTR sttLoadSkinIcon(WPARAM wParam, LPARAM lParam) -{ - switch (lParam) { - case 0: return (INT_PTR)LoadSkinIcon(wParam); - case 1: return (INT_PTR)GetSkinIconHandle(wParam); - case 2: return (INT_PTR)LoadSkinIcon(wParam, true); - case 3: return (INT_PTR)GetSkinIconName(wParam); - } - - return 0; -} - -static INT_PTR sttLoadSkinProtoIcon(WPARAM wParam, LPARAM lParam) -{ - return (INT_PTR)LoadSkinProtoIcon((char*)wParam, (int)lParam, false); -} - -static INT_PTR sttLoadSkinProtoIconBig(WPARAM wParam, LPARAM lParam) -{ - return (INT_PTR)LoadSkinProtoIcon((char*)wParam, (int)lParam, true); -} - -int LoadSkinIcons(void) -{ - int i, j = 0; - char iconName[MAX_PATH], moduleName[MAX_PATH]; - DBVARIANT dbv; - - // - // Perform "1st-time running import" - - for (i=0; i < SIZEOF(mainIcons); i++) { - _itoa(mainIcons[i].id, moduleName, 10); - if (db_get_ts(NULL, "Icons", moduleName, &dbv)) - break; - - mir_snprintf(iconName, SIZEOF(iconName), "%s%d", mainIconsFmt, i); - - db_set_ts(NULL, "SkinIcons", iconName, dbv.ptszVal); - db_free(&dbv); - - db_unset(NULL, "Icons", moduleName); - } - - for (;;) { - // get the next protocol name - moduleName[0] = 'p'; - moduleName[1] = 0; - _itoa(j++, moduleName+1, 100); - if (db_get_ts(NULL, "Icons", moduleName, &dbv)) - break; - - db_unset(NULL, "Icons", moduleName); - - // make old skinicons' prefix - mir_snprintf(moduleName, SIZEOF(moduleName), "%S", dbv.ptszVal); - // make IcoLib's prefix - mir_snprintf(iconName, SIZEOF(iconName), "%s%S", statusIconsFmt, dbv.ptszVal); - - convertOneProtocol(moduleName, iconName); - db_free(&dbv); - } - moduleName[0] = 0; - strncpy_s(iconName, "core_status_" GLOBAL_PROTO_NAME, _TRUNCATE); - convertOneProtocol(moduleName, iconName); - - CreateServiceFunction(MS_SKIN_LOADICON, sttLoadSkinIcon); - CreateServiceFunction(MS_SKIN_LOADPROTOICON, sttLoadSkinProtoIcon); - CreateServiceFunction(MS_SKIN_LOADPROTOICONBIG, sttLoadSkinProtoIconBig); - - TCHAR modulePath[MAX_PATH]; - GetModuleFileName(NULL, modulePath, SIZEOF(modulePath)); - - SKINICONDESC sid = { 0 }; - sid.defaultFile.t = modulePath; - sid.flags = SIDF_PATH_TCHAR; - sid.pszName = iconName; - - // - // Add main icons to list - // - for (i=0; i < SIZEOF(mainIcons); i++) { - mir_snprintf(iconName, SIZEOF(iconName), "%s%d", mainIconsFmt, i); - sid.section.a = mainIcons[i].section == NULL ? LPGEN("Main icons") : (char*)mainIcons[i].section; - sid.description.a = (char*)mainIcons[i].description; - sid.iDefaultIndex = mainIcons[i].resource_id; - mainIcons[i].hIcolib = IcoLib_AddNewIcon(0, &sid); - } - // - // Add global icons to list - // - sid.section.a = PROTOCOLS_PREFIX "/" LPGEN("Global"); - // - // Asterisk is used, to avoid conflict with proto-plugins - // 'coz users can't rename it to name with '*' - for (i=0; i < SIZEOF(statusIcons); i++) { - mir_snprintf(iconName, SIZEOF(iconName), "%s%s%d", statusIconsFmt, GLOBAL_PROTO_NAME, i); - sid.pszName = iconName; - sid.description.a = (char*)statusIcons[i].description; - sid.iDefaultIndex = statusIcons[i].resource_id; - statusIcons[i].hIcolib = IcoLib_AddNewIcon(0, &sid); - } - return 0; -} diff --git a/src/modules/skin/sounds.cpp b/src/modules/skin/sounds.cpp deleted file mode 100644 index 1b95f807ed..0000000000 --- a/src/modules/skin/sounds.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -struct SoundItem -{ - char* name; - TCHAR* ptszSection; - TCHAR* ptszDescription; - TCHAR* ptszTempFile; - int hLangpack; - - __inline TCHAR* getSection() const { return TranslateTH(hLangpack, ptszSection); } - __inline TCHAR* getDescr() const { return TranslateTH(hLangpack, ptszDescription); } - - __inline void clear(void) - { - mir_free(name); - mir_free(ptszSection); - mir_free(ptszDescription); - mir_free(ptszTempFile); - } -}; - -static int CompareSounds(const SoundItem* p1, const SoundItem* p2) -{ - return mir_strcmp(p1->name, p2->name); -} - -static OBJLIST arSounds(10, CompareSounds); - -/////////////////////////////////////////////////////////////////////////////// - -void KillModuleSounds(int hLangpack) -{ - for (int i = arSounds.getCount()-1; i >= 0; i--) { - SoundItem& p = arSounds[i]; - if (p.hLangpack == hLangpack) { - p.clear(); - arSounds.remove(i); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// - -static BOOL bModuleInitialized = FALSE; -static HANDLE hPlayEvent = NULL; - -static INT_PTR ServiceSkinAddNewSound(WPARAM wParam, LPARAM lParam) -{ - SKINSOUNDDESCEX *ssd = (SKINSOUNDDESCEX*)lParam; - if (ssd->cbSize != sizeof(SKINSOUNDDESCEX) || ssd->pszName == NULL || ssd->pszDescription == NULL) - return 1; - - SoundItem* item = new SoundItem; // due to OBJLIST - item->name = mir_strdup(ssd->pszName); - item->ptszTempFile = NULL; - item->hLangpack = (int)wParam; - arSounds.insert(item); - - TCHAR* ptszDefaultFile; - if (ssd->dwFlags & SSDF_UNICODE) { - item->ptszDescription = mir_tstrdup(ssd->ptszDescription); - item->ptszSection = mir_tstrdup((ssd->pszSection != NULL) ? ssd->ptszSection : _T("Other")); - ptszDefaultFile = mir_tstrdup(ssd->ptszDefaultFile); - } - else { - item->ptszDescription = mir_a2t(ssd->pszDescription); - item->ptszSection = mir_a2t((ssd->pszSection != NULL) ? ssd->pszSection : "Other"); - ptszDefaultFile = mir_a2t(ssd->pszDefaultFile); - } - - if (ptszDefaultFile) { - DBVARIANT dbv; - if (db_get_s(NULL, "SkinSounds", item->name, &dbv)) - db_set_ts(NULL, "SkinSounds", item->name, ptszDefaultFile); - else - db_free(&dbv); - mir_free(ptszDefaultFile); - } - - return 0; -} - -static int SkinPlaySoundDefault(WPARAM wParam, LPARAM lParam) -{ - TCHAR* pszFile = (TCHAR*) lParam; - if (pszFile && (db_get_b(NULL, "Skin", "UseSound", 0) || (int)wParam == 1)) - PlaySound(pszFile, NULL, SND_ASYNC | SND_FILENAME | SND_NOSTOP); - - return 0; -} - -static INT_PTR ServiceSkinPlaySoundFile(WPARAM, LPARAM lParam) -{ - TCHAR *ptszFileName = (TCHAR*)lParam; - if (ptszFileName == NULL) - return 1; - - TCHAR tszFull[MAX_PATH]; - PathToAbsoluteT(ptszFileName, tszFull); - NotifyEventHooks(hPlayEvent, 0, (LPARAM)tszFull); - return 0; -} - -static INT_PTR ServiceSkinPlaySound(WPARAM, LPARAM lParam) -{ - char* pszSoundName = (char*)lParam; - if (pszSoundName == NULL) - return 1; - - SoundItem tmp = { pszSoundName }; - int idx = arSounds.getIndex( &tmp ); - if (idx == -1) - return 1; - - if ( db_get_b(NULL, "SkinSoundsOff", pszSoundName, 0)) - return 1; - - DBVARIANT dbv; - if ( db_get_ts(NULL, "SkinSounds", pszSoundName, &dbv) == 0) { - ServiceSkinPlaySoundFile(0, (LPARAM)dbv.ptszVal); - db_free(&dbv); - return 0; - } - return 1; -} - -#define DM_REBUILD_STREE (WM_USER+1) -#define DM_HIDEPANE (WM_USER+2) -#define DM_SHOWPANE (WM_USER+3) -#define DM_CHECKENABLED (WM_USER+4) - -INT_PTR CALLBACK DlgProcSoundOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static HWND hwndTree = NULL; - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - hwndTree = GetDlgItem(hwndDlg, IDC_SOUNDTREE); - SetWindowLongPtr(hwndTree, GWL_STYLE, GetWindowLongPtr(hwndTree, GWL_STYLE)|TVS_NOHSCROLL|TVS_CHECKBOXES); - SendMessage(hwndDlg, DM_HIDEPANE, 0, 0); - SendMessage(hwndDlg, DM_REBUILD_STREE, 0, 0); - TreeView_SetItemState(hwndTree, 0, TVIS_SELECTED, TVIS_SELECTED); - CheckDlgButton(hwndDlg, IDC_ENABLESOUNDS, db_get_b(NULL, "Skin", "UseSound", 0) ? BST_CHECKED : BST_UNCHECKED); - SendMessage(hwndDlg, DM_CHECKENABLED, 0, 0); - return TRUE; - - case DM_REBUILD_STREE: - TreeView_SelectItem(hwndTree, NULL); - ShowWindow(hwndTree, SW_HIDE); - TreeView_DeleteAllItems(hwndTree); - { - TVINSERTSTRUCT tvis; - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_SORT; - tvis.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM; - tvis.item.state = tvis.item.stateMask = TVIS_EXPANDED; - for (int i=0; i < arSounds.getCount(); i++) { - tvis.item.stateMask = TVIS_EXPANDED; - tvis.item.state = TVIS_EXPANDED; - tvis.hParent = FindNamedTreeItemAtRoot(hwndTree, arSounds[i].getSection()); - if (tvis.hParent == NULL) { - tvis.item.lParam = -1; - tvis.item.pszText = arSounds[i].getSection(); - tvis.hParent = tvis.item.hItem = TreeView_InsertItem(hwndTree, &tvis); - tvis.item.stateMask = TVIS_STATEIMAGEMASK; - tvis.item.state = INDEXTOSTATEIMAGEMASK(0); - TreeView_SetItem(hwndTree, &tvis.item); - } - tvis.item.stateMask = TVIS_STATEIMAGEMASK; - tvis.item.state = INDEXTOSTATEIMAGEMASK(!db_get_b(NULL, "SkinSoundsOff", arSounds[i].name, 0)?2:1); - tvis.item.lParam = i; - tvis.item.pszText = arSounds[i].getDescr(); - TreeView_InsertItem(hwndTree, &tvis); - } } - { - TVITEM tvi; - tvi.hItem = TreeView_GetRoot(hwndTree); - while (tvi.hItem != NULL) { - tvi.mask = TVIF_PARAM | TVIF_HANDLE | TVIF_STATE; - TreeView_GetItem(hwndTree, &tvi); - if (tvi.lParam == -1) - TreeView_SetItemState(hwndTree, tvi.hItem, INDEXTOSTATEIMAGEMASK(0), TVIS_STATEIMAGEMASK); - - tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); - } } - - ShowWindow(hwndTree, SW_SHOW); - break; - - case DM_HIDEPANE: - ShowWindow( GetDlgItem(hwndDlg, IDC_SGROUP), SW_HIDE); - ShowWindow( GetDlgItem(hwndDlg, IDC_NAME), SW_HIDE); - ShowWindow( GetDlgItem(hwndDlg, IDC_NAMEVAL), SW_HIDE); - ShowWindow( GetDlgItem(hwndDlg, IDC_SLOC), SW_HIDE); - ShowWindow( GetDlgItem(hwndDlg, IDC_LOCATION), SW_HIDE); - ShowWindow( GetDlgItem(hwndDlg, IDC_CHANGE), SW_HIDE); - ShowWindow( GetDlgItem(hwndDlg, IDC_PREVIEW), SW_HIDE); - ShowWindow( GetDlgItem(hwndDlg, IDC_GETMORE), SW_HIDE); - break; - - case DM_SHOWPANE: - ShowWindow( GetDlgItem(hwndDlg, IDC_SGROUP), SW_SHOW); - ShowWindow( GetDlgItem(hwndDlg, IDC_NAME), SW_SHOW); - ShowWindow( GetDlgItem(hwndDlg, IDC_NAMEVAL), SW_SHOW); - ShowWindow( GetDlgItem(hwndDlg, IDC_SLOC), SW_SHOW); - ShowWindow( GetDlgItem(hwndDlg, IDC_LOCATION), SW_SHOW); - ShowWindow( GetDlgItem(hwndDlg, IDC_CHANGE), SW_SHOW); - ShowWindow( GetDlgItem(hwndDlg, IDC_PREVIEW), SW_SHOW); - ShowWindow( GetDlgItem(hwndDlg, IDC_GETMORE), SW_SHOW); - break; - - case DM_CHECKENABLED: - EnableWindow( GetDlgItem(hwndDlg, IDC_SOUNDTREE), IsDlgButtonChecked(hwndDlg, IDC_ENABLESOUNDS)); - if (BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_ENABLESOUNDS)) - SendMessage(hwndDlg, DM_HIDEPANE, 0, 0); - else if (TreeView_GetSelection(hwndTree) && TreeView_GetParent(hwndTree, TreeView_GetSelection(hwndTree))) - SendMessage(hwndDlg, DM_SHOWPANE, 0, 0); - break; - - case WM_COMMAND: - if (LOWORD(wParam) == IDC_ENABLESOUNDS) - SendMessage(hwndDlg, DM_CHECKENABLED, 0, 0); - - if (LOWORD(wParam) == IDC_PREVIEW) { - HTREEITEM hti = TreeView_GetSelection(hwndTree); - if (hti == NULL) - break; - - TVITEM tvi = { 0 }; - tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT; - tvi.hItem = hti; - if (TreeView_GetItem(hwndTree, &tvi) == FALSE) - break; - if (tvi.lParam == -1) - break; - - if (arSounds[tvi.lParam].ptszTempFile) - NotifyEventHooks(hPlayEvent, 1, (LPARAM)arSounds[tvi.lParam].ptszTempFile); - else { - DBVARIANT dbv; - if (!db_get_ts(NULL, "SkinSounds", arSounds[tvi.lParam].name, &dbv)) { - TCHAR szPathFull[MAX_PATH]; - PathToAbsoluteT(dbv.ptszVal, szPathFull); - NotifyEventHooks(hPlayEvent, 1, (LPARAM)szPathFull); - db_free(&dbv); - } - } - break; - } - - if (LOWORD(wParam) == IDC_CHANGE) { - HTREEITEM hti = TreeView_GetSelection(hwndTree); - if (hti == NULL) - break; - - TVITEM tvi = { 0 }; - tvi.mask = TVIF_HANDLE|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM|TVIF_TEXT; - tvi.hItem = hti; - if (TreeView_GetItem(hwndTree, &tvi) == FALSE) - break; - if (tvi.lParam == -1) - break; - - SoundItem& snd = arSounds[tvi.lParam]; - - TCHAR str[MAX_PATH], strFull[MAX_PATH], strdir[MAX_PATH], filter[MAX_PATH]; - if (snd.ptszTempFile) - _tcsncpy_s(strFull, snd.ptszTempFile, _TRUNCATE); - else { - if (db_get_b(NULL, "SkinSoundsOff", snd.name, 0) == 0) { - DBVARIANT dbv; - if (db_get_ts(NULL, "SkinSounds", snd.name, &dbv) == 0) { - PathToAbsoluteT(dbv.ptszVal, strdir); - db_free(&dbv); - } } } - - _tcsncpy_s(strFull, (snd.ptszTempFile ? snd.ptszTempFile : _T("")), _TRUNCATE); - PathToAbsoluteT(strFull, strdir); - - OPENFILENAME ofn; - memset(&ofn, 0, sizeof(ofn)); - if (GetModuleHandle(_T("bass_interface.dll"))) - mir_sntprintf(filter, SIZEOF(filter), _T("%s (*.wav, *.mp3, *.ogg)%c*.wav;*.mp3;*.ogg%c%s (*)%c*%c"), TranslateT("Sound files"), 0, 0, TranslateT("All files"), 0, 0); - else - mir_sntprintf(filter, SIZEOF(filter), _T("%s (*.wav)%c*.wav%c%s (*)%c*%c"), TranslateT("WAV files"), 0, 0, TranslateT("All files"), 0, 0); - ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; - ofn.hwndOwner = GetParent(hwndDlg); - ofn.hInstance = NULL; - ofn.lpstrFilter = filter; - - TCHAR* slash = _tcsrchr(strdir, '\\'); - if (slash) { - *slash = 0; - ofn.lpstrInitialDir = strdir; - } - - str[0] = 0; - ofn.lpstrFile = str; - ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_LONGNAMES|OFN_NOCHANGEDIR; - ofn.nMaxFile = SIZEOF(str); - ofn.nMaxFileTitle = MAX_PATH; - ofn.lpstrDefExt = _T("wav"); - if (!GetOpenFileName(&ofn)) - break; - - PathToRelativeT(str, strFull); - snd.ptszTempFile = mir_tstrdup(strFull); - SetDlgItemText(hwndDlg, IDC_LOCATION, strFull); - } - if (LOWORD(wParam) == IDC_GETMORE) { - CallService(MS_UTILS_OPENURL, OUF_NEWWINDOW, (LPARAM)"http://miranda-ng.org/addons/category/14"); - break; - } - if (LOWORD(wParam) == IDC_LOCATION) - break; - - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - - case WM_NOTIFY: - switch(((LPNMHDR)lParam)->idFrom) { - case 0: - if (((LPNMHDR)lParam)->code == PSN_APPLY) { - db_set_b(NULL, "Skin", "UseSound", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLESOUNDS)); - - for (int i=0; i < arSounds.getCount(); i++) - if (arSounds[i].ptszTempFile) - db_set_ts(NULL, "SkinSounds", arSounds[i].name, arSounds[i].ptszTempFile); - - TVITEM tvi, tvic; - tvi.hItem = TreeView_GetRoot(hwndTree); - while (tvi.hItem != NULL) { - tvi.mask = TVIF_PARAM | TVIF_HANDLE | TVIF_STATE; - TreeView_GetItem(hwndTree, &tvi); - if (tvi.lParam == -1) { - tvic.hItem = TreeView_GetChild(hwndTree, tvi.hItem); - while (tvic.hItem != NULL) { - tvic.mask = TVIF_PARAM | TVIF_HANDLE | TVIF_STATE; - TreeView_GetItem(hwndTree, &tvic); - if (((tvic.state & TVIS_STATEIMAGEMASK) >> 12 == 2)) - db_unset(NULL, "SkinSoundsOff", arSounds[tvic.lParam].name); - else - db_set_b(NULL, "SkinSoundsOff", arSounds[tvic.lParam].name, 1); - tvic.hItem = TreeView_GetNextSibling(hwndTree, tvic.hItem); - } } - - tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); - } - return TRUE; - } - break; - - case IDC_SOUNDTREE: - switch(((NMHDR*)lParam)->code) { - case TVN_SELCHANGED: - { - NMTREEVIEW *pnmtv = (NMTREEVIEW*)lParam; - TVITEM tvi = pnmtv->itemNew; - - if (tvi.lParam == -1) - SendMessage(hwndDlg, DM_HIDEPANE, 0, 0); - else { - TCHAR buf[256]; - mir_sntprintf(buf, _T("%s: %s"), arSounds[tvi.lParam].getSection(), arSounds[tvi.lParam].getDescr()); - SetDlgItemText(hwndDlg, IDC_NAMEVAL, buf); - if (arSounds[tvi.lParam].ptszTempFile) - SetDlgItemText(hwndDlg, IDC_LOCATION, arSounds[tvi.lParam].ptszTempFile); - else { - DBVARIANT dbv; - if (!db_get_ts(NULL, "SkinSounds", arSounds[tvi.lParam].name, &dbv)) { - SetDlgItemText(hwndDlg, IDC_LOCATION, dbv.ptszVal); - db_free(&dbv); - } - else SetDlgItemText(hwndDlg, IDC_LOCATION, TranslateT("")); - } - SendMessage(hwndDlg, DM_SHOWPANE, 0, 0); - } - } - break; - case TVN_KEYDOWN: - { - NMTVKEYDOWN* ptkd = (NMTVKEYDOWN*)lParam; - if (ptkd && ptkd->wVKey == VK_SPACE && TreeView_GetSelection(ptkd->hdr.hwndFrom)) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - break; - case NM_CLICK: - { - TVHITTESTINFO hti; - hti.pt.x = (short)LOWORD(GetMessagePos()); - hti.pt.y = (short)HIWORD(GetMessagePos()); - ScreenToClient(((LPNMHDR)lParam)->hwndFrom, &hti.pt); - if (TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom, &hti)) - if (hti.flags & (TVHT_ONITEM | TVHT_ONITEMSTATEICON)) - if (TreeView_GetParent(hwndTree, hti.hItem) != NULL) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - break; - } - } - break; - - case WM_DESTROY: - ImageList_Destroy(TreeView_GetImageList(hwndTree, TVSIL_STATE)); - break; - } - return FALSE; -} - -static int SkinOptionsInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.position = -200000000; - odp.hInstance = hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_SOUND); - odp.pszTitle = LPGEN("Sounds"); - odp.pfnDlgProc = DlgProcSoundOpts; - odp.flags = ODPF_BOLDGROUPS; - Options_AddPage(wParam, &odp); - return 0; -} - -static int SkinSystemModulesLoaded(WPARAM, LPARAM) -{ - HookEvent(ME_OPT_INITIALISE, SkinOptionsInit); - return 0; -} - -int LoadSkinSounds(void) -{ - bModuleInitialized = TRUE; - - CreateServiceFunction("Skin/Sounds/AddNew", ServiceSkinAddNewSound); - CreateServiceFunction(MS_SKIN_PLAYSOUND, ServiceSkinPlaySound); - CreateServiceFunction(MS_SKIN_PLAYSOUNDFILE, ServiceSkinPlaySoundFile); - HookEvent(ME_SYSTEM_MODULESLOADED, SkinSystemModulesLoaded); - hPlayEvent = CreateHookableEvent(ME_SKIN_PLAYINGSOUND); - SetHookDefaultForHookableEvent(hPlayEvent, SkinPlaySoundDefault); - return 0; -} - -void UnloadSkinSounds(void) -{ - for (int i=0; i < arSounds.getCount(); i++) - arSounds[i].clear(); -} diff --git a/src/modules/srmm/statusicon.cpp b/src/modules/srmm/statusicon.cpp deleted file mode 100644 index 01e604ff12..0000000000 --- a/src/modules/srmm/statusicon.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -struct StatusIconChild : public MZeroedObject -{ - ~StatusIconChild() - { - SafeDestroyIcon(hIcon); - SafeDestroyIcon(hIconDisabled); - mir_free(tszTooltip); - } - - MCONTACT hContact; - HICON hIcon, hIconDisabled; - int flags; - TCHAR *tszTooltip; - - void SafeDestroyIcon(HICON hIcon) - { - if (hIcon == NULL) - return; - - if (!IcoLib_IsManaged(hIcon)) - ::DestroyIcon(hIcon); - } -}; - -struct StatusIconMain : public MZeroedObject -{ - StatusIconMain() : - arChildren(3, NumericKeySortT) - {} - - ~StatusIconMain() - { - mir_free(sid.szModule); - mir_free(sid.szTooltip); - } - - StatusIconData sid; - - int hLangpack; - OBJLIST arChildren; -}; - -static int CompareIcons(const StatusIconMain *p1, const StatusIconMain *p2) -{ - int res = mir_strcmp(p1->sid.szModule, p2->sid.szModule); - if (res) - return res; - - return p1->sid.dwId - p2->sid.dwId; -} - -static OBJLIST arIcons(3, CompareIcons); - -static HANDLE hHookIconsChanged; - -INT_PTR ModifyStatusIcon(WPARAM hContact, LPARAM lParam) -{ - StatusIconData *sid = (StatusIconData *)lParam; - if (sid == NULL || sid->cbSize != sizeof(StatusIconData)) - return 1; - - StatusIconMain *p = arIcons.find((StatusIconMain*)sid); - if (p == NULL) - return 1; - - if (hContact == NULL) { - mir_free(p->sid.szModule); - mir_free(p->sid.szTooltip); - memcpy(&p->sid, sid, sizeof(p->sid)); - p->sid.szModule = mir_strdup(sid->szModule); - p->sid.tszTooltip = (sid->flags & MBF_UNICODE) ? mir_u2t(sid->wszTooltip) : mir_a2t(sid->szTooltip); - - NotifyEventHooks(hHookIconsChanged, NULL, (LPARAM)p); - return 0; - } - - StatusIconChild *pc = p->arChildren.find((StatusIconChild*)&hContact); - if (pc == NULL) { - pc = new StatusIconChild(); - pc->hContact = hContact; - p->arChildren.insert(pc); - } - else pc->SafeDestroyIcon(pc->hIcon); - - pc->flags = sid->flags; - pc->hIcon = sid->hIcon; - pc->hIconDisabled = sid->hIconDisabled; - - mir_free(pc->tszTooltip); - pc->tszTooltip = (sid->flags & MBF_UNICODE) ? mir_u2t(sid->wszTooltip) : mir_a2t(sid->szTooltip); - - NotifyEventHooks(hHookIconsChanged, hContact, (LPARAM)p); - return 0; -} - -static INT_PTR AddStatusIcon(WPARAM wParam, LPARAM lParam) -{ - StatusIconData *sid = (StatusIconData *)lParam; - if (sid == NULL || sid->cbSize != sizeof(StatusIconData)) - return 1; - - StatusIconMain *p = arIcons.find((StatusIconMain*)sid); - if (p != NULL) - return ModifyStatusIcon(0, lParam); - - p = new StatusIconMain; - memcpy(&p->sid, sid, sizeof(p->sid)); - p->hLangpack = (int)wParam; - p->sid.szModule = mir_strdup(sid->szModule); - if (sid->flags & MBF_UNICODE) - p->sid.tszTooltip = mir_u2t(sid->wszTooltip); - else - p->sid.tszTooltip = mir_a2t(sid->szTooltip); - arIcons.insert(p); - - NotifyEventHooks(hHookIconsChanged, NULL, (LPARAM)p); - return 0; -} - -static INT_PTR RemoveStatusIcon(WPARAM wParam, LPARAM lParam) -{ - StatusIconData *sid = (StatusIconData *)lParam; - if (sid == NULL || sid->cbSize != sizeof(StatusIconData)) - return 1; - - StatusIconMain *p = arIcons.find((StatusIconMain*)sid); - if (p == NULL) - return 1; - - arIcons.remove(p); - return 0; -} - -static INT_PTR GetNthIcon(WPARAM wParam, LPARAM lParam) -{ - static StatusIconData res; - - for (int i=arIcons.getCount()-1, nVis = 0; i >= 0; i--) { - StatusIconMain &p = arIcons[i]; - - StatusIconChild *pc = p.arChildren.find((StatusIconChild*)&wParam); - if (pc) { - if (pc->flags & MBF_HIDDEN) - continue; - } - else if (p.sid.flags & MBF_HIDDEN) - continue; - - if (nVis == (int)lParam) { - memcpy(&res, &p, sizeof(res)); - if (pc) { - if (pc->hIcon) res.hIcon = pc->hIcon; - if (pc->hIconDisabled) - res.hIconDisabled = pc->hIconDisabled; - else if (pc->hIcon) - res.hIconDisabled = pc->hIcon; - if (pc->tszTooltip) res.tszTooltip = pc->tszTooltip; - res.flags = pc->flags; - } - res.tszTooltip = TranslateTH(p.hLangpack, res.tszTooltip); - return (INT_PTR)&res; - } - nVis++; - } - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void KillModuleSrmmIcons(int hLangpack) -{ - for (int i=arIcons.getCount()-1; i >= 0; i--) { - StatusIconMain &p = arIcons[i]; - if (p.hLangpack == hLangpack) - arIcons.remove(i); - } -} - -int LoadSrmmModule() -{ - CreateServiceFunction("MessageAPI/AddIcon", AddStatusIcon); - CreateServiceFunction(MS_MSG_REMOVEICON, RemoveStatusIcon); - CreateServiceFunction(MS_MSG_MODIFYICON, ModifyStatusIcon); - CreateServiceFunction("MessageAPI/GetNthIcon", GetNthIcon); - - hHookIconsChanged = CreateHookableEvent(ME_MSG_ICONSCHANGED); - return 0; -} - -void UnloadSrmmModule() -{ - arIcons.destroy(); - NotifyEventHooks(hHookIconsChanged, NULL, NULL); - DestroyHookableEvent(hHookIconsChanged); -} diff --git a/src/modules/utils/colourpicker.cpp b/src/modules/utils/colourpicker.cpp deleted file mode 100644 index e93a1c90b7..0000000000 --- a/src/modules/utils/colourpicker.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -static LRESULT CALLBACK ColourPickerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch(message) { - case WM_CREATE: - SetWindowLongPtr(hwnd, 0, 0); - SetWindowLongPtr(hwnd, sizeof(COLORREF), 0); - break; - case CPM_SETDEFAULTCOLOUR: - SetWindowLongPtr(hwnd, sizeof(COLORREF), lParam); - break; - case CPM_GETDEFAULTCOLOUR: - return GetWindowLongPtr(hwnd, sizeof(COLORREF)); - case CPM_SETCOLOUR: - SetWindowLongPtr(hwnd, 0, lParam); - InvalidateRect(hwnd, NULL, FALSE); - break; - case CPM_GETCOLOUR: - return GetWindowLongPtr(hwnd, 0); - case WM_LBUTTONUP: - { - CHOOSECOLOR cc = {0}; - COLORREF custColours[16] = {0}; - custColours[0] = GetWindowLongPtr(hwnd, sizeof(COLORREF)); - cc.lStructSize = sizeof(CHOOSECOLOR); - cc.hwndOwner = hwnd; - cc.hInstance = (HWND)hInst; - cc.rgbResult = GetWindowLongPtr(hwnd, 0); - cc.lpCustColors = custColours; - cc.Flags = CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT; - if (ChooseColor(&cc)) { - SetWindowLongPtr(hwnd, 0, cc.rgbResult); - SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwnd), CPN_COLOURCHANGED), (LPARAM)hwnd); - InvalidateRect(hwnd, NULL, FALSE); - } - break; - } - case WM_ENABLE: - InvalidateRect(hwnd, NULL, FALSE); - break; - case WM_NCPAINT: - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC hdc1; - RECT rc; - HBRUSH hBrush; - - hdc1 = BeginPaint(hwnd, &ps); - GetClientRect(hwnd, &rc); - DrawEdge(hdc1, &rc, EDGE_ETCHED, BF_RECT); - InflateRect(&rc, -2, -2); - if (IsWindowEnabled(hwnd)) - hBrush = CreateSolidBrush(GetWindowLongPtr(hwnd, 0)); - else - hBrush = CreateHatchBrush(HS_BDIAGONAL, GetSysColor(COLOR_GRAYTEXT)); - SetBkColor(hdc1, GetSysColor(COLOR_BTNFACE)); - FillRect(hdc1, &rc, hBrush); - DeleteObject(hBrush); - EndPaint(hwnd, &ps); - break; - } - } - return DefWindowProc(hwnd, message, wParam, lParam); -} - -int InitColourPicker(void) -{ - WNDCLASS wcl; - - wcl.lpfnWndProc = ColourPickerWndProc; - wcl.cbClsExtra = 0; - wcl.cbWndExtra = sizeof(COLORREF)*2; - wcl.hInstance = hInst; - wcl.hCursor = NULL; - wcl.lpszClassName = _T(WNDCLASS_COLOURPICKER); - wcl.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); - wcl.hIcon = NULL; - wcl.lpszMenuName = NULL; - wcl.style = CS_HREDRAW|CS_VREDRAW|CS_GLOBALCLASS; - RegisterClass(&wcl); - return 0; -} diff --git a/src/modules/utils/enterstring.cpp b/src/modules/utils/enterstring.cpp deleted file mode 100644 index c7fd4b4001..0000000000 --- a/src/modules/utils/enterstring.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -struct EnterStringFormParam : public ENTER_STRING -{ - int idcControl; - int height; -}; - -static int UIEmulateBtnClick(HWND hwndDlg, UINT idcButton) -{ - if (IsWindowEnabled(GetDlgItem(hwndDlg, idcButton))) - PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(idcButton, BN_CLICKED), (LPARAM)GetDlgItem(hwndDlg, idcButton)); - return 0; -} - -static int sttEnterStringResizer(HWND, LPARAM, UTILRESIZECONTROL *urc) -{ - switch (urc->wId) { - case IDC_TXT_MULTILINE: - case IDC_TXT_COMBO: - case IDC_TXT_RICHEDIT: - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; - - case IDOK: - case IDCANCEL: - return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM; - } - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; -} - -static void ComboLoadRecentStrings(HWND hwndDlg, EnterStringFormParam *pForm) -{ - for (int i = 0; i < pForm->recentCount; i++) { - char setting[MAXMODULELABELLENGTH]; - mir_snprintf(setting, "%s%d", pForm->szDataPrefix, i); - ptrT tszRecent(db_get_tsa(NULL, pForm->szModuleName, setting)); - if (tszRecent != NULL) - SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_ADDSTRING, 0, tszRecent); - } - - if (!SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_GETCOUNT, 0, 0)) - SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_ADDSTRING, 0, (LPARAM)_T("")); -} - -static void ComboAddRecentString(HWND hwndDlg, EnterStringFormParam *pForm) -{ - TCHAR *string = pForm->ptszResult; - if (!string || !*string) - return; - - if (SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_FINDSTRING, (WPARAM)-1, (LPARAM)string) != CB_ERR) - return; - - int id; - SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_ADDSTRING, 0, (LPARAM)string); - if ((id = SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_FINDSTRING, (WPARAM)-1, (LPARAM)_T(""))) != CB_ERR) - SendDlgItemMessage(hwndDlg, pForm->idcControl, CB_DELETESTRING, id, 0); - - id = db_get_b(NULL, pForm->szModuleName, pForm->szDataPrefix, 0); - char setting[MAXMODULELABELLENGTH]; - mir_snprintf(setting, "%s%d", pForm->szDataPrefix, id); - db_set_ts(NULL, pForm->szModuleName, setting, string); - db_set_b(NULL, pForm->szModuleName, pForm->szDataPrefix, (id + 1) % pForm->idcControl); -} - -static INT_PTR CALLBACK sttEnterStringDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - EnterStringFormParam *params = (EnterStringFormParam *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIconBig(SKINICON_OTHER_RENAME)); - SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_RENAME)); - params = (EnterStringFormParam *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)params); - SetWindowText(hwndDlg, params->caption); - { - RECT rc; GetWindowRect(hwndDlg, &rc); - switch (params->type) { - case ESF_PASSWORD: - params->idcControl = IDC_TXT_PASSWORD; - params->height = rc.bottom - rc.top; - break; - - case ESF_MULTILINE: - params->idcControl = IDC_TXT_MULTILINE; - params->height = 0; - rc.bottom += (rc.bottom - rc.top) * 2; - SetWindowPos(hwndDlg, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOREPOSITION); - break; - - case ESF_COMBO: - params->idcControl = IDC_TXT_COMBO; - params->height = rc.bottom - rc.top; - if (params->szDataPrefix && params->recentCount) - ComboLoadRecentStrings(hwndDlg, params); - break; - - case ESF_RICHEDIT: - params->idcControl = IDC_TXT_RICHEDIT; - SendDlgItemMessage(hwndDlg, IDC_TXT_RICHEDIT, EM_AUTOURLDETECT, TRUE, 0); - SendDlgItemMessage(hwndDlg, IDC_TXT_RICHEDIT, EM_SETEVENTMASK, 0, ENM_LINK); - params->height = 0; - rc.bottom += (rc.bottom - rc.top) * 2; - SetWindowPos(hwndDlg, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOREPOSITION); - break; - } - } - ShowWindow(GetDlgItem(hwndDlg, params->idcControl), SW_SHOW); - if (params->ptszInitVal) - SetDlgItemText(hwndDlg, params->idcControl, params->ptszInitVal); - - if (params->szDataPrefix) - Utils_RestoreWindowPosition(hwndDlg, NULL, params->szModuleName, params->szDataPrefix); - - SetTimer(hwndDlg, 1000, 50, NULL); - - if (params->timeout > 0) { - SetTimer(hwndDlg, 1001, 1000, NULL); - TCHAR buf[128]; - mir_sntprintf(buf, TranslateT("OK (%d)"), params->timeout); - SetDlgItemText(hwndDlg, IDOK, buf); - } - - return TRUE; - - case WM_DESTROY: - Window_FreeIcon_IcoLib(hwndDlg); - break; - - case WM_TIMER: - switch (wParam) { - case 1000: - KillTimer(hwndDlg, 1000); - EnableWindow(GetParent(hwndDlg), TRUE); - break; - - case 1001: - TCHAR buf[128]; - mir_sntprintf(buf, TranslateT("OK (%d)"), --params->timeout); - SetDlgItemText(hwndDlg, IDOK, buf); - - if (params->timeout < 0) { - KillTimer(hwndDlg, 1001); - UIEmulateBtnClick(hwndDlg, IDOK); - } - } - return TRUE; - - case WM_SIZE: - { - UTILRESIZEDIALOG urd = { 0 }; - urd.cbSize = sizeof(urd); - urd.hInstance = hInst; - urd.hwndDlg = hwndDlg; - urd.lpTemplate = MAKEINTRESOURCEA(IDD_ENTER_STRING); - urd.pfnResizer = sttEnterStringResizer; - CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); - } - break; - - case WM_GETMINMAXINFO: - { - LPMINMAXINFO lpmmi = (LPMINMAXINFO)lParam; - if (params && params->height) - lpmmi->ptMaxSize.y = lpmmi->ptMaxTrackSize.y = params->height; - } - break; - - case WM_NOTIFY: - { - ENLINK *param = (ENLINK *)lParam; - if (param->nmhdr.idFrom != IDC_TXT_RICHEDIT) break; - if (param->nmhdr.code != EN_LINK) break; - if (param->msg != WM_LBUTTONUP) break; - - CHARRANGE sel; - SendMessage(param->nmhdr.hwndFrom, EM_EXGETSEL, 0, (LPARAM)& sel); - if (sel.cpMin != sel.cpMax) break; // allow link selection - - TEXTRANGE tr; - tr.chrg = param->chrg; - tr.lpstrText = (TCHAR *)mir_alloc(sizeof(TCHAR)*(tr.chrg.cpMax - tr.chrg.cpMin + 2)); - SendMessage(param->nmhdr.hwndFrom, EM_GETTEXTRANGE, 0, (LPARAM)& tr); - - char *tmp = mir_t2a(tr.lpstrText); - CallService(MS_UTILS_OPENURL, OUF_NEWWINDOW, (LPARAM)tmp); - mir_free(tmp); - mir_free(tr.lpstrText); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_TXT_MULTILINE: - case IDC_TXT_RICHEDIT: - if ((HIWORD(wParam) != EN_SETFOCUS) && (HIWORD(wParam) != EN_KILLFOCUS)) { - SetDlgItemText(hwndDlg, IDOK, TranslateT("OK")); - KillTimer(hwndDlg, 1001); - } - break; - - case IDC_TXT_COMBO: - if ((HIWORD(wParam) != CBN_SETFOCUS) && (HIWORD(wParam) != CBN_KILLFOCUS)) { - SetDlgItemText(hwndDlg, IDOK, TranslateT("OK")); - KillTimer(hwndDlg, 1001); - } - break; - - case IDCANCEL: - if (params->szDataPrefix) - Utils_SaveWindowPosition(hwndDlg, NULL, params->szModuleName, params->szDataPrefix); - - EndDialog(hwndDlg, 0); - break; - - case IDOK: - HWND hWnd = GetDlgItem(hwndDlg, params->idcControl); - int len = GetWindowTextLength(hWnd)+1; - params->ptszResult = (LPTSTR)mir_alloc(sizeof(TCHAR)*len); - GetWindowText(hWnd, params->ptszResult, len); - - if ((params->type == ESF_COMBO) && params->szDataPrefix && params->recentCount) - ComboAddRecentString(hwndDlg, params); - if (params->szDataPrefix) - Utils_SaveWindowPosition(hwndDlg, NULL, params->szModuleName, params->szDataPrefix); - - EndDialog(hwndDlg, 1); - break; - } - } - - return FALSE; -} - -INT_PTR __cdecl svcEnterString(WPARAM, LPARAM lParam) -{ - ENTER_STRING *pForm = (ENTER_STRING*)lParam; - if (pForm == NULL || pForm->cbSize != sizeof(ENTER_STRING)) - return FALSE; - - EnterStringFormParam param; - memcpy(¶m, pForm, sizeof(ENTER_STRING)); - if (!DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ENTER_STRING), GetForegroundWindow(), sttEnterStringDlgProc, LPARAM(¶m))) - return FALSE; - - pForm->ptszResult = param.ptszResult; - return TRUE; -} diff --git a/src/modules/utils/hyperlink.cpp b/src/modules/utils/hyperlink.cpp deleted file mode 100644 index 12e2b2790e..0000000000 --- a/src/modules/utils/hyperlink.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -struct HyperlinkWndData { - HFONT hEnableFont, hDisableFont; - RECT rcText; - COLORREF enableColor, disableColor, focusColor; - BYTE flags; /* see HLKF_* */ -}; - -/* flags */ -#define HLKF_HASENABLECOLOR 0x1 /* dat->enableColor is not system default */ -#define HLKF_HASDISABLECOLOR 0x2 /* dat->disableColor is not system default */ - -/* internal messages */ -#define HLK_MEASURETEXT (WM_USER+1) -#define HLK_INVALIDATE (WM_USER+2) - -static LRESULT CALLBACK HyperlinkWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - struct HyperlinkWndData *dat = (struct HyperlinkWndData*)GetWindowLongPtr(hwnd, 0); - switch(msg) { - case WM_NCCREATE: - dat = (struct HyperlinkWndData*)mir_calloc(sizeof(struct HyperlinkWndData)); - if (dat == NULL) return FALSE; /* fail creation */ - SetWindowLongPtr(hwnd, 0, (LONG_PTR)dat); /* always succeeds */ - /* fall thru */ - case WM_SYSCOLORCHANGE: - if (!(dat->flags&HLKF_HASENABLECOLOR)) { - if (GetSysColorBrush(COLOR_HOTLIGHT) == NULL) dat->enableColor = RGB(0, 0, 255); - else dat->enableColor = GetSysColor(COLOR_HOTLIGHT); - dat->focusColor = RGB(GetRValue(dat->enableColor) / 2, GetGValue(dat->enableColor) / 2, GetBValue(dat->enableColor) / 2); - } - if (!(dat->flags&HLKF_HASDISABLECOLOR)) - dat->disableColor = GetSysColor(COLOR_GRAYTEXT); - break; - - case WM_SETFOCUS: - case WM_KILLFOCUS: - RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE); - break; - case WM_MOUSEACTIVATE: - SetFocus(hwnd); - return MA_ACTIVATE; - case WM_GETDLGCODE: - { - if (lParam) - { - MSG *msg = (MSG *) lParam; - if (msg->message == WM_KEYDOWN) - { - if (msg->wParam == VK_TAB) - return 0; - if (msg->wParam == VK_ESCAPE) - return 0; - } else - if (msg->message == WM_CHAR) - { - if (msg->wParam == '\t') - return 0; - if (msg->wParam == 27) - return 0; - } - } - return DLGC_WANTMESSAGE; - } - - case WM_KEYDOWN: - { - switch (wParam) - { - case VK_SPACE: - case VK_RETURN: - SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwnd), STN_CLICKED), (LPARAM)hwnd); - break; - } - return 0; - } - - case WM_LBUTTONDOWN: - { POINT pt; - POINTSTOPOINT(pt, MAKEPOINTS(lParam)); - if (!PtInRect(&dat->rcText, pt)) break; - SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwnd), STN_CLICKED), (LPARAM)hwnd); - return 0; - } - case WM_SETFONT: - { LOGFONT lf; - HFONT hFont; - if ((HFONT)wParam == NULL) { /* use default system color */ - dat->hEnableFont = dat->hDisableFont = NULL; - return 0; - } - if (GetObject((HFONT)wParam, sizeof(lf), &lf)) { - lf.lfUnderline = 1; - hFont = CreateFontIndirect(&lf); - if (hFont != NULL) { - dat->hEnableFont = hFont; - dat->hDisableFont = (HFONT)wParam; - if (LOWORD(lParam)) SendMessage(hwnd, HLK_INVALIDATE, 0, 0); - SendMessage(hwnd, HLK_MEASURETEXT, 0, 0); - } - } - return 0; - } - case WM_ERASEBKGND: - return TRUE; - case WM_ENABLE: - case HLK_INVALIDATE: - { RECT rcWnd; - POINT pt; - HWND hwndParent; - if (!GetWindowRect(hwnd, &rcWnd)) break; - pt.x = rcWnd.left; - pt.y = rcWnd.top; - hwndParent = GetParent(hwnd); - if (hwndParent == NULL) hwndParent = hwnd; - if (!ScreenToClient(hwndParent, &pt)) break; - rcWnd.right = pt.x+(rcWnd.right-rcWnd.left); - rcWnd.bottom = pt.y+(rcWnd.bottom-rcWnd.top); - rcWnd.left = pt.x; - rcWnd.top = pt.y; - InvalidateRect(hwndParent, &rcWnd, TRUE); - return 0; - } - case WM_GETFONT: - return (LRESULT)dat->hDisableFont; - case WM_CREATE: - case HLK_MEASURETEXT: - { TCHAR szText[256]; - if (!GetWindowText(hwnd, szText, SIZEOF(szText))) return 0; - lParam = (LPARAM)szText; - /* fall thru */ - case WM_SETTEXT: - { HFONT hPrevFont = NULL; - SIZE textSize; - RECT rc; - HDC hdc; - LONG style; - BOOL fMeasured = FALSE; - hdc = GetDC(hwnd); - if (hdc == NULL) return 0; /* text change failed */ - if (dat->hEnableFont != NULL) hPrevFont = (HFONT)SelectObject(hdc, dat->hEnableFont); - if (dat->hEnableFont == NULL || hPrevFont != NULL) /* select failed? */ - if (GetTextExtentPoint32(hdc, (TCHAR*)lParam, (int)mir_tstrlen((TCHAR*)lParam), &textSize)) - if (GetClientRect(hwnd, &rc)) { - dat->rcText.top = 0; - dat->rcText.bottom = dat->rcText.top+textSize.cy; - style = GetWindowLongPtr(hwnd, GWL_STYLE); - if (style&SS_CENTER) dat->rcText.left = (rc.right-textSize.cx)/2; - else if (style&SS_RIGHT) dat->rcText.left = rc.right-textSize.cx; - else dat->rcText.left = 0; - dat->rcText.right = dat->rcText.left+textSize.cx; - fMeasured = TRUE; - } - if (dat->hEnableFont != NULL && hPrevFont != NULL) SelectObject(hdc, hPrevFont); - ReleaseDC(hwnd, hdc); - if (!fMeasured) return 0; /* text change failed */ - SendMessage(hwnd, HLK_INVALIDATE, 0, 0); - break; - }} - case WM_SETCURSOR: - { POINT pt; - HCURSOR hCursor; - if (!GetCursorPos(&pt)) return FALSE; - if (!ScreenToClient(hwnd, &pt)) return FALSE; - if (PtInRect(&dat->rcText, pt)) { - hCursor = (HCURSOR)GetClassLongPtr(hwnd, GCLP_HCURSOR); - if (hCursor == NULL) hCursor = LoadCursor(NULL, IDC_HAND); /* Win2000+ */ - } - else hCursor = LoadCursor(NULL, IDC_ARROW); - SetCursor(hCursor); - return TRUE; - } - case HLK_SETENABLECOLOUR: - { COLORREF prevColor = dat->enableColor; - dat->enableColor = (COLORREF)wParam; - dat->focusColor = RGB(GetRValue(dat->enableColor) / 2, GetGValue(dat->enableColor) / 2, GetBValue(dat->enableColor) / 2); - dat->flags|=HLKF_HASENABLECOLOR; - return (LRESULT)prevColor; - } - case HLK_SETDISABLECOLOUR: - { COLORREF prevColor = dat->disableColor; - dat->disableColor = (COLORREF)wParam; - dat->flags|=HLKF_HASDISABLECOLOR; - return (LRESULT)prevColor; - } - case WM_NCPAINT: - return 0; - case WM_PAINT: - { HFONT hPrevFont; - RECT rc; - TCHAR szText[256]; - UINT alignFlag; - COLORREF textColor; - PAINTSTRUCT ps; - HDC hdc; - - hdc = BeginPaint(hwnd, &ps); - if (hdc != NULL) { - if (IsWindowEnabled(hwnd)) { - hPrevFont = (HFONT)SelectObject(hdc, dat->hEnableFont); - textColor = (GetFocus() == hwnd) ? dat->focusColor : dat->enableColor; - } else { - hPrevFont = (HFONT)SelectObject(hdc, dat->hDisableFont); - textColor = dat->disableColor; - } - if (GetClientRect(hwnd, &rc) && GetWindowText(hwnd, szText, SIZEOF(szText))) { - BOOL fSmoothing; - UINT fSmoothingType; - SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fSmoothing, 0); - SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &fSmoothingType, 0); - if (fSmoothing && fSmoothingType == FE_FONTSMOOTHINGCLEARTYPE) - DrawThemeParentBackground(hwnd, hdc, &rc); - SetBkMode(hdc, TRANSPARENT); - SetTextColor(hdc, textColor); - alignFlag = (GetWindowLongPtr(hwnd, GWL_STYLE)&(SS_CENTER|SS_RIGHT|SS_LEFT)); - DrawText(hdc, szText, -1, &rc, alignFlag|DT_NOPREFIX|DT_SINGLELINE|DT_TOP); - } - if (hPrevFont != NULL) SelectObject(hdc, hPrevFont); - EndPaint(hwnd, &ps); - } - return 0; - } - case WM_NCDESTROY: - if (dat->hEnableFont != NULL) DeleteObject(dat->hEnableFont); - mir_free(dat); - break; - } - return DefWindowProc(hwnd, msg, wParam, lParam); -} - -int InitHyperlink(void) -{ - WNDCLASS wcl; - - wcl.lpfnWndProc = HyperlinkWndProc; - wcl.cbClsExtra = 0; - wcl.cbWndExtra = sizeof(struct HyperlinkWndData*); - wcl.hInstance = hInst; - wcl.hCursor = NULL; - wcl.lpszClassName = WNDCLASS_HYPERLINK; - wcl.hbrBackground = NULL; - wcl.hIcon = NULL; - wcl.lpszMenuName = NULL; - wcl.style = CS_HREDRAW|CS_VREDRAW|CS_GLOBALCLASS|CS_PARENTDC; - RegisterClass(&wcl); /* automatically unregistered on exit */ - return 0; -} diff --git a/src/modules/utils/imgconv.cpp b/src/modules/utils/imgconv.cpp deleted file mode 100644 index 8bbbb308cb..0000000000 --- a/src/modules/utils/imgconv.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -typedef DWORD ARGB; - -void InitBitmapInfo(BITMAPINFO &bmi, const SIZE &size) -{ - memset(&bmi, 0, sizeof(BITMAPINFO)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biBitCount = 32; - - bmi.bmiHeader.biWidth = size.cx; - bmi.bmiHeader.biHeight = size.cy; -} - -void ConvertToPARGB32(HDC hdc, ARGB *pargb, HBITMAP hbmp, SIZE& sizImage, int cxRow) -{ - BITMAPINFO bmi; - InitBitmapInfo(bmi, sizImage); - - void *pvBits = malloc(sizImage.cx * 4 * sizImage.cy); - if (GetDIBits(hdc, hbmp, 0, bmi.bmiHeader.biHeight, pvBits, &bmi, DIB_RGB_COLORS) == bmi.bmiHeader.biHeight) { - ULONG cxDelta = cxRow - bmi.bmiHeader.biWidth; - ARGB *pargbMask = (ARGB *)pvBits; - - for (ULONG y = bmi.bmiHeader.biHeight + 1; --y;) { - for (ULONG x = bmi.bmiHeader.biWidth + 1; --x;) { - if (*pargbMask++) { - // transparent pixel - *pargb++=0; - } - else { - // opaque pixel - *pargb++ |= 0xFF000000; - } - } - - pargb += cxDelta; - } - } - free(pvBits); -} - -bool HasAlpha(ARGB *pargb, SIZE& sizImage, int cxRow) -{ - ULONG cxDelta = cxRow - sizImage.cx; - for (ULONG y = sizImage.cy; y--;) { - for (ULONG x = sizImage.cx; x--;) { - if (*pargb++ & 0xFF000000) - return true; - } - pargb += cxDelta; - } - - return false; -} - -void ConvertBufferToPARGB32(HANDLE hPaintBuffer, HDC hdc, HICON hIcon, SIZE& sizIcon) -{ - RGBQUAD *prgbQuad; - int cxRow; - HRESULT hr = getBufferedPaintBits(hPaintBuffer, &prgbQuad, &cxRow); - if (SUCCEEDED(hr)) { - ARGB *pargb = (ARGB *)prgbQuad; - if (!HasAlpha(pargb, sizIcon, cxRow)) { - ICONINFO info; - if (GetIconInfo(hIcon, &info)) { - if (info.hbmMask) - ConvertToPARGB32(hdc, pargb, info.hbmMask, sizIcon, cxRow); - - DeleteObject(info.hbmColor); - DeleteObject(info.hbmMask); - } - } - } -} - -HBITMAP ConvertIconToBitmap(HICON hicon, HIMAGELIST hIml, int iconId) -{ - SIZE sizIcon; - sizIcon.cx = GetSystemMetrics(SM_CXSMICON); - sizIcon.cy = GetSystemMetrics(SM_CYSMICON); - - RECT rcIcon = { 0, 0, sizIcon.cx, sizIcon.cy }; - - HDC hdc = CreateCompatibleDC(NULL); - - BITMAPINFO bmi; - InitBitmapInfo(bmi, sizIcon); - - HBITMAP hbmp = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, NULL, NULL, 0); - HBITMAP hbmpOld = (HBITMAP)SelectObject(hdc, hbmp); - - BLENDFUNCTION bfAlpha = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; - BP_PAINTPARAMS paintParams = {0}; - paintParams.cbSize = sizeof(paintParams); - paintParams.dwFlags = BPPF_ERASE; - paintParams.pBlendFunction = &bfAlpha; - - HDC hdcBuffer; - HANDLE hPaintBuffer = beginBufferedPaint(hdc, &rcIcon, BPBF_DIB, &paintParams, &hdcBuffer); - if (hPaintBuffer) { - if (hIml) - ImageList_Draw(hIml, iconId, hdc, 0, 0, ILD_TRANSPARENT); - else - DrawIconEx(hdcBuffer, 0, 0, hicon, sizIcon.cx, sizIcon.cy, 0, NULL, DI_NORMAL); - - // If icon did not have an alpha channel we need to convert buffer to PARGB - ConvertBufferToPARGB32(hPaintBuffer, hdc, hicon, sizIcon); - - // This will write the buffer contents to the destination bitmap - endBufferedPaint(hPaintBuffer, TRUE); - } - - SelectObject(hdc, hbmpOld); - DeleteDC(hdc); - - return hbmp; -} diff --git a/src/modules/utils/openurl.cpp b/src/modules/utils/openurl.cpp deleted file mode 100644 index afbfa4681b..0000000000 --- a/src/modules/utils/openurl.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include - -struct TOpenUrlInfo -{ - TOpenUrlInfo(TCHAR *_url, int _bNew) : - szUrl(_url), - newWindow(_bNew) - {} - - ptrT szUrl; - int newWindow; -}; - -static void OpenURLThread(void *arg) -{ - TOpenUrlInfo *hUrlInfo = (TOpenUrlInfo*)arg; - - // wack a protocol on it - CMString tszUrl; - if ((isalpha(hUrlInfo->szUrl[0]) && hUrlInfo->szUrl[1] == ':') || hUrlInfo->szUrl[0] == '\\') - tszUrl.Format(_T("file:///%s"), hUrlInfo->szUrl); - else { - int i; - for (i = 0; _istalpha(hUrlInfo->szUrl[i]); i++); - if (hUrlInfo->szUrl[i] == ':') - tszUrl = hUrlInfo->szUrl; - else if (!_tcsnicmp(hUrlInfo->szUrl, _T("ftp."), 4)) - tszUrl.Format(_T("ftp://%s"), hUrlInfo->szUrl); - else - tszUrl.Format(_T("http://%s"), hUrlInfo->szUrl); - } - - // check user defined browser for opening urls - ptrT tszBrowser(db_get_tsa(NULL, "Miranda", "OpenUrlBrowser")); - if (tszBrowser) - ShellExecute(NULL, _T("open"), tszBrowser, tszUrl, NULL, (hUrlInfo->newWindow) ? SW_NORMAL : SW_SHOWDEFAULT); - else - ShellExecute(NULL, _T("open"), tszUrl, NULL, NULL, (hUrlInfo->newWindow) ? SW_NORMAL : SW_SHOWDEFAULT); - - delete hUrlInfo; -} - -static INT_PTR OpenURL(WPARAM wParam, LPARAM lParam) -{ - if (lParam == 0) - return 1; - - TOpenUrlInfo *hUrlInfo = new TOpenUrlInfo((wParam & OUF_UNICODE) ? mir_wstrdup((WCHAR*)lParam) : mir_a2t((char*)lParam), wParam & OUF_NEWWINDOW); - forkthread(OpenURLThread, 0, hUrlInfo); - return 0; -} - -int InitOpenUrl(void) -{ - CreateServiceFunction(MS_UTILS_OPENURL, OpenURL); - return 0; -} diff --git a/src/modules/utils/path.cpp b/src/modules/utils/path.cpp deleted file mode 100644 index a7ac429900..0000000000 --- a/src/modules/utils/path.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "../database/profilemanager.h" - -#include "..\..\..\plugins\ExternalAPI\m_folders.h" - -extern TCHAR g_profileDir[MAX_PATH], g_shortProfileName[MAX_PATH]; - -static HANDLE hAvatarFolder; -static TCHAR tszAvatarRoot[MAX_PATH]; - -static INT_PTR pathToRelative(WPARAM wParam, LPARAM lParam) -{ - return PathToRelative((char*)wParam, (char*)lParam); -} - -static INT_PTR pathToAbsolute(WPARAM wParam, LPARAM lParam) -{ - return PathToAbsolute((char*)wParam, (char*)lParam); -} - -static INT_PTR createDirTree(WPARAM, LPARAM lParam) -{ - if (lParam == 0) - return 1; - - return CreateDirectoryTree((char*)lParam); -} - -static INT_PTR pathToRelativeW(WPARAM wParam, LPARAM lParam) -{ - return PathToRelativeW((WCHAR*)wParam, (WCHAR*)lParam ); -} - -static INT_PTR pathToAbsoluteW(WPARAM wParam, LPARAM lParam) -{ - return PathToAbsoluteW((WCHAR*)wParam, (WCHAR*)lParam, NULL); -} - -static INT_PTR createDirTreeW(WPARAM, LPARAM lParam) -{ - if (lParam == 0) - return 1; - - return CreateDirectoryTreeW((WCHAR*)lParam); -} - -TCHAR *GetContactID(MCONTACT hContact) -{ - TCHAR *theValue = {0}; - char *szProto = GetContactProto(hContact); - if (db_get_b(hContact, szProto, "ChatRoom", 0) == 1) { - DBVARIANT dbv; - if (!db_get_ts(hContact, szProto, "ChatRoomID", &dbv)) { - theValue = (TCHAR *)mir_tstrdup(dbv.ptszVal); - db_free(&dbv); - return theValue; - } - } - else { - CONTACTINFO ci = {0}; - ci.cbSize = sizeof(ci); - ci.hContact = hContact; - ci.szProto = szProto; - ci.dwFlag = CNF_UNIQUEID | CNF_TCHAR; - if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) { - switch (ci.type) { - case CNFT_ASCIIZ: - return (TCHAR *)ci.pszVal; - break; - case CNFT_DWORD: - return _itot(ci.dVal, (TCHAR *)mir_alloc(sizeof(TCHAR)*32), 10); - break; - } - } - } - return NULL; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Variables parser - -#define XSTR(target, s) _xstrselect(target, s, _T(s)) - -static __forceinline int _xcscmp(const char *s1, const char *s2) { return strcmp(s1, s2); } -static __forceinline int _xcsncmp(const char *s1, const char *s2, size_t n) { return strncmp(s1, s2, n); } -static __forceinline size_t _xcslen(const char *s1) { return strlen(s1); } -static __forceinline char *_xcscpy(char *s1, const char *s2) { return strcpy(s1, s2); } -static __forceinline char *_xcsncpy(char *s1, const char *s2, size_t n) { return strncpy(s1, s2, n); } -static __forceinline char *_xstrselect(char *, char *s1, TCHAR *s2) { return s1; } -static __forceinline char *_itox(char *, int a) { return itoa(a, (char *)mir_alloc(sizeof(char)*20), 10); } -static __forceinline char *mir_a2x(char *, char *s) { return mir_strdup(s); } - -static __forceinline char *GetContactNickX(char *, MCONTACT hContact) -{ - return mir_strdup((char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, hContact, 0)); -} - -static __forceinline char *GetContactIDX(char *, MCONTACT hContact) -{ - TCHAR *id = GetContactID(hContact); - char* res = mir_t2a(id); - mir_free(id); - return res; -} - -static __forceinline char *GetEnvironmentVariableX(char *variable) -{ - char result[512]; - if (GetEnvironmentVariableA(variable, result, SIZEOF(result))) - return mir_strdup(result); - return NULL; -} - -static __forceinline char *GetProfileDirX(char*) -{ - return mir_t2a(g_profileDir); -} - -static __forceinline char *SHGetSpecialFolderPathX(int iCSIDL, char* var) -{ - char result[512]; - if (SHGetSpecialFolderPathA(NULL, result, iCSIDL, FALSE)) - return mir_strdup(result); - return NULL; -} - -static __forceinline char *GetModulePathX(char *, HMODULE hModule) -{ - char result[MAX_PATH]; - GetModuleFileNameA(hModule, result, sizeof(result)); - char* str = strrchr(result, '\\'); - if (str) *str = 0; - return mir_strdup(result); -} - -static __forceinline char *GetUserNameX(char *) -{ - char result[128]; - DWORD size = SIZEOF(result); - if (GetUserNameA(result, &size)) - return mir_strdup(result); - return NULL; -} - -static __forceinline char *GetProfileNameX(char *) -{ - return mir_t2a(g_shortProfileName); -} - -static __forceinline char *GetPathVarX(char *, int code) -{ - TCHAR szFullPath[MAX_PATH]; - - switch(code) { - case 1: - if (hAvatarFolder != NULL) - _tcsncpy_s(szFullPath, tszAvatarRoot, _TRUNCATE); - else - mir_sntprintf(szFullPath, SIZEOF(szFullPath), _T("%s\\%s\\AvatarCache"), g_profileDir, g_shortProfileName); - break; - case 2: - mir_sntprintf(szFullPath, SIZEOF(szFullPath), _T("%s\\%s\\Logs"), g_profileDir, g_shortProfileName); - break; - case 3: - mir_sntprintf(szFullPath, SIZEOF(szFullPath), _T("%s\\%s"), g_profileDir, g_shortProfileName); - break; - } - return makeFileName(szFullPath); -} - -static __forceinline int _xcscmp(const TCHAR *s1, const TCHAR *s2) { return _tcscmp(s1, s2); } -static __forceinline int _xcsncmp(const TCHAR *s1, const TCHAR *s2, size_t n) { return _tcsncmp(s1, s2, n); } -static __forceinline size_t _xcslen(const TCHAR *s1) { return _tcslen(s1); } -static __forceinline TCHAR *_xcscpy(TCHAR *s1, const TCHAR *s2) { return _tcscpy(s1, s2); } -static __forceinline TCHAR *_xcsncpy(TCHAR *s1, const TCHAR *s2, size_t n) { return _tcsncpy(s1, s2, n); } -static __forceinline TCHAR *_xstrselect(TCHAR *, char *s1, TCHAR *s2) { return s2; } -static __forceinline TCHAR *_itox(TCHAR *, int a) { return _itot(a, (TCHAR *)mir_alloc(sizeof(TCHAR)*20), 10); } -static __forceinline TCHAR *mir_a2x(TCHAR *, char *s) { return mir_a2t(s); } - -static __forceinline TCHAR *GetContactNickX(TCHAR *, MCONTACT hContact) -{ - return mir_tstrdup((TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, hContact, GCDNF_TCHAR)); -} - -static __forceinline TCHAR *GetContactIDX(TCHAR *, MCONTACT hContact) -{ - return GetContactID(hContact); -} - -static __forceinline TCHAR *GetEnvironmentVariableX(TCHAR *variable) -{ - TCHAR result[512]; - if (GetEnvironmentVariable(variable, result, SIZEOF(result))) - return mir_tstrdup(result); - return NULL; -} - -static __forceinline TCHAR *SHGetSpecialFolderPathX(int iCSIDL, TCHAR* var) -{ - TCHAR result[512]; - if (SHGetSpecialFolderPath(NULL, result, iCSIDL, FALSE)) - return mir_tstrdup(result); - return NULL; -} - -static __forceinline TCHAR *GetProfileDirX(TCHAR*) -{ - return mir_tstrdup(g_profileDir); -} - -static __forceinline TCHAR *GetModulePathX(TCHAR *, HMODULE hModule) -{ - TCHAR result[MAX_PATH]; - GetModuleFileName(hModule, result, SIZEOF(result)); - TCHAR* str = _tcsrchr(result, '\\'); - if (str) *str = 0; - return mir_tstrdup(result); -} - -static __forceinline TCHAR *GetUserNameX(TCHAR *) -{ - TCHAR result[128]; - DWORD size = SIZEOF(result); - if (GetUserName(result, &size)) - return mir_tstrdup(result); - return NULL; -} - -static __forceinline TCHAR *GetProfileNameX(TCHAR *) -{ - return mir_tstrdup(g_shortProfileName); -} - -static __forceinline TCHAR *GetPathVarX(TCHAR *, int code) -{ - TCHAR szFullPath[MAX_PATH]; - - switch(code) { - case 1: - if (hAvatarFolder != NULL) - _tcsncpy_s(szFullPath, tszAvatarRoot, _TRUNCATE); - else - mir_sntprintf(szFullPath, SIZEOF(szFullPath), _T("%s\\%s\\AvatarCache"), g_profileDir, g_shortProfileName); - break; - case 2: - mir_sntprintf(szFullPath, SIZEOF(szFullPath), _T("%s\\%s\\Logs"), g_profileDir, g_shortProfileName); - break; - case 3: - mir_sntprintf(szFullPath, SIZEOF(szFullPath), _T("%s\\%s"), g_profileDir, g_shortProfileName); - break; - } - return mir_tstrdup(szFullPath); -} - -template -XCHAR *GetInternalVariable(XCHAR *key, size_t keyLength, MCONTACT hContact) -{ - XCHAR *theValue = NULL; - XCHAR *theKey = (XCHAR *)_alloca(sizeof(XCHAR) * (keyLength + 1)); - _xcsncpy(theKey, key, keyLength); - theKey[keyLength] = 0; - - if (hContact) { - if (!_xcscmp(theKey, XSTR(key, "nick"))) - theValue = GetContactNickX(key, hContact); - else if (!_xcscmp(theKey, XSTR(key, "proto"))) - theValue = mir_a2x(key, GetContactProto(hContact)); - else if (!_xcscmp(theKey, XSTR(key, "accountname"))) { - PROTOACCOUNT *acc = ProtoGetAccount(GetContactProto(hContact)); - if (acc != NULL) - theValue = mir_a2x(key, _T2A(acc->tszAccountName)); - } - else if (!_xcscmp(theKey, XSTR(key, "userid"))) - theValue = GetContactIDX(key, hContact); - } - - if (!theValue) { - if (!_xcscmp(theKey, XSTR(key, "miranda_path"))) - theValue = GetModulePathX(key, NULL); - else if (!_xcscmp(theKey, XSTR(key, "appdata"))) - theValue = SHGetSpecialFolderPathX(CSIDL_APPDATA, theKey); - else if (!_xcscmp(theKey, XSTR(key, "mydocuments"))) - theValue = SHGetSpecialFolderPathX(CSIDL_PERSONAL, theKey); - else if (!_xcscmp(theKey, XSTR(key, "desktop"))) - theValue = SHGetSpecialFolderPathX(CSIDL_DESKTOPDIRECTORY, theKey); - else if (!_xcscmp(theKey, XSTR(key, "miranda_profilesdir"))) - theValue = GetProfileDirX(key); - else if (!_xcscmp(theKey, XSTR(key, "miranda_profilename"))) - theValue = GetProfileNameX(key); - else if (!_xcscmp(theKey, XSTR(key, "username"))) - theValue = GetUserNameX(key); - else if (!_xcscmp(theKey, XSTR(key, "miranda_avatarcache"))) - theValue = GetPathVarX(key, 1); - else if (!_xcscmp(theKey, XSTR(key, "miranda_logpath"))) - theValue = GetPathVarX(key, 2); - else if (!_xcscmp(theKey, XSTR(key, "miranda_userdata"))) - theValue = GetPathVarX(key, 3); - } - - if (!theValue) - theValue = GetEnvironmentVariableX(theKey); - - return theValue; -} - -template -XCHAR *GetVariableFromArray(REPLACEVARSARRAY *vars, XCHAR *key, size_t keyLength, MCONTACT hContact, bool *bFree) -{ - *bFree = false; - for (REPLACEVARSARRAY *var = vars; var && var->lptzKey; ++var) - if ((_xcslen((XCHAR *)var->lptzKey) == keyLength) && !_xcsncmp(key, (XCHAR *)var->lptzKey, keyLength)) - return (XCHAR *)var->lptzValue; - - *bFree = true; - return GetInternalVariable(key, keyLength, hContact); -} - -template -XCHAR *ReplaceVariables(XCHAR *str, REPLACEVARSDATA *data) -{ - if (!str) - return NULL; - - XCHAR *p; - XCHAR *varStart = 0; - size_t length = 0; - bool bFree; - - for (p = str; *p; ++p) { - if (*p == '%') { - if (varStart) { - if (p == varStart) - length++; - else if (XCHAR *value = GetVariableFromArray(data->variables, varStart, p-varStart, data->hContact, &bFree)) { - length += _xcslen(value); - if (bFree) mir_free(value); - } - else // variable not found - length += p-varStart+2; - - varStart = 0; - } - else varStart = p+1; - } - else if (!varStart) - length++; - } - if (varStart) - length += (p - varStart)+1; - - XCHAR *result = (XCHAR *)mir_alloc(sizeof(XCHAR) * (length + 1)); - XCHAR *q = result; - varStart = NULL; - - for (p = str; *p; ++p) { - if (*p == '%') { - if (varStart) { - if (p == varStart) - *q++='%'; - else if (XCHAR *value = GetVariableFromArray(data->variables, varStart, p-varStart, data->hContact, &bFree)) { - _xcscpy(q, value); - q += _xcslen(value); - if (bFree) mir_free(value); - } - else { - // variable not found - _xcsncpy(q, varStart-1, p-varStart+2); - q += p-varStart+2; - } - varStart = 0; - } - else varStart = p+1; - } - else if (!varStart) - *q++=*p; - } - - if (varStart) { - size_t len = p - varStart + 1; - _xcsncpy(q, varStart-1, len); - q += len; - } - - *q = 0; - - return result; -} - -static INT_PTR replaceVars(WPARAM wParam, LPARAM lParam) -{ - REPLACEVARSDATA *data = (REPLACEVARSDATA *)lParam; - if (data->dwFlags & RVF_UNICODE) - return (INT_PTR)ReplaceVariables((WCHAR *)wParam, data); - - return (INT_PTR)ReplaceVariables((char *)wParam, data); -} - -int InitPathUtils(void) -{ - CreateServiceFunction(MS_UTILS_PATHTORELATIVE, pathToRelative); - CreateServiceFunction(MS_UTILS_PATHTORELATIVEW, pathToRelativeW); - - CreateServiceFunction(MS_UTILS_PATHTOABSOLUTE, pathToAbsolute); - CreateServiceFunction(MS_UTILS_PATHTOABSOLUTEW, pathToAbsoluteW); - - CreateServiceFunction(MS_UTILS_CREATEDIRTREE, createDirTree); - CreateServiceFunction(MS_UTILS_CREATEDIRTREEW, createDirTreeW); - - CreateServiceFunction(MS_UTILS_REPLACEVARS, replaceVars); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static int OnFoldersChanged(WPARAM, LPARAM) -{ - mir_sntprintf(tszAvatarRoot, SIZEOF(tszAvatarRoot), _T("%s\\%s\\AvatarCache"), g_profileDir, g_shortProfileName); - - TCHAR tmpVar[MAX_PATH]; - if (!FoldersGetCustomPathT(hAvatarFolder, tmpVar, SIZEOF(tmpVar), tszAvatarRoot)) - _tcsncpy_s(tszAvatarRoot, tmpVar, _TRUNCATE); - return 0; -} - -void InitPathVar() -{ - mir_sntprintf(tszAvatarRoot, SIZEOF(tszAvatarRoot), _T("%s\\%s\\AvatarCache"), g_profileDir, g_shortProfileName); - if (hAvatarFolder = FoldersRegisterCustomPathT( LPGEN("Avatars"), LPGEN("Avatars root folder"), tszAvatarRoot)) { - TCHAR tmpVar[MAX_PATH]; - if (!FoldersGetCustomPathT(hAvatarFolder, tmpVar, SIZEOF(tmpVar), tszAvatarRoot)) - _tcsncpy_s(tszAvatarRoot, tmpVar, _TRUNCATE); - HookEvent(ME_FOLDERS_PATH_CHANGED, OnFoldersChanged); - } -} diff --git a/src/modules/utils/resizer.cpp b/src/modules/utils/resizer.cpp deleted file mode 100644 index 17f9e5bd34..0000000000 --- a/src/modules/utils/resizer.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#pragma pack(2) - -typedef struct { - DWORD helpID; - DWORD exStyle; - DWORD style; - short x; - short y; - short cx; - short cy; - DWORD id; -} START_OF_DLGITEMTEMPLATEEX; - -typedef struct { - WORD dlgVer; - WORD signature; - DWORD helpID; - DWORD exStyle; - DWORD style; - WORD cDlgItems; - short x; - short y; - short cx; - short cy; -} START_OF_DLGTEMPLATEEX; - -INT_PTR ResizeDialog(WPARAM, LPARAM lParam) -{ - UTILRESIZEDIALOG *urd = (UTILRESIZEDIALOG*)lParam; - HDWP hDwp; - int i; - DLGITEMTEMPLATE *pItem = NULL; - START_OF_DLGITEMTEMPLATEEX *pItemEx = NULL; - RECT rc; - PWORD pWord; - DLGTEMPLATE *pTemplate; - START_OF_DLGTEMPLATEEX *pTemplateEx; - UTILRESIZECONTROL urc; - int procResult; - int extendedDlg, itemCount; - - if (urd == NULL || urd->cbSize != sizeof(UTILRESIZEDIALOG)) return 1; - pTemplate = (DLGTEMPLATE*)LockResource(LoadResource(urd->hInstance, FindResourceA(urd->hInstance, urd->lpTemplate, MAKEINTRESOURCEA(5)))); - pTemplateEx = (START_OF_DLGTEMPLATEEX*)pTemplate; - extendedDlg = pTemplateEx->signature == 0xFFFF; - if (extendedDlg && pTemplateEx->dlgVer != 1) - return 1; - - if (extendedDlg) pWord = (PWORD)(pTemplateEx+1); - else pWord = (PWORD)(pTemplate+1); - if (*pWord == 0xFFFF) pWord+=2; else while (*pWord++); //menu - if (*pWord == 0xFFFF) pWord+=2; else while (*pWord++); //class - while (*pWord++); //title - if (extendedDlg) { - if (pTemplateEx->style&DS_SETFONT) { - pWord+=3; //font size, weight, italic - while (*pWord++); //font name - } - } - else { - if (pTemplate->style&DS_SETFONT) { - pWord++; //font size - while (*pWord++); //font name - } - } - - urc.cbSize = sizeof(UTILRESIZECONTROL); - rc.left = 0; rc.top = 0; - if (extendedDlg) {rc.right = pTemplateEx->cx; rc.bottom = pTemplateEx->cy;} - else {rc.right = pTemplate->cx; rc.bottom = pTemplate->cy;} - MapDialogRect(urd->hwndDlg, &rc); - urc.dlgOriginalSize.cx = rc.right; urc.dlgOriginalSize.cy = rc.bottom; - GetClientRect(urd->hwndDlg, &rc); - urc.dlgNewSize.cx = rc.right; urc.dlgNewSize.cy = rc.bottom; - - if (extendedDlg) itemCount = pTemplateEx->cDlgItems; - else itemCount = pTemplate->cdit; - hDwp = BeginDeferWindowPos(itemCount); - for (i=0;iid; - urc.rcItem.left = pItemEx->x; urc.rcItem.top = pItemEx->y; - urc.rcItem.right = urc.rcItem.left+pItemEx->cx; urc.rcItem.bottom = urc.rcItem.top+pItemEx->cy; - } - else { - pItem = (DLGITEMTEMPLATE*)pWord; - pWord = (PWORD)(pItem+1); - - urc.wId = pItem->id; - urc.rcItem.left = pItem->x; urc.rcItem.top = pItem->y; - urc.rcItem.right = urc.rcItem.left+pItem->cx; urc.rcItem.bottom = urc.rcItem.top+pItem->cy; - } - if (*pWord == 0xFFFF) pWord+=2; else while (*pWord++); //menu - if (*pWord == 0xFFFF) pWord+=2; else while (*pWord++); //class - pWord+=1+(1+*pWord)/2; //creation data - - if (urc.wId == 65535) continue; //using this breaks the dwp, so just ignore it - - MapDialogRect(urd->hwndDlg, &urc.rcItem); - procResult = (urd->pfnResizer)(urd->hwndDlg, urd->lParam, &urc); - if (procResult&RD_ANCHORX_RIGHT) { - urc.rcItem.left+=urc.dlgNewSize.cx-urc.dlgOriginalSize.cx; - urc.rcItem.right+=urc.dlgNewSize.cx-urc.dlgOriginalSize.cx; - } - else if (procResult&RD_ANCHORX_WIDTH) - urc.rcItem.right+=urc.dlgNewSize.cx-urc.dlgOriginalSize.cx; - else if (procResult&RD_ANCHORX_CENTRE) { - urc.rcItem.left+=(urc.dlgNewSize.cx-urc.dlgOriginalSize.cx)/2; - urc.rcItem.right+=(urc.dlgNewSize.cx-urc.dlgOriginalSize.cx)/2; - } - if (procResult&RD_ANCHORY_BOTTOM) { - urc.rcItem.top+=urc.dlgNewSize.cy-urc.dlgOriginalSize.cy; - urc.rcItem.bottom+=urc.dlgNewSize.cy-urc.dlgOriginalSize.cy; - } - else if (procResult&RD_ANCHORY_HEIGHT) - urc.rcItem.bottom+=urc.dlgNewSize.cy-urc.dlgOriginalSize.cy; - else if (procResult&RD_ANCHORY_CENTRE) { - urc.rcItem.top+=(urc.dlgNewSize.cy-urc.dlgOriginalSize.cy)/2; - urc.rcItem.bottom+=(urc.dlgNewSize.cy-urc.dlgOriginalSize.cy)/2; - } - HWND hCtrl = GetDlgItem(urd->hwndDlg, extendedDlg ? pItemEx->id : pItem->id); - if (NULL != hCtrl) /* Wine fix. */ - hDwp = DeferWindowPos(hDwp, hCtrl, 0, urc.rcItem.left, urc.rcItem.top, urc.rcItem.right-urc.rcItem.left, urc.rcItem.bottom-urc.rcItem.top, SWP_NOZORDER); - } - EndDeferWindowPos(hDwp); - return 0; -} diff --git a/src/modules/utils/timeutils.cpp b/src/modules/utils/timeutils.cpp deleted file mode 100644 index a2f926f74d..0000000000 --- a/src/modules/utils/timeutils.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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. - -implements services to handle location - based timezones, instead of -simple UTC offsets. -*/ - -#include "..\..\core\commonheaders.h" - -// KB167296 -void UnixTimeToFileTime(mir_time ts, LPFILETIME pft) -{ - unsigned __int64 ll = UInt32x32To64(ts, 10000000) + 116444736000000000i64; - pft->dwLowDateTime = (DWORD)ll; - pft->dwHighDateTime = ll >> 32; -} - -mir_time FileTimeToUnixTime(LPFILETIME pft) -{ - unsigned __int64 ll = (unsigned __int64)pft->dwHighDateTime << 32 | pft->dwLowDateTime; - ll -= 116444736000000000i64; - return (mir_time)(ll / 10000000); -} - -void FormatTime(const SYSTEMTIME *st, const TCHAR *szFormat, TCHAR *szDest, int cbDest) -{ - if (szDest == NULL || cbDest == 0) return; - - CMString tszTemp; - - for (const TCHAR* pFormat = szFormat; *pFormat; ++pFormat) { - DWORD fmt; - bool date, iso = false; - switch (*pFormat) { - case 't': - fmt = TIME_NOSECONDS; - date = false; - break; - - case 's': - fmt = 0; - date = false; - break; - - case 'm': - fmt = TIME_NOMINUTESORSECONDS; - date = false; - break; - - case 'd': - fmt = DATE_SHORTDATE; - date = true; - break; - - case 'D': - fmt = DATE_LONGDATE; - date = true; - break; - - case 'I': - iso = true; - break; - - default: - tszTemp.AppendChar(*pFormat); - continue; - } - - TCHAR dateTimeStr[64]; - if (iso) - tszTemp.AppendFormat(_T("%d-%02d-%02dT%02d:%02d:%02dZ"), st->wYear, st->wMonth, st->wDay, st->wHour, st->wMinute, st->wSecond); - else if (date) { - GetDateFormat(LOCALE_USER_DEFAULT, fmt, st, NULL, dateTimeStr, SIZEOF(dateTimeStr)); - tszTemp.Append(dateTimeStr); - } - else { - GetTimeFormat(LOCALE_USER_DEFAULT, fmt, st, NULL, dateTimeStr, SIZEOF(dateTimeStr)); - tszTemp.Append(dateTimeStr); - } - } - - _tcsncpy_s(szDest, cbDest, tszTemp, _TRUNCATE); -} diff --git a/src/modules/utils/timezones.cpp b/src/modules/utils/timezones.cpp deleted file mode 100644 index 6cf2a9c0f6..0000000000 --- a/src/modules/utils/timezones.cpp +++ /dev/null @@ -1,557 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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. - -implements services to handle location - based timezones, instead of -simple UTC offsets. -*/ - -#include "..\..\core\commonheaders.h" - -TIME_API tmi; - -typedef DWORD (WINAPI *pfnGetDynamicTimeZoneInformation_t)(DYNAMIC_TIME_ZONE_INFORMATION *pdtzi); -static pfnGetDynamicTimeZoneInformation_t pfnGetDynamicTimeZoneInformation; - -struct REG_TZI_FORMAT -{ - LONG Bias; - LONG StandardBias; - LONG DaylightBias; - SYSTEMTIME StandardDate; - SYSTEMTIME DaylightDate; -}; - -#define MIM_TZ_DISPLAYLEN 128 - -struct MIM_TIMEZONE -{ - unsigned hash; - int offset; - - TCHAR tszName[MIM_TZ_NAMELEN]; // windows name for the time zone - wchar_t szDisplay[MIM_TZ_DISPLAYLEN]; // more descriptive display name (that's what usually appears in dialogs) - // every hour should be sufficient. - TIME_ZONE_INFORMATION tzi; - - static int compareBias(const MIM_TIMEZONE* p1, const MIM_TIMEZONE* p2) - { return p2->tzi.Bias - p1->tzi.Bias; } -}; - -struct TZ_INT_INFO -{ - DWORD timestamp; // last time updated - MIM_TIMEZONE myTZ; // set to my own timezone -}; - -static TZ_INT_INFO myInfo; - -static OBJLIST g_timezones(55, NumericKeySortT); -static LIST g_timezonesBias(55, MIM_TIMEZONE::compareBias); - -void FormatTime(const SYSTEMTIME *st, const TCHAR *szFormat, TCHAR *szDest, int cbDest); -void UnixTimeToFileTime(mir_time ts, LPFILETIME pft); -mir_time FileTimeToUnixTime(LPFILETIME pft); - -#define fnSystemTimeToTzSpecificLocalTime SystemTimeToTzSpecificLocalTime - -static int timeapiGetTimeZoneTime(HANDLE hTZ, SYSTEMTIME *st) -{ - if (st == NULL) return 1; - - MIM_TIMEZONE *tz = (MIM_TIMEZONE*)hTZ; - if (tz == UTC_TIME_HANDLE) - GetSystemTime(st); - else if (tz && tz != &myInfo.myTZ) { - SYSTEMTIME sto; - GetSystemTime(&sto); - return !fnSystemTimeToTzSpecificLocalTime(&tz->tzi, &sto, st); - } - else - GetLocalTime(st); - - return 0; -} - -static LPCTSTR timeapiGetTzName(HANDLE hTZ) -{ - MIM_TIMEZONE *tz = (MIM_TIMEZONE*)hTZ; - if (tz == NULL) - return myInfo.myTZ.tszName; - else if (tz == UTC_TIME_HANDLE) - return _T("UTC"); - - return tz->tszName; -} - -static LPCTSTR timeapiGetTzDescription(LPCTSTR TZname) -{ - for (int i = 0; i < g_timezonesBias.getCount(); i++) { - MIM_TIMEZONE *tz = g_timezonesBias[i]; - - if (!mir_tstrcmp(tz->tszName, TZname)) - return tz->szDisplay; - } - return _T(""); -} - -static void CalcTsOffset(MIM_TIMEZONE *tz) -{ - SYSTEMTIME st, stl; - GetSystemTime(&st); - - FILETIME ft; - SystemTimeToFileTime(&st, &ft); - mir_time ts1 = FileTimeToUnixTime(&ft); - - if (!fnSystemTimeToTzSpecificLocalTime(&tz->tzi, &st, &stl)) - return; - - SystemTimeToFileTime(&stl, &ft); - mir_time ts2 = FileTimeToUnixTime(&ft); - - tz->offset = ts2 - ts1; -} - -static bool IsSameTime(MIM_TIMEZONE *tz) -{ - SYSTEMTIME st, stl; - - if (tz == &myInfo.myTZ) - return true; - - timeapiGetTimeZoneTime(tz, &stl); - timeapiGetTimeZoneTime(NULL, &st); - - return st.wHour == stl.wHour && st.wMinute == stl.wMinute; -} - -static HANDLE timeapiGetInfoByName(LPCTSTR tszName, DWORD dwFlags) -{ - if (tszName == NULL) - return (dwFlags & (TZF_DIFONLY | TZF_KNOWNONLY)) ? NULL : &myInfo.myTZ; - - if (mir_tstrcmp(myInfo.myTZ.tszName, tszName) == 0) - return (dwFlags & TZF_DIFONLY) ? NULL : &myInfo.myTZ; - - MIM_TIMEZONE tzsearch; - tzsearch.hash = mir_hashstrT(tszName); - - MIM_TIMEZONE *tz = g_timezones.find(&tzsearch); - if (tz == NULL) - return (dwFlags & (TZF_DIFONLY | TZF_KNOWNONLY)) ? NULL : &myInfo.myTZ; - - if (dwFlags & TZF_DIFONLY) - return IsSameTime(tz) ? NULL : tz; - - return tz; -} - -static HANDLE timeapiGetInfoByContact(MCONTACT hContact, LPCSTR szModule, DWORD dwFlags) -{ - if (hContact == NULL && szModule == NULL) - return (dwFlags & (TZF_DIFONLY | TZF_KNOWNONLY)) ? NULL : &myInfo.myTZ; - - if (szModule == NULL) szModule = "UserInfo"; - - DBVARIANT dbv; - if (!db_get_ts(hContact, szModule, "TzName", &dbv)) { - HANDLE res = timeapiGetInfoByName(dbv.ptszVal, dwFlags); - db_free(&dbv); - if (res) return res; - } - - signed char timezone = (signed char)db_get_b(hContact, szModule, "Timezone", -1); - if (timezone == -1) { - char *szProto = GetContactProto(hContact); - if (!db_get_ts(hContact, szProto, "TzName", &dbv)) { - HANDLE res = timeapiGetInfoByName(dbv.ptszVal, dwFlags); - db_free(&dbv); - if (res) return res; - } - timezone = (signed char)db_get_b(hContact, szProto, "Timezone", -1); - } - - if (timezone != -1) { - MIM_TIMEZONE tzsearch; - tzsearch.tzi.Bias = timezone * 30; - if (myInfo.myTZ.tzi.Bias == tzsearch.tzi.Bias) { - if (dwFlags & TZF_DIFONLY) return NULL; - return &myInfo.myTZ; - } - - int i = g_timezonesBias.getIndex(&tzsearch); - while (i >= 0 && g_timezonesBias[i]->tzi.Bias == tzsearch.tzi.Bias) --i; - - int delta = LONG_MAX; - for (int j = ++i; j < g_timezonesBias.getCount() && g_timezonesBias[j]->tzi.Bias == tzsearch.tzi.Bias; ++j) { - int delta1 = abs(g_timezonesBias[j]->tzi.DaylightDate.wMonth - myInfo.myTZ.tzi.DaylightDate.wMonth); - if (delta1 <= delta) { - delta = delta1; - i = j; - } - } - - if (i >= 0) { - MIM_TIMEZONE *tz = g_timezonesBias[i]; - return ((dwFlags & TZF_DIFONLY) && IsSameTime(tz)) ? NULL : tz; - } - } - return (dwFlags & (TZF_DIFONLY | TZF_KNOWNONLY)) ? NULL : &myInfo.myTZ; -} - -static void timeapiSetInfoByContact(MCONTACT hContact, LPCSTR szModule, HANDLE hTZ) -{ - if (szModule == NULL) szModule = "UserInfo"; - - MIM_TIMEZONE *tz = (MIM_TIMEZONE*)hTZ; - if (tz) { - db_set_ts(hContact, szModule, "TzName", tz->tszName); - db_set_b(hContact, szModule, "Timezone", (char)((tz->tzi.Bias + tz->tzi.StandardBias) / 30)); - } - else { - db_unset(hContact, szModule, "TzName"); - db_unset(hContact, szModule, "Timezone"); - } -} - -static int timeapiPrintDateTime(HANDLE hTZ, LPCTSTR szFormat, LPTSTR szDest, int cbDest, DWORD dwFlags) -{ - MIM_TIMEZONE *tz = (MIM_TIMEZONE*)hTZ; - if (tz == NULL && (dwFlags & (TZF_DIFONLY | TZF_KNOWNONLY))) - return 1; - - SYSTEMTIME st; - if (timeapiGetTimeZoneTime(tz, &st)) - return 1; - - FormatTime(&st, szFormat, szDest, cbDest); - return 0; -} - -static int timeapiPrintTimeStamp(HANDLE hTZ, mir_time ts, LPCTSTR szFormat, LPTSTR szDest, int cbDest, DWORD dwFlags) -{ - MIM_TIMEZONE *tz = (MIM_TIMEZONE*)hTZ; - if (tz == NULL && (dwFlags & (TZF_DIFONLY | TZF_KNOWNONLY))) - return 1; - - if (tz == NULL) - tz = &myInfo.myTZ; - - FILETIME ft; - if (tz == UTC_TIME_HANDLE) - UnixTimeToFileTime(ts, &ft); - else { - if (tz->offset == INT_MIN) - CalcTsOffset(tz); - - UnixTimeToFileTime(ts + tz->offset, &ft); - } - - SYSTEMTIME st; - FileTimeToSystemTime(&ft, &st); - - FormatTime(&st, szFormat, szDest, cbDest); - return 0; -} - -static LPTIME_ZONE_INFORMATION timeapiGetTzi(HANDLE hTZ) -{ - MIM_TIMEZONE *tz = (MIM_TIMEZONE*)hTZ; - return tz ? &tz->tzi : &myInfo.myTZ.tzi; -} - -static mir_time timeapiTimeStampToTimeZoneTimeStamp(HANDLE hTZ, mir_time ts) -{ - MIM_TIMEZONE *tz = (MIM_TIMEZONE*)hTZ; - if (tz == NULL) - tz = &myInfo.myTZ; - - if (tz == UTC_TIME_HANDLE) - return ts; - - if (tz->offset == INT_MIN) - CalcTsOffset(tz); - - return ts + tz->offset; -} - -struct ListMessages -{ - UINT addStr, getSel, setSel, getData, setData; -}; - -static const ListMessages lbMessages = { LB_ADDSTRING, LB_GETCURSEL, LB_SETCURSEL, LB_GETITEMDATA, LB_SETITEMDATA }; -static const ListMessages cbMessages = { CB_ADDSTRING, CB_GETCURSEL, CB_SETCURSEL, CB_GETITEMDATA, CB_SETITEMDATA }; - -static const ListMessages* GetListMessages(HWND hWnd, DWORD dwFlags) -{ - if (hWnd == NULL) - return NULL; - - if (!(dwFlags & (TZF_PLF_CB | TZF_PLF_LB))) { - TCHAR tszClassName[128]; - GetClassName(hWnd, tszClassName, SIZEOF(tszClassName)); - if (!mir_tstrcmpi(tszClassName, _T("COMBOBOX"))) - dwFlags |= TZF_PLF_CB; - else if (!mir_tstrcmpi(tszClassName, _T("LISTBOX"))) - dwFlags |= TZF_PLF_LB; - } - if (dwFlags & TZF_PLF_CB) - return &cbMessages; - else if (dwFlags & TZF_PLF_LB) - return &lbMessages; - else - return NULL; -} - -/////////////////////////////////////////////////////////////////////////////// - -static int timeapiSelectListItem(MCONTACT hContact, LPCSTR szModule, HWND hWnd, DWORD dwFlags) -{ - const ListMessages *lstMsg = GetListMessages(hWnd, dwFlags); - if (lstMsg == NULL) - return -1; - - if (szModule == NULL) szModule = "UserInfo"; - - int iSelection = 0; - ptrT tszName(db_get_tsa(hContact, szModule, "TzName")); - if (tszName != NULL) { - unsigned hash = mir_hashstrT(tszName); - for (int i = 0; i < g_timezonesBias.getCount(); i++) { - if (hash == g_timezonesBias[i]->hash) { - iSelection = i + 1; - break; - } - } - } - else { - signed char cBias = db_get_b(hContact, szModule, "Timezone", -100); - if (cBias != -100) { - int iBias = cBias * 30; - for (int i = 0; i < g_timezonesBias.getCount(); i++) { - if (iBias == g_timezonesBias[i]->tzi.Bias) { - iSelection = i + 1; - break; - } - } - } - } - - SendMessage(hWnd, lstMsg->setSel, iSelection, 0); - return iSelection; -} - -static int timeapiPrepareList(MCONTACT hContact, LPCSTR szModule, HWND hWnd, DWORD dwFlags) -{ - const ListMessages *lstMsg = GetListMessages(hWnd, dwFlags); - if (lstMsg == NULL) - return 0; - - SendMessage(hWnd, lstMsg->addStr, 0, (LPARAM)TranslateT("")); - - for (int i = 0; i < g_timezonesBias.getCount(); i++) { - MIM_TIMEZONE *tz = g_timezonesBias[i]; - - SendMessage(hWnd, lstMsg->addStr, 0, (LPARAM)tz->szDisplay); - SendMessage(hWnd, lstMsg->setData, i + 1, (LPARAM)tz); - } - - return timeapiSelectListItem(hContact, szModule, hWnd, dwFlags); -} - -static void timeapiStoreListResult(MCONTACT hContact, LPCSTR szModule, HWND hWnd, DWORD dwFlags) -{ - if (szModule == NULL) szModule = "UserInfo"; - - const ListMessages *lstMsg = GetListMessages(hWnd, dwFlags); - if (lstMsg) { - LRESULT offset = SendMessage(hWnd, lstMsg->getSel, 0, 0); - if (offset > 0) { - MIM_TIMEZONE *tz = (MIM_TIMEZONE*)SendMessage(hWnd, lstMsg->getData, offset, 0); - if ((INT_PTR)tz != CB_ERR && tz != NULL) - timeapiSetInfoByContact(hContact, szModule, tz); - } - else timeapiSetInfoByContact(hContact, szModule, NULL); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -static INT_PTR GetTimeApi(WPARAM, LPARAM lParam) -{ - TIME_API* tmi = (TIME_API*)lParam; - if (tmi == NULL) - return FALSE; - - if (tmi->cbSize != sizeof(TIME_API)) - return FALSE; - - tmi->createByName = timeapiGetInfoByName; - tmi->createByContact = timeapiGetInfoByContact; - tmi->storeByContact = timeapiSetInfoByContact; - - tmi->printDateTime = timeapiPrintDateTime; - tmi->printTimeStamp = timeapiPrintTimeStamp; - - tmi->prepareList = timeapiPrepareList; - tmi->selectListItem = timeapiSelectListItem; - tmi->storeListResults = timeapiStoreListResult; - - tmi->getTimeZoneTime = timeapiGetTimeZoneTime; - tmi->timeStampToTimeZoneTimeStamp = timeapiTimeStampToTimeZoneTimeStamp; - tmi->getTzi = timeapiGetTzi; - tmi->getTzName = timeapiGetTzName; - tmi->getTzDescription = timeapiGetTzDescription; - - return TRUE; -} - -static INT_PTR TimestampToLocal(WPARAM wParam, LPARAM) -{ - return timeapiTimeStampToTimeZoneTimeStamp(NULL, (mir_time)wParam); -} - -static INT_PTR TimestampToStringT(WPARAM wParam, LPARAM lParam) -{ - DBTIMETOSTRINGT *tts = (DBTIMETOSTRINGT*)lParam; - if (tts != NULL) - timeapiPrintTimeStamp(NULL, (mir_time)wParam, tts->szFormat, tts->szDest, tts->cbDest, 0); - return 0; -} - -static INT_PTR TimestampToStringA(WPARAM wParam, LPARAM lParam) -{ - DBTIMETOSTRING *tts = (DBTIMETOSTRING*)lParam; - if (tts != NULL) { - TCHAR *szDest = (TCHAR*)alloca(tts->cbDest*sizeof(TCHAR)); - timeapiPrintTimeStamp(NULL, (mir_time)wParam, _A2T(tts->szFormat), szDest, tts->cbDest, 0); - WideCharToMultiByte(CP_ACP, 0, szDest, -1, tts->szDest, tts->cbDest, NULL, NULL); - } - return 0; -} - -void GetLocalizedString(HKEY hSubKey, const TCHAR *szName, wchar_t *szBuf, DWORD cbLen) -{ - DWORD dwLength = cbLen * sizeof(wchar_t); - RegQueryValueEx(hSubKey, szName, NULL, NULL, (unsigned char *)szBuf, &dwLength); - szBuf[min(dwLength / sizeof(TCHAR), cbLen - 1)] = 0; -} - -extern "C" void RecalculateTime(void) -{ - GetTimeZoneInformation(&myInfo.myTZ.tzi); - myInfo.timestamp = time(NULL); - myInfo.myTZ.offset = INT_MIN; - - bool found = false; - DYNAMIC_TIME_ZONE_INFORMATION dtzi; - - if (pfnGetDynamicTimeZoneInformation && pfnGetDynamicTimeZoneInformation(&dtzi) != TIME_ZONE_ID_INVALID) { - TCHAR *myTzKey = mir_u2t(dtzi.TimeZoneKeyName); - _tcsncpy_s(myInfo.myTZ.tszName, myTzKey, _TRUNCATE); - mir_free(myTzKey); - found = true; - } - - for (int i = 0; i < g_timezones.getCount(); i++) { - MIM_TIMEZONE &tz = g_timezones[i]; - if (tz.offset != INT_MIN) - tz.offset = INT_MIN; - - if (!found) { - if (!mir_wstrcmp(tz.tzi.StandardName, myInfo.myTZ.tzi.StandardName) || !mir_wstrcmp(tz.tzi.DaylightName, myInfo.myTZ.tzi.DaylightName)) { - _tcsncpy_s(myInfo.myTZ.tszName, tz.tszName, _TRUNCATE); - found = true; - } - } - } -} - -void InitTimeZones(void) -{ - REG_TZI_FORMAT tzi; - HKEY hKey; - - const TCHAR *tszKey = _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones"); - - /* - * use GetDynamicTimeZoneInformation() on Vista+ - this will return a structure with - * the registry key name, so finding our own time zone later will be MUCH easier for - * localized systems or systems with a MUI pack installed - */ - if (IsWinVerVistaPlus()) - pfnGetDynamicTimeZoneInformation = (pfnGetDynamicTimeZoneInformation_t)GetProcAddress(GetModuleHandle(_T("kernel32")), "GetDynamicTimeZoneInformation"); - - if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, tszKey, 0, KEY_ENUMERATE_SUB_KEYS, &hKey)) { - DWORD dwIndex = 0; - HKEY hSubKey; - TCHAR tszName[MIM_TZ_NAMELEN]; - - DWORD dwSize = SIZEOF(tszName); - while (ERROR_NO_MORE_ITEMS != RegEnumKeyEx(hKey, dwIndex++, tszName, &dwSize, NULL, NULL, 0, NULL)) { - if (ERROR_SUCCESS == RegOpenKeyEx(hKey, tszName, 0, KEY_QUERY_VALUE, &hSubKey)) { - dwSize = sizeof(tszName); - - DWORD dwLength = sizeof(tzi); - if (ERROR_SUCCESS != RegQueryValueEx(hSubKey, _T("TZI"), NULL, NULL, (unsigned char *)&tzi, &dwLength)) - continue; - - MIM_TIMEZONE *tz = new MIM_TIMEZONE; - - tz->tzi.Bias = tzi.Bias; - tz->tzi.StandardDate = tzi.StandardDate; - tz->tzi.StandardBias = tzi.StandardBias; - tz->tzi.DaylightDate = tzi.DaylightDate; - tz->tzi.DaylightBias = tzi.DaylightBias; - - mir_tstrcpy(tz->tszName, tszName); - tz->hash = mir_hashstrT(tszName); - tz->offset = INT_MIN; - - GetLocalizedString(hSubKey, _T("Display"), tz->szDisplay, SIZEOF(tz->szDisplay)); - GetLocalizedString(hSubKey, _T("Std"), tz->tzi.StandardName, SIZEOF(tz->tzi.StandardName)); - GetLocalizedString(hSubKey, _T("Dlt"), tz->tzi.DaylightName, SIZEOF(tz->tzi.DaylightName)); - - g_timezones.insert(tz); - g_timezonesBias.insert(tz); - - RegCloseKey(hSubKey); - } - dwSize = SIZEOF(tszName); - } - RegCloseKey(hKey); - } - - RecalculateTime(); - - CreateServiceFunction(MS_SYSTEM_GET_TMI, GetTimeApi); - - CreateServiceFunction(MS_DB_TIME_TIMESTAMPTOLOCAL, TimestampToLocal); - CreateServiceFunction(MS_DB_TIME_TIMESTAMPTOSTRINGT, TimestampToStringT); - - CreateServiceFunction(MS_DB_TIME_TIMESTAMPTOSTRING, TimestampToStringA); - - tmi.cbSize = sizeof(tmi); - GetTimeApi(0, (LPARAM)&tmi); -} diff --git a/src/modules/utils/utils.cpp b/src/modules/utils/utils.cpp deleted file mode 100644 index abcca9426f..0000000000 --- a/src/modules/utils/utils.cpp +++ /dev/null @@ -1,496 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (с) 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -#define MS_SYSTEM_GET_MD5I "Miranda/System/GetMD5I" - -INT_PTR ResizeDialog(WPARAM wParam, LPARAM lParam); - -int InitOpenUrl(void); -int InitWindowList(void); -int InitPathUtils(void); -int InitHyperlink(void); -int InitColourPicker(void); -void InitXmlApi(void); - -void InitTimeZones(void); - -int InitCrypt(void); -void UninitCrypt(void); - -INT_PTR __cdecl svcEnterString(WPARAM, LPARAM lParam); - -static BOOL bModuleInitialized = FALSE; - -static CountryListEntry countries[] = { - {0, LPGEN("Unspecified"), ""}, - {9999, LPGEN("Other"), ""}, - {0xFFFF, LPGEN("Unknown"), ""}, - {93, LPGEN("Afghanistan"), "AF"}, - {358, LPGEN("Aland Islands"), "AX"}, - {355, LPGEN("Albania"), "AL"}, - {213, LPGEN("Algeria"), "DZ"}, - {1684, LPGEN("American Samoa"), "AS"}, - {376, LPGEN("Andorra"), "AD"}, - {244, LPGEN("Angola"), "AO"}, - {1264, LPGEN("Anguilla"), "AI"}, - {0xFFFE, LPGEN("Antarctica"), "AQ"}, - {1268, LPGEN("Antigua and Barbuda"), "AG"}, - {54, LPGEN("Argentina"), "AR"}, - {374, LPGEN("Armenia"), "AM"}, - {297, LPGEN("Aruba"), "AW"}, - {61, LPGEN("Australia"), "AU"}, - {43, LPGEN("Austria"), "AT"}, - {994, LPGEN("Azerbaijan"), "AZ"}, - {1242, LPGEN("Bahamas"), "BS"}, - {973, LPGEN("Bahrain"), "BH"}, - {880, LPGEN("Bangladesh"), "BD"}, - {1246, LPGEN("Barbados"), "BB"}, - {375, LPGEN("Belarus"), "BY"}, - {32, LPGEN("Belgium"), "BE"}, - {501, LPGEN("Belize"), "BZ"}, - {229, LPGEN("Benin"), "BJ"}, - {1441, LPGEN("Bermuda"), "BM"}, - {975, LPGEN("Bhutan"), "BT"}, - {591, LPGEN("Bolivia"), "BO"}, - {5997, LPGEN("Bonaire, Sint Eustatius and Saba"), "BQ"}, - {387, LPGEN("Bosnia and Herzegovina"), "BA"}, - {267, LPGEN("Botswana"), "BW"}, - {55, LPGEN("Bouvet Island"), "BV"}, - {55, LPGEN("Brazil"), "BR"}, - {246, LPGEN("British Indian Ocean Territory"), "IO"}, - {673, LPGEN("Brunei"), "BN"}, - {359, LPGEN("Bulgaria"), "BG"}, - {226, LPGEN("Burkina Faso"), "BF"}, - {257, LPGEN("Burundi"), "BI"}, - {855, LPGEN("Cambodia"), "KH"}, - {237, LPGEN("Cameroon"), "CM"}, - {1, LPGEN("Canada"), "CA"}, - {238, LPGEN("Cape Verde"), "CV"}, - {1345, LPGEN("Cayman Islands"), "KY"}, - {236, LPGEN("Central African Republic"), "CF"}, - {235, LPGEN("Chad"), "TD"}, - {56, LPGEN("Chile"), "CL"}, - {86, LPGEN("China"), "CN"}, - {61, LPGEN("Christmas Island"), "CX"}, - {61, LPGEN("Cocos (Keeling) Islands"), "CC"}, - {57, LPGEN("Colombia"), "CO"}, - {269, LPGEN("Comoros"), "KM"}, - {242, LPGEN("Congo, Republic of the"), "CG"}, - {243, LPGEN("Congo, Democratic Republic of the"), "CD"}, - {682, LPGEN("Cook Islands"), "CK"}, - {506, LPGEN("Costa Rica"), "CR"}, - {225, LPGEN("Cote d'Ivoire"), "CI"}, - {385, LPGEN("Croatia"), "HR"}, - {53, LPGEN("Cuba"), "CU"}, - {5999, LPGEN("Curacao"), "CW"}, - {357, LPGEN("Cyprus"), "CY"}, - {420, LPGEN("Czech Republic"), "CZ"}, - {45, LPGEN("Denmark"), "DK"}, - {253, LPGEN("Djibouti"), "DJ"}, - {1767, LPGEN("Dominica"), "DM"}, - {1809, LPGEN("Dominican Republic"), "DO"}, - {670, LPGEN("East Timor"), "TL"}, - {593, LPGEN("Ecuador"), "EC"}, - {20, LPGEN("Egypt"), "EG"}, - {503, LPGEN("El Salvador"), "SV"}, - {240, LPGEN("Equatorial Guinea"), "GQ"}, - {291, LPGEN("Eritrea"), "ER"}, - {372, LPGEN("Estonia"), "EE"}, - {251, LPGEN("Ethiopia"), "ET"}, - {500, LPGEN("Falkland Islands (Malvinas)"), "FK"}, - {298, LPGEN("Faroe Islands"), "FO"}, - {679, LPGEN("Fiji"), "FJ"}, - {358, LPGEN("Finland"), "FI"}, - {33, LPGEN("France"), "FR"}, - {594, LPGEN("French Guiana"), "GF"}, - {689, LPGEN("French Polynesia"), "PF"}, - {0xFFFE, LPGEN("French Southern and Antarctic Lands"), "TF"}, - {241, LPGEN("Gabon"), "GA"}, - {220, LPGEN("Gambia"), "GM"}, - {995, LPGEN("Georgia"), "GE"}, - {49, LPGEN("Germany"), "DE"}, - {233, LPGEN("Ghana"), "GH"}, - {350, LPGEN("Gibraltar"), "GI"}, - {30, LPGEN("Greece"), "GR"}, - {299, LPGEN("Greenland"), "GL"}, - {1473, LPGEN("Grenada"), "GD"}, - {590, LPGEN("Guadeloupe"), "GP"}, - {1671, LPGEN("Guam"), "GU"}, - {502, LPGEN("Guatemala"), "GT"}, - {44, LPGEN("Guernsey"), "GG"}, - {224, LPGEN("Guinea"), "GN"}, - {245, LPGEN("Guinea-Bissau"), "GW"}, - {592, LPGEN("Guyana"), "GY"}, - {509, LPGEN("Haiti"), "HT"}, - {0xFFFE, LPGEN("Heard Island and McDonald Islands"), "HM"}, - {504, LPGEN("Honduras"), "HN"}, - {852, LPGEN("Hong Kong"), "HK"}, - {36, LPGEN("Hungary"), "HU"}, - {354, LPGEN("Iceland"), "IS"}, - {91, LPGEN("India"), "IN"}, - {62, LPGEN("Indonesia"), "ID"}, - {98, LPGEN("Iran"), "IR"}, - {964, LPGEN("Iraq"), "IQ"}, - {353, LPGEN("Ireland"), "IE"}, - {44, LPGEN("Isle of Man"), "IM"}, - {972, LPGEN("Israel"), "IL"}, - {39, LPGEN("Italy"), "IT"}, - {1876, LPGEN("Jamaica"), "JM"}, - {81, LPGEN("Japan"), "JP"}, - {44, LPGEN("Jersey"), "JE"}, - {962, LPGEN("Jordan"), "JO"}, - {76, LPGEN("Kazakhstan"), "KZ"}, - {254, LPGEN("Kenya"), "KE"}, - {686, LPGEN("Kiribati"), "KI"}, - {850, LPGEN("North Korea"), "KP"}, - {82, LPGEN("South Korea"), "KR"}, - {965, LPGEN("Kuwait"), "KW"}, - {996, LPGEN("Kyrgyzstan"), "KG"}, - {856, LPGEN("Laos"), "LA"}, - {371, LPGEN("Latvia"), "LV"}, - {961, LPGEN("Lebanon"), "LB"}, - {266, LPGEN("Lesotho"), "LS"}, - {231, LPGEN("Liberia"), "LR"}, - {218, LPGEN("Libya"), "LY"}, - {423, LPGEN("Liechtenstein"), "LI"}, - {370, LPGEN("Lithuania"), "LT"}, - {352, LPGEN("Luxembourg"), "LU"}, - {853, LPGEN("Macau"), "MO"}, - {389, LPGEN("Macedonia"), "MK"}, - {261, LPGEN("Madagascar"), "MG"}, - {265, LPGEN("Malawi"), "MW"}, - {60, LPGEN("Malaysia"), "MY"}, - {960, LPGEN("Maldives"), "MV"}, - {223, LPGEN("Mali"), "ML"}, - {356, LPGEN("Malta"), "MT"}, - {692, LPGEN("Marshall Islands"), "MH"}, - {596, LPGEN("Martinique"), "MQ"}, - {222, LPGEN("Mauritania"), "MR"}, - {230, LPGEN("Mauritius"), "MU"}, - {262, LPGEN("Mayotte"), "YT"}, - {52, LPGEN("Mexico"), "MX"}, - {691, LPGEN("Micronesia, Federated States of"), "FM"}, - {373, LPGEN("Moldova"), "MD"}, - {377, LPGEN("Monaco"), "MC"}, - {976, LPGEN("Mongolia"), "MN"}, - {382, LPGEN("Montenegro"), "ME"}, - {1664, LPGEN("Montserrat"), "MS"}, - {212, LPGEN("Morocco"), "MA"}, - {258, LPGEN("Mozambique"), "MZ"}, - {95, LPGEN("Myanmar"), "MM"}, - {264, LPGEN("Namibia"), "NA"}, - {674, LPGEN("Nauru"), "NR"}, - {977, LPGEN("Nepal"), "NP"}, - {31, LPGEN("Netherlands"), "NL"}, - {687, LPGEN("New Caledonia"), "NC"}, - {64, LPGEN("New Zealand"), "NZ"}, - {505, LPGEN("Nicaragua"), "NI"}, - {227, LPGEN("Niger"), "NE"}, - {234, LPGEN("Nigeria"), "NG"}, - {683, LPGEN("Niue"), "NU"}, - {672, LPGEN("Norfolk Island"), "NF"}, - {1670, LPGEN("Northern Mariana Islands"), "MP"}, - {47, LPGEN("Norway"), "NO"}, - {968, LPGEN("Oman"), "OM"}, - {92, LPGEN("Pakistan"), "PK"}, - {680, LPGEN("Palau"), "PW"}, - {970, LPGEN("Palestinian Territories"), "PS"}, - {507, LPGEN("Panama"), "PA"}, - {675, LPGEN("Papua New Guinea"), "PG"}, - {595, LPGEN("Paraguay"), "PY"}, - {51, LPGEN("Peru"), "PE"}, - {63, LPGEN("Philippines"), "PH"}, - {64, LPGEN("Pitcairn Islands"), "PN"}, - {48, LPGEN("Poland"), "PL"}, - {351, LPGEN("Portugal"), "PT"}, - {1787, LPGEN("Puerto Rico"), "PR"}, - {974, LPGEN("Qatar"), "QA"}, - {262, LPGEN("Reunion"), "RE"}, - {40, LPGEN("Romania"), "RO"}, - {7, LPGEN("Russia"), "RU"}, - {250, LPGEN("Rwanda"), "RW"}, - {590, LPGEN("Saint Barthelemy"), "BL"}, - {290, LPGEN("Saint Helena, Ascension and Tristan da Cunha"), "SH"}, - {1869, LPGEN("Saint Kitts and Nevis"), "KN"}, - {1758, LPGEN("Saint Lucia"), "LC"}, - {590, LPGEN("Saint Martin (French part)"), "MF"}, - {508, LPGEN("Saint Pierre and Miquelon"), "PM"}, - {1784, LPGEN("Saint Vincent and the Grenadines"), "VC"}, - {685, LPGEN("Samoa"), "WS"}, - {378, LPGEN("San Marino"), "SM"}, - {239, LPGEN("Sao Tome and Principe"), "ST"}, - {966, LPGEN("Saudi Arabia"), "SA"}, - {221, LPGEN("Senegal"), "SN"}, - {381, LPGEN("Serbia"), "RS"}, - {248, LPGEN("Seychelles"), "SC"}, - {232, LPGEN("Sierra Leone"), "SL"}, - {65, LPGEN("Singapore"), "SG"}, - {1721, LPGEN("Sint Maarten (Dutch part)"), "SX"}, - {421, LPGEN("Slovakia"), "SK"}, - {386, LPGEN("Slovenia"), "SI"}, - {677, LPGEN("Solomon Islands"), "SB"}, - {252, LPGEN("Somalia"), "SO"}, - {27, LPGEN("South Africa"), "ZA"}, - {500, LPGEN("South Georgia and the South Sandwich Islands"), "GS"}, - {211, LPGEN("South Sudan"), "SS"}, - {34, LPGEN("Spain"), "ES"}, - {94, LPGEN("Sri Lanka"), "LK"}, - {249, LPGEN("Sudan"), "SD"}, - {597, LPGEN("Suriname"), "SR"}, - {4779, LPGEN("Svalbard and Jan Mayen"), "SJ"}, - {268, LPGEN("Swaziland"), "SZ"}, - {46, LPGEN("Sweden"), "SE"}, - {41, LPGEN("Switzerland"), "CH"}, - {963, LPGEN("Syria"), "SY"}, - {886, LPGEN("Taiwan"), "TW"}, - {992, LPGEN("Tajikistan"), "TJ"}, - {255, LPGEN("Tanzania"), "TZ"}, - {66, LPGEN("Thailand"), "TH"}, - {228, LPGEN("Togo"), "TG"}, - {690, LPGEN("Tokelau"), "TK"}, - {676, LPGEN("Tonga"), "TO"}, - {1868, LPGEN("Trinidad and Tobago"), "TT"}, - {216, LPGEN("Tunisia"), "TN"}, - {90, LPGEN("Turkey"), "TR"}, - {993, LPGEN("Turkmenistan"), "TM"}, - {1649, LPGEN("Turks and Caicos Islands"), "TC"}, - {688, LPGEN("Tuvalu"), "TV"}, - {256, LPGEN("Uganda"), "UG"}, - {380, LPGEN("Ukraine"), "UA"}, - {971, LPGEN("United Arab Emirates"), "AE"}, - {44, LPGEN("United Kingdom"), "GB"}, - {1, LPGEN("United States"), "US"}, - {699, LPGEN("United States Minor Outlying Islands"), "UM"}, - {598, LPGEN("Uruguay"), "UY"}, - {998, LPGEN("Uzbekistan"), "UZ"}, - {678, LPGEN("Vanuatu"), "VU"}, - {379, LPGEN("Vatican City"), "VA"}, - {58, LPGEN("Venezuela"), "VE"}, - {84, LPGEN("Vietnam"), "VN"}, - {1284, LPGEN("Virgin Islands (British)"), "VG"}, - {1340, LPGEN("Virgin Islands (United States)"), "VI"}, - {681, LPGEN("Wallis and Futuna"), "WF"}, - {5289, LPGEN("Western Sahara"), "EH"}, - {967, LPGEN("Yemen"), "YE"}, - {260, LPGEN("Zambia"), "ZM"}, - {263, LPGEN("Zimbabwe"), "ZW"} -}; - -static INT_PTR GetCountryByNumber(WPARAM wParam, LPARAM) -{ - for (int i = 0; i < SIZEOF(countries); i++) - if ((int)wParam == countries[i].id) - return (INT_PTR)countries[i].szName; - - return NULL; -} - -static INT_PTR GetCountryByISOCode(WPARAM wParam, LPARAM) -{ - for (int i = 0; i < SIZEOF(countries); i++) - if ( mir_strcmpi((char*)wParam, countries[i].ISOcode) == 0) - return (INT_PTR)countries[i].szName; - - return NULL; -} - -static INT_PTR GetCountryList(WPARAM wParam, LPARAM lParam) -{ - *(int*)wParam = SIZEOF(countries); - *(CountryListEntry**)lParam = countries; - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR SaveWindowPosition(WPARAM, LPARAM lParam) -{ - SAVEWINDOWPOS *swp = (SAVEWINDOWPOS*)lParam; - WINDOWPLACEMENT wp; - char szSettingName[64]; - - wp.length = sizeof(wp); - GetWindowPlacement(swp->hwnd, &wp); - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%sx", swp->szNamePrefix); - db_set_dw(swp->hContact, swp->szModule, szSettingName, wp.rcNormalPosition.left); - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%sy", swp->szNamePrefix); - db_set_dw(swp->hContact, swp->szModule, szSettingName, wp.rcNormalPosition.top); - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%swidth", swp->szNamePrefix); - db_set_dw(swp->hContact, swp->szModule, szSettingName, wp.rcNormalPosition.right-wp.rcNormalPosition.left); - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%sheight", swp->szNamePrefix); - db_set_dw(swp->hContact, swp->szModule, szSettingName, wp.rcNormalPosition.bottom-wp.rcNormalPosition.top); - return 0; -} - -static INT_PTR svcAssertInsideScreen(WPARAM wParam, LPARAM lParam) -{ - LPRECT rc = (LPRECT)wParam; - if (rc == NULL) - return -1; - - return AssertInsideScreen(*rc); -} - -int AssertInsideScreen(RECT &rc) -{ - RECT rcScreen; - SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, FALSE); - if (MonitorFromRect(&rc, MONITOR_DEFAULTTONULL)) - return 0; - - MONITORINFO mi = {0}; - HMONITOR hMonitor = MonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST); - mi.cbSize = sizeof(mi); - if (GetMonitorInfo(hMonitor, &mi)) - rcScreen = mi.rcWork; - - if (rc.top >= rcScreen.bottom) - OffsetRect(&rc, 0, rcScreen.bottom - rc.bottom); - else if (rc.bottom <= rcScreen.top) - OffsetRect(&rc, 0, rcScreen.top - rc.top); - if (rc.left >= rcScreen.right) - OffsetRect(&rc, rcScreen.right - rc.right, 0); - else if (rc.right <= rcScreen.left) - OffsetRect(&rc, rcScreen.left - rc.left, 0); - - return 1; -} - -static INT_PTR RestoreWindowPosition(WPARAM wParam, LPARAM lParam) -{ - SAVEWINDOWPOS *swp = (SAVEWINDOWPOS*)lParam; - WINDOWPLACEMENT wp; - char szSettingName[64]; - int x, y; - - wp.length = sizeof(wp); - GetWindowPlacement(swp->hwnd, &wp); - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%sx", swp->szNamePrefix); - x = db_get_dw(swp->hContact, swp->szModule, szSettingName, -1); - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%sy", swp->szNamePrefix); - y = (int)db_get_dw(swp->hContact, swp->szModule, szSettingName, -1); - if (x == -1) return 1; - if (wParam&RWPF_NOSIZE) { - OffsetRect(&wp.rcNormalPosition, x-wp.rcNormalPosition.left, y-wp.rcNormalPosition.top); - } - else { - wp.rcNormalPosition.left = x; - wp.rcNormalPosition.top = y; - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%swidth", swp->szNamePrefix); - wp.rcNormalPosition.right = wp.rcNormalPosition.left+db_get_dw(swp->hContact, swp->szModule, szSettingName, -1); - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%sheight", swp->szNamePrefix); - wp.rcNormalPosition.bottom = wp.rcNormalPosition.top+db_get_dw(swp->hContact, swp->szModule, szSettingName, -1); - } - wp.flags = 0; - if (wParam & RWPF_HIDDEN) - wp.showCmd = SW_HIDE; - if (wParam & RWPF_NOACTIVATE) - wp.showCmd = SW_SHOWNOACTIVATE; - - if (!(wParam & RWPF_NOMOVE)) - AssertInsideScreen(wp.rcNormalPosition); - - SetWindowPlacement(swp->hwnd, &wp); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR RestartMiranda(WPARAM wParam, LPARAM) -{ - TCHAR mirandaPath[MAX_PATH], cmdLine[MAX_PATH]; - PROCESS_INFORMATION pi; - STARTUPINFO si = {0}; - si.cb = sizeof(si); - GetModuleFileName(NULL, mirandaPath, SIZEOF(mirandaPath)); - if (wParam) { - VARST profilename( _T("%miranda_profilename%")); - mir_sntprintf(cmdLine, SIZEOF(cmdLine), _T("\"%s\" /restart:%d /profile=%s"), mirandaPath, GetCurrentProcessId(), (TCHAR*)profilename); - } - else mir_sntprintf(cmdLine, SIZEOF(cmdLine), _T("\"%s\" /restart:%d"), mirandaPath, GetCurrentProcessId()); - - CallService("CloseAction", 0, 0); - CreateProcess(mirandaPath, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -typedef BOOL (APIENTRY *PGENRANDOM)(PVOID, ULONG); - -static INT_PTR GenerateRandom(WPARAM wParam, LPARAM lParam) -{ - if (wParam == 0 || lParam == 0) return 0; - - PGENRANDOM pfnRtlGenRandom = NULL; - HMODULE hModule = GetModuleHandleA("advapi32"); - if (hModule) - { - pfnRtlGenRandom = (PGENRANDOM)GetProcAddress(hModule, "SystemFunction036"); - if (pfnRtlGenRandom) - { - if (!pfnRtlGenRandom((PVOID)lParam, wParam)) - pfnRtlGenRandom = NULL; - } - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -int LoadUtilsModule(void) -{ - bModuleInitialized = TRUE; - - CreateServiceFunction(MS_UTILS_RESIZEDIALOG, ResizeDialog); - CreateServiceFunction(MS_UTILS_SAVEWINDOWPOSITION, SaveWindowPosition); - CreateServiceFunction(MS_UTILS_RESTOREWINDOWPOSITION, RestoreWindowPosition); - CreateServiceFunction(MS_UTILS_ASSERTINSIDESCREEN, svcAssertInsideScreen); - CreateServiceFunction(MS_UTILS_GETCOUNTRYBYNUMBER, GetCountryByNumber); - CreateServiceFunction(MS_UTILS_GETCOUNTRYBYISOCODE, GetCountryByISOCode); - CreateServiceFunction(MS_UTILS_GETCOUNTRYLIST, GetCountryList); - CreateServiceFunction(MS_UTILS_GETRANDOM, GenerateRandom); - CreateServiceFunction(MS_UTILS_ENTERSTRING, svcEnterString); - CreateServiceFunction(MS_SYSTEM_RESTART, RestartMiranda); - - InitOpenUrl(); - InitWindowList(); - InitHyperlink(); - InitPathUtils(); - InitColourPicker(); - InitXmlApi(); - InitTimeZones(); - InitCrypt(); - return 0; -} - -void UnloadUtilsModule(void) -{ - if (!bModuleInitialized) - return; - - UninitCrypt(); -} diff --git a/src/modules/utils/windowlist.cpp b/src/modules/utils/windowlist.cpp deleted file mode 100644 index 19445a3851..0000000000 --- a/src/modules/utils/windowlist.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -struct TWindowListItem -{ - TWindowListItem(MCONTACT _contact, HWND _wnd) : - hContact(_contact), - hWnd(_wnd) - {} - - MCONTACT hContact; - HWND hWnd; -}; - -typedef OBJLIST TWindowList; - -static INT_PTR AllocWindowList(WPARAM, LPARAM) -{ - return (INT_PTR)new TWindowList(10, NumericKeySortT); -} - -static INT_PTR DestroyWindowList(WPARAM wParam, LPARAM) -{ - delete (TWindowList*)wParam; - return 0; -} - -static INT_PTR AddToWindowList(WPARAM, LPARAM lParam) -{ - WINDOWLISTENTRY *pEntry = (WINDOWLISTENTRY*)lParam; - TWindowList *pList = (TWindowList*)pEntry->hList; - if (pList != NULL) - pList->insert(new TWindowListItem(pEntry->hContact, pEntry->hwnd)); - return 0; -} - -static INT_PTR RemoveFromWindowList(WPARAM wParam, LPARAM lParam) -{ - if (wParam == 0) return 1; - TWindowList &pList = *(TWindowList*)wParam; - for (int i = 0; i < pList.getCount(); i++) { - if (pList[i].hWnd == (HWND)lParam) { - pList.remove(i); - return 0; - } - } - return 1; -} - -static INT_PTR FindInWindowList(WPARAM wParam, LPARAM lParam) -{ - if (wParam == 0) return NULL; - TWindowList &pList = *(TWindowList*)wParam; - TWindowListItem *p = pList.find((TWindowListItem*)&lParam); - return (p == NULL) ? NULL : (INT_PTR)p->hWnd; -} - -static INT_PTR BroadcastToWindowList(WPARAM wParam, LPARAM lParam) -{ - if (wParam == 0 || lParam == 0) return NULL; - TWindowList &pList = *(TWindowList*)wParam; - MSG *msg = (MSG*)lParam; - for (int i = pList.getCount()-1; i >= 0; i--) - SendMessage(pList[i].hWnd, msg->message, msg->wParam, msg->lParam); - return 0; -} - -static INT_PTR BroadcastToWindowListAsync(WPARAM wParam, LPARAM lParam) -{ - if (wParam == 0 || lParam == 0) return NULL; - TWindowList &pList = *(TWindowList*)wParam; - MSG *msg = (MSG*)lParam; - for (int i = pList.getCount()-1; i >= 0; i--) - PostMessage(pList[i].hWnd, msg->message, msg->wParam, msg->lParam); - return 0; -} - -int InitWindowList(void) -{ - CreateServiceFunction(MS_UTILS_ALLOCWINDOWLIST, AllocWindowList); - CreateServiceFunction(MS_UTILS_DESTROYWINDOWLIST, DestroyWindowList); - CreateServiceFunction(MS_UTILS_ADDTOWINDOWLIST, AddToWindowList); - CreateServiceFunction(MS_UTILS_REMOVEFROMWINDOWLIST, RemoveFromWindowList); - CreateServiceFunction(MS_UTILS_BROADCASTTOWINDOWLIST, BroadcastToWindowList); - CreateServiceFunction(MS_UTILS_BROADCASTTOWINDOWLIST_ASYNC, BroadcastToWindowListAsync); - CreateServiceFunction(MS_UTILS_FINDWINDOWINLIST, FindInWindowList); - return 0; -} diff --git a/src/modules/visibility/visibility.cpp b/src/modules/visibility/visibility.cpp deleted file mode 100644 index 6f694ef660..0000000000 --- a/src/modules/visibility/visibility.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" - -static void SetListGroupIcons(HWND hwndList, HANDLE hFirstItem, HANDLE hParentItem, int *groupChildCount) -{ - int iconOn[2] = {1, 1}; - int childCount[2] = {0, 0}; - - int typeOfFirst = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hFirstItem, 0); - //check groups - HANDLE hItem; - if (typeOfFirst == CLCIT_GROUP) - hItem = hFirstItem; - else - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hFirstItem); - - while (hItem) { - HANDLE hChildItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); - if (hChildItem) SetListGroupIcons(hwndList, hChildItem, hItem, childCount); - for (int i=0; i < SIZEOF(iconOn); i++) - if (iconOn[i] && SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, i) == 0) iconOn[i] = 0; - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hItem); - } - //check contacts - if (typeOfFirst == CLCIT_CONTACT) - hItem = hFirstItem; - else - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hFirstItem); - while (hItem) { - for (int i=0; i < SIZEOF(iconOn); i++) { - int iImage = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, i); - if (iconOn[i] && iImage == 0) iconOn[i] = 0; - if (iImage != EMPTY_EXTRA_ICON) - childCount[i]++; - } - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hItem); - } - //set icons - for (int i=0; i < SIZEOF(iconOn); i++) { - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hParentItem, MAKELPARAM(i, childCount[i]?(iconOn[i]?i+1:0):EMPTY_EXTRA_ICON)); - if (groupChildCount) groupChildCount[i]+=childCount[i]; - } -} - -static void SetAllChildIcons(HWND hwndList, HANDLE hFirstItem, int iColumn, int iImage) -{ - int typeOfFirst = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hFirstItem, 0); - //check groups - HANDLE hItem; - if (typeOfFirst == CLCIT_GROUP) - hItem = hFirstItem; - else - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hFirstItem); - while (hItem) { - HANDLE hChildItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); - if (hChildItem) - SetAllChildIcons(hwndList, hChildItem, iColumn, iImage); - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hItem); - } - //check contacts - if (typeOfFirst == CLCIT_CONTACT) - hItem = hFirstItem; - else - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hFirstItem); - while (hItem) { - int iOldIcon = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, iColumn); - if (iOldIcon != EMPTY_EXTRA_ICON && iOldIcon != iImage) - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hItem); - } -} - -static void ResetListOptions(HWND hwndList) -{ - SetWindowLongPtr(hwndList, GWL_STYLE, GetWindowLongPtr(hwndList, GWL_STYLE)|CLS_SHOWHIDDEN); -} - -static void SetAllContactIcons(HWND hwndList) -{ - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - HANDLE hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, hContact, 0); - if (hItem == NULL) - continue; - - DWORD flags; - WORD status; - char *szProto = GetContactProto(hContact); - if (szProto == NULL) { - flags = 0; - status = 0; - } - else { - flags = CallProtoServiceInt(NULL,szProto, PS_GETCAPS, PFLAGNUM_1, 0); - status = db_get_w(hContact, szProto, "ApparentMode", 0); - } - - if (flags & PF1_INVISLIST) - if (SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(0, 0)) == EMPTY_EXTRA_ICON) - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(0, status == ID_STATUS_ONLINE ? 1 : 0)); - - if (flags & PF1_VISLIST) - if (SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(1, 0)) == EMPTY_EXTRA_ICON) - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(1, status == ID_STATUS_OFFLINE ? 2 : 0)); - } -} - -static INT_PTR CALLBACK DlgProcVisibilityOpts(HWND hwndDlg, UINT msg, WPARAM, LPARAM lParam) -{ - static HICON hVisibleIcon, hInvisibleIcon; - static HANDLE hItemAll; - - HIMAGELIST hIml; - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - hIml = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 3, 3); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_SMALLDOT); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_VISIBLE_ALL); - ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_INVISIBLE_ALL); - SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_SETEXTRAIMAGELIST, 0, (LPARAM)hIml); - hVisibleIcon = ImageList_GetIcon(hIml, 1, ILD_NORMAL); - SendDlgItemMessage(hwndDlg, IDC_VISIBLEICON, STM_SETICON, (WPARAM)hVisibleIcon, 0); - hInvisibleIcon = ImageList_GetIcon(hIml, 2, ILD_NORMAL); - SendDlgItemMessage(hwndDlg, IDC_INVISIBLEICON, STM_SETICON, (WPARAM)hInvisibleIcon, 0); - - ResetListOptions(GetDlgItem(hwndDlg, IDC_LIST)); - SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_SETEXTRACOLUMNS, 2, 0); - { - CLCINFOITEM cii = { sizeof(cii) }; - cii.flags = CLCIIF_GROUPFONT; - cii.pszText = TranslateT("** All contacts **"); - hItemAll = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_ADDINFOITEM, 0, (LPARAM)&cii); - } - SetAllContactIcons(GetDlgItem(hwndDlg, IDC_LIST)); - SetListGroupIcons(GetDlgItem(hwndDlg, IDC_LIST), (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll, NULL); - return TRUE; - - case WM_SETFOCUS: - SetFocus(GetDlgItem(hwndDlg, IDC_LIST)); - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->idFrom) { - case IDC_LIST: - switch (((LPNMHDR)lParam)->code) { - case CLN_NEWCONTACT: - case CLN_LISTREBUILT: - SetAllContactIcons(GetDlgItem(hwndDlg, IDC_LIST)); - //fall through - case CLN_CONTACTMOVED: - SetListGroupIcons(GetDlgItem(hwndDlg, IDC_LIST), (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll, NULL); - break; - - case CLN_OPTIONSCHANGED: - ResetListOptions(GetDlgItem(hwndDlg, IDC_LIST)); - break; - - case NM_CLICK: - // Make sure we have an extra column - NMCLISTCONTROL *nm = (NMCLISTCONTROL*)lParam; - if (nm->iColumn == -1) - break; - - // Find clicked item - DWORD hitFlags; - HANDLE hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_HITTEST, (WPARAM)&hitFlags, MAKELPARAM(nm->pt.x, nm->pt.y)); - if (hItem == NULL) - break; - - // It was not a visbility icon - if (!(hitFlags & CLCHT_ONITEMEXTRA)) - break; - - // Get image in clicked column (0 = none, 1 = visible, 2 = invisible) - int iImage = SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(nm->iColumn, 0)); - if (iImage == 0) - iImage = nm->iColumn + 1; - else if (iImage == 1 || iImage == 2) - iImage = 0; - - // Get item type (contact, group, etc...) - int itemType = SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETITEMTYPE, (WPARAM)hItem, 0); - - // Update list, making sure that the options are mutually exclusive - if (itemType == CLCIT_CONTACT) { // A contact - SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(nm->iColumn, iImage)); - if (iImage && SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(nm->iColumn ? 0 : 1, 0)) != EMPTY_EXTRA_ICON) - SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(nm->iColumn ? 0 : 1, 0)); - } - else if (itemType == CLCIT_INFO) { // All Contacts - SetAllChildIcons(GetDlgItem(hwndDlg, IDC_LIST), hItem, nm->iColumn, iImage); - if (iImage) - SetAllChildIcons(GetDlgItem(hwndDlg, IDC_LIST), hItem, nm->iColumn ? 0 : 1, 0); - } - else if (itemType == CLCIT_GROUP) { // A group - hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); - if (hItem) { - SetAllChildIcons(GetDlgItem(hwndDlg, IDC_LIST), hItem, nm->iColumn, iImage); - if (iImage) - SetAllChildIcons(GetDlgItem(hwndDlg, IDC_LIST), hItem, nm->iColumn ? 0 : 1, 0); - } - } - // Update the all/none icons - SetListGroupIcons(GetDlgItem(hwndDlg, IDC_LIST), (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll, NULL); - - // Activate Apply button - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - break; - - case 0: - if (((LPNMHDR)lParam)->code == PSN_APPLY) { - for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - HANDLE hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_FINDCONTACT, hContact, 0); - if (hItem == NULL) - continue; - - int set = 0; - for (int i = 0; i < 2; i++) { - int iImage = SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(i, 0)); - if (iImage == i + 1) { - CallContactService(hContact, PSS_SETAPPARENTMODE, iImage == 1 ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE, 0); - set = 1; - break; - } - } - if (!set) - CallContactService(hContact, PSS_SETAPPARENTMODE, 0, 0); - } - return TRUE; - } - } - break; - - case WM_DESTROY: - DestroyIcon(hVisibleIcon); - DestroyIcon(hInvisibleIcon); - - hIml = (HIMAGELIST)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETEXTRAIMAGELIST, 0, 0); - ImageList_Destroy(hIml); - break; - } - return FALSE; -} - -static int VisibilityOptInitialise(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.position = 850000000; - odp.hInstance = hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_VISIBILITY); - odp.pszTitle = LPGEN("Visibility"); - odp.pszGroup = LPGEN("Contacts"); - odp.pfnDlgProc = DlgProcVisibilityOpts; - odp.flags = ODPF_BOLDGROUPS; - Options_AddPage(wParam, &odp); - return 0; -} - -int LoadVisibilityModule(void) -{ - HookEvent(ME_OPT_INITIALISE, VisibilityOptInitialise); - return 0; -} diff --git a/src/modules/xml/xmlApi.cpp b/src/modules/xml/xmlApi.cpp deleted file mode 100644 index 37aadfa12b..0000000000 --- a/src/modules/xml/xmlApi.cpp +++ /dev/null @@ -1,467 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright () 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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 "..\..\core\commonheaders.h" -#include "xmlParser.h" - -static HXML xmlapiCreateNode(LPCTSTR name, LPCTSTR text, char isDeclaration) -{ - XMLNode result = XMLNode::createXMLTopNode(name, isDeclaration); - if (text) - result.updateText(text); - return result.detach(); -} - -static void xmlapiDestroyNode(HXML n) -{ - XMLNode tmp; tmp.attach(n); -} - -static HXML xmlapiParseFile(LPCTSTR str, int* datalen, LPCTSTR tag) -{ - if (str == NULL) return NULL; - - XMLResults res; - XMLNode result = XMLNode::parseFile(str, tag, &res); - - if (datalen != NULL) - datalen[0] += res.nChars; - - return (res.error == eXMLErrorNone || (tag != NULL && res.error == eXMLErrorMissingEndTag)) ? result.detach() : NULL; -} - -static HXML xmlapiParseString(LPCTSTR str, int* datalen, LPCTSTR tag) -{ - if (str == NULL) return NULL; - - XMLResults res; - XMLNode result = XMLNode::parseString(str, tag, &res); - - if (datalen != NULL) - datalen[0] += res.nChars; - - return (res.error == eXMLErrorNone || (tag != NULL && res.error == eXMLErrorMissingEndTag)) ? result.detach() : NULL; -} - -static HXML xmlapiAddChild(HXML _n, LPCTSTR name, LPCTSTR text) -{ - XMLNode result = XMLNode(_n).addChild(name); - if (text != NULL) - result.updateText(text); - return result; -} - -static void xmlapiAddChild2(HXML _child, HXML _parent) -{ - XMLNode child(_child), parent(_parent); - parent.addChild(child); -} - -static HXML xmlapiCopyNode(HXML _n) -{ - XMLNode result = XMLNode(_n); - return result.detach(); -} - -static LPCTSTR xmlapiGetAttr(HXML _n, int i) -{ - return XMLNode(_n).getAttributeValue(i); -} - -static int xmlapiGetAttrCount(HXML _n) -{ - return XMLNode(_n).nAttribute(); -} - -static LPCTSTR xmlapiGetAttrName(HXML _n, int i) -{ - return XMLNode(_n).getAttributeName(i); -} - -static HXML xmlapiGetChild(HXML _n, int i) -{ - return XMLNode(_n).getChildNode(i); -} - -static HXML xmlapiGetChildByAttrValue(HXML _n, LPCTSTR name, LPCTSTR attrName, LPCTSTR attrValue) -{ - return XMLNode(_n).getChildNodeWithAttribute(name, attrName, attrValue); -} - -static int xmlapiGetChildCount(HXML _n) -{ - return XMLNode(_n).nChildNode(); -} - -static HXML xmlapiGetFirstChild(HXML _n) -{ - return XMLNode(_n).getChildNode(0); -} - -static HXML xmlapiGetNthChild(HXML _n, LPCTSTR name, int i) -{ - return XMLNode(_n).getChildNode(name, i); -} - -static HXML xmlapiGetNextChild(HXML _n, LPCTSTR name, int* i) -{ - return XMLNode(_n).getChildNode(name, i); -} - -static HXML xmlapiGetNextNode(HXML _n) -{ - return XMLNode(_n).getNextNode(); -} - -static HXML xmlapiGetChildByPath(HXML _n, LPCTSTR path, char createNodeIfMissing) -{ - return XMLNode(_n).getChildNodeByPath(path, createNodeIfMissing); -} - -static LPCTSTR xmlapiGetName(HXML _n) -{ - return XMLNode(_n).getName(); -} - -static HXML xmlapiGetParent(HXML _n) -{ - return XMLNode(_n).getParentNode(); -} - -static LPCTSTR xmlapiGetText(HXML _n) -{ - return XMLNode(_n).getInnerText(); -} - -static LPCTSTR xmlapiGetAttrValue(HXML _n, LPCTSTR attrName) -{ - return XMLNode(_n).getAttribute(attrName); -} - -static void xmlapiSetText(HXML _n, LPCTSTR _text) -{ - XMLNode(_n).updateText(_text); -} - -static LPTSTR xmlapiToString(HXML _n, int* datalen) -{ - return XMLNode(_n).createXMLString(0, datalen); -} - -static XMLError xmlapiToFile(HXML _n, LPCTSTR filename, int withformatting) -{ - return XMLNode(_n).writeToFile(filename, NULL, withformatting); -} - -static void xmlapiAddAttr(HXML _n, LPCTSTR attrName, LPCTSTR attrValue) -{ - if (attrName != NULL && attrValue != NULL) - XMLNode(_n).addAttribute(attrName, attrValue); -} - -static void xmlapiAddAttrInt(HXML _n, LPCTSTR attrName, int attrValue) -{ - TCHAR buf[40]; - _itot(attrValue, buf, 10); - XMLNode(_n).addAttribute(attrName, buf); -} - -static void xmlapiFree(void* p) -{ - free(p); -} - -// XML API v2 methods -static int xmlapiGetTextCount(HXML _n) -{ - return XMLNode(_n).nText(); -} - -static LPCTSTR xmlapiGetTextByIndex(HXML _n, int i) -{ - return XMLNode(_n).getText(i); -} - -static void xmlapiSetTextByIndex(HXML _n, int i, LPCTSTR value) -{ - XMLNode(_n).updateText(value, i); -} - -static void xmlapiAddText(HXML _n, LPCTSTR value, XML_ELEMENT_POS pos) -{ - XMLNode(_n).addText(value, (XMLElementPosition)pos); -} - -static LPTSTR xmlapiToStringWithFormatting(HXML _n, int* datalen) -{ - return XMLNode(_n).createXMLString(1, datalen); -} - -static int xmlapiGetClearCount(HXML _n) -{ - return XMLNode(_n).nClear(); -} - -static LPCTSTR xmlapiGetClear(HXML _n, int i, LPCTSTR *openTag, LPCTSTR *closeTag) -{ - XMLClear c = XMLNode(_n).getClear(i); - if (openTag) - *openTag = c.lpszOpenTag; - if (closeTag) - *closeTag = c.lpszCloseTag; - return c.lpszValue; -} - -static void xmlapiAddClear(HXML _n, LPCTSTR lpszValue, LPCTSTR openTag, LPCTSTR closeTag, XML_ELEMENT_POS pos) -{ - XMLNode(_n).addClear(lpszValue, openTag, closeTag, (XMLElementPosition)pos); -} - -static void xmlapiSetClear(HXML _n, int i, LPCTSTR lpszValue) -{ - XMLNode(_n).updateClear(lpszValue, i); -} - -static int xmlapiGetElement(HXML _n, XML_ELEMENT_POS pos, XML_ELEMENT_TYPE *type, HXML *child, LPCTSTR *value, LPCTSTR *name, LPCTSTR *openTag, LPCTSTR *closeTag) -{ - // reset all values - if (child) - *child = NULL; - if (value) - *value = NULL; - if (name) - *name = NULL; - if (openTag) - *openTag = NULL; - if (closeTag) - *closeTag = NULL; - - if (!type || pos >= XMLNode(_n).nElement()) - return false; - XMLNodeContents c(XMLNode(_n).enumContents((XMLElementPosition)pos)); - switch (c.etype) { - case eNodeChild: - { - *type = XML_ELEM_TYPE_CHILD; - if (child) - *child = c.child; - } break; - case eNodeAttribute: - { - *type = XML_ELEM_TYPE_ATTRIBUTE; - if (name) - *name = c.attrib.lpszName; - if (value) - *value = c.attrib.lpszValue; - } break; - case eNodeText: - { - *type = XML_ELEM_TYPE_TEXT; - if (value) - *value = c.text; - } break; - case eNodeClear: - { - *type = XML_ELEM_TYPE_CLEAR; - if (value) - *value = c.clear.lpszValue; - if (openTag) - *openTag = c.clear.lpszOpenTag; - if (closeTag) - *closeTag = c.clear.lpszCloseTag; - } break; - case eNodeNULL: - { - return false; - } break; - } - return true; -} - -static int xmlapiGetElementCount(HXML _n) -{ - return XMLNode(_n).nElement(); -} - -static char xmlapiIsDeclaration(HXML _n) -{ - return XMLNode(_n).isDeclaration(); -} - -static HXML xmlapiDeepCopy(HXML _n) -{ - return XMLNode(_n).deepCopy().detach(); -} - -static HXML xmlapiAddChildEx(HXML _n, LPCTSTR name, char isDeclaration, XML_ELEMENT_POS pos) -{ - return XMLNode(_n).addChild(name, isDeclaration, (XMLElementPosition)pos); -} - -static void xmlapiAddChildEx2(HXML _n, HXML parent, XML_ELEMENT_POS pos) -{ - XMLNode(_n).addChild(parent, (XMLElementPosition)pos); -} - -static void xmlapiSetAttrByIndex(HXML _n, int i, LPCTSTR value) -{ - XMLNode(_n).updateAttribute(value, NULL, i); -} - -static void xmlapiSetAttrByName(HXML _n, LPCTSTR name, LPCTSTR value) -{ - XMLNode(_n).updateAttribute(value, NULL, name); -} - -static void xmlapiDeleteNodeContent(HXML _n) -{ - XMLNode(_n).deleteNodeContent(); -} - -static void xmlapiDeleteAttrByIndex(HXML _n, int i) -{ - XMLNode(_n).deleteAttribute(i); -} - -static void xmlapiDeleteAttrByName(HXML _n, LPCTSTR name) -{ - XMLNode(_n).deleteAttribute(name); -} - -static void xmlapiDeleteText(HXML _n, int i) -{ - XMLNode(_n).deleteText(i); -} - -static void xmlapiDeleteClear(HXML _n, int i) -{ - XMLNode(_n).deleteClear(i); -} - -static XML_ELEMENT_POS xmlapiPositionOfText(HXML _n, int i) -{ - return (XML_ELEMENT_POS)XMLNode(_n).positionOfText(i); -} - -static XML_ELEMENT_POS xmlapiPositionOfClear(HXML _n, int i) -{ - return (XML_ELEMENT_POS)XMLNode(_n).positionOfClear(i); -} - -static XML_ELEMENT_POS xmlapiPositionOfChildByIndex(HXML _n, int i) -{ - return (XML_ELEMENT_POS)XMLNode(_n).positionOfChildNode(i); -} - -static XML_ELEMENT_POS xmlapiPositionOfChildByNode(HXML _n, HXML child) -{ - return (XML_ELEMENT_POS)XMLNode(_n).positionOfChildNode(child); -} - -static XML_ELEMENT_POS xmlapiPositionOfChildByName(HXML _n, LPCTSTR name, int i) -{ - return (XML_ELEMENT_POS)XMLNode(_n).positionOfChildNode(name, i); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR GetXmlApi(WPARAM, LPARAM lParam) -{ - XML_API* xi = (XML_API*)lParam; - if (xi == NULL) - return FALSE; - - if (xi->cbSize != XML_API_SIZEOF_V1 && xi->cbSize != sizeof(XML_API)) - return FALSE; - - xi->createNode = xmlapiCreateNode; - xi->destroyNode = xmlapiDestroyNode; - - xi->parseString = xmlapiParseString; - xi->toString = xmlapiToString; - xi->freeMem = xmlapiFree; - xi->parseFile = xmlapiParseFile; - xi->toFile = xmlapiToFile; - - xi->addChild = xmlapiAddChild; - xi->addChild2 = xmlapiAddChild2; - xi->copyNode = xmlapiCopyNode; - xi->getChild = xmlapiGetChild; - xi->getChildByAttrValue = xmlapiGetChildByAttrValue; - xi->getChildCount = xmlapiGetChildCount; - xi->getFirstChild = xmlapiGetFirstChild; - xi->getNthChild = xmlapiGetNthChild; - xi->getNextChild = xmlapiGetNextChild; - xi->getNextNode = xmlapiGetNextNode; - xi->getChildByPath = xmlapiGetChildByPath; - xi->getName = xmlapiGetName; - xi->getParent = xmlapiGetParent; - xi->getText = xmlapiGetText; - xi->setText = xmlapiSetText; - - xi->getAttr = xmlapiGetAttr; - xi->getAttrCount = xmlapiGetAttrCount; - xi->getAttrName = xmlapiGetAttrName; - xi->getAttrValue = xmlapiGetAttrValue; - xi->addAttr = xmlapiAddAttr; - xi->addAttrInt = xmlapiAddAttrInt; - - if (xi->cbSize > XML_API_SIZEOF_V1) { - xi->isDeclaration = xmlapiIsDeclaration; - xi->toStringWithFormatting = xmlapiToStringWithFormatting; - xi->deepCopy = xmlapiDeepCopy; - xi->setAttrByIndex = xmlapiSetAttrByIndex; - xi->setAttrByName = xmlapiSetAttrByName; - xi->addChildEx = xmlapiAddChildEx; - xi->addChildEx2 = xmlapiAddChildEx2; - xi->getTextCount = xmlapiGetTextCount; - xi->getTextByIndex = xmlapiGetTextByIndex; - xi->addText = xmlapiAddText; - xi->setTextByIndex = xmlapiSetTextByIndex; - xi->getClearCount = xmlapiGetClearCount; - xi->getClear = xmlapiGetClear; - xi->addClear = xmlapiAddClear; - xi->setClear = xmlapiSetClear; - xi->getElementCount = xmlapiGetElementCount; - xi->getElement = xmlapiGetElement; - - xi->deleteNodeContent = xmlapiDeleteNodeContent; - xi->deleteAttrByIndex = xmlapiDeleteAttrByIndex; - xi->deleteAttrByName = xmlapiDeleteAttrByName; - xi->deleteText = xmlapiDeleteText; - xi->deleteClear = xmlapiDeleteClear; - - xi->positionOfChildByIndex = xmlapiPositionOfChildByIndex; - xi->positionOfChildByNode = xmlapiPositionOfChildByNode; - xi->positionOfChildByName = xmlapiPositionOfChildByName; - xi->positionOfText = xmlapiPositionOfText; - xi->positionOfClear = xmlapiPositionOfClear; - } - return TRUE; -} - -void InitXmlApi(void) -{ - CreateServiceFunction(MS_SYSTEM_GET_XI, GetXmlApi); -} diff --git a/src/modules/xml/xmlParser.cpp b/src/modules/xml/xmlParser.cpp deleted file mode 100644 index eae664e888..0000000000 --- a/src/modules/xml/xmlParser.cpp +++ /dev/null @@ -1,3076 +0,0 @@ -/** -**************************************************************************** -*

XML.c - implementation file for basic XML parser written in ANSI C++ -* for portability. It works by using recursion and a node tree for breaking -* down the elements of an XML document.

-* -* @version V2.43 -* @author Frank Vanden Berghen -* -* NOTE: -* -* If you add "#define STRICT_PARSING", on the first line of this file -* the parser will see the following XML-stream: -* some textother text -* as an error. Otherwise, this tring will be equivalent to: -* some textother text -* -* NOTE: -* -* If you add "#define APPROXIMATE_PARSING" on the first line of this file -* the parser will see the following XML-stream: -* -* -* -* as equivalent to the following XML-stream: -* -* -* -* This can be useful for badly-formed XML-streams but prevent the use -* of the following XML-stream (problem is: tags at contiguous levels -* have the same names): -* -* -* -* -* -* -* NOTE: -* -* If you add "#define _XMLPARSER_NO_MESSAGEBOX_" on the first line of this file -* the "openFileHelper" function will always display error messages inside the -* console instead of inside a message-box-window. Message-box-windows are -* available on windows 9x/NT/2000/XP/Vista only. -* -* Copyright (c) 2002, Business-Insight -* Business-Insight -* All rights reserved. -* See the file "AFPL-license.txt" about the licensing terms -* -**************************************************************************** -*/ - -#include "..\..\core\commonheaders.h" -#include "xmlParser.h" - -#include -#include -#include -#include -#include - -XMLCSTR XMLNode::getVersion() { return _CXML("v2.43"); } -void freeXMLString(XMLSTR t) {if(t)free(t);} - -static XMLNode::XMLCharEncoding characterEncoding = XMLNode::char_encoding_UTF8; -static char guessWideCharChars = 1, dropWhiteSpace = 0, removeCommentsInMiddleOfText = 1; - -inline int mmin(const int t1, const int t2) { return t1 < t2 ? t1 : t2; } - -// You can modify the initialization of the variable "XMLClearTags" below -// to change the clearTags that are currently recognized by the library. -// The number on the second columns is the length of the string inside the -// first column. -// The "") }, - { _CXML("") }, - { _CXML("") }, - { _CXML("
")    , 5,  _CXML("
") }, - // { _CXML("")}, - { NULL , 0, NULL } -}; - -// You can modify the initialization of the variable "XMLEntities" below -// to change the character entities that are currently recognized by the library. -// The number on the second columns is the length of the string inside the -// first column. Additionally, the syntaxes " " and " " are recognized. -typedef struct { XMLCSTR s; int l; XMLCHAR c;} XMLCharacterEntity; -static XMLCharacterEntity XMLEntities[] = -{ - { _CXML("&"), 5, _CXML('&')}, - { _CXML("<"), 4, _CXML('<')}, - { _CXML(">"), 4, _CXML('>')}, - { _CXML("""), 6, _CXML('\"')}, - { _CXML("'"), 6, _CXML('\'')}, - { NULL , 0, '\0' } -}; - -// When rendering the XMLNode to a string (using the "createXMLString" function), -// you can ask for a beautiful formatting. This formatting is using the -// following indentation character: -#define INDENTCHAR _CXML('\t') - -// The following function parses the XML errors into a user friendly string. -// You can edit this to change the output language of the library to something else. -XMLCSTR XMLNode::getError(XMLError xerror) -{ - switch (xerror) - { - case eXMLErrorNone: return _CXML("No error"); - case eXMLErrorMissingEndTag: return _CXML("Warning: Unmatched end tag"); - case eXMLErrorNoXMLTagFound: return _CXML("Warning: No XML tag found"); - case eXMLErrorEmpty: return _CXML("Error: No XML data"); - case eXMLErrorMissingTagName: return _CXML("Error: Missing start tag name"); - case eXMLErrorMissingEndTagName: return _CXML("Error: Missing end tag name"); - case eXMLErrorUnmatchedEndTag: return _CXML("Error: Unmatched end tag"); - case eXMLErrorUnmatchedEndClearTag: return _CXML("Error: Unmatched clear tag end"); - case eXMLErrorUnexpectedToken: return _CXML("Error: Unexpected token found"); - case eXMLErrorNoElements: return _CXML("Error: No elements found"); - case eXMLErrorFileNotFound: return _CXML("Error: File not found"); - case eXMLErrorFirstTagNotFound: return _CXML("Error: First Tag not found"); - case eXMLErrorUnknownCharacterEntity:return _CXML("Error: Unknown character entity"); - case eXMLErrorCharacterCodeAbove255: return _CXML("Error: Character code above 255 is forbidden in MultiByte char mode."); - case eXMLErrorCharConversionError: return _CXML("Error: unable to convert between WideChar and MultiByte chars"); - case eXMLErrorCannotOpenWriteFile: return _CXML("Error: unable to open file for writing"); - case eXMLErrorCannotWriteFile: return _CXML("Error: cannot write into file"); - - case eXMLErrorBase64DataSizeIsNotMultipleOf4: return _CXML("Warning: Base64-string length is not a multiple of 4"); - case eXMLErrorBase64DecodeTruncatedData: return _CXML("Warning: Base64-string is truncated"); - case eXMLErrorBase64DecodeIllegalCharacter: return _CXML("Error: Base64-string contains an illegal character"); - case eXMLErrorBase64DecodeBufferTooSmall: return _CXML("Error: Base64 decode output buffer is too small"); - }; - return _CXML("Unknown"); -} - -///////////////////////////////////////////////////////////////////////// -// Here start the abstraction layer to be OS-independent // -///////////////////////////////////////////////////////////////////////// - -// Here is an abstraction layer to access some common string manipulation functions. -// The abstraction layer is currently working for gcc, Microsoft Visual Studio 6.0, -// Microsoft Visual Studio .NET, CC (sun compiler) and Borland C++. -// If you plan to "port" the library to a new system/compiler, all you have to do is -// to edit the following lines. -#ifdef XML_NO_WIDE_CHAR -char myIsTextWideChar(const void *b, int len) { return FALSE; } -#else -#if defined (UNDER_CE) || !defined(_XMLWINDOWS) -char myIsTextWideChar(const void *b, int len) // inspired by the Wine API: RtlIsTextUnicode -{ -#ifdef sun - // for SPARC processors: wchar_t* buffers must always be alligned, otherwise it's a char* buffer. - if ((((unsigned long)b)%sizeof(wchar_t)) != 0) return FALSE; -#endif - const wchar_t *s = (const wchar_t*)b; - - // buffer too small: - if (lenlen/2) return TRUE; - - // Check for UNICODE NULL chars - for (i=0; i -static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return wsncasecmp(c1, c2, l);} -static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return wsncmp(c1, c2, l);} -static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return wscasecmp(c1, c2); } -#else -static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return wcsncmp(c1, c2, l);} -#ifdef __linux__ -// for gcc/linux -static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return wcsncasecmp(c1, c2, l);} -static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return wcscasecmp(c1, c2); } -#else -#include -// for gcc/non-linux (MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX 4.3.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Cygwin, mingw) -static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) -{ - wchar_t left, right; - do - { - left = towlower(*c1++); right = towlower(*c2++); - } while (left&&(left == right)); - return (int)left-(int)right; -} -static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) -{ - wchar_t left, right; - while (l--) - { - left = towlower(*c1++); right = towlower(*c2++); - if ((!left) || (left != right)) return (int)left-(int)right; - } - return 0; -} -#endif -#endif -static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)wcsstr(c1, c2); } -static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)mir_wstrcpy(c1, c2); } -static inline FILE *xfopen(XMLCSTR filename, XMLCSTR mode) -{ - char *filenameAscii = myWideCharToMultiByte(filename); - FILE *f; - if (mode[0] == _CXML('r')) f = fopen(filenameAscii, "rb"); - else f = fopen(filenameAscii, "wb"); - free(filenameAscii); - return f; -} -#else -static inline FILE *xfopen(XMLCSTR filename, XMLCSTR mode) { return fopen(filename, mode); } -static inline int xstrlen(XMLCSTR c) { return mir_strlen(c); } -static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return strncasecmp(c1, c2, l);} -static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return strncmp(c1, c2, l);} -static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return strcasecmp(c1, c2); } -static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)strstr(c1, c2); } -static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)mir_strcpy(c1, c2); } -#endif -static inline int _strnicmp(const char *c1, const char *c2, int l) { return strncasecmp(c1, c2, l);} -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// the "xmltoc, xmltob, xmltoi, xmltol, xmltof, xmltoa" functions // -/////////////////////////////////////////////////////////////////////////////// -// These 6 functions are not used inside the XMLparser. -// There are only here as "convenience" functions for the user. -// If you don't need them, you can delete them without any trouble. -#ifdef _XMLWIDECHAR -#ifdef _XMLWINDOWS -// for Microsoft Visual Studio 6.0 and Microsoft Visual Studio .NET and Borland C++ Builder 6.0 -char xmltob(XMLCSTR t, char v) { if (t&&(*t)) return (char)_wtoi(t); return v; } -int xmltoi(XMLCSTR t, int v) { if (t&&(*t)) return _wtoi(t); return v; } -long xmltol(XMLCSTR t, long v) { if (t&&(*t)) return _wtol(t); return v; } -double xmltof(XMLCSTR t, double v) { if (t&&(*t)) swscanf(t, L"%lf", &v); /*v = _wtof(t);*/ return v; } -#else -#ifdef sun -// for CC -#include -char xmltob(XMLCSTR t, char v) { if (t) return (char)wstol(t, NULL, 10); return v; } -int xmltoi(XMLCSTR t, int v) { if (t) return (int)wstol(t, NULL, 10); return v; } -long xmltol(XMLCSTR t, long v) { if (t) return wstol(t, NULL, 10); return v; } -#else -// for gcc -char xmltob(XMLCSTR t, char v) { if (t) return (char)wcstol(t, NULL, 10); return v; } -int xmltoi(XMLCSTR t, int v) { if (t) return (int)wcstol(t, NULL, 10); return v; } -long xmltol(XMLCSTR t, long v) { if (t) return wcstol(t, NULL, 10); return v; } -#endif -double xmltof(XMLCSTR t, double v) { if (t&&(*t)) swscanf(t, L"%lf", &v); /*v = _wtof(t);*/ return v; } -#endif -#else -char xmltob(XMLCSTR t, char v) { if (t&&(*t)) return (char)atoi(t); return v; } -int xmltoi(XMLCSTR t, int v) { if (t&&(*t)) return atoi(t); return v; } -long xmltol(XMLCSTR t, long v) { if (t&&(*t)) return atol(t); return v; } -double xmltof(XMLCSTR t, double v) { if (t&&(*t)) return atof(t); return v; } -#endif -XMLCSTR xmltoa(XMLCSTR t, XMLCSTR v) { if (t) return t; return v; } -XMLCHAR xmltoc(XMLCSTR t, const XMLCHAR v) { if (t&&(*t)) return *t; return v; } - -///////////////////////////////////////////////////////////////////////// -// the "openFileHelper" function // -///////////////////////////////////////////////////////////////////////// - -// Since each application has its own way to report and deal with errors, you should modify & rewrite -// the following "openFileHelper" function to get an "error reporting mechanism" tailored to your needs. -XMLNode XMLNode::openFileHelper(XMLCSTR filename, XMLCSTR tag) -{ - // guess the value of the global parameter "characterEncoding" - // (the guess is based on the first 200 bytes of the file). - FILE *f = xfopen(filename, _CXML("rb")); - if (f) - { - char bb[205]; - int l = (int)fread(bb, 1, 200, f); - setGlobalOptions(guessCharEncoding(bb, l), guessWideCharChars, dropWhiteSpace, removeCommentsInMiddleOfText); - fclose(f); - } - - // parse the file - XMLResults pResults; - XMLNode xnode = XMLNode::parseFile(filename, tag, &pResults); - - // display error message (if any) - if (pResults.error != eXMLErrorNone) - { - // create message - char message[2000], *s1 = (char*)"", *s3 = (char*)""; XMLCSTR s2 = _CXML(""); - if (pResults.error == eXMLErrorFirstTagNotFound) { s1 = (char*)"First Tag should be '"; s2 = tag; s3 = (char*)"'.\n"; } - mir_snprintf(message, SIZEOF(message), -#ifdef _XMLWIDECHAR - "XML Parsing error inside file '%S'.\n%S\nAt line %i, column %i.\n%s%S%s" -#else - "XML Parsing error inside file '%s'.\n%s\nAt line %i, column %i.\n%s%s%s" -#endif - , filename, XMLNode::getError(pResults.error), pResults.nLine, pResults.nColumn, s1, s2, s3); - - // display message -#if defined(_XMLWINDOWS) && !defined(UNDER_CE) && !defined(_XMLPARSER_NO_MESSAGEBOX_) - MessageBoxA(NULL, message, "XML Parsing error", MB_OK|MB_ICONERROR|MB_TOPMOST); -#else - printf("%s", message); -#endif - exit(255); - } - return xnode; -} - -///////////////////////////////////////////////////////////////////////// -// Here start the core implementation of the XMLParser library // -///////////////////////////////////////////////////////////////////////// - -// You should normally not change anything below this point. - -#ifndef _XMLWIDECHAR -// If "characterEncoding = ascii" then we assume that all characters have the same length of 1 byte. -// If "characterEncoding = UTF8" then the characters have different lengths (from 1 byte to 4 bytes). -// If "characterEncoding = ShiftJIS" then the characters have different lengths (from 1 byte to 2 bytes). -// This table is used as lookup-table to know the length of a character (in byte) based on the -// content of the first byte of the character. -// (note: if you modify this, you must always have XML_utf8ByteTable[0] = 0). -static const char XML_utf8ByteTable[256] = -{ - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 - 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte - 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid -}; -static const char XML_legacyByteTable[256] = -{ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 -}; -static const char XML_sjisByteTable[256] = -{ - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0x80 0x81 to 0x9F 2 bytes - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0x90 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 0xe0 to 0xef 2 bytes - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 -}; -static const char XML_gb2312ByteTable[256] = -{ - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xa0 0xa1 to 0xf7 2 bytes - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xb0 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 - 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 -}; -static const char XML_gbk_big5_ByteTable[256] = -{ - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0x80 0x81 to 0xfe 2 bytes - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0x90 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xa0 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xb0 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 // 0xf0 -}; -static const char *XML_ByteTable = (const char *)XML_utf8ByteTable; // the default is "characterEncoding = XMLNode::encoding_UTF8" -#endif - - -XMLNode XMLNode::emptyXMLNode; -XMLClear XMLNode::emptyXMLClear = { NULL, NULL, NULL}; -XMLAttribute XMLNode::emptyXMLAttribute = { NULL, NULL}; - -// Enumeration used to decipher what type a token is -typedef enum XMLTokenTypeTag -{ - eTokenText = 0, - eTokenQuotedText, - eTokenTagStart, /* "<" */ - eTokenTagEnd, /* "" */ - eTokenEquals, /* " = " */ - eTokenDeclaration, /* "" */ - eTokenClear, - eTokenError -} XMLTokenType; - -// Main structure used for parsing XML -typedef struct XML -{ - XMLCSTR lpXML; - XMLCSTR lpszText; - int nIndex, nIndexMissigEndTag; - enum XMLError error; - XMLCSTR lpEndTag; - int cbEndTag; - XMLCSTR lpNewElement; - int cbNewElement; - int nFirst; -} XML; - -typedef struct -{ - ALLXMLClearTag *pClr; - XMLCSTR pStr; -} NextToken; - -// Enumeration used when parsing attributes -typedef enum Attrib -{ - eAttribName = 0, - eAttribEquals, - eAttribValue -} Attrib; - -// Enumeration used when parsing elements to dictate whether we are currently -// inside a tag -typedef enum XMLStatus -{ - eInsideTag = 0, - eOutsideTag -} XMLStatus; - -XMLError XMLNode::writeToFile(XMLCSTR filename, const char *encoding, char nFormat) const -{ - if (!d) return eXMLErrorNone; - FILE *f = xfopen(filename, _CXML("wb")); - if (!f) return eXMLErrorCannotOpenWriteFile; -#ifdef _XMLWIDECHAR - unsigned char h[2] = { 0xFF, 0xFE }; - if (!fwrite(h, 2, 1, f)) - { - fclose(f); - return eXMLErrorCannotWriteFile; - } - if ((!isDeclaration())&&((d->lpszName) || (!getChildNode().isDeclaration()))) - { - if ( fputws(L"\n", f) == EOF) - { - fclose(f); - return eXMLErrorCannotWriteFile; - } - } -#else - if ((!isDeclaration())&&((d->lpszName) || (!getChildNode().isDeclaration()))) - { - if (characterEncoding == char_encoding_UTF8) - { - // header so that windows recognize the file as UTF-8: - unsigned char h[3] = {0xEF, 0xBB, 0xBF}; - if (!fwrite(h, 3, 1, f)) - { - fclose(f); - return eXMLErrorCannotWriteFile; - } - encoding = "utf-8"; - } else if (characterEncoding == char_encoding_ShiftJIS) encoding = "SHIFT-JIS"; - - if (!encoding) encoding = "ISO-8859-1"; - if (fprintf(f, "\n", encoding)<0) - { - fclose(f); - return eXMLErrorCannotWriteFile; - } - } else - { - if (characterEncoding == char_encoding_UTF8) - { - unsigned char h[3] = {0xEF, 0xBB, 0xBF}; - if (!fwrite(h, 3, 1, f)) - { - fclose(f); - return eXMLErrorCannotWriteFile; - } - } - } -#endif - int i; - XMLSTR t = createXMLString(nFormat, &i); - if (!fwrite(t, sizeof(XMLCHAR)*i, 1, f)) - { - free(t); - fclose(f); - return eXMLErrorCannotWriteFile; - } - if (fclose(f) != 0) - { - free(t); - return eXMLErrorCannotWriteFile; - } - free(t); - return eXMLErrorNone; -} - -// Duplicate a given string. -XMLSTR stringDup(XMLCSTR lpszData, int cbData) -{ - if (lpszData == NULL) return NULL; - - XMLSTR lpszNew; - if (cbData == -1) cbData = (int)xstrlen(lpszData); - lpszNew = (XMLSTR)malloc((cbData+1) * sizeof(XMLCHAR)); - if (lpszNew) - { - memcpy(lpszNew, lpszData, (cbData) * sizeof(XMLCHAR)); - lpszNew[cbData] = (XMLCHAR)NULL; - } - return lpszNew; -} - -XMLSTR ToXMLStringTool::toXMLUnSafe(XMLSTR dest, XMLCSTR source) -{ - XMLSTR dd = dest; - XMLCHAR ch; - XMLCharacterEntity *entity; - while ((ch = *source)) - { - entity = XMLEntities; - do - { - if (ch == entity->c) {xstrcpy(dest, entity->s); dest+=entity->l; source++; goto out_of_loop1; } - entity++; - } while (entity->s); -#ifdef _XMLWIDECHAR - *(dest++) = *(source++); -#else - switch(XML_ByteTable[(unsigned char)ch]) - { - case 4: *(dest++) = *(source++); - case 3: *(dest++) = *(source++); - case 2: *(dest++) = *(source++); - case 1: *(dest++) = *(source++); - } -#endif -out_of_loop1: - ; - } - *dest = 0; - return dd; -} - -// private (used while rendering): -int ToXMLStringTool::lengthXMLString(XMLCSTR source) -{ - int r = 0; - XMLCharacterEntity *entity; - XMLCHAR ch; - while ((ch = *source)) - { - entity = XMLEntities; - do - { - if (ch == entity->c) { r+=entity->l; source++; goto out_of_loop1; } - entity++; - } while (entity->s); -#ifdef _XMLWIDECHAR - r++; source++; -#else - ch = XML_ByteTable[(unsigned char)ch]; r+=ch; source+=ch; -#endif -out_of_loop1: - ; - } - return r; -} - -ToXMLStringTool::~ToXMLStringTool() { freeBuffer(); } -void ToXMLStringTool::freeBuffer() { if (buf) free(buf); buf = NULL; buflen = 0; } -XMLSTR ToXMLStringTool::toXML(XMLCSTR source) -{ - if (!source) - { - if (buflen<1) { buflen = 1; buf = (XMLSTR)malloc(sizeof(XMLCHAR)); } - *buf = 0; - return buf; - } - int l = lengthXMLString(source)+1; - if (l>buflen) { freeBuffer(); buflen = l; buf = (XMLSTR)malloc(l*sizeof(XMLCHAR)); } - return toXMLUnSafe(buf, source); -} - -// private: -XMLSTR fromXMLString(XMLCSTR s, int lo, XML *pXML) -{ - // This function is the opposite of the function "toXMLString". It decodes the escape - // sequences &, ", ', <, > and replace them by the characters - // &, ", ', <, >. This function is used internally by the XML Parser. All the calls to - // the XML library will always gives you back "decoded" strings. - // - // in: string (s) and length (lo) of string - // out: new allocated string converted from xml - if (!s) return NULL; - - int ll = 0, j; - XMLSTR d; - XMLCSTR ss = s; - XMLCharacterEntity *entity; - while ((lo>0)&&(*s)) - { - if (*s == _CXML('&')) - { - if ((lo>2)&&(s[1] == _CXML('#'))) - { - s+=2; lo-=2; - if ((*s == _CXML('X')) || (*s == _CXML('x'))) { s++; lo--; } - while ((*s)&&(*s != _CXML(';'))&&((lo--)>0)) s++; - if (*s != _CXML(';')) - { - pXML->error = eXMLErrorUnknownCharacterEntity; - return NULL; - } - s++; lo--; - } else - { - entity = XMLEntities; - do - { - if ((lo>=entity->l)&&(xstrnicmp(s, entity->s, entity->l) == 0)) { s+=entity->l; lo-=entity->l; break; } - entity++; - } while (entity->s); - if (!entity->s) - { - pXML->error = eXMLErrorUnknownCharacterEntity; - return NULL; - } - } - } else - { -#ifdef _XMLWIDECHAR - s++; lo--; -#else - j = XML_ByteTable[(unsigned char)*s]; s+=j; lo-=j; ll+=j-1; -#endif - } - ll++; - } - - d = (XMLSTR)malloc((ll+1)*sizeof(XMLCHAR)); - s = d; - while (ll-->0) - { - if (*ss == _CXML('&')) - { - if (ss[1] == _CXML('#')) - { - ss+=2; j = 0; - if ((*ss == _CXML('X')) || (*ss == _CXML('x'))) - { - ss++; - while (*ss != _CXML(';')) - { - if ((*ss>=_CXML('0'))&&(*ss <= _CXML('9'))) j = (j<<4)+*ss-_CXML('0'); - else if ((*ss>=_CXML('A'))&&(*ss <= _CXML('F'))) j = (j<<4)+*ss-_CXML('A')+10; - else if ((*ss>=_CXML('a'))&&(*ss <= _CXML('f'))) j = (j<<4)+*ss-_CXML('a')+10; - else { free((void*)s); pXML->error = eXMLErrorUnknownCharacterEntity;return NULL;} - ss++; - } - } else - { - while (*ss != _CXML(';')) - { - if ((*ss>=_CXML('0'))&&(*ss <= _CXML('9'))) j = (j*10)+*ss-_CXML('0'); - else { free((void*)s); pXML->error = eXMLErrorUnknownCharacterEntity;return NULL;} - ss++; - } - } -#ifndef _XMLWIDECHAR - if (j>255) { free((void*)s); pXML->error = eXMLErrorCharacterCodeAbove255;return NULL;} -#endif - (*d++) = (XMLCHAR)j; ss++; - } else - { - entity = XMLEntities; - do - { - if (xstrnicmp(ss, entity->s, entity->l) == 0) { *(d++) = entity->c; ss+=entity->l; break; } - entity++; - } while (entity->s); - } - } else - { -#ifdef _XMLWIDECHAR - *(d++) = *(ss++); -#else - switch(XML_ByteTable[(unsigned char)*ss]) - { - case 4: *(d++) = *(ss++); ll--; - case 3: *(d++) = *(ss++); ll--; - case 2: *(d++) = *(ss++); ll--; - case 1: *(d++) = *(ss++); - } -#endif - } - } - *d = 0; - -#ifndef _XMLWIDECHAR - if (characterEncoding != XMLNode::char_encoding_legacy) - Utf8Decode((XMLSTR)s, NULL); -#endif - - return (XMLSTR)s; -} - -#define XML_isSPACECHAR(ch) ((ch == _CXML('\n')) || (ch == _CXML(' ')) || (ch == _CXML('\t')) || (ch == _CXML('\r'))) - -// private: -char myTagCompare(XMLCSTR cclose, XMLCSTR copen) -// !!!! WARNING strange convention&: -// return 0 if equals -// return 1 if different -{ - if (!cclose) return 1; - int l = (int)xstrlen(cclose); - if (xstrnicmp(cclose, copen, l) != 0) return 1; - const XMLCHAR c = copen[l]; - if (XML_isSPACECHAR(c) || - (c == _CXML('/')) || - (c == _CXML('<')) || - (c == _CXML('>')) || - (c == _CXML('='))) return 0; - return 1; -} - -// Obtain the next character from the string. -static inline XMLCHAR getNextChar(XML *pXML) -{ - XMLCHAR ch = pXML->lpXML[pXML->nIndex]; -#ifdef _XMLWIDECHAR - if (ch != 0) pXML->nIndex++; -#else - pXML->nIndex+=XML_ByteTable[(unsigned char)ch]; -#endif - return ch; -} - -// Find the next token in a string. -// pcbToken contains the number of characters that have been read. -static NextToken GetNextToken(XML *pXML, int *pcbToken, enum XMLTokenTypeTag *pType) -{ - NextToken result; - XMLCHAR ch; - XMLCHAR chTemp; - int indexStart, nFoundMatch, nIsText = FALSE; - result.pClr = NULL; // prevent warning - - // Find next non-white space character - do { indexStart = pXML->nIndex; ch = getNextChar(pXML); } while XML_isSPACECHAR(ch); - - if (ch) - { - // Cache the current string pointer - result.pStr = &pXML->lpXML[indexStart]; - - // check for standard tokens - switch(ch) - { - // Check for quotes - case _CXML('\''): - case _CXML('\"'): - // Type of token - *pType = eTokenQuotedText; - chTemp = ch; - - // Set the size - nFoundMatch = FALSE; - - // Search through the string to find a matching quote - while ((ch = getNextChar(pXML))) - { - if (ch == chTemp) { nFoundMatch = TRUE; break; } - if (ch == _CXML('<')) break; - } - - // If we failed to find a matching quote - if (nFoundMatch == FALSE) - { - pXML->nIndex = indexStart+1; - nIsText = TRUE; - break; - } - - // 4.02.2002 - // if (FindNonWhiteSpace(pXML)) pXML->nIndex--; - - break; - - // Equals (used with attribute values) - case _CXML('='): - *pType = eTokenEquals; - break; - - // Close tag - case _CXML('>'): - *pType = eTokenCloseTag; - break; - - // Check for tag start and tag end - case _CXML('<'): - - { - // First check whether the token is in the clear tag list (meaning it - // does not need formatting). - ALLXMLClearTag *ctag = XMLClearTags; - do - { - if (!xstrncmp(ctag->lpszOpen, result.pStr, ctag->openTagLen)) - { - result.pClr = ctag; - pXML->nIndex+=ctag->openTagLen-1; - *pType = eTokenClear; - return result; - } - ctag++; - } while (ctag->lpszOpen); - - // Peek at the next character to see if we have an end tag 'lpXML[pXML->nIndex]; - - // If we have a tag end... - if (chTemp == _CXML('/')) - { - // Set the type and ensure we point at the next character - getNextChar(pXML); - *pType = eTokenTagEnd; - } - - // If we have an XML declaration tag - else if (chTemp == _CXML('?')) - { - - // Set the type and ensure we point at the next character - getNextChar(pXML); - *pType = eTokenDeclaration; - } - - // Otherwise we must have a start tag - else - { - *pType = eTokenTagStart; - } - break; - } - - // Check to see if we have a short hand type end tag ('/>'). - case _CXML('/'): - - // Peek at the next character to see if we have a short end tag '/>' - chTemp = pXML->lpXML[pXML->nIndex]; - - // If we have a short hand end tag... - if (chTemp == _CXML('>')) - { - // Set the type and ensure we point at the next character - getNextChar(pXML); - *pType = eTokenShortHandClose; - break; - } - - // If we haven't found a short hand closing tag then drop into the - // text process - - // Other characters - default: - nIsText = TRUE; - } - - // If this is a TEXT node - if (nIsText) - { - // Indicate we are dealing with text - *pType = eTokenText; - while ((ch = getNextChar(pXML))) - { - if XML_isSPACECHAR(ch) - { - indexStart++; break; - - } else if (ch == _CXML('/')) - { - // If we find a slash then this maybe text or a short hand end tag - // Peek at the next character to see it we have short hand end tag - ch = pXML->lpXML[pXML->nIndex]; - // If we found a short hand end tag then we need to exit the loop - if (ch == _CXML('>')) { pXML->nIndex--; break; } - - } else if ((ch == _CXML('<')) || (ch == _CXML('>')) || (ch == _CXML('='))) - { - pXML->nIndex--; break; - } - } - } - *pcbToken = pXML->nIndex-indexStart; - } else - { - // If we failed to obtain a valid character - *pcbToken = 0; - *pType = eTokenError; - result.pStr = NULL; - } - - return result; -} - -XMLCSTR XMLNode::updateName_WOSD(XMLSTR lpszName) -{ - if (!d) { free(lpszName); return NULL; } - if (d->lpszName&&(lpszName != d->lpszName)) free((void*)d->lpszName); - d->lpszName = lpszName; - return lpszName; -} - -// private: -XMLNode::XMLNode(struct XMLNodeDataTag *p) { d = p; (p->ref_count)++; } -XMLNode::XMLNode(XMLNodeData *pParent, XMLSTR lpszName, char isDeclaration) -{ - d = (XMLNodeData*)malloc(sizeof(XMLNodeData)); - d->ref_count = 1; - - d->lpszName = NULL; - d->nChild = 0; - d->nText = 0; - d->nClear = 0; - d->nAttribute = 0; - - d->isDeclaration = isDeclaration; - - d->pParent = pParent; - d->pChild = NULL; - d->pText = NULL; - d->pClear = NULL; - d->pAttribute = NULL; - d->pOrder = NULL; - - d->pInnerText = NULL; - - updateName_WOSD(lpszName); - - d->lpszNS = NULL; - if (lpszName && pParent && pParent->lpszName && !pParent->isDeclaration) { - TCHAR* p = _tcschr(lpszName, ':'); - if (p) { - *p = 0; - d->lpszNS = d->lpszName; - d->lpszName = p+1; - } - } -} - -XMLNode XMLNode::createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration) { return XMLNode(NULL, lpszName, isDeclaration); } -XMLNode XMLNode::createXMLTopNode(XMLCSTR lpszName, char isDeclaration) { return XMLNode(NULL, stringDup(lpszName), isDeclaration); } - -#define MEMORYINCREASE 50 - -static inline void myFree(void *p) { if (p) free(p); } -static inline void *myRealloc(void *p, int newsize, int memInc, int sizeofElem) -{ - if (p == NULL) { if (memInc) return malloc(memInc*sizeofElem); return malloc(sizeofElem); } - if ((memInc == 0) || ((newsize%memInc) == 0)) p = realloc(p, (newsize+memInc)*sizeofElem); - // if (!p) - // { - // printf("XMLParser Error: Not enough memory! Aborting...\n"); exit(220); - // } - return p; -} - -// private: -XMLElementPosition XMLNode::findPosition(XMLNodeData *d, int index, XMLElementType xxtype) -{ - if (index<0) return -1; - int i=0, j = (int)((index<<2)+xxtype), *o = d->pOrder; while (o[i] != j) i++; return i; -} - -// private: -// update "order" information when deleting a content of a XMLNode -int XMLNode::removeOrderElement(XMLNodeData *d, XMLElementType t, int index) -{ - int n = d->nChild+d->nText+d->nClear, *o = d->pOrder, i = findPosition(d, index, t); - memmove(o+i, o+i+1, (n-i)*sizeof(int)); - for (;ipOrder = (int)realloc(d->pOrder, n*sizeof(int)); - // but we skip reallocation because it's too time consuming. - // Anyway, at the end, it will be free'd completely at once. - return i; -} - -void *XMLNode::addToOrder(int memoryIncrease, int *_pos, int nc, void *p, int size, XMLElementType xtype) -{ - // in: *_pos is the position inside d->pOrder ("-1" means "EndOf") - // out: *_pos is the index inside p - p = myRealloc(p, (nc+1), memoryIncrease, size); - int n = d->nChild+d->nText+d->nClear; - d->pOrder = (int*)myRealloc(d->pOrder, n+1, memoryIncrease*3, sizeof(int)); - int pos = *_pos, *o = d->pOrder; - - if ((pos<0) || (pos>=n)) { *_pos = nc; o[n] = (int)((nc<<2)+xtype); return p; } - - int i = pos; - memmove(o+i+1, o+i, (n-i)*sizeof(int)); - - while ((pos>2; - memmove(((char*)p)+(pos+1)*size, ((char*)p)+pos*size, (nc-pos)*size); - - return p; -} - -// Add a child node to the given element. -XMLNode XMLNode::addChild_priv(int memoryIncrease, XMLSTR lpszName, char isDeclaration, int pos) -{ - if (!lpszName) return emptyXMLNode; - d->pChild = (XMLNode*)addToOrder(memoryIncrease, &pos, d->nChild, d->pChild, sizeof(XMLNode), eNodeChild); - d->pChild[pos].d = NULL; - d->pChild[pos] = XMLNode(d, lpszName, isDeclaration); - d->nChild++; - return d->pChild[pos]; -} - -// Add an attribute to an element. -XMLAttribute *XMLNode::addAttribute_priv(int memoryIncrease, XMLSTR lpszName, XMLSTR lpszValuev) -{ - if (!lpszName) return &emptyXMLAttribute; - if (!d) { myFree(lpszName); myFree(lpszValuev); return &emptyXMLAttribute; } - int nc = d->nAttribute; - d->pAttribute = (XMLAttribute*)myRealloc(d->pAttribute, (nc+1), memoryIncrease, sizeof(XMLAttribute)); - XMLAttribute *pAttr = d->pAttribute+nc; - pAttr->lpszName = lpszName; - pAttr->lpszValue = lpszValuev; - d->nAttribute++; - - TCHAR* p = _tcschr(lpszName, ':'); - if (p) - if (!mir_tstrcmp(p+1, d->lpszNS) || (d->pParent && !mir_tstrcmp(p+1, d->pParent->lpszNS))) - *p = 0; - - return pAttr; -} - -// Add text to the element. -XMLCSTR XMLNode::addText_priv(int memoryIncrease, XMLSTR lpszValue, int pos) -{ - if (!lpszValue) return NULL; - if (!d) { myFree(lpszValue); return NULL; } - invalidateInnerText(); - d->pText = (XMLCSTR*)addToOrder(memoryIncrease, &pos, d->nText, d->pText, sizeof(XMLSTR), eNodeText); - d->pText[pos] = lpszValue; - d->nText++; - return lpszValue; -} - -// Add clear (unformatted) text to the element. -XMLClear *XMLNode::addClear_priv(int memoryIncrease, XMLSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, int pos) -{ - if (!lpszValue) return &emptyXMLClear; - if (!d) { myFree(lpszValue); return &emptyXMLClear; } - invalidateInnerText(); - d->pClear = (XMLClear *)addToOrder(memoryIncrease, &pos, d->nClear, d->pClear, sizeof(XMLClear), eNodeClear); - XMLClear *pNewClear = d->pClear+pos; - pNewClear->lpszValue = lpszValue; - if (!lpszOpen) lpszOpen = XMLClearTags->lpszOpen; - if (!lpszClose) lpszClose = XMLClearTags->lpszClose; - pNewClear->lpszOpenTag = lpszOpen; - pNewClear->lpszCloseTag = lpszClose; - d->nClear++; - return pNewClear; -} - -// private: -// Parse a clear (unformatted) type node. -char XMLNode::parseClearTag(void *px, void *_pClear) -{ - XML *pXML = (XML *)px; - ALLXMLClearTag pClear = *((ALLXMLClearTag*)_pClear); - int cbTemp = 0; - XMLCSTR lpszTemp = NULL; - XMLCSTR lpXML = &pXML->lpXML[pXML->nIndex]; - static XMLCSTR docTypeEnd = _CXML("]>"); - - // Find the closing tag - // Seems the ')) { lpszTemp = pCh; break; } -#ifdef _XMLWIDECHAR - pCh++; -#else - pCh+=XML_ByteTable[(unsigned char)(*pCh)]; -#endif - } - } else lpszTemp = xstrstr(lpXML, pClear.lpszClose); - - if (lpszTemp) - { - // Cache the size and increment the index - cbTemp = (int)(lpszTemp - lpXML); - - pXML->nIndex += cbTemp+(int)xstrlen(pClear.lpszClose); - - // Add the clear node to the current element - addClear_priv(MEMORYINCREASE, cbTemp?stringDup(lpXML, cbTemp):NULL, pClear.lpszOpen, pClear.lpszClose, -1); - return 0; - } - - // If we failed to find the end tag - pXML->error = eXMLErrorUnmatchedEndClearTag; - return 1; -} - -void XMLNode::exactMemory(XMLNodeData *d) -{ - if (d->pOrder) d->pOrder = (int*)realloc(d->pOrder, (d->nChild+d->nText+d->nClear)*sizeof(int)); - if (d->pChild) d->pChild = (XMLNode*)realloc(d->pChild, d->nChild*sizeof(XMLNode)); - if (d->pAttribute) d->pAttribute = (XMLAttribute*)realloc(d->pAttribute, d->nAttribute*sizeof(XMLAttribute)); - if (d->pText) d->pText = (XMLCSTR*)realloc(d->pText, d->nText*sizeof(XMLSTR)); - if (d->pClear) d->pClear = (XMLClear *)realloc(d->pClear, d->nClear*sizeof(XMLClear)); -} - -char XMLNode::maybeAddTxT(void *pa, XMLCSTR tokenPStr) -{ - XML *pXML = (XML *)pa; - XMLCSTR lpszText = pXML->lpszText; - if (!lpszText) return 0; - if (dropWhiteSpace) while (XML_isSPACECHAR(*lpszText)&&(lpszText != tokenPStr)) lpszText++; - int cbText = (int)(tokenPStr - lpszText); - if (!cbText) { pXML->lpszText = NULL; return 0; } - if (dropWhiteSpace) { cbText--; while ((cbText)&&XML_isSPACECHAR(lpszText[cbText])) cbText--; cbText++; } - if (!cbText) { pXML->lpszText = NULL; return 0; } - XMLSTR lpt = fromXMLString(lpszText, cbText, pXML); - if (!lpt) return 1; - pXML->lpszText = NULL; - if (removeCommentsInMiddleOfText && d->nText && d->nClear) - { - // if the previous insertion was a comment () AND - // if the previous previous insertion was a text then, delete the comment and append the text - size_t n = d->nChild+d->nText+d->nClear-1; - int *o = d->pOrder; - if (((o[n]&3) == eNodeClear)&&((o[n-1]&3) == eNodeText)) - { - int i = o[n]>>2; - if (d->pClear[i].lpszOpenTag == XMLClearTags[2].lpszOpen) - { - deleteClear(i); - i = o[n-1]>>2; - n = xstrlen(d->pText[i]); - size_t n2 = xstrlen(lpt)+1; - d->pText[i] = (XMLSTR)realloc((void*)d->pText[i], (n+n2)*sizeof(XMLCHAR)); - if (!d->pText[i]) { - free(lpt); - return 1; - } - memcpy((void*)(d->pText[i]+n), lpt, n2*sizeof(XMLCHAR)); - free(lpt); - return 0; - } - } - } - addText_priv(MEMORYINCREASE, lpt, -1); - return 0; -} -// private: -// Recursively parse an XML element. -int XMLNode::ParseXMLElement(void *pa) -{ - XML *pXML = (XML *)pa; - int cbToken; - enum XMLTokenTypeTag xtype; - NextToken token; - XMLCSTR lpszTemp = NULL; - int cbTemp = 0; - char nDeclaration; - XMLNode pNew; - enum XMLStatus status; // inside or outside a tag - enum Attrib attrib = eAttribName; - - assert(pXML); - - // If this is the first call to the function - if (pXML->nFirst) - { - // Assume we are outside of a tag definition - pXML->nFirst = FALSE; - status = eOutsideTag; - } else - { - // If this is not the first call then we should only be called when inside a tag. - status = eInsideTag; - } - - // Iterate through the tokens in the document - for (;;) - { - // Obtain the next token - token = GetNextToken(pXML, &cbToken, &xtype); - - if (xtype != eTokenError) - { - // Check the current status - switch(status) - { - - // If we are outside of a tag definition - case eOutsideTag: - - // Check what type of token we obtained - switch(xtype) - { - // If we have found text or quoted text - case eTokenText: - case eTokenCloseTag: /* '>' */ - case eTokenShortHandClose: /* '/>' */ - case eTokenQuotedText: - case eTokenEquals: - break; - - // If we found a start tag '<' and declarations 'error = eXMLErrorMissingTagName; - return FALSE; - } - - // If we found a new element which is the same as this - // element then we need to pass this back to the caller.. - -#ifdef APPROXIMATE_PARSING - if (d->lpszName && - myTagCompare(d->lpszName, token.pStr) == 0) - { - // Indicate to the caller that it needs to create a - // new element. - pXML->lpNewElement = token.pStr; - pXML->cbNewElement = cbToken; - return TRUE; - } else -#endif - { - // If the name of the new element differs from the name of - // the current element we need to add the new element to - // the current one and recurse - pNew = addChild_priv(MEMORYINCREASE, stringDup(token.pStr, cbToken), nDeclaration, -1); - - while (!pNew.isEmpty()) - { - // Callself to process the new node. If we return - // FALSE this means we dont have any more - // processing to do... - - if (!pNew.ParseXMLElement(pXML)) return FALSE; - else - { - // If the call to recurse this function - // evented in a end tag specified in XML then - // we need to unwind the calls to this - // function until we find the appropriate node - // (the element name and end tag name must - // match) - if (pXML->cbEndTag) - { - // If we are back at the root node then we - // have an unmatched end tag - if (!d->lpszName) - { - pXML->error = eXMLErrorUnmatchedEndTag; - return FALSE; - } - - // If the end tag matches the name of this - // element then we only need to unwind - // once more... - - if (myTagCompare(d->lpszName, pXML->lpEndTag) == 0) - { - pXML->cbEndTag = 0; - } - - return TRUE; - } else - if (pXML->cbNewElement) - { - // If the call indicated a new element is to - // be created on THIS element. - - // If the name of this element matches the - // name of the element we need to create - // then we need to return to the caller - // and let it process the element. - - if (myTagCompare(d->lpszName, pXML->lpNewElement) == 0) - { - return TRUE; - } - - // Add the new element and recurse - pNew = addChild_priv(MEMORYINCREASE, stringDup(pXML->lpNewElement, pXML->cbNewElement), 0, -1); - pXML->cbNewElement = 0; - } - else - { - // If we didn't have a new element to create - pNew = emptyXMLNode; - - } - } - } - } - break; - - // If we found an end tag - case eTokenTagEnd: - - // If we have node text then add this to the element - if (maybeAddTxT(pXML, token.pStr)) return FALSE; - - // Find the name of the end tag - token = GetNextToken(pXML, &cbTemp, &xtype); - - // The end tag should be text - if (xtype != eTokenText) - { - pXML->error = eXMLErrorMissingEndTagName; - return FALSE; - } - lpszTemp = token.pStr; - - // After the end tag we should find a closing tag - token = GetNextToken(pXML, &cbToken, &xtype); - if (xtype != eTokenCloseTag) - { - pXML->error = eXMLErrorMissingEndTagName; - return FALSE; - } - pXML->lpszText = pXML->lpXML+pXML->nIndex; - - // We need to return to the previous caller. If the name - // of the tag cannot be found we need to keep returning to - // caller until we find a match - if (!d->lpszNS) { - if (myTagCompare(d->lpszName, lpszTemp) != 0) -#ifdef STRICT_PARSING - { -LBL_Error: - pXML->error = eXMLErrorUnmatchedEndTag; - pXML->nIndexMissigEndTag = pXML->nIndex; - return FALSE; - } -#else - { -LBL_Error: - pXML->error = eXMLErrorMissingEndTag; - pXML->nIndexMissigEndTag = pXML->nIndex; - pXML->lpEndTag = lpszTemp; - pXML->cbEndTag = cbTemp; - } -#endif - } - else { - const TCHAR* p = _tcschr(lpszTemp, ':'); - if (!p) - goto LBL_Error; - - if (myTagCompare(d->lpszName, p+1) != 0) - goto LBL_Error; - } - - // Return to the caller - exactMemory(d); - return TRUE; - - // If we found a clear (unformatted) token - case eTokenClear: - // If we have node text then add this to the element - if (maybeAddTxT(pXML, token.pStr)) return FALSE; - if (parseClearTag(pXML, token.pClr)) return FALSE; - pXML->lpszText = pXML->lpXML+pXML->nIndex; - break; - - default: - break; - } - break; - - // If we are inside a tag definition we need to search for attributes - case eInsideTag: - - // Check what part of the attribute (name, equals, value) we - // are looking for. - switch(attrib) - { - // If we are looking for a new attribute - case eAttribName: - - // Check what the current token type is - switch(xtype) - { - // If the current type is text... - // Eg. 'attribute' - case eTokenText: - // Cache the token then indicate that we are next to - // look for the equals - lpszTemp = token.pStr; - cbTemp = cbToken; - attrib = eAttribEquals; - break; - - // If we found a closing tag... - // Eg. '>' - case eTokenCloseTag: - // We are now outside the tag - status = eOutsideTag; - pXML->lpszText = pXML->lpXML+pXML->nIndex; - break; - - // If we found a short hand '/>' closing tag then we can - // return to the caller - case eTokenShortHandClose: - exactMemory(d); - pXML->lpszText = pXML->lpXML+pXML->nIndex; - return TRUE; - - // Errors... - case eTokenQuotedText: /* '"SomeText"' */ - case eTokenTagStart: /* '<' */ - case eTokenTagEnd: /* 'error = eXMLErrorUnexpectedToken; - return FALSE; - default: break; - } - break; - - // If we are looking for an equals - case eAttribEquals: - // Check what the current token type is - switch(xtype) - { - // If the current type is text... - // Eg. 'Attribute AnotherAttribute' - case eTokenText: - // Add the unvalued attribute to the list - addAttribute_priv(MEMORYINCREASE, stringDup(lpszTemp, cbTemp), NULL); - // Cache the token then indicate. We are next to - // look for the equals attribute - lpszTemp = token.pStr; - cbTemp = cbToken; - break; - - // If we found a closing tag 'Attribute >' or a short hand - // closing tag 'Attribute />' - case eTokenShortHandClose: - case eTokenCloseTag: - // If we are a declaration element 'lpszText = pXML->lpXML+pXML->nIndex; - - if (d->isDeclaration && - (lpszTemp[cbTemp-1]) == _CXML('?')) - { - cbTemp--; - if (d->pParent && d->pParent->pParent) xtype = eTokenShortHandClose; - } - - if (cbTemp) - { - // Add the unvalued attribute to the list - addAttribute_priv(MEMORYINCREASE, stringDup(lpszTemp, cbTemp), NULL); - } - - // If this is the end of the tag then return to the caller - if (xtype == eTokenShortHandClose) - { - exactMemory(d); - return TRUE; - } - - // We are now outside the tag - status = eOutsideTag; - break; - - // If we found the equals token... - // Eg. 'Attribute = ' - case eTokenEquals: - // Indicate that we next need to search for the value - // for the attribute - attrib = eAttribValue; - break; - - // Errors... - case eTokenQuotedText: /* 'Attribute "InvalidAttr"'*/ - case eTokenTagStart: /* 'Attribute <' */ - case eTokenTagEnd: /* 'Attribute error = eXMLErrorUnexpectedToken; - return FALSE; - default: break; - } - break; - - // If we are looking for an attribute value - case eAttribValue: - // Check what the current token type is - switch(xtype) - { - // If the current type is text or quoted text... - // Eg. 'Attribute = "Value"' or 'Attribute = Value' or - // 'Attribute = 'Value''. - case eTokenText: - case eTokenQuotedText: - // If we are a declaration element 'isDeclaration && - (token.pStr[cbToken-1]) == _CXML('?')) - { - cbToken--; - } - - if (cbTemp) - { - // Add the valued attribute to the list - if (xtype == eTokenQuotedText) { token.pStr++; cbToken-=2; } - XMLSTR attrVal = (XMLSTR)token.pStr; - if (attrVal) - { - attrVal = fromXMLString(attrVal, cbToken, pXML); - if (!attrVal) return FALSE; - } - addAttribute_priv(MEMORYINCREASE, stringDup(lpszTemp, cbTemp), attrVal); - } - - // Indicate we are searching for a new attribute - attrib = eAttribName; - break; - - // Errors... - case eTokenTagStart: /* 'Attr = <' */ - case eTokenTagEnd: /* 'Attr = ' */ - case eTokenShortHandClose: /* "Attr = />" */ - case eTokenEquals: /* 'Attr = = ' */ - case eTokenDeclaration: /* 'Attr = error = eXMLErrorUnexpectedToken; - return FALSE; - break; - default: break; - } - } - } - } - // If we failed to obtain the next token - else - { - if ((!d->isDeclaration)&&(d->pParent)) - { -#ifdef STRICT_PARSING - pXML->error = eXMLErrorUnmatchedEndTag; -#else - pXML->error = eXMLErrorMissingEndTag; -#endif - pXML->nIndexMissigEndTag = pXML->nIndex; - } - maybeAddTxT(pXML, pXML->lpXML+pXML->nIndex); - return FALSE; - } - } -} - -// Count the number of lines and columns in an XML string. -static void CountLinesAndColumns(XMLCSTR lpXML, int nUpto, XMLResults *pResults) -{ - XMLCHAR ch; - assert(lpXML); - assert(pResults); - - struct XML xml = { lpXML, lpXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE }; - - pResults->nLine = 1; - pResults->nColumn = 1; - while (xml.nIndexnColumn++; - else - { - pResults->nLine++; - pResults->nColumn = 1; - } - } -} - -// Parse XML and return the root element. -XMLNode XMLNode::parseString(XMLCSTR lpszXML, XMLCSTR tag, XMLResults *pResults) -{ - if (!lpszXML) - { - if (pResults) - { - pResults->error = eXMLErrorNoElements; - pResults->nLine = 0; - pResults->nColumn = 0; - } - return emptyXMLNode; - } - - XMLNode xnode(NULL, NULL, FALSE); - struct XML xml = { lpszXML, lpszXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE }; - - // Create header element - xnode.ParseXMLElement(&xml); - enum XMLError error = xml.error; - if (!xnode.nChildNode()) error = eXMLErrorNoXMLTagFound; - if ((xnode.nChildNode() == 1)&&(xnode.nElement() == 1)) xnode = xnode.getChildNode(); // skip the empty node - - // If no error occurred - if ((error == eXMLErrorNone) || (error == eXMLErrorMissingEndTag) || (error == eXMLErrorNoXMLTagFound)) - { - XMLCSTR name = xnode.getName(); - if (tag&&(*tag)&&((!name) || (xstricmp(name, tag)))) - { - xnode = xnode.getChildNode(tag); - if (xnode.isEmpty()) - { - if (pResults) - { - pResults->error = eXMLErrorFirstTagNotFound; - pResults->nLine = 0; - pResults->nColumn = 0; - pResults->nChars = xml.nIndex; - } - return emptyXMLNode; - } - } - } else - { - // Cleanup: this will destroy all the nodes - xnode = emptyXMLNode; - } - - - // If we have been given somewhere to place results - if (pResults) - { - pResults->error = error; - - // If we have an error - if (error != eXMLErrorNone) - { - if (error == eXMLErrorMissingEndTag) xml.nIndex = xml.nIndexMissigEndTag; - // Find which line and column it starts on. - CountLinesAndColumns(xml.lpXML, xml.nIndex, pResults); - } - - pResults->nChars = xml.nIndex; - } - return xnode; -} - -XMLNode XMLNode::parseFile(XMLCSTR filename, XMLCSTR tag, XMLResults *pResults) -{ - if (pResults) { pResults->nLine = 0; pResults->nColumn = 0; } - FILE *f = xfopen(filename, _CXML("rb")); - if (f == NULL) { if (pResults) pResults->error = eXMLErrorFileNotFound; return emptyXMLNode; } - fseek(f, 0, SEEK_END); - int l = (int)ftell(f), headerSz = 0; - if (!l) { if (pResults) pResults->error = eXMLErrorEmpty; fclose(f); return emptyXMLNode; } - fseek(f, 0, SEEK_SET); - unsigned char *buf = (unsigned char*)malloc(l+4); - l = (int)fread(buf, 1, l, f); - fclose(f); - buf[l] = 0;buf[l+1] = 0;buf[l+2] = 0;buf[l+3] = 0; -#ifdef _XMLWIDECHAR - if (guessWideCharChars) - { - if (!myIsTextWideChar(buf, l)) - { - XMLNode::XMLCharEncoding ce = XMLNode::char_encoding_legacy; - if ((buf[0] == 0xef)&&(buf[1] == 0xbb)&&(buf[2] == 0xbf)) { headerSz = 3; ce = XMLNode::char_encoding_UTF8; } - XMLSTR b2 = myMultiByteToWideChar((const char*)(buf+headerSz), ce); - if (!b2) - { - // todo: unable to convert - } - free(buf); buf = (unsigned char*)b2; headerSz = 0; - } else - { - if ((buf[0] == 0xef)&&(buf[1] == 0xff)) headerSz = 2; - if ((buf[0] == 0xff)&&(buf[1] == 0xfe)) headerSz = 2; - } - } else - { - if ((buf[0] == 0xef)&&(buf[1] == 0xff)) headerSz = 2; - if ((buf[0] == 0xff)&&(buf[1] == 0xfe)) headerSz = 2; - if ((buf[0] == 0xef)&&(buf[1] == 0xbb)&&(buf[2] == 0xbf)) headerSz = 3; - } -#else - if (guessWideCharChars) - { - if (myIsTextWideChar(buf, l)) - { - if ((buf[0] == 0xef)&&(buf[1] == 0xff)) headerSz = 2; - if ((buf[0] == 0xff)&&(buf[1] == 0xfe)) headerSz = 2; - char *b2 = myWideCharToMultiByte((const wchar_t*)(buf+headerSz)); - free(buf); buf = (unsigned char*)b2; headerSz = 0; - } else - { - if ((buf[0] == 0xef)&&(buf[1] == 0xbb)&&(buf[2] == 0xbf)) headerSz = 3; - } - } else - { - if ((buf[0] == 0xef)&&(buf[1] == 0xff)) headerSz = 2; - if ((buf[0] == 0xff)&&(buf[1] == 0xfe)) headerSz = 2; - if ((buf[0] == 0xef)&&(buf[1] == 0xbb)&&(buf[2] == 0xbf)) headerSz = 3; - } -#endif - - if (!buf) { if (pResults) pResults->error = eXMLErrorCharConversionError; return emptyXMLNode; } - XMLNode x = parseString((XMLSTR)(buf+headerSz), tag, pResults); - free(buf); - return x; -} - -static inline void charmemset(XMLSTR dest, XMLCHAR c, int l) { while (l--) *(dest++) = c; } -// private: -// Creates an user friendly XML string from a given element with -// appropriate white space and carriage returns. -// -// This recurses through all subnodes then adds contents of the nodes to the -// string. -int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat) -{ - int nResult = 0; - int cb = nFormat<0?0:nFormat; - int cbElement; - int nChildFormat = -1; - int nElementI; - int i, j; - - assert(pEntry); - - nElementI = pEntry->nChild+pEntry->nText+pEntry->nClear; - if ((nFormat>=0)&&(nElementI == 1)&&(pEntry->nText == 1)&&(!pEntry->isDeclaration)) nFormat = -2; - -#define LENSTR(lpsz) (lpsz ? xstrlen(lpsz) : 0) - - // If the element has no name then assume this is the head node. - cbElement = (int)LENSTR(pEntry->lpszName); - - if (cbElement) - { - // "isDeclaration) lpszMarker[nResult++] = _CXML('?'); - xstrcpy(&lpszMarker[nResult], pEntry->lpszName); - nResult+=cbElement; - lpszMarker[nResult++] = _CXML(' '); - - } else - { - nResult+=cbElement+2+cb; - if (pEntry->isDeclaration) nResult++; - } - - // Enumerate attributes and add them to the string - XMLAttribute *pAttr = pEntry->pAttribute; - for (i=0; inAttribute; i++) - { - // "Attrib - cb = (int)LENSTR(pAttr->lpszName); - if (cb) - { - if (lpszMarker) xstrcpy(&lpszMarker[nResult], pAttr->lpszName); - nResult += cb; - // "Attrib = Value " - if (pAttr->lpszValue) - { - cb = (int)ToXMLStringTool::lengthXMLString(pAttr->lpszValue); - if (lpszMarker) - { - lpszMarker[nResult] = _CXML('='); - lpszMarker[nResult+1] = _CXML('"'); - if (cb) ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult+2], pAttr->lpszValue); - lpszMarker[nResult+cb+2] = _CXML('"'); - } - nResult+=cb+3; - } - if (lpszMarker) lpszMarker[nResult] = _CXML(' '); - nResult++; - } - pAttr++; - } - - if (pEntry->isDeclaration) - { - if (lpszMarker) - { - lpszMarker[nResult-1] = _CXML('?'); - lpszMarker[nResult] = _CXML('>'); - } - nResult++; - if (nFormat != -1) - { - if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); - nResult++; - } - } else - // If there are child nodes we need to terminate the start tag - if (nElementI) - { - if (lpszMarker) lpszMarker[nResult-1] = _CXML('>'); - if (nFormat>=0) - { - if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); - nResult++; - } - } else nResult--; - } - - // Calculate the child format for when we recurse. This is used to - // determine the number of spaces used for prefixes. - if (nFormat != -1) - { - if (cbElement&&(!pEntry->isDeclaration)) nChildFormat = nFormat+1; - else nChildFormat = nFormat; - } - - // Enumerate through remaining children - for (i=0; ipOrder[i]; - switch((XMLElementType)(j&3)) - { - // Text nodes - case eNodeText: - { - // "Text" - XMLCSTR pChild = pEntry->pText[j>>2]; - cb = (int)ToXMLStringTool::lengthXMLString(pChild); - if (cb) - { - if (nFormat>=0) - { - if (lpszMarker) - { - charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat+1); - ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult+nFormat+1], pChild); - lpszMarker[nResult+nFormat+1+cb] = _CXML('\n'); - } - nResult+=cb+nFormat+2; - } else - { - if (lpszMarker) ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult], pChild); - nResult += cb; - } - } - break; - } - - // Clear type nodes - case eNodeClear: - { - XMLClear *pChild = pEntry->pClear+(j>>2); - // "OpenTag" - cb = (int)LENSTR(pChild->lpszOpenTag); - if (cb) - { - if (nFormat != -1) - { - if (lpszMarker) - { - charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat+1); - xstrcpy(&lpszMarker[nResult+nFormat+1], pChild->lpszOpenTag); - } - nResult+=cb+nFormat+1; - } - else - { - if (lpszMarker)xstrcpy(&lpszMarker[nResult], pChild->lpszOpenTag); - nResult += cb; - } - } - - // "OpenTag Value" - cb = (int)LENSTR(pChild->lpszValue); - if (cb) - { - if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszValue); - nResult += cb; - } - - // "OpenTag Value CloseTag" - cb = (int)LENSTR(pChild->lpszCloseTag); - if (cb) - { - if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszCloseTag); - nResult += cb; - } - - if (nFormat != -1) - { - if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); - nResult++; - } - break; - } - - // Element nodes - case eNodeChild: - { - // Recursively add child nodes - nResult += CreateXMLStringR(pEntry->pChild[j>>2].d, lpszMarker ? lpszMarker + nResult : 0, nChildFormat); - break; - } - default: break; - } - } - - if ((cbElement)&&(!pEntry->isDeclaration)) - { - // If we have child entries we need to use long XML notation for - // closing the element - "blah blah blah" - if (nElementI) - { - // "\0" - if (lpszMarker) - { - if (nFormat >=0) - { - charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat); - nResult+=nFormat; - } - - lpszMarker[nResult] = _CXML('<'); lpszMarker[nResult+1] = _CXML('/'); - nResult += 2; - xstrcpy(&lpszMarker[nResult], pEntry->lpszName); - nResult += cbElement; - - lpszMarker[nResult] = _CXML('>'); - if (nFormat == -1) nResult++; - else - { - lpszMarker[nResult+1] = _CXML('\n'); - nResult+=2; - } - } else - { - if (nFormat>=0) nResult+=cbElement+4+nFormat; - else if (nFormat == -1) nResult+=cbElement+3; - else nResult+=cbElement+4; - } - } else - { - // If there are no children we can use shorthand XML notation - - // "" - // "/>\0" - if (lpszMarker) - { - lpszMarker[nResult] = _CXML('/'); lpszMarker[nResult+1] = _CXML('>'); - if (nFormat != -1) lpszMarker[nResult+2] = _CXML('\n'); - } - nResult += nFormat == -1 ? 2 : 3; - } - } - - return nResult; -} - -#undef LENSTR - -// Create an XML string -// @param int nFormat - 0 if no formatting is required -// otherwise nonzero for formatted text -// with carriage returns and indentation. -// @param int *pnSize - [out] pointer to the size of the -// returned string not including the -// NULL terminator. -// @return XMLSTR - Allocated XML string, you must free -// this with free(). -XMLSTR XMLNode::createXMLString(int nFormat, int *pnSize) const -{ - if (!d) { if (pnSize) *pnSize = 0; return NULL; } - - XMLSTR lpszResult = NULL; - int cbStr; - - // Recursively Calculate the size of the XML string - if (!dropWhiteSpace) nFormat = 0; - nFormat = nFormat ? 0 : -1; - cbStr = CreateXMLStringR(d, 0, nFormat); - // Alllocate memory for the XML string + the NULL terminator and - // create the recursively XML string. - lpszResult = (XMLSTR)malloc((cbStr+1)*sizeof(XMLCHAR)); - CreateXMLStringR(d, lpszResult, nFormat); - lpszResult[cbStr] = _CXML('\0'); - if (pnSize) *pnSize = cbStr; - return lpszResult; -} - -int XMLNode::detachFromParent(XMLNodeData *d) -{ - XMLNode *pa = d->pParent->pChild; - int i=0; - while (((void*)(pa[i].d)) != ((void*)d)) i++; - d->pParent->nChild--; - if (d->pParent->nChild) memmove(pa+i, pa+i+1, (d->pParent->nChild-i)*sizeof(XMLNode)); - else { free(pa); d->pParent->pChild = NULL; } - return removeOrderElement(d->pParent, eNodeChild, i); -} - -XMLNode::~XMLNode() -{ - if (!d) return; - d->ref_count--; - emptyTheNode(0); -} -void XMLNode::deleteNodeContent() -{ - if (!d) return; - if (d->pParent) { detachFromParent(d); d->pParent = NULL; d->ref_count--; } - emptyTheNode(1); -} -void XMLNode::emptyTheNode(char force) -{ - XMLNodeData *dd = d; // warning: must stay this way! - if ((dd->ref_count == 0) || force) - { - if (d->pParent) detachFromParent(d); - int i; - XMLNode *pc; - for (i=0; inChild; i++) - { - pc = dd->pChild+i; - pc->d->pParent = NULL; - pc->d->ref_count--; - pc->emptyTheNode(force); - } - myFree(dd->pChild); - for (i=0; inText; i++) free((void*)dd->pText[i]); - myFree(dd->pText); - for (i=0; inClear; i++) free((void*)dd->pClear[i].lpszValue); - myFree(dd->pClear); - for (i=0; inAttribute; i++) - { - free((void*)dd->pAttribute[i].lpszName); - if (dd->pAttribute[i].lpszValue) free((void*)dd->pAttribute[i].lpszValue); - } - myFree(dd->pAttribute); - myFree(dd->pOrder); - myFree(dd->pInnerText); - if (dd->lpszNS) - myFree((void*)dd->lpszNS); - else - myFree((void*)dd->lpszName); - dd->nChild = 0; dd->nText = 0; dd->nClear = 0; dd->nAttribute = 0; - dd->pChild = NULL; dd->pText = NULL; dd->pClear = NULL; dd->pAttribute = NULL; - dd->pOrder = NULL; dd->pInnerText = NULL; dd->lpszNS = dd->lpszName = NULL; dd->pParent = NULL; - } - if (dd->ref_count == 0) - { - free(dd); - d = NULL; - } -} -void XMLNode::invalidateInnerText() -{ - if (!d) return; - myFree(d->pInnerText); - d->pInnerText = NULL; -} - -XMLNode& XMLNode::operator = (const XMLNode& A) -{ - // shallow copy - if (this != &A) - { - if (d) { d->ref_count--; emptyTheNode(0); } - d = A.d; - if (d) (d->ref_count) ++; - } - return *this; -} - -XMLNode::XMLNode(const XMLNode &A) -{ - // shallow copy - d = A.d; - if (d) (d->ref_count)++; -} - -XMLNode XMLNode::deepCopy() const -{ - if (!d) return XMLNode::emptyXMLNode; - XMLNode x(NULL, stringDup(d->lpszName), d->isDeclaration); - XMLNodeData *p = x.d; - int n = d->nAttribute; - if (n) - { - p->nAttribute = n; p->pAttribute = (XMLAttribute*)malloc(n*sizeof(XMLAttribute)); - while (n--) - { - p->pAttribute[n].lpszName = stringDup(d->pAttribute[n].lpszName); - p->pAttribute[n].lpszValue = stringDup(d->pAttribute[n].lpszValue); - } - } - if (d->pOrder) - { - n = (d->nChild+d->nText+d->nClear)*sizeof(int); p->pOrder = (int*)malloc(n); memcpy(p->pOrder, d->pOrder, n); - } - n = d->nText; - if (n) - { - p->nText = n; p->pText = (XMLCSTR*)malloc(n*sizeof(XMLCSTR)); - while (n--) p->pText[n] = stringDup(d->pText[n]); - } - n = d->nClear; - if (n) - { - p->nClear = n; p->pClear = (XMLClear*)malloc(n*sizeof(XMLClear)); - while (n--) - { - p->pClear[n].lpszCloseTag = d->pClear[n].lpszCloseTag; - p->pClear[n].lpszOpenTag = d->pClear[n].lpszOpenTag; - p->pClear[n].lpszValue = stringDup(d->pClear[n].lpszValue); - } - } - n = d->nChild; - if (n) - { - p->nChild = n; p->pChild = (XMLNode*)malloc(n*sizeof(XMLNode)); - while (n--) - { - p->pChild[n].d = NULL; - p->pChild[n] = d->pChild[n].deepCopy(); - p->pChild[n].d->pParent = p; - } - } - return x; -} - -XMLNode XMLNode::addChild(XMLNode childNode, int pos) -{ - XMLNodeData *dc = childNode.d; - if ((!dc) || (!d)) return childNode; - if (!dc->lpszName) - { - // this is a root node: todo: correct fix - int j = pos; - while (dc->nChild) - { - addChild(dc->pChild[0], j); - if (pos>=0) j++; - } - return childNode; - } - if (dc->pParent) { if ((detachFromParent(dc) <= pos)&&(dc->pParent == d)) pos--; } else dc->ref_count++; - dc->pParent = d; - // int nc = d->nChild; - // d->pChild = (XMLNode*)myRealloc(d->pChild, (nc+1), memoryIncrease, sizeof(XMLNode)); - d->pChild = (XMLNode*)addToOrder(0, &pos, d->nChild, d->pChild, sizeof(XMLNode), eNodeChild); - d->pChild[pos].d = dc; - d->nChild++; - return childNode; -} - -void XMLNode::deleteAttribute(int i) -{ - if ((!d) || (i<0) || (i>=d->nAttribute)) return; - d->nAttribute--; - XMLAttribute *p = d->pAttribute+i; - free((void*)p->lpszName); - if (p->lpszValue) free((void*)p->lpszValue); - if (d->nAttribute) memmove(p, p+1, (d->nAttribute-i)*sizeof(XMLAttribute)); else { free(p); d->pAttribute = NULL; } -} - -void XMLNode::deleteAttribute(XMLAttribute *a) { if (a) deleteAttribute(a->lpszName); } -void XMLNode::deleteAttribute(XMLCSTR lpszName) -{ - int j = 0; - getAttribute(lpszName, &j); - if (j) deleteAttribute(j-1); -} - -XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName, int i) -{ - if (!d) { if (lpszNewValue) free(lpszNewValue); if (lpszNewName) free(lpszNewName); return NULL; } - if (i>=d->nAttribute) - { - if (lpszNewName) return addAttribute_WOSD(lpszNewName, lpszNewValue); - return NULL; - } - XMLAttribute *p = d->pAttribute+i; - if (p->lpszValue&&p->lpszValue != lpszNewValue) free((void*)p->lpszValue); - p->lpszValue = lpszNewValue; - if (lpszNewName&&p->lpszName != lpszNewName) { free((void*)p->lpszName); p->lpszName = lpszNewName; }; - return p; -} - -XMLAttribute *XMLNode::updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute) -{ - if (oldAttribute) return updateAttribute_WOSD((XMLSTR)newAttribute->lpszValue, (XMLSTR)newAttribute->lpszName, oldAttribute->lpszName); - return addAttribute_WOSD((XMLSTR)newAttribute->lpszName, (XMLSTR)newAttribute->lpszValue); -} - -XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName, XMLCSTR lpszOldName) -{ - int j = 0; - getAttribute(lpszOldName, &j); - if (j) return updateAttribute_WOSD(lpszNewValue, lpszNewName, j-1); - else - { - if (lpszNewName) return addAttribute_WOSD(lpszNewName, lpszNewValue); - else return addAttribute_WOSD(stringDup(lpszOldName), lpszNewValue); - } -} - -int XMLNode::indexText(XMLCSTR lpszValue) const -{ - if (!d) return -1; - int i, l = d->nText; - if (!lpszValue) { if (l) return 0; return -1; } - XMLCSTR *p = d->pText; - for (i=0; i=d->nText)) return; - invalidateInnerText(); - d->nText--; - XMLCSTR *p = d->pText+i; - free((void*)*p); - if (d->nText) memmove(p, p+1, (d->nText-i)*sizeof(XMLCSTR)); else { free(p); d->pText = NULL; } - removeOrderElement(d, eNodeText, i); -} - -void XMLNode::deleteText(XMLCSTR lpszValue) { deleteText(indexText(lpszValue)); } - -XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, int i) -{ - if (!d) { if (lpszNewValue) free(lpszNewValue); return NULL; } - if (i>=d->nText) return addText_WOSD(lpszNewValue); - invalidateInnerText(); - XMLCSTR *p = d->pText+i; - if (*p != lpszNewValue) { free((void*)*p); *p = lpszNewValue; } - return lpszNewValue; -} - -XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue) -{ - if (!d) { if (lpszNewValue) free(lpszNewValue); return NULL; } - int i = indexText(lpszOldValue); - if (i>=0) return updateText_WOSD(lpszNewValue, i); - return addText_WOSD(lpszNewValue); -} - -void XMLNode::deleteClear(int i) -{ - if ((!d) || (i<0) || (i>=d->nClear)) return; - invalidateInnerText(); - d->nClear--; - XMLClear *p = d->pClear+i; - free((void*)p->lpszValue); - if (d->nClear) memmove(p, p+1, (d->nClear-i)*sizeof(XMLClear)); else { free(p); d->pClear = NULL; } - removeOrderElement(d, eNodeClear, i); -} - -int XMLNode::indexClear(XMLCSTR lpszValue) const -{ - if (!d) return -1; - int i, l = d->nClear; - if (!lpszValue) { if (l) return 0; return -1; } - XMLClear *p = d->pClear; - for (i=0; ilpszValue); } - -XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, int i) -{ - if (!d) { if (lpszNewContent) free(lpszNewContent); return NULL; } - if (i>=d->nClear) return addClear_WOSD(lpszNewContent); - invalidateInnerText(); - XMLClear *p = d->pClear+i; - if (lpszNewContent != p->lpszValue) { free((void*)p->lpszValue); p->lpszValue = lpszNewContent; } - return p; -} - -XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, XMLCSTR lpszOldValue) -{ - if (!d) { if (lpszNewContent) free(lpszNewContent); return NULL; } - int i = indexClear(lpszOldValue); - if (i>=0) return updateClear_WOSD(lpszNewContent, i); - return addClear_WOSD(lpszNewContent); -} - -XMLClear *XMLNode::updateClear_WOSD(XMLClear *newP, XMLClear *oldP) -{ - if (oldP) return updateClear_WOSD((XMLSTR)newP->lpszValue, (XMLSTR)oldP->lpszValue); - return NULL; -} - -int XMLNode::nChildNode(XMLCSTR name) const -{ - if (!d) return 0; - int i, j = 0, n = d->nChild; - XMLNode *pc = d->pChild; - for (i=0; id->lpszName, name) == 0) j++; - pc++; - } - return j; -} - -XMLNode XMLNode::getChildNode(XMLCSTR name, int *j) const -{ - if (!d) return emptyXMLNode; - int i=0, n = d->nChild; - if (j) i = *j; - XMLNode *pc = d->pChild+i; - for (; id->lpszName, name)) - { - if (j) *j = i+1; - return *pc; - } - pc++; - } - return emptyXMLNode; -} - -XMLNode XMLNode::getChildNode(XMLCSTR name, int j) const -{ - if (!d) return emptyXMLNode; - if (j>=0) - { - int i=0; - while (j-->0) getChildNode(name, &i); - return getChildNode(name, &i); - } - int i = d->nChild; - while (i--) if (!xstricmp(name, d->pChild[i].d->lpszName)) break; - if (i<0) return emptyXMLNode; - return getChildNode(i); -} - -XMLNode XMLNode::getNextNode() const -{ - if (!d) return emptyXMLNode; - XMLNodeDataTag *par = d->pParent; - if (!par) return emptyXMLNode; - int i, n = par->nChild; - for (i=0; ipChild[i].d == d) - break; - - return XMLNode(par).getChildNode(d->lpszName, &++i); -} - -XMLNode XMLNode::getChildNodeByPath(XMLCSTR _path, char createMissing, XMLCHAR sep) -{ - XMLSTR path = stringDup(_path); - XMLNode x = getChildNodeByPathNonConst(path, createMissing, sep); - if (path) free(path); - return x; -} - -XMLNode XMLNode::getChildNodeByPathNonConst(XMLSTR path, char createIfMissing, XMLCHAR sep) -{ - if ((!path) || (!(*path))) return *this; - XMLNode xn, xbase = *this; - XMLCHAR *tend1, sepString[2]; sepString[0] = sep; sepString[1] = 0; - tend1 = xstrstr(path, sepString); - while (tend1) - { - *tend1 = 0; - xn = xbase.getChildNode(path); - if (xn.isEmpty()) - { - if (createIfMissing) xn = xbase.addChild(path); - else { *tend1 = sep; return XMLNode::emptyXMLNode; } - } - *tend1 = sep; - xbase = xn; - path = tend1+1; - tend1 = xstrstr(path, sepString); - } - xn = xbase.getChildNode(path); - if (xn.isEmpty()&&createIfMissing) xn = xbase.addChild(path); - return xn; -} - -XMLElementPosition XMLNode::positionOfText (int i) const { if (i>=d->nText) i = d->nText-1; return findPosition(d, i, eNodeText); } -XMLElementPosition XMLNode::positionOfClear (int i) const { if (i>=d->nClear) i = d->nClear-1; return findPosition(d, i, eNodeClear); } -XMLElementPosition XMLNode::positionOfChildNode(int i) const { if (i>=d->nChild) i = d->nChild-1; return findPosition(d, i, eNodeChild); } -XMLElementPosition XMLNode::positionOfText (XMLCSTR lpszValue) const { return positionOfText (indexText (lpszValue)); } -XMLElementPosition XMLNode::positionOfClear(XMLCSTR lpszValue) const { return positionOfClear(indexClear(lpszValue)); } -XMLElementPosition XMLNode::positionOfClear(XMLClear *a) const { if (a) return positionOfClear(a->lpszValue); return positionOfClear(); } -XMLElementPosition XMLNode::positionOfChildNode(XMLNode x) const -{ - if ((!d) || (!x.d)) return -1; - XMLNodeData *dd = x.d; - XMLNode *pc = d->pChild; - int i = d->nChild; - while (i--) if (pc[i].d == dd) return findPosition(d, i, eNodeChild); - return -1; -} -XMLElementPosition XMLNode::positionOfChildNode(XMLCSTR name, int count) const -{ - if (!name) return positionOfChildNode(count); - int j = 0; - do { getChildNode(name, &j); if (j<0) return -1; } while (count--); - return findPosition(d, j-1, eNodeChild); -} - -XMLNode XMLNode::getChildNodeWithAttribute(XMLCSTR name, XMLCSTR attributeName, XMLCSTR attributeValue, int *k) const -{ - int i=0, j; - if (k) i = *k; - XMLNode x; - XMLCSTR t; - do - { - x = getChildNode(name, &i); - if (!x.isEmpty()) - { - if (attributeValue) - { - j = 0; - do - { - t = x.getAttribute(attributeName, &j); - if (t&&(xstricmp(attributeValue, t) == 0)) { if (k) *k = i; return x; } - } while (t); - } else - { - if (x.isAttributeSet(attributeName)) { if (k) *k = i; return x; } - } - } - } while (!x.isEmpty()); - return emptyXMLNode; -} - -// Find an attribute on an node. -XMLCSTR XMLNode::getAttribute(XMLCSTR lpszAttrib, int *j) const -{ - if (!d) return NULL; - int i=0, n = d->nAttribute; - if (j) i = *j; - XMLAttribute *pAttr = d->pAttribute+i; - for (; ilpszName, lpszAttrib) == 0) - { - if (j) *j = i+1; - return pAttr->lpszValue; - } - pAttr++; - } - return NULL; -} - -char XMLNode::isAttributeSet(XMLCSTR lpszAttrib) const -{ - if (!d) return FALSE; - int i, n = d->nAttribute; - XMLAttribute *pAttr = d->pAttribute; - for (i=0; ilpszName, lpszAttrib) == 0) - { - return TRUE; - } - pAttr++; - } - return FALSE; -} - -XMLCSTR XMLNode::getAttribute(XMLCSTR name, int j) const -{ - if (!d) return NULL; - int i=0; - while (j-->0) getAttribute(name, &i); - return getAttribute(name, &i); -} - -XMLNodeContents XMLNode::enumContents(int i) const -{ - XMLNodeContents c; - if (!d) { c.etype = eNodeNULL; return c; } - if (inAttribute) - { - c.etype = eNodeAttribute; - c.attrib = d->pAttribute[i]; - return c; - } - i-=d->nAttribute; - c.etype = (XMLElementType)(d->pOrder[i]&3); - i = (d->pOrder[i])>>2; - switch (c.etype) - { - case eNodeChild: c.child = d->pChild[i]; break; - case eNodeText: c.text = d->pText[i]; break; - case eNodeClear: c.clear = d->pClear[i]; break; - default: break; - } - return c; -} - -XMLCSTR XMLNode::getInnerText() const -{ - if (!d) return NULL; - if (nText() <= 1 && nClear() == 0) return getText(); - if (d->pInnerText) return d->pInnerText; - - int count = nElement(); - size_t length = 1; - for (int i=0; i < count; i++) - { - XMLNodeContents c = enumContents(i); - switch (c.etype) - { - case eNodeText: - length += xstrlen(c.text); - break; - case eNodeClear: - length += xstrlen(c.clear.lpszValue); - break; - } - } - XMLCHAR *buf = (XMLCHAR *)malloc(sizeof(XMLCHAR) * length); - XMLCHAR *pos = buf; - for (int i=0; i < count; i++) - { - XMLNodeContents c = enumContents(i); - switch (c.etype) - { - case eNodeText: - xstrcpy(pos, c.text); - pos += xstrlen(c.text); - break; - case eNodeClear: - xstrcpy(pos, c.clear.lpszValue); - pos += xstrlen(c.clear.lpszValue); - break; - } - } - return d->pInnerText = buf; -} - -XMLCSTR XMLNode::getName() const { if (!d) return NULL; return d->lpszName; } -int XMLNode::nText() const { if (!d) return 0; return d->nText; } -int XMLNode::nChildNode() const { if (!d) return 0; return d->nChild; } -int XMLNode::nAttribute() const { if (!d) return 0; return d->nAttribute; } -int XMLNode::nClear() const { if (!d) return 0; return d->nClear; } -int XMLNode::nElement() const { if (!d) return 0; return d->nAttribute+d->nChild+d->nText+d->nClear; } -XMLClear XMLNode::getClear (int i) const { if ((!d) || (i>=d->nClear)) return emptyXMLClear; return d->pClear[i]; } -XMLAttribute XMLNode::getAttribute (int i) const { if ((!d) || (i>=d->nAttribute)) return emptyXMLAttribute; return d->pAttribute[i]; } -XMLCSTR XMLNode::getAttributeName (int i) const { if ((!d) || (i>=d->nAttribute)) return NULL; return d->pAttribute[i].lpszName; } -XMLCSTR XMLNode::getAttributeValue(int i) const { if ((!d) || (i>=d->nAttribute)) return NULL; return d->pAttribute[i].lpszValue; } -XMLCSTR XMLNode::getText (int i) const { if ((!d) || (i>=d->nText)) return NULL; return d->pText[i]; } -XMLNode XMLNode::getChildNode (int i) const { if ((!d) || (i>=d->nChild)) return emptyXMLNode; return d->pChild[i]; } -XMLNode XMLNode::getParentNode () const { if ((!d) || (!d->pParent)) return emptyXMLNode; return XMLNode(d->pParent); } -char XMLNode::isDeclaration () const { if (!d) return 0; return d->isDeclaration; } -char XMLNode::isEmpty () const { return (d == NULL); } -XMLNode XMLNode::emptyNode () { return XMLNode::emptyXMLNode; } - -XMLNode XMLNode::addChild(XMLCSTR lpszName, char isDeclaration, XMLElementPosition pos) -{ return addChild_priv(0, stringDup(lpszName), isDeclaration, pos); } -XMLNode XMLNode::addChild_WOSD(XMLSTR lpszName, char isDeclaration, XMLElementPosition pos) -{ return addChild_priv(0, lpszName, isDeclaration, pos); } -XMLAttribute *XMLNode::addAttribute(XMLCSTR lpszName, XMLCSTR lpszValue) -{ return addAttribute_priv(0, stringDup(lpszName), stringDup(lpszValue)); } -XMLAttribute *XMLNode::addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValuev) -{ return addAttribute_priv(0, lpszName, lpszValuev); } -XMLCSTR XMLNode::addText(XMLCSTR lpszValue, XMLElementPosition pos) -{ return addText_priv(0, stringDup(lpszValue), pos); } -XMLCSTR XMLNode::addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos) -{ return addText_priv(0, lpszValue, pos); } -XMLClear *XMLNode::addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, XMLElementPosition pos) -{ return addClear_priv(0, stringDup(lpszValue), lpszOpen, lpszClose, pos); } -XMLClear *XMLNode::addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, XMLElementPosition pos) -{ return addClear_priv(0, lpszValue, lpszOpen, lpszClose, pos); } -XMLCSTR XMLNode::updateName(XMLCSTR lpszName) -{ return updateName_WOSD(stringDup(lpszName)); } -XMLAttribute *XMLNode::updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute) -{ return updateAttribute_WOSD(stringDup(newAttribute->lpszValue), stringDup(newAttribute->lpszName), oldAttribute->lpszName); } -XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName, int i) -{ return updateAttribute_WOSD(stringDup(lpszNewValue), stringDup(lpszNewName), i); } -XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName, XMLCSTR lpszOldName) -{ return updateAttribute_WOSD(stringDup(lpszNewValue), stringDup(lpszNewName), lpszOldName); } -XMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, int i) -{ return updateText_WOSD(stringDup(lpszNewValue), i); } -XMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue) -{ return updateText_WOSD(stringDup(lpszNewValue), lpszOldValue); } -XMLClear *XMLNode::updateClear(XMLCSTR lpszNewContent, int i) -{ return updateClear_WOSD(stringDup(lpszNewContent), i); } -XMLClear *XMLNode::updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue) -{ return updateClear_WOSD(stringDup(lpszNewValue), lpszOldValue); } -XMLClear *XMLNode::updateClear(XMLClear *newP, XMLClear *oldP) -{ return updateClear_WOSD(stringDup(newP->lpszValue), oldP->lpszValue); } - -char XMLNode::setGlobalOptions(XMLCharEncoding _characterEncoding, char _guessWideCharChars, - char _dropWhiteSpace, char _removeCommentsInMiddleOfText) -{ - guessWideCharChars = _guessWideCharChars; dropWhiteSpace = _dropWhiteSpace; removeCommentsInMiddleOfText = _removeCommentsInMiddleOfText; -#ifdef _XMLWIDECHAR - if (_characterEncoding) characterEncoding = _characterEncoding; -#else - switch(_characterEncoding) - { - case char_encoding_UTF8: characterEncoding = _characterEncoding; XML_ByteTable = XML_utf8ByteTable; break; - case char_encoding_legacy: characterEncoding = _characterEncoding; XML_ByteTable = XML_legacyByteTable; break; - case char_encoding_ShiftJIS: characterEncoding = _characterEncoding; XML_ByteTable = XML_sjisByteTable; break; - case char_encoding_GB2312: characterEncoding = _characterEncoding; XML_ByteTable = XML_gb2312ByteTable; break; - case char_encoding_Big5: - case char_encoding_GBK: characterEncoding = _characterEncoding; XML_ByteTable = XML_gbk_big5_ByteTable; break; - default: return 1; - } -#endif - return 0; -} - -XMLNode::XMLCharEncoding XMLNode::guessCharEncoding(void *buf, int l, char useXMLEncodingAttribute) -{ -#ifdef _XMLWIDECHAR - return (XMLCharEncoding)0; -#else - if (l<25) return (XMLCharEncoding)0; - if (guessWideCharChars&&(myIsTextWideChar(buf, l))) return (XMLCharEncoding)0; - unsigned char *b = (unsigned char*)buf; - if ((b[0] == 0xef)&&(b[1] == 0xbb)&&(b[2] == 0xbf)) return char_encoding_UTF8; - - // Match utf-8 model ? - XMLCharEncoding bestGuess = char_encoding_UTF8; - int i=0; - while (i>2 ]; - *(curr++) = base64EncodeTable[(inbuf[0]<<4)&0x3F]; - *(curr++) = base64Fillchar; - *(curr++) = base64Fillchar; - } else if (eLen == 2) - { - j = (inbuf[0]<<8)|inbuf[1]; - *(curr++) = base64EncodeTable[ j>>10 ]; - *(curr++) = base64EncodeTable[(j>> 4)&0x3f]; - *(curr++) = base64EncodeTable[(j<< 2)&0x3f]; - *(curr++) = base64Fillchar; - } - *(curr++) = 0; - return (XMLSTR)buf; -} - -unsigned int XMLParserBase64Tool::decodeSize(XMLCSTR data, XMLError *xe) -{ - if (!data) return 0; - if (xe) *xe = eXMLErrorNone; - int size = 0; - unsigned char c; - //skip any extra characters (e.g. newlines or spaces) - while (*data) - { -#ifdef _XMLWIDECHAR - if (*data>255) { if (xe) *xe = eXMLErrorBase64DecodeIllegalCharacter; return 0; } -#endif - c = base64DecodeTable[(unsigned char)(*data)]; - if (c<97) size++; - else if (c == 98) { if (xe) *xe = eXMLErrorBase64DecodeIllegalCharacter; return 0; } - data++; - } - if (xe&&(size%4 != 0)) *xe = eXMLErrorBase64DataSizeIsNotMultipleOf4; - if (size == 0) return 0; - do { data--; size--; } while (*data == base64Fillchar); size++; - return (unsigned int)((size*3)/4); -} - -unsigned char XMLParserBase64Tool::decode(XMLCSTR data, unsigned char *buf, int len, XMLError *xe) -{ - if (!data) return 0; - if (xe) *xe = eXMLErrorNone; - int i=0, p = 0; - unsigned char d, c; - for (;;) - { - -#ifdef _XMLWIDECHAR -#define BASE64DECODE_READ_NEXT_CHAR(c) \ - do { \ - if (data[i]>255) { c = 98; break; } \ - c = base64DecodeTable[(unsigned char)data[i++]]; \ - }while (c == 97); \ - if(c == 98) { if(xe)*xe = eXMLErrorBase64DecodeIllegalCharacter; return 0; } -#else -#define BASE64DECODE_READ_NEXT_CHAR(c) \ - do { c = base64DecodeTable[(unsigned char)data[i++]]; }while (c == 97); \ - if(c == 98) { if(xe)*xe = eXMLErrorBase64DecodeIllegalCharacter; return 0; } -#endif - - BASE64DECODE_READ_NEXT_CHAR(c) - if (c == 99) { return 2; } - if (c == 96) - { - if (p == (int)len) return 2; - if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; - return 1; - } - - BASE64DECODE_READ_NEXT_CHAR(d) - if ((d == 99) || (d == 96)) { if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; return 1; } - if (p == (int)len) { if (xe) *xe = eXMLErrorBase64DecodeBufferTooSmall; return 0; } - buf[p++] = (unsigned char)((c<<2)|((d>>4)&0x3)); - - BASE64DECODE_READ_NEXT_CHAR(c) - if (c == 99) { if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; return 1; } - if (p == (int)len) - { - if (c == 96) return 2; - if (xe) *xe = eXMLErrorBase64DecodeBufferTooSmall; - return 0; - } - if (c == 96) { if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; return 1; } - buf[p++] = (unsigned char)(((d<<4)&0xf0)|((c>>2)&0xf)); - - BASE64DECODE_READ_NEXT_CHAR(d) - if (d == 99) { if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; return 1; } - if (p == (int)len) - { - if (d == 96) return 2; - if (xe) *xe = eXMLErrorBase64DecodeBufferTooSmall; - return 0; - } - if (d == 96) { if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; return 1; } - buf[p++] = (unsigned char)(((c<<6)&0xc0)|d); - } -} -#undef BASE64DECODE_READ_NEXT_CHAR - -void XMLParserBase64Tool::alloc(int newsize) -{ - if ((!buf)&&(newsize)) { buf = malloc(newsize); buflen = newsize; return; } - if (newsize>buflen) { buf = realloc(buf, newsize); buflen = newsize; } -} - -unsigned char *XMLParserBase64Tool::decode(XMLCSTR data, int *outlen, XMLError *xe) -{ - if (xe) - *xe = eXMLErrorNone; - if (!data) { - if (outlen) - *outlen = 0; - return (unsigned char*)""; // XXX: check me! - } - - unsigned int len = decodeSize(data, xe); - if (outlen) - *outlen = len; - if (!len) - return NULL; - alloc(len+1); - if(!decode(data, (unsigned char*)buf, len, xe)) - return NULL; - return (unsigned char*)buf; -} - -////////////////////////////////////////////////////////// -// Helpers for external C APIs. // -////////////////////////////////////////////////////////// - -XMLNode::XMLNode(HXML h) : -d((XMLNodeDataTag*)h) -{ - if (d) - d->ref_count++; -} - -void XMLNode::attach(HXML h) -{ - d = (XMLNodeDataTag*)h; -} - -HXML XMLNode::detach() -{ - HXML res = (HXML)d; - d = NULL; - return res; -} diff --git a/src/modules/xml/xmlParser.h b/src/modules/xml/xmlParser.h deleted file mode 100644 index aa9bf91a88..0000000000 --- a/src/modules/xml/xmlParser.h +++ /dev/null @@ -1,715 +0,0 @@ -/****************************************************************************/ -/*! \mainpage XMLParser library - * \section intro_sec Introduction - * - * This is a basic XML parser written in ANSI C++ for portability. - * It works by using recursion and a node tree for breaking - * down the elements of an XML document. - * - * @version V2.43 - * @author Frank Vanden Berghen - * - * Copyright (c) 2002, Business-Insight - * Business-Insight - * All rights reserved. - * See the file AFPL-license.txt about the licensing terms - * - * \section tutorial First Tutorial - * You can follow a simple Tutorial to know the basics... - * - * \section usage General usage: How to include the XMLParser library inside your project. - * - * The library is composed of two files: xmlParser.cpp and - * xmlParser.h. These are the ONLY 2 files that you need when - * using the library inside your own projects. - * - * All the functions of the library are documented inside the comments of the file - * xmlParser.h. These comments can be transformed in - * full-fledged HTML documentation using the DOXYGEN software: simply type: "doxygen doxy.cfg" - * - * By default, the XMLParser library uses (char*) for string representation.To use the (wchar_t*) - * version of the library, you need to define the "_UNICODE" preprocessor definition variable - * (this is usually done inside your project definition file) (This is done automatically for you - * when using Visual Studio). - * - * \section example Advanced Tutorial and Many Examples of usage. - * - * Some very small introductory examples are described inside the Tutorial file - * xmlParser.html - * - * Some additional small examples are also inside the file xmlTest.cpp - * (for the "char*" version of the library) and inside the file - * xmlTestUnicode.cpp (for the "wchar_t*" - * version of the library). If you have a question, please review these additionnal examples - * before sending an e-mail to the author. - * - * To build the examples: - * - linux/unix: type "make" - * - solaris: type "make -f makefile.solaris" - * - windows: Visual Studio: double-click on xmlParser.dsw - * (under Visual Studio .NET, the .dsp and .dsw files will be automatically converted to .vcproj and .sln files) - * - * In order to build the examples you need some additional files: - * - linux/unix: makefile - * - solaris: makefile.solaris - * - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and xmlParser.dll - * - * \section debugging Debugging with the XMLParser library - * - * \subsection debugwin Debugging under WINDOWS - * - * Inside Visual C++, the "debug versions" of the memory allocation functions are - * very slow: Do not forget to compile in "release mode" to get maximum speed. - * When I had to debug a software that was using the XMLParser Library, it was usually - * a nightmare because the library was sooOOOoooo slow in debug mode (because of the - * slow memory allocations in Debug mode). To solve this - * problem, during all the debugging session, I am now using a very fast DLL version of the - * XMLParser Library (the DLL is compiled in release mode). Using the DLL version of - * the XMLParser Library allows me to have lightening XML parsing speed even in debug! - * Other than that, the DLL version is useless: In the release version of my tool, - * I always use the normal, ".cpp"-based, XMLParser Library (I simply include the - * xmlParser.cpp and - * xmlParser.h files into the project). - * - * The file XMLNodeAutoexp.txt contains some - * "tweaks" that improve substancially the display of the content of the XMLNode objects - * inside the Visual Studio Debugger. Believe me, once you have seen inside the debugger - * the "smooth" display of the XMLNode objects, you cannot live without it anymore! - * - * \subsection debuglinux Debugging under LINUX/UNIX - * - * The speed of the debug version of the XMLParser library is tolerable so no extra - * work.has been done. - * - ****************************************************************************/ - -#ifndef __INCLUDE_XML_NODE__ -#define __INCLUDE_XML_NODE__ - -#include - -// If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters). -// This is useful when you get error messages like: -// 'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *' -// The _XMLWIDECHAR preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable -// must be defined) or utf8-mode(the pre-processor variable must be undefined). -#define _XMLWIDECHAR - -#if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || defined(_WIN64) || defined(__BORLANDC__) -// comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET) or Borland -#define _XMLWINDOWS -#endif - -#ifdef XMLDLLENTRY -#undef XMLDLLENTRY -#endif -#ifdef _USE_XMLPARSER_DLL -#ifdef _DLL_EXPORTS_ -#define XMLDLLENTRY __declspec(dllexport) -#else -#define XMLDLLENTRY __declspec(dllimport) -#endif -#else -#define XMLDLLENTRY -#endif - -// uncomment the next line if you want no support for wchar_t* (no need for the or libraries anymore to compile) -//#define XML_NO_WIDE_CHAR - -#ifdef XML_NO_WIDE_CHAR -#undef _XMLWINDOWS -#undef _XMLWIDECHAR -#endif - -#ifdef _XMLWINDOWS -#include -#else -#define XMLDLLENTRY -#ifndef XML_NO_WIDE_CHAR -#include // to have 'wcsrtombs' for ANSI version - // to have 'mbsrtowcs' for WIDECHAR version -#endif -#endif - -// Some common types for char set portable code -#ifdef _XMLWIDECHAR - #define _CXML(c) L ## c - #define XMLCSTR const wchar_t * - #define XMLSTR wchar_t * - #define XMLCHAR wchar_t -#else - #define _CXML(c) c - #define XMLCSTR const char * - #define XMLSTR char * - #define XMLCHAR char -#endif -#ifndef FALSE - #define FALSE 0 -#endif /* FALSE */ -#ifndef TRUE - #define TRUE 1 -#endif /* TRUE */ - -/// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents -typedef enum XMLElementType -{ - eNodeChild = 0, - eNodeAttribute = 1, - eNodeText = 2, - eNodeClear = 3, - eNodeNULL = 4 -} XMLElementType; - -/// Structure used to obtain error details if the parse fails. -typedef struct XMLResults -{ - enum XMLError error; - int nLine, nColumn, nChars; -} XMLResults; - -/// Structure for XML clear (unformatted) node (usually comments) -typedef struct XMLClear { - XMLCSTR lpszValue; XMLCSTR lpszOpenTag; XMLCSTR lpszCloseTag; -} XMLClear; - -/// Structure for XML attribute. -typedef struct XMLAttribute { - XMLCSTR lpszName; XMLCSTR lpszValue; -} XMLAttribute; - -/// XMLElementPosition are not interchangeable with simple indexes -typedef int XMLElementPosition; - -struct XMLNodeContents; - -/** @defgroup XMLParserGeneral The XML parser */ - -/// Main Class representing a XML node -/** - * All operations are performed using this class. - * \note The constructors of the XMLNode class are protected, so use instead one of these four methods to get your first instance of XMLNode: - *
    - *
  • XMLNode::parseString
  • - *
  • XMLNode::parseFile
  • - *
  • XMLNode::openFileHelper
  • - *
  • XMLNode::createXMLTopNode (or XMLNode::createXMLTopNode_WOSD)
  • - *
*/ -typedef struct XMLDLLENTRY XMLNode -{ -private: - - struct XMLNodeDataTag; - - /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode - XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration); - /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode - XMLNode(struct XMLNodeDataTag *p); - -public: - static XMLCSTR getVersion();///< Return the XMLParser library version number - - /** @defgroup conversions Parsing XML files/strings to an XMLNode structure and Rendering XMLNode's to files/string. - * @ingroup XMLParserGeneral - * @{ */ - - /// Parse an XML string and return the root of a XMLNode tree representing the string. - static XMLNode parseString (XMLCSTR lpXMLString, XMLCSTR tag = NULL, XMLResults *pResults = NULL); - /**< The "parseString" function parse an XML string and return the root of a XMLNode tree. The "opposite" of this function is - * the function "createXMLString" that re-creates an XML string from an XMLNode tree. If the XML document is corrupted, the - * "parseString" method will initialize the "pResults" variable with some information that can be used to trace the error. - * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the - * beginning of the "xmlParser.cpp" file. - * - * @param lpXMLString the XML string to parse - * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (). - * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function. - */ - - /// Parse an XML file and return the root of a XMLNode tree representing the file. - static XMLNode parseFile (XMLCSTR filename, XMLCSTR tag = NULL, XMLResults *pResults = NULL); - /**< The "parseFile" function parse an XML file and return the root of a XMLNode tree. The "opposite" of this function is - * the function "writeToFile" that re-creates an XML file from an XMLNode tree. If the XML document is corrupted, the - * "parseFile" method will initialize the "pResults" variable with some information that can be used to trace the error. - * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the - * beginning of the "xmlParser.cpp" file. - * - * @param filename the path to the XML file to parse - * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (). - * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function. - */ - - /// Parse an XML file and return the root of a XMLNode tree representing the file. A very crude error checking is made. An attempt to guess the Char Encoding used in the file is made. - static XMLNode openFileHelper(XMLCSTR filename, XMLCSTR tag = NULL); - /**< The "openFileHelper" function reports to the screen all the warnings and errors that occurred during parsing of the XML file. - * This function also tries to guess char Encoding (UTF-8, ASCII or SHIT-JIS) based on the first 200 bytes of the file. Since each - * application has its own way to report and deal with errors, you should rather use the "parseFile" function to parse XML files - * and program yourself thereafter an "error reporting" tailored for your needs (instead of using the very crude "error reporting" - * mechanism included inside the "openFileHelper" function). - * - * If the XML document is corrupted, the "openFileHelper" method will: - * - display an error message on the console (or inside a messageBox for windows). - * - stop execution (exit). - * - * I strongly suggest that you write your own "openFileHelper" method tailored to your needs. If you still want to parse - * the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the beginning of the "xmlParser.cpp" file. - * - * @param filename the path of the XML file to parse. - * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (). - */ - - static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly explanation of the parsing error - - /// Create an XML string starting from the current XMLNode. - XMLSTR createXMLString(int nFormat = 1, int *pnSize = NULL) const; - /**< The returned string should be free'd using the "freeXMLString" function. - * - * If nFormat == 0, no formatting is required otherwise this returns an user friendly XML string from a given element - * with appropriate white spaces and carriage returns. if pnSize is given it returns the size in character of the string. */ - - /// Save the content of an xmlNode inside a file - XMLError writeToFile(XMLCSTR filename, - const char *encoding = NULL, - char nFormat = 1) const; - /**< If nFormat == 0, no formatting is required otherwise this returns an user friendly XML string from a given element with appropriate white spaces and carriage returns. - * If the global parameter "characterEncoding == encoding_UTF8", then the "encoding" parameter is ignored and always set to "utf-8". - * If the global parameter "characterEncoding == encoding_ShiftJIS", then the "encoding" parameter is ignored and always set to "SHIFT-JIS". - * If "_XMLWIDECHAR = 1", then the "encoding" parameter is ignored and always set to "utf-16". - * If no "encoding" parameter is given the "ISO-8859-1" encoding is used. */ - /** @} */ - - /** @defgroup navigate Navigate the XMLNode structure - * @ingroup XMLParserGeneral - * @{ */ - XMLCSTR getName() const; ///< name of the node - XMLCSTR getText(int i=0) const; ///< return ith text field - XMLCSTR getInnerText() const; - int nText() const; ///< nbr of text field - XMLNode getParentNode() const; ///< return the parent node - XMLNode getChildNode(int i=0) const; ///< return ith child node - XMLNode getChildNode(XMLCSTR name, int i) const; ///< return ith child node with specific name (return an empty node if failing). If i == -1, this returns the last XMLNode with the given name. - XMLNode getChildNode(XMLCSTR name, int *i = NULL) const; ///< return next child node with specific name (return an empty node if failing) - XMLNode getChildNodeWithAttribute(XMLCSTR tagName, - XMLCSTR attributeName, - XMLCSTR attributeValue = NULL, - int *i = NULL) const; ///< return child node with specific name/attribute (return an empty node if failing) - XMLNode getChildNodeByPath(XMLSTR path, char createNodeIfMissing = 0, XMLCHAR sep = '/'); - ///< return the first child node with specific path. WARNING: the value of the parameter "path" is destroyed! - XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing = 0, XMLCHAR sep = '/'); - ///< return the first child node with specific path - XMLNode getChildNodeByPathNonConst(XMLSTR path, char createNodeIfMissing = 0, XMLCHAR sep = '/'); - ///< return the first child node with specific path. - XMLNode getNextNode() const; - - int nChildNode(XMLCSTR name) const; ///< return the number of child node with specific name - int nChildNode() const; ///< nbr of child node - XMLAttribute getAttribute(int i=0) const; ///< return ith attribute - XMLCSTR getAttributeName(int i=0) const; ///< return ith attribute name - XMLCSTR getAttributeValue(int i=0) const; ///< return ith attribute value - char isAttributeSet(XMLCSTR name) const; ///< test if an attribute with a specific name is given - XMLCSTR getAttribute(XMLCSTR name, int i) const; ///< return ith attribute content with specific name (return a NULL if failing) - XMLCSTR getAttribute(XMLCSTR name, int *i = NULL) const; ///< return next attribute content with specific name (return a NULL if failing) - int nAttribute() const; ///< nbr of attribute - XMLClear getClear(int i=0) const; ///< return ith clear field (comments) - int nClear() const; ///< nbr of clear field - XMLNodeContents enumContents(XMLElementPosition i) const; ///< enumerate all the different contents (attribute, child, text, clear) of the current XMLNode. The order is reflecting the order of the original file/string. NOTE: 0 <= i < nElement(); - int nElement() const; ///< nbr of different contents for current node - char isEmpty() const; ///< is this node Empty? - char isDeclaration() const; ///< is this node a declaration - XMLNode deepCopy() const; ///< deep copy (duplicate/clone) a XMLNode - static XMLNode emptyNode(); ///< return XMLNode::emptyXMLNode; - /** @} */ - - ~XMLNode(); - XMLNode(const XMLNode &A); ///< to allow shallow/fast copy: - XMLNode& operator = (const XMLNode& A); ///< to allow shallow/fast copy: - - XMLNode(): d(NULL) {}; - static XMLNode emptyXMLNode; - static XMLClear emptyXMLClear; - static XMLAttribute emptyXMLAttribute; - - /** helpers for external C applications **/ - XMLNode(HXML h); - void attach(HXML h); - HXML detach(); - operator HXML() const { return (HXML)d; } - - /** @defgroup xmlModify Create or Update the XMLNode structure - * @ingroup XMLParserGeneral - * The functions in this group allows you to create from scratch (or update) a XMLNode structure. Start by creating your top - * node with the "createXMLTopNode" function and then add new nodes with the "addChild" function. The parameter 'pos' gives - * the position where the childNode, the text or the XMLClearTag will be inserted. The default value (pos = -1) inserts at the - * end. The value (pos = 0) insert at the beginning (Insertion at the beginning is slower than at the end).
- * - * REMARK: 0 <= pos < nChild()+nText()+nClear()
- */ - - /** @defgroup creation Creating from scratch a XMLNode structure - * @ingroup xmlModify - * @{ */ - static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration = FALSE); ///< Create the top node of an XMLNode structure - XMLNode addChild(XMLCSTR lpszName, char isDeclaration = FALSE, XMLElementPosition pos = -1); ///< Add a new child node - XMLNode addChild(XMLNode nodeToAdd, XMLElementPosition pos = -1); ///< If the "nodeToAdd" has some parents, it will be detached from it's parents before being attached to the current XMLNode - XMLAttribute *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev); ///< Add a new attribute - XMLCSTR addText(XMLCSTR lpszValue, XMLElementPosition pos = -1); ///< Add a new text content - XMLClear *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen = NULL, XMLCSTR lpszClose = NULL, XMLElementPosition pos = -1); - /**< Add a new clear tag - * @param lpszOpen default value "" - */ - /** @} */ - - /** @defgroup xmlUpdate Updating Nodes - * @ingroup xmlModify - * Some update functions: - * @{ - */ - XMLCSTR updateName(XMLCSTR lpszName); ///< change node's name - XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the attribute to update is missing, a new one will be added - XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName = NULL, int i=0); ///< if the attribute to update is missing, a new one will be added - XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName, XMLCSTR lpszOldName);///< set lpszNewName = NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added - XMLCSTR updateText(XMLCSTR lpszNewValue, int i=0); ///< if the text to update is missing, a new one will be added - XMLCSTR updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one will be added - XMLClear *updateClear(XMLCSTR lpszNewContent, int i=0); ///< if the clearTag to update is missing, a new one will be added - XMLClear *updateClear(XMLClear *newP, XMLClear *oldP); ///< if the clearTag to update is missing, a new one will be added - XMLClear *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new one will be added - /** @} */ - - /** @defgroup xmlDelete Deleting Nodes or Attributes - * @ingroup xmlModify - * Some deletion functions: - * @{ - */ - /// The "deleteNodeContent" function forces the deletion of the content of this XMLNode and the subtree. - void deleteNodeContent(); - /**< \note The XMLNode instances that are referring to the part of the subtree that has been deleted CANNOT be used anymore!!. Unexpected results will occur if you continue using them. */ - void deleteAttribute(int i=0); ///< Delete the ith attribute of the current XMLNode - void deleteAttribute(XMLCSTR lpszName); ///< Delete the attribute with the given name (the "mir_strcmp" function is used to find the right attribute) - void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute with the name "anAttribute->lpszName" (the "mir_strcmp" function is used to find the right attribute) - void deleteText(int i=0); ///< Delete the Ith text content of the current XMLNode - void deleteText(XMLCSTR lpszValue); ///< Delete the text content "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the right text) - void deleteClear(int i=0); ///< Delete the Ith clear tag inside the current XMLNode - void deleteClear(XMLCSTR lpszValue); ///< Delete the clear tag "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the clear tag) - void deleteClear(XMLClear *p); ///< Delete the clear tag "p" inside the current XMLNode (direct "pointer-to-pointer" comparison on the lpszName of the clear tag is used to find the clear tag) - /** @} */ - - /** @defgroup xmlWOSD ???_WOSD functions. - * @ingroup xmlModify - * The strings given as parameters for the "add" and "update" methods that have a name with - * the postfix "_WOSD" (that means "WithOut String Duplication")(for example "addText_WOSD") - * will be free'd by the XMLNode class. For example, it means that this is incorrect: - * \code - * xNode.addText_WOSD("foo"); - * xNode.updateAttribute_WOSD("#newcolor" , NULL, "color"); - * \endcode - * In opposition, this is correct: - * \code - * xNode.addText("foo"); - * xNode.addText_WOSD(stringDup("foo")); - * xNode.updateAttribute("#newcolor" , NULL, "color"); - * xNode.updateAttribute_WOSD(stringDup("#newcolor"), NULL, "color"); - * \endcode - * Typically, you will never do: - * \code - * char *b = (char*)malloc(...); - * xNode.addText(b); - * free(b); - * \endcode - * ... but rather: - * \code - * char *b = (char*)malloc(...); - * xNode.addText_WOSD(b); - * \endcode - * ('free(b)' is performed by the XMLNode class) - * @{ */ - static XMLNode createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration = FALSE); ///< Create the top node of an XMLNode structure - XMLNode addChild_WOSD(XMLSTR lpszName, char isDeclaration = FALSE, XMLElementPosition pos = -1); ///< Add a new child node - XMLAttribute *addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValue); ///< Add a new attribute - XMLCSTR addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos = -1); ///< Add a new text content - XMLClear *addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen = NULL, XMLCSTR lpszClose = NULL, XMLElementPosition pos = -1); ///< Add a new clear Tag - - XMLCSTR updateName_WOSD(XMLSTR lpszName); ///< change node's name - XMLAttribute *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the attribute to update is missing, a new one will be added - XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName = NULL, int i=0); ///< if the attribute to update is missing, a new one will be added - XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName, XMLCSTR lpszOldName); ///< set lpszNewName = NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added - XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, int i=0); ///< if the text to update is missing, a new one will be added - XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one will be added - XMLClear *updateClear_WOSD(XMLSTR lpszNewContent, int i=0); ///< if the clearTag to update is missing, a new one will be added - XMLClear *updateClear_WOSD(XMLClear *newP, XMLClear *oldP); ///< if the clearTag to update is missing, a new one will be added - XMLClear *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new one will be added - /** @} */ - - /** @defgroup xmlPosition Position helper functions (use in conjunction with the update&add functions - * @ingroup xmlModify - * These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the - * middle (at a specified position) of a XMLNode tree already constructed. The value returned by these - * methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear. - * @{ */ - XMLElementPosition positionOfText(int i=0) const; - XMLElementPosition positionOfText(XMLCSTR lpszValue) const; - XMLElementPosition positionOfClear(int i=0) const; - XMLElementPosition positionOfClear(XMLCSTR lpszValue) const; - XMLElementPosition positionOfClear(XMLClear *a) const; - XMLElementPosition positionOfChildNode(int i=0) const; - XMLElementPosition positionOfChildNode(XMLNode x) const; - XMLElementPosition positionOfChildNode(XMLCSTR name, int i=0) const; ///< return the position of the ith childNode with the specified name if (name == NULL) return the position of the ith childNode - /** @} */ - - /// Enumeration for XML character encoding. - typedef enum XMLCharEncoding - { - char_encoding_error = 0, - char_encoding_UTF8 = 1, - char_encoding_legacy = 2, - char_encoding_ShiftJIS = 3, - char_encoding_GB2312 = 4, - char_encoding_Big5 = 5, - char_encoding_GBK = 6 // this is actually the same as Big5 - } XMLCharEncoding; - - /** \addtogroup conversions - * @{ */ - - /// Sets the global options for the conversions - static char setGlobalOptions(XMLCharEncoding characterEncoding = XMLNode::char_encoding_UTF8, char guessWideCharChars = 1, - char dropWhiteSpace = 1, char removeCommentsInMiddleOfText = 1); - /**< The "setGlobalOptions" function allows you to change four global parameters that affect string & file - * parsing. First of all, you most-probably will never have to change these 3 global parameters. - * - * @param guessWideCharChars If "guessWideCharChars" = 1 and if this library is compiled in WideChar mode, then the - * XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains ASCII - * characters. If this is the case, then the file will be loaded and converted in memory to - * WideChar before being parsed. If 0, no conversion will be performed. - * - * @param guessWideCharChars If "guessWideCharChars" = 1 and if this library is compiled in ASCII/UTF8/char* mode, then the - * XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains WideChar - * characters. If this is the case, then the file will be loaded and converted in memory to - * ASCII/UTF8/char* before being parsed. If 0, no conversion will be performed. - * - * @param characterEncoding This parameter is only meaningful when compiling in char* mode (multibyte character mode). - * In wchar_t* (wide char mode), this parameter is ignored. This parameter should be one of the - * three currently recognized encodings: XMLNode::encoding_UTF8, XMLNode::encoding_ascii, - * XMLNode::encoding_ShiftJIS. - * - * @param dropWhiteSpace In most situations, text fields containing only white spaces (and carriage returns) - * are useless. Even more, these "empty" text fields are annoying because they increase the - * complexity of the user's code for parsing. So, 99% of the time, it's better to drop - * the "empty" text fields. However The XML specification indicates that no white spaces - * should be lost when parsing the file. So to be perfectly XML-compliant, you should set - * dropWhiteSpace = 0. A note of caution: if you set "dropWhiteSpace = 0", the parser will be - * slower and your code will be more complex. - * - * @param removeCommentsInMiddleOfText To explain this parameter, let's consider this code: - * \code - * XMLNode x = XMLNode::parseString("foobarchu", "a"); - * \endcode - * If removeCommentsInMiddleOfText = 0, then we will have: - * \code - * x.getText(0) -> "foo" - * x.getText(1) -> "bar" - * x.getText(2) -> "chu" - * x.getClear(0) --> "" - * x.getClear(1) --> "" - * \endcode - * If removeCommentsInMiddleOfText = 1, then we will have: - * \code - * x.getText(0) -> "foobar" - * x.getText(1) -> "chu" - * x.getClear(0) --> "" - * \endcode - * - * \return "0" when there are no errors. If you try to set an unrecognized encoding then the return value will be "1" to signal an error. - * - * \note Sometime, it's useful to set "guessWideCharChars = 0" to disable any conversion - * because the test to detect the file-type (ASCII/UTF8/char* or WideChar) may fail (rarely). */ - - /// Guess the character encoding of the string (ascii, utf8 or shift-JIS) - static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, char useXMLEncodingAttribute = 1); - /**< The "guessCharEncoding" function try to guess the character encoding. You most-probably will never - * have to use this function. It then returns the appropriate value of the global parameter - * "characterEncoding" described in the XMLNode::setGlobalOptions. The guess is based on the content of a buffer of length - * "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the - * file to be parsed. The XMLNode::openFileHelper function is using this function to automatically compute - * the value of the "characterEncoding" global parameter. There are several heuristics used to do the - * guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications - * forbids to use this attribute to do the guess but you can still use it if you set - * "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers). - * If an inconsistency in the encoding is detected, then the return value is "0". */ - /** @} */ - -private: - // these are functions and structures used internally by the XMLNode class (don't bother about them): - - typedef struct XMLNodeDataTag // to allow shallow copy and "intelligent/smart" pointers (automatic delete): - { - XMLCSTR lpszName; // Element name ( = NULL if root) - XMLCSTR lpszNS; // Namespace - int nChild, // Number of child nodes - nText, // Number of text fields - nClear, // Number of Clear fields (comments) - nAttribute; // Number of attributes - char isDeclaration; // Whether node is an XML declaration - '' - struct XMLNodeDataTag *pParent; // Pointer to parent element ( = NULL if root) - XMLNode *pChild; // Array of child nodes - XMLCSTR *pText; // Array of text fields - XMLClear *pClear; // Array of clear fields - XMLAttribute *pAttribute; // Array of attributes - int *pOrder; // order of the child_nodes, text_fields, clear_fields - int ref_count; // for garbage collection (smart pointers) - XMLSTR pInnerText; // cached value of inner text, for memory manadgement purposes - } XMLNodeData; - XMLNodeData *d; - - char parseClearTag(void *px, void *pa); - char maybeAddTxT(void *pa, XMLCSTR tokenPStr); - int ParseXMLElement(void *pXML); - void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype); - int indexText(XMLCSTR lpszValue) const; - int indexClear(XMLCSTR lpszValue) const; - XMLNode addChild_priv(int, XMLSTR, char, int); - XMLAttribute *addAttribute_priv(int, XMLSTR, XMLSTR); - XMLCSTR addText_priv(int, XMLSTR, int); - XMLClear *addClear_priv(int, XMLSTR, XMLCSTR, XMLCSTR, int); - void emptyTheNode(char force); - void invalidateInnerText(); - static inline XMLElementPosition findPosition(XMLNodeData *d, int index, XMLElementType xtype); - static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat); - static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index); - static void exactMemory(XMLNodeData *d); - static int detachFromParent(XMLNodeData *d); -} XMLNode; - -/// This structure is given by the function XMLNode::enumContents. -typedef struct XMLNodeContents -{ - /// This dictates what's the content of the XMLNodeContent - enum XMLElementType etype; - /**< should be an union to access the appropriate data. Compiler does not allow union of object with constructor... too bad. */ - XMLNode child; - XMLAttribute attrib; - XMLCSTR text; - XMLClear clear; - -} XMLNodeContents; - -/** @defgroup StringAlloc String Allocation/Free functions -* @ingroup xmlModify -* @{ */ -/// Duplicate (copy in a new allocated buffer) the source string. -XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData = -1); -/**< This is -* a very handy function when used with all the "XMLNode::*_WOSD" functions (\link xmlWOSD \endlink). -* @param cbData If != 0 then cbData is the number of chars to duplicate. New strings allocated with -* this function should be free'd using the "freeXMLString" function. */ - -/// to free the string allocated inside the "stringDup" function or the "createXMLString" function. -XMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);} -/** @} */ - -/** @defgroup atoX ato? like functions -* @ingroup XMLParserGeneral -* The "xmlto?" functions are equivalents to the atoi, atol, atof functions. -* The only difference is: If the variable "xmlString" is NULL, than the return value -* is "defautValue". These 6 functions are only here as "convenience" functions for the -* user (they are not used inside the XMLparser). If you don't need them, you can -* delete them without any trouble. -* -* @{ */ -XMLDLLENTRY char xmltob(XMLCSTR xmlString, char defautValue = 0); -XMLDLLENTRY int xmltoi(XMLCSTR xmlString, int defautValue = 0); -XMLDLLENTRY long xmltol(XMLCSTR xmlString, long defautValue = 0); -XMLDLLENTRY double xmltof(XMLCSTR xmlString, double defautValue = .0); -XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString, XMLCSTR defautValue = _CXML("")); -XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString, const XMLCHAR defautValue = _CXML('\0')); -/** @} */ - -/** @defgroup ToXMLStringTool Helper class to create XML files using "printf", "fprintf", "cout", ... functions. -* @ingroup XMLParserGeneral -* @{ */ -/// Helper class to create XML files using "printf", "fprintf", "cout", ... functions. -/** The ToXMLStringTool class helps you creating XML files using "printf", "fprintf", "cout", ... functions. -* The "ToXMLStringTool" class is processing strings so that all the characters -* &, ", ', <, > are replaced by their XML equivalent: -* \verbatim &, ", ', <, > \endverbatim -* Using the "ToXMLStringTool class" and the "fprintf function" is THE most efficient -* way to produce VERY large XML documents VERY fast. -* \note If you are creating from scratch an XML file using the provided XMLNode class -* you must not use the "ToXMLStringTool" class (because the "XMLNode" class does the -* processing job for you during rendering).*/ -typedef struct XMLDLLENTRY ToXMLStringTool -{ -public: - ToXMLStringTool(): buf(NULL), buflen(0) {} - ~ToXMLStringTool(); - void freeBuffer();///