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/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 ------ 25 files changed, 13012 deletions(-) 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 (limited to 'src/modules/clist') 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; -} -- cgit v1.2.3