summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Weimer <wishmaster51@googlemail.com>2016-03-24 21:07:55 +0000
committerTobias Weimer <wishmaster51@googlemail.com>2016-03-24 21:07:55 +0000
commit2ad9dacc6b572b8a2d7d925668cae10abec5ef95 (patch)
tree25d1eb125a1ca128a5b8d516ff5897457e2eca96
parent49df455909f265452893494c7ffedf2298d6206d (diff)
CList_modern: cleanup
git-svn-id: http://svn.miranda-ng.org/main/trunk@16537 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--plugins/Clist_modern/src/cluiframes.cpp9
-rw-r--r--plugins/Clist_modern/src/modern_cachefuncs.cpp39
-rw-r--r--plugins/Clist_modern/src/modern_clc.cpp3704
-rw-r--r--plugins/Clist_modern/src/modern_clcitems.cpp1479
-rw-r--r--plugins/Clist_modern/src/modern_clcmsgs.cpp3
-rw-r--r--plugins/Clist_modern/src/modern_clcpaint.cpp8
-rw-r--r--plugins/Clist_modern/src/modern_skinselector.cpp10
-rw-r--r--plugins/Clist_modern/src/modern_skinselector.h7
8 files changed, 2626 insertions, 2633 deletions
diff --git a/plugins/Clist_modern/src/cluiframes.cpp b/plugins/Clist_modern/src/cluiframes.cpp
index fd8987d36e..4356d59893 100644
--- a/plugins/Clist_modern/src/cluiframes.cpp
+++ b/plugins/Clist_modern/src/cluiframes.cpp
@@ -2439,14 +2439,7 @@ void DrawBackGround(HWND hwnd, HDC mhdc, HBITMAP hBmpBackground, COLORREF bkColo
}
break;
case CLB_STRETCHH:
- if (backgroundBmpUse & CLBF_PROPORTIONAL) {
- destw = clRect.right;
- //desth = destw*bmp.bmHeight / bmp.bmWidth;
- }
- else {
- destw = clRect.right;
- //desth = bmp.bmHeight;
- }
+ destw = clRect.right;
break;
case CLB_STRETCHV:
if (backgroundBmpUse & CLBF_PROPORTIONAL) {
diff --git a/plugins/Clist_modern/src/modern_cachefuncs.cpp b/plugins/Clist_modern/src/modern_cachefuncs.cpp
index f6451f1849..ebf7b25640 100644
--- a/plugins/Clist_modern/src/modern_cachefuncs.cpp
+++ b/plugins/Clist_modern/src/modern_cachefuncs.cpp
@@ -2,7 +2,7 @@
Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (ñ) 2012-16 Miranda NG project (http://miranda-ng.org),
+Copyright (c) 2012-16 Miranda NG project (http://miranda-ng.org),
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
@@ -49,7 +49,7 @@ void CListSettings_FreeCacheItemDataOption(ClcCacheEntry *pDst, DWORD flag);
/////////////////////////////////////////////////////////////////////////////////////////
// Get time zone for contact
-
+//
void Cache_GetTimezone(ClcData *dat, MCONTACT hContact)
{
ClcCacheEntry *pdnce = pcli->pfnGetCacheEntry(hContact);
@@ -64,7 +64,7 @@ void Cache_GetTimezone(ClcData *dat, MCONTACT hContact)
/////////////////////////////////////////////////////////////////////////////////////////
// Get all lines of text
-
+//
void Cache_GetText(ClcData *dat, ClcContact *contact, BOOL forceRenew)
{
Cache_GetFirstLineText(dat, contact);
@@ -173,7 +173,7 @@ void CSmileyString::DestroySmileyList()
/////////////////////////////////////////////////////////////////////////////////////////
// Parsing of text for smiley
-
+//
void CSmileyString::ReplaceSmileys(SHORTDATA *dat, ClcCacheEntry *pdnce, TCHAR * szText, BOOL replace_smileys)
{
int last_pos = 0;
@@ -273,7 +273,7 @@ void CSmileyString::ReplaceSmileys(SHORTDATA *dat, ClcCacheEntry *pdnce, TCHAR *
/////////////////////////////////////////////////////////////////////////////////////////
// Getting Status name
// returns -1 for XStatus, 1 for Status
-
+//
int GetStatusName(TCHAR *text, int text_size, ClcCacheEntry *pdnce, BOOL xstatus_has_priority)
{
BOOL noAwayMsg = FALSE;
@@ -320,7 +320,7 @@ int GetStatusName(TCHAR *text, int text_size, ClcCacheEntry *pdnce, BOOL xstatus
/////////////////////////////////////////////////////////////////////////////////////////
// Get Listening to information
-
+//
void GetListeningTo(TCHAR *text, int text_size, ClcCacheEntry *pdnce)
{
*text = _T('\0');
@@ -336,7 +336,7 @@ void GetListeningTo(TCHAR *text, int text_size, ClcCacheEntry *pdnce)
/////////////////////////////////////////////////////////////////////////////////////////
// Getting Status message(Away message)
// returns -1 for XStatus, 1 for Status
-
+//
int GetStatusMessage(TCHAR *text, int text_size, ClcCacheEntry *pdnce, BOOL xstatus_has_priority)
{
BOOL noAwayMsg = FALSE;
@@ -383,7 +383,7 @@ int GetStatusMessage(TCHAR *text, int text_size, ClcCacheEntry *pdnce, BOOL xsta
/////////////////////////////////////////////////////////////////////////////////////////
// Get the text for specified lines
-
+//
int Cache_GetLineText(
ClcCacheEntry *pdnce, int type, LPTSTR text, int text_size, TCHAR *variable_text, BOOL xstatus_has_priority,
BOOL show_status_if_no_away, BOOL show_listening_if_no_away, BOOL use_name_and_message_for_xstatus,
@@ -423,15 +423,16 @@ int Cache_GetLineText(
if (tszXStatusName != NULL && tszXStatusName[0] != 0) {
TCHAR *tmp = NEWTSTR_ALLOCA(text);
mir_sntprintf(text, text_size, _T("%s: %s"), tszXStatusName, tmp);
+ CopySkipUnprintableChars(text, text, text_size - 1);
}
- CopySkipUnprintableChars(text, text, text_size - 1);
}
else if (use_name_and_message_for_xstatus && xstatus_has_priority) {
// Try to get XStatusName
ptrT tszXStatusName(db_get_tsa(pdnce->hContact, pdnce->m_pszProto, "XStatusName"));
- if (tszXStatusName != NULL && tszXStatusName[0] != 0)
+ if (tszXStatusName != NULL && tszXStatusName[0] != 0) {
mir_tstrncpy(text, tszXStatusName, text_size);
- CopySkipUnprintableChars(text, text, text_size - 1);
+ CopySkipUnprintableChars(text, text, text_size - 1);
+ }
}
if (text[0] == '\0') {
@@ -470,9 +471,9 @@ int Cache_GetLineText(
return TEXT_EMPTY;
}
-/*
-* Get the text for First Line
-*/
+/////////////////////////////////////////////////////////////////////////////////////////
+// Get the text for First Line
+//
void Cache_GetFirstLineText(ClcData *dat, ClcContact *contact)
{
if (GetCurrentThreadId() != g_dwMainThreadID)
@@ -506,7 +507,7 @@ void Cache_GetFirstLineText(ClcData *dat, ClcContact *contact)
/////////////////////////////////////////////////////////////////////////////////////////
// Get the text for Second Line
-
+//
void Cache_GetSecondLineText(SHORTDATA *dat, ClcCacheEntry *pdnce)
{
TCHAR Text[240 - EXTRA_ICON_COUNT] = { 0 };
@@ -531,7 +532,7 @@ void Cache_GetSecondLineText(SHORTDATA *dat, ClcCacheEntry *pdnce)
/////////////////////////////////////////////////////////////////////////////////////////
// Get the text for Third Line
-
+//
void Cache_GetThirdLineText(SHORTDATA *dat, ClcCacheEntry *pdnce)
{
TCHAR Text[240 - EXTRA_ICON_COUNT] = { 0 };
@@ -565,7 +566,7 @@ void RemoveTag(TCHAR *to, TCHAR *tag)
/////////////////////////////////////////////////////////////////////////////////////////
//Copy string with removing Escape chars from text and BBcodes
-
+//
static int CopySkipUnprintableChars(TCHAR *to, TCHAR * buf, DWORD size)
{
DWORD i;
@@ -611,8 +612,10 @@ static int CopySkipUnprintableChars(TCHAR *to, TCHAR * buf, DWORD size)
return i;
}
+/////////////////////////////////////////////////////////////////////////////////////////
// If ExecuteOnAllContactsFuncPtr returns FALSE, stop loop
// Return TRUE if finished, FALSE if was stoped
+//
static BOOL ExecuteOnAllContacts(ClcData *dat, ExecuteOnAllContactsFuncPtr func, void *param)
{
return ExecuteOnAllContactsOfGroup(&dat->list, func, param);
@@ -644,7 +647,7 @@ static BOOL ExecuteOnAllContactsOfGroup(ClcGroup *group, ExecuteOnAllContactsFun
/////////////////////////////////////////////////////////////////////////////////////////
// Avatar working routines
-
+//
BOOL UpdateAllAvatarsProxy(ClcContact *contact, BOOL, void *param)
{
Cache_GetAvatar((ClcData *)param, contact);
diff --git a/plugins/Clist_modern/src/modern_clc.cpp b/plugins/Clist_modern/src/modern_clc.cpp
index 8f62018a4f..5b79dede54 100644
--- a/plugins/Clist_modern/src/modern_clc.cpp
+++ b/plugins/Clist_modern/src/modern_clc.cpp
@@ -1,1855 +1,1855 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-16 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-08 Miranda ICQ/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.
-*/
-
-/************************************************************************/
-/* Module responsible for working with contact list control */
-/************************************************************************/
-
-#include "stdafx.h"
-#include "m_skin.h"
-#include "modern_commonprototypes.h"
-
-#include "modern_clc.h"
-#include "modern_clist.h"
-#include "modern_clcpaint.h"
-
-#include "m_modernopt.h"
-
-int ModernOptInit(WPARAM wParam, LPARAM lParam);
-int ModernSkinOptInit(WPARAM wParam, LPARAM lParam);
-
-/*
-* Private module variables
-*/
-static HANDLE hShowInfoTipEvent;
-static POINT HitPoint;
-static BOOL fMouseUpped;
-static BYTE IsDragToScrollMode = 0;
-static int StartDragPos = 0;
-static int StartScrollPos = 0;
-static BOOL g_bSortTimerIsSet = FALSE;
-static ClcContact *hitcontact = NULL;
-HANDLE hSkinFolder;
-TCHAR SkinsFolder[MAX_PATH];
-
-static int clcHookSmileyAddOptionsChanged(WPARAM wParam, LPARAM lParam);
-static int clcHookIconsChanged(WPARAM wParam, LPARAM lParam);
-static int clcHookBkgndConfigChanged(WPARAM wParam, LPARAM lParam);
-static int clcProceedDragToScroll(HWND hwnd, int Y);
-static int clcExitDragToScroll();
-
-
-int ReloadSkinFolder(WPARAM, LPARAM)
-{
- FoldersGetCustomPathT(hSkinFolder, SkinsFolder, _countof(SkinsFolder), _T(DEFAULT_SKIN_FOLDER));
- return 0;
-}
-
-static int clcHookSmileyAddOptionsChanged(WPARAM, LPARAM)
-{
- if (MirandaExiting()) return 0;
- pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
- pcli->pfnClcBroadcast(INTM_INVALIDATE, 0, 0);
- return 0;
-}
-
-static int clcHookProtoAck(WPARAM wParam, LPARAM lParam)
-{
- return ClcDoProtoAck(wParam, (ACKDATA*)lParam);
-}
-
-static int clcHookIconsChanged(WPARAM, LPARAM)
-{
- int i;
- if (MirandaExiting()) return 0;
- for (i = 0; i < _countof(g_pAvatarOverlayIcons); i++) {
- g_pAvatarOverlayIcons[i].listID = -1;
- g_pStatusOverlayIcons[i].listID = -1;
- }
-
- if (hAvatarOverlays)
- ImageList_Destroy(hAvatarOverlays);
- hAvatarOverlays = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, _countof(g_pAvatarOverlayIcons) * 2, 1);
-
- for (i = 0; i < _countof(g_pAvatarOverlayIcons); i++) {
- HICON hIcon = IcoLib_GetIcon(g_pAvatarOverlayIcons[i].name);
- g_pAvatarOverlayIcons[i].listID = ImageList_AddIcon(hAvatarOverlays, hIcon);
- IcoLib_Release(g_pAvatarOverlayIcons[i].name);
-
- hIcon = IcoLib_GetIcon(g_pStatusOverlayIcons[i].name);
- g_pStatusOverlayIcons[i].listID = ImageList_AddIcon(hAvatarOverlays, hIcon);
- IcoLib_Release(g_pStatusOverlayIcons[i].name);
- }
-
- g_hListeningToIcon = IcoLib_GetIcon("LISTENING_TO_ICON");
-
- pcli->pfnClcBroadcast(INTM_INVALIDATE, 0, 0);
- AniAva_UpdateOptions();
- return 0;
-}
-
-static int clcMetaModeChanged(WPARAM, LPARAM)
-{
- pcli->pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0);
- return 0;
-}
-
-static int clcMetacontactChanged(WPARAM, LPARAM)
-{
- pcli->pfnClcBroadcast(INTM_NAMEORDERCHANGED, 0, 0);
- return 0;
-}
-
-static int clcHookSettingChanged(WPARAM hContact, LPARAM lParam)
-{
- if (MirandaExiting())
- return 0;
-
- DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;
- if (hContact == NULL) {
- if (!strcmp(cws->szModule, "CListGroups"))
- pcli->pfnClcBroadcast(INTM_GROUPSCHANGED, hContact, lParam);
- else if (!strcmp(cws->szSetting, "XStatusId") || !strcmp(cws->szSetting, "XStatusName"))
- cliCluiProtocolStatusChanged(0, cws->szModule);
- else if (!strcmp(cws->szModule, "CList")) {
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (c) 2012-16 Miranda NG project (http://miranda-ng.org),
+Copyright (c) 2000-08 Miranda ICQ/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.
+*/
+
+/************************************************************************/
+/* Module responsible for working with contact list control */
+/************************************************************************/
+
+#include "stdafx.h"
+#include "m_skin.h"
+#include "modern_commonprototypes.h"
+
+#include "modern_clc.h"
+#include "modern_clist.h"
+#include "modern_clcpaint.h"
+
+#include "m_modernopt.h"
+
+int ModernOptInit(WPARAM wParam, LPARAM lParam);
+int ModernSkinOptInit(WPARAM wParam, LPARAM lParam);
+
+/*
+* Private module variables
+*/
+static HANDLE hShowInfoTipEvent;
+static POINT HitPoint;
+static BOOL fMouseUpped;
+static BYTE IsDragToScrollMode = 0;
+static int StartDragPos = 0;
+static int StartScrollPos = 0;
+static BOOL g_bSortTimerIsSet = FALSE;
+static ClcContact *hitcontact = NULL;
+HANDLE hSkinFolder;
+TCHAR SkinsFolder[MAX_PATH];
+
+static int clcHookSmileyAddOptionsChanged(WPARAM wParam, LPARAM lParam);
+static int clcHookIconsChanged(WPARAM wParam, LPARAM lParam);
+static int clcHookBkgndConfigChanged(WPARAM wParam, LPARAM lParam);
+static int clcProceedDragToScroll(HWND hwnd, int Y);
+static int clcExitDragToScroll();
+
+
+int ReloadSkinFolder(WPARAM, LPARAM)
+{
+ FoldersGetCustomPathT(hSkinFolder, SkinsFolder, _countof(SkinsFolder), _T(DEFAULT_SKIN_FOLDER));
+ return 0;
+}
+
+static int clcHookSmileyAddOptionsChanged(WPARAM, LPARAM)
+{
+ if (MirandaExiting()) return 0;
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+ pcli->pfnClcBroadcast(INTM_INVALIDATE, 0, 0);
+ return 0;
+}
+
+static int clcHookProtoAck(WPARAM wParam, LPARAM lParam)
+{
+ return ClcDoProtoAck(wParam, (ACKDATA*)lParam);
+}
+
+static int clcHookIconsChanged(WPARAM, LPARAM)
+{
+ int i;
+ if (MirandaExiting()) return 0;
+ for (i = 0; i < _countof(g_pAvatarOverlayIcons); i++) {
+ g_pAvatarOverlayIcons[i].listID = -1;
+ g_pStatusOverlayIcons[i].listID = -1;
+ }
+
+ if (hAvatarOverlays)
+ ImageList_Destroy(hAvatarOverlays);
+ hAvatarOverlays = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, _countof(g_pAvatarOverlayIcons) * 2, 1);
+
+ for (i = 0; i < _countof(g_pAvatarOverlayIcons); i++) {
+ HICON hIcon = IcoLib_GetIcon(g_pAvatarOverlayIcons[i].name);
+ g_pAvatarOverlayIcons[i].listID = ImageList_AddIcon(hAvatarOverlays, hIcon);
+ IcoLib_Release(g_pAvatarOverlayIcons[i].name);
+
+ hIcon = IcoLib_GetIcon(g_pStatusOverlayIcons[i].name);
+ g_pStatusOverlayIcons[i].listID = ImageList_AddIcon(hAvatarOverlays, hIcon);
+ IcoLib_Release(g_pStatusOverlayIcons[i].name);
+ }
+
+ g_hListeningToIcon = IcoLib_GetIcon("LISTENING_TO_ICON");
+
+ pcli->pfnClcBroadcast(INTM_INVALIDATE, 0, 0);
+ AniAva_UpdateOptions();
+ return 0;
+}
+
+static int clcMetaModeChanged(WPARAM, LPARAM)
+{
+ pcli->pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0);
+ return 0;
+}
+
+static int clcMetacontactChanged(WPARAM, LPARAM)
+{
+ pcli->pfnClcBroadcast(INTM_NAMEORDERCHANGED, 0, 0);
+ return 0;
+}
+
+static int clcHookSettingChanged(WPARAM hContact, LPARAM lParam)
+{
+ if (MirandaExiting())
+ return 0;
+
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;
+ if (hContact == NULL) {
+ if (!strcmp(cws->szModule, "CListGroups"))
+ pcli->pfnClcBroadcast(INTM_GROUPSCHANGED, hContact, lParam);
+ else if (!strcmp(cws->szSetting, "XStatusId") || !strcmp(cws->szSetting, "XStatusName"))
+ cliCluiProtocolStatusChanged(0, cws->szModule);
+ else if (!strcmp(cws->szModule, "CList")) {
if (!strcmp(cws->szSetting, "OnTop"))
SetWindowPos(pcli->hwndContactList, cws->value.bVal ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
- }
- else {
- if (!strcmp(cws->szSetting, "TickTS"))
- pcli->pfnClcBroadcast(INTM_STATUSCHANGED, hContact, 0);
- else if (!strcmp(cws->szModule, "UserInfo")) {
- if (!strcmp(cws->szSetting, "Timezone"))
- pcli->pfnClcBroadcast(INTM_TIMEZONECHANGED, hContact, 0);
- }
- else if (!strcmp(cws->szModule, "CList")) {
- if (!strcmp(cws->szSetting, "StatusMsg"))
- pcli->pfnClcBroadcast(INTM_STATUSMSGCHANGED, hContact, 0);
- }
- else if (!strcmp(cws->szModule, "ContactPhoto")) {
- if (!strcmp(cws->szSetting, "File"))
- pcli->pfnClcBroadcast(INTM_AVATARCHANGED, hContact, 0);
- }
- else {
- if ((!strcmp(cws->szSetting, "XStatusName") || !strcmp(cws->szSetting, "XStatusMsg")))
- pcli->pfnClcBroadcast(INTM_STATUSMSGCHANGED, hContact, 0);
- else if (!strcmp(cws->szSetting, "XStatusId"))
- pcli->pfnClcBroadcast(INTM_STATUSCHANGED, hContact, 0);
- else if (!strcmp(cws->szSetting, "Timezone"))
- pcli->pfnClcBroadcast(INTM_TIMEZONECHANGED, hContact, 0);
- else if (!strcmp(cws->szSetting, "ListeningTo"))
- pcli->pfnClcBroadcast(INTM_STATUSMSGCHANGED, hContact, 0);
- else if (!strcmp(cws->szSetting, "Transport") || !strcmp(cws->szSetting, "IsTransported")) {
- pcli->pfnInvalidateDisplayNameCacheEntry(hContact);
- pcli->pfnClcBroadcast(CLM_AUTOREBUILD, hContact, 0);
- }
- }
- }
- return 0;
-}
-
-static int clcHookDbEventAdded(WPARAM hContact, LPARAM lParam)
-{
- g_CluiData.t_now = time(NULL);
- if (hContact && lParam) {
- DBEVENTINFO dbei = { sizeof(dbei) };
- db_event_get(lParam, &dbei);
- if (dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_SENT)) {
- db_set_dw(hContact, "CList", "mf_lastmsg", dbei.timestamp);
- ClcCacheEntry *pdnce = pcli->pfnGetCacheEntry(hContact);
- if (pdnce)
- pdnce->dwLastMsgTime = dbei.timestamp;
- }
- }
- return 0;
-}
-
-static int clcHookBkgndConfigChanged(WPARAM, LPARAM)
-{
- pcli->pfnClcOptionsChanged();
- return 0;
-}
-
-static int clcHookAvatarChanged(WPARAM wParam, LPARAM lParam)
-{
- if (MirandaExiting()) return 0;
- pcli->pfnClcBroadcast(INTM_AVATARCHANGED, wParam, lParam);
- return 0;
-}
-
-static int clcExitDragToScroll()
-{
- if (!IsDragToScrollMode) return 0;
- IsDragToScrollMode = 0;
- ReleaseCapture();
- return 1;
-}
-
-static int clcProceedDragToScroll(HWND hwnd, int Y)
-{
- int pos, dy;
- if (!IsDragToScrollMode) return 0;
- if (GetCapture() != hwnd) clcExitDragToScroll();
- dy = StartDragPos - Y;
- pos = StartScrollPos + dy;
- if (pos < 0)
- pos = 0;
- SendMessage(hwnd, WM_VSCROLL, MAKEWPARAM(SB_THUMBTRACK, pos), 0);
- return 1;
-}
-
-
-
-static int clcSearchNextContact(HWND hwnd, ClcData *dat, int index, const TCHAR *text, int prefixOk, BOOL fSearchUp)
-{
- ClcGroup *group = &dat->list;
- int testlen = (int)mir_tstrlen(text);
- BOOL fReturnAsFound = FALSE;
- int nLastFound = -1;
- if (index == -1) fReturnAsFound = TRUE;
- 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 found;
- if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) {
- found = true;
- }
- else if (dat->filterSearch) {
- TCHAR *lowered_szText = CharLowerW(NEWTSTR_ALLOCA(group->cl.items[group->scanIndex]->szText));
- TCHAR *lowered_search = CharLowerW(NEWTSTR_ALLOCA(dat->szQuickSearch));
- found = _tcsstr(lowered_szText, lowered_search) != NULL;
- }
- else {
- found = ((prefixOk && CSTR_EQUAL == CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, text, -1, group->cl.items[group->scanIndex]->szText, testlen)) || (!prefixOk && !mir_tstrcmpi(text, group->cl.items[group->scanIndex]->szText)));
- }
- if (found) {
- ClcGroup *contactGroup = group;
- int contactScanIndex = group->scanIndex;
- int foundindex;
- for (; group; group = group->parent)
- pcli->pfnSetGroupExpand(hwnd, dat, group, 1);
- foundindex = pcli->pfnGetRowsPriorTo(&dat->list, contactGroup, contactScanIndex);
- if (fReturnAsFound)
- return foundindex;
- else if (nLastFound != -1 && fSearchUp && foundindex == index)
- return nLastFound;
- else if (!fSearchUp && foundindex == index)
- fReturnAsFound = TRUE;
- else
- nLastFound = foundindex;
- group = contactGroup;
- group->scanIndex = 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;
-}
-
-static BOOL clcItemNotHiddenOffline(ClcGroup *group, ClcContact *contact)
-{
- if (g_CluiData.bFilterEffective) return FALSE;
-
- if (!contact) return FALSE;
- ClcCacheEntry *pdnce = pcli->pfnGetCacheEntry(contact->hContact);
- if (!pdnce) return FALSE;
- if (pdnce->m_bNoHiddenOffline) return TRUE;
-
- if (!group) return FALSE;
- if (group->hideOffline) return FALSE;
-
- if (CLCItems_IsShowOfflineGroup(group)) return TRUE;
-
- return FALSE;
-}
-
-static LRESULT clcOnCreate(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- dat = (ClcData*)mir_calloc(sizeof(ClcData));
- SetWindowLongPtr(hwnd, 0, (LONG_PTR)dat);
- dat->hCheckBoxTheme = xpt_AddThemeHandle(hwnd, L"BUTTON");
- dat->m_paintCouter = 0;
- dat->hWnd = hwnd;
-
- ImageArray_Initialize(&dat->avatar_cache, FALSE, 20); //this array will be used to keep small avatars too
-
- RowHeights_Initialize(dat);
-
- dat->needsResort = 1;
- dat->MetaIgnoreEmptyExtra = db_get_b(NULL, "CLC", "MetaIgnoreEmptyExtra", SETTING_METAIGNOREEMPTYEXTRA_DEFAULT);
-
- dat->IsMetaContactsEnabled = (!(GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_MANUALUPDATE)) && db_mc_isEnabled();
-
- dat->expandMeta = db_get_b(NULL, "CLC", "MetaExpanding", SETTING_METAEXPANDING_DEFAULT);
- dat->useMetaIcon = db_get_b(NULL, "CLC", "Meta", SETTING_USEMETAICON_DEFAULT);
- dat->drawOverlayedStatus = db_get_b(NULL, "CLC", "DrawOverlayedStatus", SETTING_DRAWOVERLAYEDSTATUS_DEFAULT);
- g_CluiData.bSortByOrder[0] = db_get_b(NULL, "CList", "SortBy1", SETTING_SORTBY1_DEFAULT);
- g_CluiData.bSortByOrder[1] = db_get_b(NULL, "CList", "SortBy2", SETTING_SORTBY2_DEFAULT);
- g_CluiData.bSortByOrder[2] = db_get_b(NULL, "CList", "SortBy3", SETTING_SORTBY3_DEFAULT);
- g_CluiData.fSortNoOfflineBottom = db_get_b(NULL, "CList", "NoOfflineBottom", SETTING_NOOFFLINEBOTTOM_DEFAULT);
- dat->menuOwnerID = -1;
- dat->menuOwnerType = CLCIT_INVALID;
-
- corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
- LoadCLCOptions(hwnd, dat, TRUE);
- if (dat->contact_time_show || dat->second_line_type == TEXT_CONTACT_TIME || dat->third_line_type == TEXT_CONTACT_TIME)
- CLUI_SafeSetTimer(hwnd, TIMERID_INVALIDATE, 5000, NULL);
- else
- KillTimer(hwnd, TIMERID_INVALIDATE);
-
- TRACE("Create New ClistControl TO END\r\n");
- return 0;
-}
-
-static LRESULT clcOnHitTest(ClcData *, HWND hwnd, UINT, WPARAM wParam, LPARAM lParam)
-{
- return DefWindowProc(hwnd, WM_NCHITTEST, wParam, lParam);
-}
-
-static LRESULT clcOnCommand(ClcData *dat, HWND hwnd, UINT, WPARAM wParam, LPARAM lParam)
-{
- ClcContact *contact;
- int hit = pcli->pfnGetRowByIndex(dat, dat->selection, &contact, NULL);
- if (hit != -1) {
- switch (LOWORD(wParam)) {
- case POPUP_NEWSUBGROUP:
- if (contact->type == CLCIT_GROUP) {
- SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~CLS_HIDEEMPTYGROUPS);
- SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) | CLS_USEGROUPS);
- CallService(MS_CLIST_GROUPCREATE, contact->groupId, 0);
- }
- return 0;
-
- case POPUP_GROUPSHOWOFFLINE:
- if (contact->type == CLCIT_GROUP) {
- CallService(MS_CLIST_GROUPSETFLAGS, contact->groupId, MAKELPARAM(CLCItems_IsShowOfflineGroup(contact->group) ? 0 : GROUPF_SHOWOFFLINE, GROUPF_SHOWOFFLINE));
- pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
- }
- return 0;
- }
- }
-
- return corecli.pfnContactListControlWndProc(hwnd, WM_COMMAND, wParam, lParam);
-}
-
-static LRESULT clcOnSize(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- pcli->pfnEndRename(hwnd, dat, 1);
- KillTimer(hwnd, TIMERID_INFOTIP);
- KillTimer(hwnd, TIMERID_RENAME);
- cliRecalcScrollBar(hwnd, dat);
- if (g_CluiData.fDisableSkinEngine || dat->force_in_dialog) {
- RECT rc = { 0 };
- GetClientRect(hwnd, &rc);
- if (rc.right == 0)
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-
- rc.bottom = max(dat->row_min_heigh, 1);
-
- 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 || dat->force_in_dialog) ? 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);
- }
- else if (dat->himlHighlight) {
- ImageList_Destroy(dat->himlHighlight);
- dat->himlHighlight = NULL;
- }
- return 0;
-}
-
-static LRESULT clcOnChar(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- if (wParam == 27 && dat->szQuickSearch[0] == '\0') { //escape and not quick search
- // minimize clist
- CListMod_HideWindow();
- }
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-}
-static LRESULT clcOnPaint(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- if (IsWindowVisible(hwnd)) {
- if (!g_CluiData.fLayered || GetParent(hwnd) != pcli->hwndContactList) {
- PAINTSTRUCT ps;
- HDC hdc = BeginPaint(hwnd, &ps);
- g_clcPainter.cliPaintClc(hwnd, dat, hdc, &ps.rcPaint);
- EndPaint(hwnd, &ps);
- }
- else CallService(MS_SKINENG_INVALIDATEFRAMEIMAGE, (WPARAM)hwnd, 0);
- }
- return DefWindowProc(hwnd, msg, wParam, lParam);
-}
-
-static LRESULT clcOnEraseBkGround(ClcData *, HWND, UINT, WPARAM, LPARAM)
-{
- return 1;
-}
-
-static LRESULT clcOnKeyDown(ClcData *dat, HWND hwnd, UINT, WPARAM wParam, LPARAM lParam)
-{
- if (wParam == VK_CONTROL)
- return 0;
-
- pcli->pfnHideInfoTip(hwnd, dat);
- KillTimer(hwnd, TIMERID_INFOTIP);
- KillTimer(hwnd, TIMERID_RENAME);
-
- if (CallService(MS_CLIST_MENUPROCESSHOTKEY, wParam, MPCF_CONTACTMENU))
- return 0;
-
- RECT clRect;
- GetClientRect(hwnd, &clRect);
- int pageSize = (dat->rowHeight) ? clRect.bottom / dat->rowHeight : 0;
- int selMoved = 0;
- int changeGroupExpand = 0;
-
- switch (wParam) {
- case VK_DOWN:
- case VK_UP:
- if (dat->szQuickSearch[0] != '\0' && dat->selection != -1) { //get next contact
- //get next contact
- int index = clcSearchNextContact(hwnd, dat, dat->selection, dat->szQuickSearch, 1, (wParam == VK_UP));
- if (index == -1) {
- MessageBeep(MB_OK);
- return 0;
- }
-
- dat->selection = index;
- pcli->pfnInvalidateRect(hwnd, NULL, FALSE);
- pcli->pfnEnsureVisible(hwnd, dat, dat->selection, 0);
- return 0;
- }
-
- if (wParam == VK_DOWN) dat->selection++;
- if (wParam == 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 = pcli->pfnGetGroupContentsCount(&dat->list, 1) - 1; selMoved = 1; break;
- case VK_LEFT: changeGroupExpand = 1; break;
- case VK_RIGHT: changeGroupExpand = 2; break;
- case VK_RETURN:
- pcli->pfnDoSelectionDefaultAction(hwnd, dat);
- SetCapture(hwnd);
- dat->szQuickSearch[0] = 0;
- if (dat->filterSearch)
- pcli->pfnSaveStateAndRebuildList(hwnd, dat);
- return 0;
-
- case VK_F2: cliBeginRenameSelection(hwnd, dat); /*SetCapture(hwnd);*/ return 0;
- case VK_DELETE: pcli->pfnDeleteFromContactList(hwnd, dat); SetCapture(hwnd); return 0;
- case VK_ESCAPE:
- if ((dat->dragStage & DRAGSTAGEM_STAGE) == DRAGSTAGE_ACTIVE) {
- dat->iDragItem = -1;
- dat->iInsertionMark = -1;
- dat->dragStage = 0;
- ReleaseCapture();
- }
- 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)) {
- SetCapture(hwnd);
- return 0;
- }
- }
-
- if (changeGroupExpand) {
- ClcContact *contact;
- ClcGroup *group;
- int hit = cliGetRowByIndex(dat, dat->selection, &contact, &group);
- if (hit == -1) {
- SetCapture(hwnd);
- return 0;
- }
-
- if (contact->type == CLCIT_CONTACT && (contact->isSubcontact || contact->SubAllocated > 0)) {
- if (contact->isSubcontact && changeGroupExpand == 1) {
- dat->selection -= contact->isSubcontact;
- selMoved = 1;
- }
- else if (!contact->isSubcontact && contact->SubAllocated > 0) {
- if (changeGroupExpand == 1 && !contact->SubExpanded) {
- dat->selection = cliGetRowsPriorTo(&dat->list, group, -1);
- selMoved = 1;
- }
- else if (changeGroupExpand == 1 && contact->SubExpanded) {
- //Contract
- ClcContact *ht = NULL;
- KillTimer(hwnd, TIMERID_SUBEXPAND);
- contact->SubExpanded = 0;
- db_set_b(contact->hContact, "CList", "Expanded", 0);
- ht = contact;
- dat->needsResort = 1;
- pcli->pfnSortCLC(hwnd, dat, 1);
- cliRecalcScrollBar(hwnd, dat);
- hitcontact = NULL;
- }
- else if (changeGroupExpand == 2 && contact->SubExpanded) {
- dat->selection++;
- selMoved = 1;
- }
- else if (changeGroupExpand == 2 && !contact->SubExpanded && dat->expandMeta) {
- ClcContact *ht = NULL;
- KillTimer(hwnd, TIMERID_SUBEXPAND);
- contact->SubExpanded = 1;
- db_set_b(contact->hContact, "CList", "Expanded", 1);
- ht = contact;
- dat->needsResort = 1;
- pcli->pfnSortCLC(hwnd, dat, 1);
- cliRecalcScrollBar(hwnd, dat);
- if (ht) {
- ClcContact *contact2;
- ClcGroup *group2;
- if (FindItem(hwnd, dat, contact->hContact, &contact2, &group2, NULL, FALSE)) {
- int i = cliGetRowsPriorTo(&dat->list, group2, GetContactIndex(group2, contact2));
- pcli->pfnEnsureVisible(hwnd, dat, i + contact->SubAllocated, 0);
- }
- }
- hitcontact = NULL;
- }
- }
- }
- else {
- if (changeGroupExpand == 1 && contact->type == CLCIT_CONTACT) {
- if (group == &dat->list) { SetCapture(hwnd); return 0; }
- dat->selection = cliGetRowsPriorTo(&dat->list, group, -1);
- selMoved = 1;
- }
- else {
- if (contact->type == CLCIT_GROUP) {
- if (changeGroupExpand == 1) {
- if (!contact->group->expanded) {
- dat->selection--;
- selMoved = 1;
- }
- else pcli->pfnSetGroupExpand(hwnd, dat, contact->group, 0);
- }
- else if (changeGroupExpand == 2) {
- pcli->pfnSetGroupExpand(hwnd, dat, contact->group, 1);
- dat->selection++;
- selMoved = 1;
- }
- else { SetCapture(hwnd); return 0; }
- }
- }
- }
- }
- if (selMoved) {
- if (dat->selection >= pcli->pfnGetGroupContentsCount(&dat->list, 1))
- dat->selection = pcli->pfnGetGroupContentsCount(&dat->list, 1) - 1;
- if (dat->selection < 0) dat->selection = 0;
- if (dat->bCompactMode)
- SendMessage(hwnd, WM_SIZE, 0, 0);
- CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
- pcli->pfnEnsureVisible(hwnd, dat, dat->selection, 0);
- UpdateWindow(hwnd);
- SetCapture(hwnd);
- return 0;
- }
- SetCapture(hwnd);
- return 0;
-}
-
-void clcSetDelayTimer(UINT_PTR uIDEvent, HWND hwnd, int nDelay)
-{
- KillTimer(hwnd, uIDEvent);
- int delay = nDelay;
- if (delay == -1) {
- switch (uIDEvent) {
- case TIMERID_DELAYEDRESORTCLC: delay = 10; break;
- case TIMERID_RECALCSCROLLBAR: delay = 10; break;
- case TIMERID_REBUILDAFTER: delay = 50; break;
- default: delay = 100; break;
- }
- }
- CLUI_SafeSetTimer(hwnd, uIDEvent, delay, NULL);
-}
-
-static LRESULT clcOnTimer(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch (wParam) {
- case TIMERID_INVALIDATE_FULL:
- KillTimer(hwnd, TIMERID_INVALIDATE_FULL);
- pcli->pfnRecalcScrollBar(hwnd, dat);
- pcli->pfnInvalidateRect(hwnd, NULL, 0);
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-
- case TIMERID_INVALIDATE:
- {
- time_t cur_time = (time(NULL) / 60);
- if (cur_time != dat->last_tick_time) {
- CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
- dat->last_tick_time = cur_time;
- }
- }
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-
- case TIMERID_SUBEXPAND:
- KillTimer(hwnd, TIMERID_SUBEXPAND);
- {
- ClcContact *ht = NULL;
- if (hitcontact && dat->expandMeta) {
- if (hitcontact->SubExpanded) hitcontact->SubExpanded = 0; else hitcontact->SubExpanded = 1;
- db_set_b(hitcontact->hContact, "CList", "Expanded", hitcontact->SubExpanded);
- if (hitcontact->SubExpanded)
- ht = &(hitcontact->subcontacts[hitcontact->SubAllocated - 1]);
- }
-
- dat->needsResort = 1;
- pcli->pfnSortCLC(hwnd, dat, 1);
- cliRecalcScrollBar(hwnd, dat);
- if (ht) {
- int i = 0;
- ClcContact *contact;
- ClcGroup *group;
- if (FindItem(hwnd, dat, hitcontact->hContact, &contact, &group, NULL, FALSE)) {
- i = cliGetRowsPriorTo(&dat->list, group, GetContactIndex(group, contact));
- pcli->pfnEnsureVisible(hwnd, dat, i + hitcontact->SubAllocated, 0);
- }
- }
- hitcontact = NULL;
- }
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-
- case TIMERID_DELAYEDRESORTCLC:
- TRACE("Do sort on Timer\n");
- KillTimer(hwnd, TIMERID_DELAYEDRESORTCLC);
- pcli->pfnSortCLC(hwnd, dat, 1);
- pcli->pfnInvalidateRect(hwnd, NULL, FALSE);
- return 0;
-
- case TIMERID_RECALCSCROLLBAR:
- KillTimer(hwnd, TIMERID_RECALCSCROLLBAR);
- pcli->pfnRecalcScrollBar(hwnd, dat);
- return 0;
-
- default:
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
- }
-}
-
-
-static LRESULT clcOnActivate(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- TRACE("clcOnActivate\n");
- if (dat->bCompactMode) {
- cliRecalcScrollBar(hwnd, dat);
- if (dat->hwndRenameEdit == NULL)
- PostMessage(hwnd, WM_SIZE, 0, 0);
- }
- dat->dragStage |= DRAGSTAGEF_SKIPRENAME;
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-}
-
-static LRESULT clcOnSetCursor(ClcData *, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- if (!CLUI_IsInMainWindow(hwnd))
- return DefWindowProc(hwnd, msg, wParam, lParam);
-
- if (g_CluiData.nBehindEdgeState > 0)
- CLUI_ShowFromBehindEdge();
-
- if (g_CluiData.bBehindEdgeSettings)
- CLUI_UpdateTimer();
-
- int lResult = CLUI_TestCursorOnBorders();
- return lResult ? lResult : DefWindowProc(hwnd, msg, wParam, lParam);
-}
-
-static LRESULT clcOnLButtonDown(ClcData *dat, HWND hwnd, UINT, WPARAM, LPARAM lParam)
-{
- POINT pt = { LOWORD(lParam), HIWORD(lParam) };
- ClientToScreen(hwnd, &pt);
- int k = CLUI_SizingOnBorder(pt, 0);
- if (k) {
- int io = dat->iHotTrack;
- dat->iHotTrack = 0;
- if (dat->exStyle & CLS_EX_TRACKSELECT)
- pcli->pfnInvalidateItem(hwnd, dat, io);
-
- if (k && GetCapture() == hwnd)
- SendMessage(GetParent(hwnd), WM_PARENTNOTIFY, WM_LBUTTONDOWN, lParam);
- return FALSE;
- }
-
- fMouseUpped = FALSE;
- pcli->pfnHideInfoTip(hwnd, dat);
- KillTimer(hwnd, TIMERID_INFOTIP);
- KillTimer(hwnd, TIMERID_RENAME);
- KillTimer(hwnd, TIMERID_SUBEXPAND);
-
- pcli->pfnEndRename(hwnd, dat, 1);
- dat->ptDragStart.x = (short)LOWORD(lParam);
- dat->ptDragStart.y = (short)HIWORD(lParam);
-
- ClcContact *contact;
- ClcGroup *group;
- DWORD hitFlags;
- int hit = cliHitTest(hwnd, dat, (short)LOWORD(lParam), (short)HIWORD(lParam), &contact, &group, &hitFlags);
- if (GetFocus() != hwnd)
- SetFocus(hwnd);
- if (hit != -1 && !(hitFlags & CLCHT_NOWHERE)) {
- if (hit == dat->selection && hitFlags & CLCHT_ONITEMLABEL && dat->exStyle & CLS_EX_EDITLABELS) {
- if (!(dat->dragStage & DRAGSTAGEF_SKIPRENAME)) {
- SetCapture(hwnd);
- dat->iDragItem = dat->selection;
- dat->dragStage = DRAGSTAGE_NOTMOVED | DRAGSTAGEF_MAYBERENAME;
- dat->dragAutoScrolling = 0;
- return TRUE;
- }
- else {
- dat->dragStage &= ~DRAGSTAGEF_SKIPRENAME;
- return TRUE;
- }
- }
- }
-
- if (hit != -1 && !(hitFlags & CLCHT_NOWHERE) && contact->type == CLCIT_CONTACT && contact->SubAllocated && !contact->isSubcontact)
- if (hitFlags & CLCHT_ONITEMICON && dat->expandMeta) {
- hitcontact = contact;
- HitPoint.x = (short)LOWORD(lParam);
- HitPoint.y = (short)HIWORD(lParam);
- fMouseUpped = FALSE;
- if ((GetKeyState(VK_SHIFT) & 0x8000) || (GetKeyState(VK_CONTROL) & 0x8000) || (GetKeyState(VK_MENU) & 0x8000)) {
- fMouseUpped = TRUE;
- hitcontact = contact;
- KillTimer(hwnd, TIMERID_SUBEXPAND);
- CLUI_SafeSetTimer(hwnd, TIMERID_SUBEXPAND, 0, NULL);
- }
- }
- else hitcontact = NULL;
-
- if (hit != -1 && !(hitFlags & CLCHT_NOWHERE) && contact->type == CLCIT_GROUP && (hitFlags & CLCHT_ONITEMICON)) {
- ClcGroup *selgroup;
- ClcContact *selcontact;
- dat->selection = cliGetRowByIndex(dat, dat->selection, &selcontact, &selgroup);
- pcli->pfnSetGroupExpand(hwnd, dat, contact->group, -1);
- if (dat->selection != -1) {
- dat->selection = cliGetRowsPriorTo(&dat->list, selgroup, GetContactIndex(selgroup, selcontact));
- if (dat->selection == -1)
- dat->selection = cliGetRowsPriorTo(&dat->list, contact->group, -1);
- }
-
- if (dat->bCompactMode)
- SendMessage(hwnd, WM_SIZE, 0, 0);
- else {
- CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
- UpdateWindow(hwnd);
- }
- return TRUE;
- }
-
- if (hit != -1 && !(hitFlags & CLCHT_NOWHERE) && (hitFlags & CLCHT_ONITEMCHECK)) {
- int bNewState = (contact->flags & CONTACTF_CHECKED) == 0; // inversion
-
- if (contact->type == CLCIT_GROUP)
- pcli->pfnSetGroupChildCheckboxes(contact->group, bNewState);
- else
- pcli->pfnSetContactCheckboxes(contact, bNewState);
- pcli->pfnRecalculateGroupCheckboxes(hwnd, dat);
- CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
-
- NMCLISTCONTROL nm;
- nm.hdr.code = CLN_CHECKCHANGED;
- nm.hdr.hwndFrom = hwnd;
- nm.hdr.idFrom = GetDlgCtrlID(hwnd);
- nm.flags = 0;
- nm.hItem = ContactToItemHandle(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;
- nm.hItem = (hit == -1 || hitFlags & CLCHT_NOWHERE) ? NULL : ContactToItemHandle(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))
- return FALSE;
-
- dat->selection = (hitFlags & CLCHT_NOWHERE) ? -1 : hit;
- CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
-
- UpdateWindow(hwnd);
- if (dat->selection != -1 && (contact->type == CLCIT_CONTACT || contact->type == CLCIT_GROUP) && !(hitFlags & (CLCHT_ONITEMEXTRA | CLCHT_ONITEMCHECK | CLCHT_NOWHERE))) {
- SetCapture(hwnd);
- dat->iDragItem = dat->selection;
- dat->dragStage = DRAGSTAGE_NOTMOVED;
- dat->dragAutoScrolling = 0;
- }
-
- if (dat->bCompactMode)
- SendMessage(hwnd, WM_SIZE, 0, 0);
-
- if (dat->selection != -1)
- pcli->pfnEnsureVisible(hwnd, dat, hit, 0);
- return TRUE;
-}
-
-static LRESULT clcOnCaptureChanged(ClcData *dat, HWND hwnd, UINT, WPARAM, LPARAM lParam)
-{
- if ((HWND)lParam != hwnd) {
- if (dat->iHotTrack != -1) {
- int i;
- i = dat->iHotTrack;
- dat->iHotTrack = -1;
- pcli->pfnInvalidateItem(hwnd, dat, i);
- pcli->pfnHideInfoTip(hwnd, dat);
- }
- }
- return 0;
-}
-
-static LRESULT clcOnMouseMove(ClcData *dat, HWND hwnd, UINT, WPARAM wParam, LPARAM lParam)
-{
- BOOL isOutside = FALSE;
- if (CLUI_IsInMainWindow(hwnd)) {
- if (g_CluiData.bBehindEdgeSettings)
- CLUI_UpdateTimer();
- CLUI_TestCursorOnBorders();
- }
-
- if (clcProceedDragToScroll(hwnd, (short)HIWORD(lParam)))
- return 0;
-
- if (dat->dragStage & DRAGSTAGEF_MAYBERENAME) {
- POINT pt = UNPACK_POINT(lParam);
- if (abs(pt.x - dat->ptDragStart.x) > GetSystemMetrics(SM_CXDOUBLECLK) || abs(pt.y - dat->ptDragStart.y) > GetSystemMetrics(SM_CYDOUBLECLK)) {
- KillTimer(hwnd, TIMERID_RENAME);
- dat->dragStage &= (~DRAGSTAGEF_MAYBERENAME);
- }
- }
-
- if (dat->iDragItem == -1) {
- POINT pt = UNPACK_POINT(lParam);
- ClientToScreen(hwnd, &pt);
- HWND window = WindowFromPoint(pt);
- if (window != hwnd)
- isOutside = TRUE;
- }
-
- if (hitcontact != NULL) {
- int x = (short)LOWORD(lParam);
- int y = (short)HIWORD(lParam);
- int xm = GetSystemMetrics(SM_CXDOUBLECLK);
- int ym = GetSystemMetrics(SM_CYDOUBLECLK);
- if (abs(HitPoint.x - x) > xm || abs(HitPoint.y - y) > ym) {
- if (fMouseUpped) {
- KillTimer(hwnd, TIMERID_SUBEXPAND);
- CLUI_SafeSetTimer(hwnd, TIMERID_SUBEXPAND, 0, NULL);
- fMouseUpped = FALSE;
- }
- else {
- KillTimer(hwnd, TIMERID_SUBEXPAND);
- hitcontact = NULL;
- fMouseUpped = FALSE;
- }
- }
- }
-
- if (dat->iDragItem == -1) {
- DWORD flag = 0;
- int iOldHotTrack = dat->iHotTrack;
-
- if (dat->hwndRenameEdit != NULL || GetKeyState(VK_MENU) & 0x8000 || GetKeyState(VK_F10) & 0x8000)
- return 0;
-
- dat->iHotTrack = isOutside ? -1 : cliHitTest(hwnd, dat, (short)LOWORD(lParam), (short)HIWORD(lParam), NULL, NULL, &flag);
-
- if (flag & CLCHT_NOWHERE)
- dat->iHotTrack = -1;
-
- if (iOldHotTrack != dat->iHotTrack || isOutside) {
- if (iOldHotTrack == -1 && !isOutside)
- SetCapture(hwnd);
-
- if (dat->iHotTrack == -1 || isOutside)
- ReleaseCapture();
-
- if (dat->exStyle & CLS_EX_TRACKSELECT) {
- pcli->pfnInvalidateItem(hwnd, dat, iOldHotTrack);
- pcli->pfnInvalidateItem(hwnd, dat, dat->iHotTrack);
- }
-
- pcli->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);
- CLUI_SafeSetTimer(hwnd, TIMERID_INFOTIP, dat->infoTipTimeout, NULL);
- }
- return 0;
- }
-
- 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) {
- RECT clRect;
- GetClientRect(hwnd, &clRect);
-
- POINT pt = UNPACK_POINT(lParam);
- HCURSOR hNewCursor = LoadCursor(NULL, IDC_NO);
- CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
- if (dat->dragAutoScrolling) {
- KillTimer(hwnd, TIMERID_DRAGAUTOSCROLL);
- dat->dragAutoScrolling = 0;
- }
- int target = GetDropTargetInformation(hwnd, dat, pt);
- if ((dat->dragStage & DRAGSTAGEF_OUTSIDE) && target != DROPTARGET_OUTSIDE) {
- ClcContact *contact;
- cliGetRowByIndex(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 = ContactToItemHandle(contact, &nm.flags);
- SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)&nm);
- dat->dragStage &= ~DRAGSTAGEF_OUTSIDE;
- }
-
- ClcContact *contSour, *contDest;
-
- switch (target) {
- case DROPTARGET_ONSELF:
- break;
-
- case DROPTARGET_ONCONTACT:
- cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
- if (contSour->isChat())
- break;
- if (contSour->type == CLCIT_CONTACT && mir_strcmp(contSour->proto, META_PROTO)) {
- if (!contSour->isSubcontact)
- hNewCursor = LoadCursor(g_hMirApp, MAKEINTRESOURCE(IDC_DROPUSER)); /// Add to meta
- else
- hNewCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_DROPMETA));
- }
- break;
-
- case DROPTARGET_ONMETACONTACT:
- cliGetRowByIndex(dat, dat->selection, &contDest, NULL);
- cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
- if (contSour->isChat() || contDest->isChat())
- break;
- if (contSour->type == CLCIT_CONTACT && mir_strcmp(contSour->proto, META_PROTO)) {
- if (!contSour->isSubcontact)
- hNewCursor = LoadCursor(g_hMirApp, MAKEINTRESOURCE(IDC_DROPUSER)); /// Add to meta
- else if (contSour->subcontacts == contDest)
- hNewCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_DEFAULTSUB)); ///MakeDefault
- else
- hNewCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_REGROUP));
- }
- break;
-
- case DROPTARGET_ONSUBCONTACT:
- cliGetRowByIndex(dat, dat->selection, &contDest, NULL);
- cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
- if (contSour->isChat() || contDest->isChat())
- break;
- if (contSour->type == CLCIT_CONTACT && mir_strcmp(contSour->proto, META_PROTO)) {
- if (!contSour->isSubcontact)
- hNewCursor = LoadCursor(g_hMirApp, MAKEINTRESOURCE(IDC_DROPUSER)); /// Add to meta
- else if (contDest->subcontacts == contSour->subcontacts)
- break;
- else
- hNewCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_REGROUP));
- }
- break;
-
- case DROPTARGET_ONGROUP:
- hNewCursor = LoadCursor(g_hMirApp, MAKEINTRESOURCE(IDC_DROPUSER));
- break;
-
- case DROPTARGET_INSERTION:
- hNewCursor = LoadCursor(g_hMirApp, MAKEINTRESOURCE(IDC_DROP));
- break;
-
- case DROPTARGET_OUTSIDE:
- 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) {
- dat->dragAutoScrolling = (pt.y < 0) ? -1 : 1;
- CLUI_SafeSetTimer(hwnd, TIMERID_DRAGAUTOSCROLL, dat->scrollTime, NULL);
- }
- SendMessage(hwnd, WM_TIMER, TIMERID_DRAGAUTOSCROLL, 0);
- }
-
- dat->dragStage |= DRAGSTAGEF_OUTSIDE;
- {
- ClcContact *contact;
- cliGetRowByIndex(dat, dat->iDragItem, &contact, NULL);
-
- NMCLISTCONTROL nm;
- nm.hdr.code = CLN_DRAGGING;
- nm.hdr.hwndFrom = hwnd;
- nm.hdr.idFrom = GetDlgCtrlID(hwnd);
- nm.flags = 0;
- nm.hItem = ContactToItemHandle(contact, &nm.flags);
- nm.pt = pt;
- if (SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)&nm))
- return 0;
- }
- break;
-
- default:
- ClcGroup *group = NULL;
- cliGetRowByIndex(dat, dat->iDragItem, NULL, &group);
- if (group && group->parent) {
- cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
- if (!contSour->isSubcontact)
- hNewCursor = LoadCursor(g_hMirApp, MAKEINTRESOURCE(IDC_DROPUSER));
- }
- break;
- }
- SetCursor(hNewCursor);
- }
- return 0;
-}
-
-static LRESULT clcOnLButtonUp(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- if (clcExitDragToScroll())
- return 0;
-
- fMouseUpped = TRUE;
-
- if (hitcontact != NULL && dat->expandMeta) {
- BYTE doubleClickExpand = db_get_b(NULL, "CLC", "MetaDoubleClick", SETTING_METAAVOIDDBLCLICK_DEFAULT);
- CLUI_SafeSetTimer(hwnd, TIMERID_SUBEXPAND, GetDoubleClickTime()*doubleClickExpand, NULL);
- }
- else if (dat->iHotTrack == -1 && dat->iDragItem == -1)
- ReleaseCapture();
-
- if (dat->iDragItem == -1)
- return 0;
-
- SetCursor((HCURSOR)GetClassLongPtr(hwnd, GCLP_HCURSOR));
- if (dat->exStyle & CLS_EX_TRACKSELECT) {
- DWORD flags;
- dat->iHotTrack = cliHitTest(hwnd, dat, (short)LOWORD(lParam), (short)HIWORD(lParam), NULL, NULL, &flags);
- if (dat->iHotTrack == -1)
- ReleaseCapture();
- }
- else if (hitcontact == NULL)
- ReleaseCapture();
- KillTimer(hwnd, TIMERID_DRAGAUTOSCROLL);
- if (dat->dragStage == (DRAGSTAGE_NOTMOVED | DRAGSTAGEF_MAYBERENAME))
- CLUI_SafeSetTimer(hwnd, TIMERID_RENAME, GetDoubleClickTime(), NULL);
- else if ((dat->dragStage & DRAGSTAGEM_STAGE) == DRAGSTAGE_ACTIVE) {
- TCHAR Wording[500];
- ClcContact *contDest, *contSour;
- POINT pt = UNPACK_POINT(lParam);
- int target = GetDropTargetInformation(hwnd, dat, pt);
- switch (target) {
- case DROPTARGET_ONSELF:
- break;
-
- case DROPTARGET_ONCONTACT:
- cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
- cliGetRowByIndex(dat, dat->selection, &contDest, NULL);
- if (contSour->isChat() || contDest->isChat())
- break;
- if (contSour->type == CLCIT_CONTACT) {
- MCONTACT hcontact = contSour->hContact;
- if (mir_strcmp(contSour->proto, META_PROTO)) {
- if (!contSour->isSubcontact) {
- MCONTACT hDest = contDest->hContact;
- mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be converted to metacontact and '%s' be added to it?"), contDest->szText, contSour->szText);
- int res = MessageBox(hwnd, Wording, TranslateT("Converting to metacontact"), MB_OKCANCEL | MB_ICONQUESTION);
- if (res == 1) {
- MCONTACT handle = CallService(MS_MC_CONVERTTOMETA, hDest, 0);
- if (!handle)
- return 0;
-
- CallService(MS_MC_ADDTOMETA, hcontact, handle);
- }
- }
- else {
- hcontact = contSour->hContact;
- MCONTACT hdest = contDest->hContact;
- mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be converted to metacontact and '%s' be added to it (remove it from '%s')?"), contDest->szText, contSour->szText, contSour->subcontacts->szText);
- int res = MessageBox(hwnd, Wording, TranslateT("Converting to metacontact (moving)"), MB_OKCANCEL | MB_ICONQUESTION);
- if (res == 1) {
- MCONTACT handle = (MCONTACT)CallService(MS_MC_CONVERTTOMETA, (WPARAM)hdest, 0);
- if (!handle)
- return 0;
-
- CallService(MS_MC_REMOVEFROMMETA, 0, hcontact);
- CallService(MS_MC_ADDTOMETA, hcontact, handle);
- }
- }
- }
- }
- break;
-
- case DROPTARGET_ONMETACONTACT:
- cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
- cliGetRowByIndex(dat, dat->selection, &contDest, NULL);
- if (contSour->isChat() || contDest->isChat())
- break;
- if (contSour->type == CLCIT_CONTACT) {
- if (!mir_strcmp(contSour->proto, META_PROTO))
- break;
- if (!contSour->isSubcontact) {
- MCONTACT hcontact = contSour->hContact;
- MCONTACT handle = contDest->hContact;
- mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be added to metacontact '%s'?"), contSour->szText, contDest->szText);
- int res = MessageBox(hwnd, Wording, TranslateT("Adding contact to metacontact"), MB_OKCANCEL | MB_ICONQUESTION);
- if (res == 1) {
- if (!handle)
- return 0;
- CallService(MS_MC_ADDTOMETA, hcontact, handle);
- }
- }
- else if (contSour->subcontacts == contDest) {
- MCONTACT hsour = contSour->hContact;
- mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be default?"), contSour->szText);
- int res = MessageBox(hwnd, Wording, TranslateT("Set default contact"), MB_OKCANCEL | MB_ICONQUESTION);
- if (res == 1)
- db_mc_setDefault(contDest->hContact, hsour, true);
- }
- else {
- MCONTACT hcontact = contSour->hContact;
- MCONTACT handle = contDest->hContact;
- mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be removed from metacontact '%s' and added to '%s'?"), contSour->szText, contSour->subcontacts->szText, contDest->szText);
- int res = MessageBox(hwnd, Wording, TranslateT("Changing metacontacts (moving)"), MB_OKCANCEL | MB_ICONQUESTION);
- if (res == 1) {
- if (!handle)
- return 0;
-
- CallService(MS_MC_REMOVEFROMMETA, 0, hcontact);
- CallService(MS_MC_ADDTOMETA, hcontact, handle);
- }
- }
- }
- break;
-
- case DROPTARGET_ONSUBCONTACT:
- cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
- cliGetRowByIndex(dat, dat->selection, &contDest, NULL);
- if (contSour->isChat() || contDest->isChat())
- break;
- if (contSour->type == CLCIT_CONTACT) {
- if (!mir_strcmp(contSour->proto, META_PROTO))
- break;
- if (!contSour->isSubcontact) {
- MCONTACT hcontact = contSour->hContact;
- MCONTACT handle = contDest->subcontacts->hContact;
- mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be added to metacontact '%s'?"), contSour->szText, contDest->subcontacts->szText);
- int res = MessageBox(hwnd, Wording, TranslateT("Changing metacontacts (moving)"), MB_OKCANCEL | MB_ICONQUESTION);
- if (res == 1) {
- if (!handle)
- return 0;
-
- CallService(MS_MC_ADDTOMETA, hcontact, handle);
- }
- }
- else if (contSour->subcontacts != contDest->subcontacts) {
- MCONTACT hcontact = contSour->hContact;
- MCONTACT handle = contDest->subcontacts->hContact;
- mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be removed from metacontact '%s' and added to '%s'?"), contSour->szText, contSour->subcontacts->szText, contDest->subcontacts->szText);
- int res = MessageBox(hwnd, Wording, TranslateT("Changing metacontacts (moving)"), MB_OKCANCEL | MB_ICONQUESTION);
- if (res == 1) {
- if (!handle)
- return 0;
-
- CallService(MS_MC_REMOVEFROMMETA, 0, hcontact);
- CallService(MS_MC_ADDTOMETA, hcontact, handle);
- }
- }
- }
- break;
-
- case DROPTARGET_ONGROUP:
- corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
- break;
-
- case DROPTARGET_INSERTION:
- {
- ClcContact *contact, *destcontact;
- ClcGroup *group, *destgroup;
- BOOL NeedRename = FALSE;
- TCHAR newName[128] = { 0 };
- pcli->pfnGetRowByIndex(dat, dat->iDragItem, &contact, &group);
- int i = pcli->pfnGetRowByIndex(dat, dat->iInsertionMark, &destcontact, &destgroup);
- if (i != -1 && group->groupId != destgroup->groupId) {
- TCHAR *groupName = mir_tstrdup(pcli->pfnGetGroupName(contact->groupId, 0));
- TCHAR *shortGroup = NULL;
- TCHAR *sourceGrName = mir_tstrdup(pcli->pfnGetGroupName(destgroup->groupId, 0));
- if (groupName) {
- int len = (int)mir_tstrlen(groupName);
- do { len--; } while (len >= 0 && groupName[len] != '\\');
- if (len >= 0) shortGroup = groupName + len + 1;
- else shortGroup = groupName;
- }
- if (shortGroup) {
- NeedRename = TRUE;
- if (sourceGrName)
- mir_sntprintf(newName, _T("%s\\%s"), sourceGrName, shortGroup);
- else
- mir_tstrncpy(newName, shortGroup, _countof(newName));
- }
- mir_free(groupName);
- mir_free(sourceGrName);
- }
- int newIndex = CallService(MS_CLIST_GROUPMOVEBEFORE, contact->groupId, (destcontact && i != -1) ? destcontact->groupId : 0);
- newIndex = newIndex ? newIndex : contact->groupId;
- if (NeedRename) pcli->pfnRenameGroup(newIndex, newName);
- }
- break;
-
- case DROPTARGET_OUTSIDE:
- corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
- break;
-
- default:
- corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
- break;
- }
- }
-
- CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
- dat->iDragItem = -1;
- dat->iInsertionMark = -1;
- return 0;
-}
-
-static LRESULT clcOnLButtonDblClick(ClcData *, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- KillTimer(hwnd, TIMERID_SUBEXPAND);
- hitcontact = NULL;
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-}
-
-static LRESULT clcOnDestroy(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- for (int i = 0; i <= FONTID_MODERN_MAX; i++) {
- if (dat->fontModernInfo[i].hFont)
- DeleteObject(dat->fontModernInfo[i].hFont);
- dat->fontModernInfo[i].hFont = NULL;
- }
- if (dat->hMenuBackground) {
- DeleteObject(dat->hMenuBackground);
- dat->hMenuBackground = NULL;
- }
- if (dat->hBmpBackground) {
- DeleteObject(dat->hBmpBackground);
- dat->hBmpBackground = NULL;
- }
-
- ImageArray_Clear(&dat->avatar_cache);
- DeleteDC(dat->avatar_cache.hdc);
- ImageArray_Free(&dat->avatar_cache, FALSE);
- if (dat->himlHighlight) {
- ImageList_Destroy(dat->himlHighlight);
- dat->himlHighlight = NULL;
- }
-
- RowHeights_Free(dat);
- corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
- xpt_FreeThemeForWindow(hwnd);
- return 0;
-}
-
-static LRESULT clcOnIntmGroupChanged(ClcData *dat, HWND hwnd, UINT, WPARAM wParam, LPARAM)
-{
- WORD iExtraImage[EXTRA_ICON_COUNT];
- BYTE flags = 0;
-
- ClcContact *contact;
- if (!pcli->pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL))
- memset(iExtraImage, 0xFF, sizeof(iExtraImage));
- else {
- memcpy(iExtraImage, contact->iExtraImage, sizeof(iExtraImage));
- flags = contact->flags;
- }
- pcli->pfnDeleteItemFromTree(hwnd, wParam);
- if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_SHOWHIDDEN || !db_get_b(wParam, "CList", "Hidden", 0)) {
- NMCLISTCONTROL nm;
- pcli->pfnAddContactToTree(hwnd, dat, wParam, 1, 1);
- if (pcli->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);
- return 0;
-}
-
-static LRESULT clcOnIntmIconChanged(ClcData *dat, HWND hwnd, UINT, WPARAM wParam, LPARAM lParam)
-{
- ClcContact *contact = NULL;
- ClcGroup *group = NULL;
- int recalcScrollBar = 0, shouldShow;
- BOOL needRepaint = FALSE;
- int contacticon = corecli.pfnGetContactIcon(wParam);
- MCONTACT hSelItem = NULL;
- ClcContact *selcontact = NULL;
-
- char *szProto = GetContactProto(wParam);
- WORD status = (szProto == NULL) ? ID_STATUS_OFFLINE : GetContactCachedStatus(wParam);
- BOOL image_is_special = (LOWORD(contacticon) != (LOWORD(lParam))); //check only base icons
-
- int nHiddenStatus = CLVM_GetContactHiddenStatus(wParam, szProto, dat);
-
- DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE);
- bool isVisiblebyFilter = (((style & CLS_SHOWHIDDEN) && nHiddenStatus != -1) || !nHiddenStatus);
- bool ifVisibleByClui = !pcli->pfnIsHiddenMode(dat, status);
- bool isVisible = g_CluiData.bFilterEffective&CLVM_FILTER_STATUS ? TRUE : ifVisibleByClui;
- bool isIconChanged = cli_GetContactIcon(wParam) != LOWORD(lParam);
-
- shouldShow = isVisiblebyFilter && (isVisible || isIconChanged);
-
- // XXX CLVM changed - this means an offline msg is flashing, so the contact should be shown
-
- if (!pcli->pfnFindItem(hwnd, dat, wParam, &contact, &group, NULL)) {
- if (shouldShow && CallService(MS_DB_CONTACT_IS, wParam, 0)) {
- if (dat->selection >= 0 && pcli->pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) != -1)
- hSelItem = (DWORD_PTR)pcli->pfnContactToHItem(selcontact);
- pcli->pfnAddContactToTree(hwnd, dat, wParam, (style & CLS_CONTACTLIST) == 0, 0);
- recalcScrollBar = 1;
- needRepaint = TRUE;
- pcli->pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL);
- if (contact) {
- contact->iImage = lParam;
- contact->image_is_special = image_is_special;
- pcli->pfnNotifyNewContact(hwnd, wParam);
- dat->needsResort = 1;
- }
- }
- }
- else {
- //item in list already
- if (contact && contact->iImage == lParam)
- return 0;
-
- if (!shouldShow && !(style & CLS_NOHIDEOFFLINE) && (style & CLS_HIDEOFFLINE || group->hideOffline) && clcItemNotHiddenOffline(group, contact))
- shouldShow = TRUE;
-
- if (!shouldShow && !(style & CLS_NOHIDEOFFLINE) && ((style & CLS_HIDEOFFLINE) || group->hideOffline || g_CluiData.bFilterEffective)) { // CLVM changed
- if (dat->selection >= 0 && pcli->pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) != -1)
- hSelItem = (DWORD_PTR)pcli->pfnContactToHItem(selcontact);
- pcli->pfnRemoveItemFromGroup(hwnd, group, contact, (style & CLS_CONTACTLIST) == 0);
- needRepaint = TRUE;
- recalcScrollBar = 1;
- dat->needsResort = 1;
- }
- else if (contact) {
- contact->iImage = lParam;
- if (!pcli->pfnIsHiddenMode(dat, status))
- contact->flags |= CONTACTF_ONLINE;
- else
- contact->flags &= ~CONTACTF_ONLINE;
- contact->image_is_special = image_is_special;
- if (!image_is_special) { //Only if it is status changing
- dat->needsResort = 1;
- needRepaint = TRUE;
- }
- else if (dat->m_paintCouter == contact->lastPaintCounter) //if contacts is visible
- needRepaint = TRUE;
- }
- }
-
- if (hSelItem) {
- ClcGroup *selgroup;
- if (pcli->pfnFindItem(hwnd, dat, hSelItem, &selcontact, &selgroup, NULL))
- dat->selection = pcli->pfnGetRowsPriorTo(&dat->list, selgroup, List_IndexOf((SortedList*)&selgroup->cl, selcontact));
- else
- dat->selection = -1;
- }
-
- if (dat->needsResort) {
- TRACE("Sort required\n");
- clcSetDelayTimer(TIMERID_DELAYEDRESORTCLC, hwnd);
- }
- else if (needRepaint) {
- if (contact && contact->pos_icon.bottom != 0 && contact->pos_icon.right != 0)
- CLUI__cliInvalidateRect(hwnd, &(contact->pos_icon), FALSE);
- else
- CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
- //try only needed rectangle
- }
-
- return 0;
-}
-
-static LRESULT clcOnIntmAvatarChanged(ClcData *dat, HWND hwnd, UINT, WPARAM hContact, LPARAM)
-{
- ClcContact *contact;
- if (FindItem(hwnd, dat, hContact, &contact, NULL, NULL, FALSE))
- Cache_GetAvatar(dat, contact);
- else if (hContact == 0)
- UpdateAllAvatars(dat);
-
- CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
- return 0;
-}
-
-static LRESULT clcOnIntmTimeZoneChanged(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- ClcContact *contact;
- if (!FindItem(hwnd, dat, wParam, &contact, NULL, NULL, FALSE))
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-
- if (contact) {
- Cache_GetTimezone(dat, contact->hContact);
- Cache_GetText(dat, contact, 1);
- cliRecalcScrollBar(hwnd, dat);
- }
- return 0;
-}
-
-static LRESULT clcOnIntmNameChanged(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- int ret = corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-
- pcli->pfnInvalidateDisplayNameCacheEntry(wParam);
-
- ClcContact *contact;
- if (!FindItem(hwnd, dat, wParam, &contact, NULL, NULL, FALSE))
- return ret;
-
- if (contact) {
- mir_tstrncpy(contact->szText, pcli->pfnGetContactDisplayName(wParam, 0), _countof(contact->szText));
- Cache_GetText(dat, contact, 1);
- cliRecalcScrollBar(hwnd, dat);
- }
-
- dat->needsResort = 1;
- return ret;
-}
-
-static LRESULT clcOnIntmApparentModeChanged(ClcData *, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-}
-
-static LRESULT clcOnIntmStatusMsgChanged(ClcData *dat, HWND hwnd, UINT msg, WPARAM hContact, LPARAM lParam)
-{
- if (hContact == NULL || IsHContactInfo(hContact) || IsHContactGroup(hContact))
- return corecli.pfnContactListControlWndProc(hwnd, msg, hContact, lParam);
-
- ClcContact *contact;
- if (!FindItem(hwnd, dat, hContact, &contact, NULL, NULL, FALSE))
- return corecli.pfnContactListControlWndProc(hwnd, msg, hContact, lParam);
-
- if (contact) {
- Cache_GetText(dat, contact, 1);
- cliRecalcScrollBar(hwnd, dat);
- PostMessage(hwnd, INTM_INVALIDATE, 0, 0);
- }
- return corecli.pfnContactListControlWndProc(hwnd, msg, hContact, lParam);
-}
-
-static LRESULT clcOnIntmNotOnListChanged(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING*)lParam;
-
- ClcContact *contact;
- if (!FindItem(hwnd, dat, wParam, &contact, NULL, NULL, TRUE))
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-
- if (contact->type != CLCIT_CONTACT)
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-
- if (dbcws->value.type == DBVT_DELETED || dbcws->value.bVal == 0)
- contact->flags &= ~CONTACTF_NOTONLIST;
- else
- contact->flags |= CONTACTF_NOTONLIST;
-
- CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
-}
-
-static LRESULT clcOnIntmScrollBarChanged(ClcData *dat, HWND hwnd, UINT, WPARAM, LPARAM)
-{
- if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_CONTACTLIST) {
- if (dat->noVScrollbar)
- ShowScrollBar(hwnd, SB_VERT, FALSE);
- else
- pcli->pfnRecalcScrollBar(hwnd, dat);
- }
- return 0;
-}
-
-static LRESULT clcOnIntmStatusChanged(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- int ret = corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
- if (wParam != 0) {
- ClcCacheEntry *pdnce = pcli->pfnGetCacheEntry(wParam);
- if (pdnce && pdnce->m_pszProto) {
- pdnce->m_iStatus = GetStatusForContact(pdnce->hContact, pdnce->m_pszProto);
- if (!dat->force_in_dialog && (dat->second_line_show || dat->third_line_show))
- gtaRenewText(pdnce->hContact);
- SendMessage(hwnd, INTM_ICONCHANGED, wParam, corecli.pfnGetContactIcon(wParam));
-
- ClcContact *contact;
- if (FindItem(hwnd, dat, wParam, &contact, NULL, NULL, TRUE)) {
- if (contact && contact->type == CLCIT_CONTACT) {
- if (!contact->image_is_special && pdnce->getStatus() > ID_STATUS_OFFLINE)
- contact->iImage = corecli.pfnGetContactIcon(wParam);
- if (contact->isSubcontact && contact->subcontacts && contact->subcontacts->type == CLCIT_CONTACT)
- pcli->pfnClcBroadcast(INTM_STATUSCHANGED, contact->subcontacts->hContact, 0); //forward status changing to host meta contact
- }
- }
- }
- }
-
- if (db_get_b(NULL, "CList", "PlaceOfflineToRoot", SETTING_PLACEOOFLINETOROOT_DEFAULT))
- pcli->pfnInitAutoRebuild(hwnd);
- else
- PostMessage(hwnd, INTM_INVALIDATE, 0, 0);
-
- return ret;
-}
-
-static LRESULT clcOnIntmReloadOptions(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
- pcli->pfnLoadClcOptions(hwnd, dat, FALSE);
- LoadCLCOptions(hwnd, dat, FALSE);
- pcli->pfnSaveStateAndRebuildList(hwnd, dat);
- pcli->pfnSortCLC(hwnd, dat, 1);
- if (IsWindowVisible(hwnd))
- pcli->pfnInvalidateRect(GetParent(hwnd), NULL, FALSE);
- return TRUE;
-}
-
-static int clcHookModulesLoaded(WPARAM, LPARAM)
-{
- if (MirandaExiting())
- return 0;
-
- if (!ServiceExists(MS_AV_GETAVATARBITMAP))
- MessageBox(NULL,
- TranslateT("Clist Modern requires AVS plugin to be present. Install it using PluginUpdater or download from http://wiki.miranda-ng.org/Download"),
- TranslateT("Error loading plugin"), MB_ICONERROR | MB_OK);
-
- HookEvent(ME_AV_AVATARCHANGED, clcHookAvatarChanged);
-
- HookEvent(ME_MODERNOPT_INITIALIZE, ModernOptInit);
- HookEvent(ME_MODERNOPT_INITIALIZE, ModernSkinOptInit);
-
- HookEvent(ME_FOLDERS_PATH_CHANGED, ReloadSkinFolder);
- hSkinFolder = FoldersRegisterCustomPathT(LPGEN("Skins"), LPGEN("Modern contact list"), MIRANDA_PATHT _T("\\") _T(DEFAULT_SKIN_FOLDER));
- FoldersGetCustomPathT(hSkinFolder, SkinsFolder, _countof(SkinsFolder), _T(DEFAULT_SKIN_FOLDER));
-
- // Get icons
- TCHAR szMyPath[MAX_PATH];
- GetModuleFileName(g_hInst, szMyPath, _countof(szMyPath));
-
- SKINICONDESC sid = { 0 };
- sid.defaultFile.t = szMyPath;
- sid.flags = SIDF_PATH_TCHAR;
-
- sid.section.a = LPGEN("Contact list");
- sid.description.a = LPGEN("Listening to");
- sid.pszName = "LISTENING_TO_ICON";
- sid.iDefaultIndex = -IDI_LISTENING_TO;
- IcoLib_AddIcon(&sid);
-
- sid.section.a = LPGEN("Contact list") "/" LPGEN("Avatar overlay");
- for (int i = 0; i < _countof(g_pAvatarOverlayIcons); i++) {
- sid.description.a = g_pAvatarOverlayIcons[i].description;
- sid.pszName = g_pAvatarOverlayIcons[i].name;
- sid.iDefaultIndex = -g_pAvatarOverlayIcons[i].id;
- IcoLib_AddIcon(&sid);
- }
-
- sid.section.a = LPGEN("Contact list") "/" LPGEN("Status overlay");
- for (int i = 0; i < _countof(g_pStatusOverlayIcons); i++) {
- sid.description.a = g_pStatusOverlayIcons[i].description;
- sid.pszName = g_pStatusOverlayIcons[i].name;
- sid.iDefaultIndex = -g_pStatusOverlayIcons[i].id;
- IcoLib_AddIcon(&sid);
- }
-
- clcHookIconsChanged(0, 0);
-
- HookEvent(ME_SKIN2_ICONSCHANGED, clcHookIconsChanged);
-
- // Register smiley category
- if (ServiceExists(MS_SMILEYADD_REGISTERCATEGORY)) {
- SMADD_REGCAT rc;
- rc.cbSize = sizeof(rc);
- rc.name = "clist";
- rc.dispname = Translate("Contact list smileys");
-
- CallService(MS_SMILEYADD_REGISTERCATEGORY, 0, (LPARAM)&rc);
-
- HookEvent(ME_SMILEYADD_OPTIONSCHANGED, clcHookSmileyAddOptionsChanged);
- }
-
- CallService(MS_BACKGROUNDCONFIG_REGISTER, (WPARAM)(LPGEN("List background")"/CLC"), 0);
- CallService(MS_BACKGROUNDCONFIG_REGISTER, (WPARAM)(LPGEN("Menu background")"/Menu"), 0);
- CallService(MS_BACKGROUNDCONFIG_REGISTER, (WPARAM)(LPGEN("Status bar background")"/StatusBar"), 0);
- CallService(MS_BACKGROUNDCONFIG_REGISTER, (WPARAM)(LPGEN("Frames title bar background")"/FrameTitleBar"), 0);
-
- HookEvent(ME_BACKGROUNDCONFIG_CHANGED, clcHookBkgndConfigChanged);
- HookEvent(ME_BACKGROUNDCONFIG_CHANGED, BgStatusBarChange);
- HookEvent(ME_BACKGROUNDCONFIG_CHANGED, OnFrameTitleBarBackgroundChange);
- HookEvent(ME_COLOUR_RELOAD, OnFrameTitleBarBackgroundChange);
-
- AniAva_UpdateOptions();
- return 0;
-}
-
-HRESULT ClcLoadModule()
-{
- g_himlCListClc = (HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0);
-
- HookEvent(ME_MC_SUBCONTACTSCHANGED, clcMetacontactChanged);
- HookEvent(ME_MC_ENABLED, clcMetaModeChanged);
- HookEvent(ME_DB_CONTACT_SETTINGCHANGED, clcHookSettingChanged);
- HookEvent(ME_OPT_INITIALISE, ClcOptInit);
- HookEvent(ME_PROTO_ACK, clcHookProtoAck);
- HookEvent(ME_SYSTEM_MODULESLOADED, clcHookModulesLoaded);
- HookEvent(ME_DB_EVENT_ADDED, clcHookDbEventAdded);
- return S_OK;
-}
-
-int ClcUnloadModule()
-{
- if (g_CluiData.bOldUseGroups != (BYTE)-1)
- db_set_b(NULL, "CList", "UseGroups", (BYTE)g_CluiData.bOldUseGroups);
- if (g_CluiData.boldHideOffline != (BYTE)-1)
- db_set_b(NULL, "CList", "HideOffline", (BYTE)g_CluiData.boldHideOffline);
-
- return 0;
-}
-
-int ClcDoProtoAck(MCONTACT, ACKDATA *ack)
-{
- if (MirandaExiting()) return 0;
- if (ack->type == ACKTYPE_STATUS) {
- if (ack->result == ACKRESULT_SUCCESS) {
- for (int i = 0; i < pcli->hClcProtoCount; i++) {
- if (!mir_strcmp(pcli->clcProto[i].szProto, ack->szModule)) {
- pcli->clcProto[i].dwStatus = (WORD)ack->lParam;
- if (pcli->clcProto[i].dwStatus >= ID_STATUS_OFFLINE)
- pcli->pfnTrayIconUpdateBase(pcli->clcProto[i].szProto);
- return 0;
- }
- }
- }
- }
- else if (ack->type == ACKTYPE_AWAYMSG) {
- if (ack->result == ACKRESULT_SUCCESS && ack->lParam) {
- if (ack->szModule != NULL)
- if (db_get_b(ack->hContact, ack->szModule, "ChatRoom", 0) != 0)
- return 0;
-
- db_set_ws(ack->hContact, "CList", "StatusMsg", (const TCHAR *)ack->lParam);
- gtaRenewText(ack->hContact);
- }
- else {
- if (ack->szModule != NULL)
- if (db_get_b(ack->hContact, ack->szModule, "ChatRoom", 0) != 0)
- return 0;
-
- if (ack->hContact) {
- char *val = db_get_sa(ack->hContact, "CList", "StatusMsg");
- if (val) {
- if (mir_strcmpi(val, ""))
- db_set_s(ack->hContact, "CList", "StatusMsg", "");
- else
- gtaRenewText(ack->hContact);
- mir_free(val);
- }
- }
- }
- }
- else if (ack->type == ACKTYPE_EMAIL) {
- CLUIUnreadEmailCountChanged(0, 0);
- }
- return 0;
-}
-
-int ClcGetShortData(ClcData* pData, SHORTDATA *pShortData)
-{
- if (!pData || !pShortData)
- return -1;
-
- pShortData->hWnd = pData->hWnd;
- pShortData->text_replace_smileys = pData->text_replace_smileys;
- pShortData->text_smiley_height = pData->text_smiley_height;
- pShortData->text_use_protocol_smileys = pData->text_use_protocol_smileys;
- pShortData->contact_time_show_only_if_different = pData->contact_time_show_only_if_different;
-
- // Second line
- pShortData->second_line_show = pData->second_line_show;
- pShortData->second_line_draw_smileys = pData->second_line_draw_smileys;
- pShortData->second_line_type = pData->second_line_type;
-
- mir_tstrncpy(pShortData->second_line_text, pData->second_line_text, _countof(pShortData->second_line_text));
-
- pShortData->second_line_xstatus_has_priority = pData->second_line_xstatus_has_priority;
- pShortData->second_line_show_status_if_no_away = pData->second_line_show_status_if_no_away;
- pShortData->second_line_show_listening_if_no_away = pData->second_line_show_listening_if_no_away;
- pShortData->second_line_use_name_and_message_for_xstatus = pData->second_line_use_name_and_message_for_xstatus;
-
- // Third line
- pShortData->third_line_show = pData->third_line_show;
- pShortData->third_line_draw_smileys = pData->third_line_draw_smileys;
- pShortData->third_line_type = pData->third_line_type;
-
- mir_tstrncpy(pShortData->third_line_text, pData->third_line_text, _countof(pShortData->third_line_text));
-
- pShortData->third_line_xstatus_has_priority = pData->third_line_xstatus_has_priority;
- pShortData->third_line_show_status_if_no_away = pData->third_line_show_status_if_no_away;
- pShortData->third_line_show_listening_if_no_away = pData->third_line_show_listening_if_no_away;
- pShortData->third_line_use_name_and_message_for_xstatus = pData->third_line_use_name_and_message_for_xstatus;
- return 0;
-}
-
-int ClcEnterDragToScroll(HWND hwnd, int Y)
-{
- if (IsDragToScrollMode)
- return 0;
-
- ClcData *dat = (ClcData*)GetWindowLongPtr(hwnd, 0);
- if (!dat)
- return 0;
-
- StartDragPos = Y;
- StartScrollPos = dat->yScroll;
- IsDragToScrollMode = 1;
- SetCapture(hwnd);
- return 1;
-}
-
-
-/*
-* Contact list control window procedure
-*/
-LRESULT CALLBACK cli_ContactListControlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-
-#define CASE_MSG_RET(msg, handler) case msg: return handler(dat, hwnd, msg, wParam, lParam);
-
- ClcData *dat = (ClcData*)GetWindowLongPtr(hwnd, 0);
-
- if (msg >= CLM_FIRST && msg < CLM_LAST)
- return cli_ProcessExternalMessages(hwnd, dat, msg, wParam, lParam);
-
- switch (msg) {
- CASE_MSG_RET(INTM_GROUPCHANGED, clcOnIntmGroupChanged);
- CASE_MSG_RET(INTM_ICONCHANGED, clcOnIntmIconChanged);
- CASE_MSG_RET(INTM_AVATARCHANGED, clcOnIntmAvatarChanged);
- CASE_MSG_RET(INTM_TIMEZONECHANGED, clcOnIntmTimeZoneChanged);
- CASE_MSG_RET(INTM_NAMECHANGED, clcOnIntmNameChanged);
- CASE_MSG_RET(INTM_APPARENTMODECHANGED, clcOnIntmApparentModeChanged);
- CASE_MSG_RET(INTM_STATUSMSGCHANGED, clcOnIntmStatusMsgChanged);
- CASE_MSG_RET(INTM_NOTONLISTCHANGED, clcOnIntmNotOnListChanged);
- CASE_MSG_RET(INTM_SCROLLBARCHANGED, clcOnIntmScrollBarChanged);
- CASE_MSG_RET(INTM_STATUSCHANGED, clcOnIntmStatusChanged);
- CASE_MSG_RET(INTM_RELOADOPTIONS, clcOnIntmReloadOptions);
-
- CASE_MSG_RET(WM_CREATE, clcOnCreate);
- CASE_MSG_RET(WM_NCHITTEST, clcOnHitTest);
- CASE_MSG_RET(WM_COMMAND, clcOnCommand);
- CASE_MSG_RET(WM_SIZE, clcOnSize);
- CASE_MSG_RET(WM_CHAR, clcOnChar);
- CASE_MSG_RET(WM_PAINT, clcOnPaint);
- CASE_MSG_RET(WM_ERASEBKGND, clcOnEraseBkGround);
- CASE_MSG_RET(WM_KEYDOWN, clcOnKeyDown);
- CASE_MSG_RET(WM_TIMER, clcOnTimer);
- CASE_MSG_RET(WM_ACTIVATE, clcOnActivate);
- CASE_MSG_RET(WM_SETCURSOR, clcOnSetCursor);
- CASE_MSG_RET(WM_LBUTTONDOWN, clcOnLButtonDown);
- CASE_MSG_RET(WM_CAPTURECHANGED, clcOnCaptureChanged);
- CASE_MSG_RET(WM_MOUSEMOVE, clcOnMouseMove);
- CASE_MSG_RET(WM_LBUTTONUP, clcOnLButtonUp);
- CASE_MSG_RET(WM_LBUTTONDBLCLK, clcOnLButtonDblClick);
- CASE_MSG_RET(WM_DESTROY, clcOnDestroy);
-
- default:
- return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
- }
-}
+ }
+ else {
+ if (!strcmp(cws->szSetting, "TickTS"))
+ pcli->pfnClcBroadcast(INTM_STATUSCHANGED, hContact, 0);
+ else if (!strcmp(cws->szModule, "UserInfo")) {
+ if (!strcmp(cws->szSetting, "Timezone"))
+ pcli->pfnClcBroadcast(INTM_TIMEZONECHANGED, hContact, 0);
+ }
+ else if (!strcmp(cws->szModule, "CList")) {
+ if (!strcmp(cws->szSetting, "StatusMsg"))
+ pcli->pfnClcBroadcast(INTM_STATUSMSGCHANGED, hContact, 0);
+ }
+ else if (!strcmp(cws->szModule, "ContactPhoto")) {
+ if (!strcmp(cws->szSetting, "File"))
+ pcli->pfnClcBroadcast(INTM_AVATARCHANGED, hContact, 0);
+ }
+ else {
+ if ((!strcmp(cws->szSetting, "XStatusName") || !strcmp(cws->szSetting, "XStatusMsg")))
+ pcli->pfnClcBroadcast(INTM_STATUSMSGCHANGED, hContact, 0);
+ else if (!strcmp(cws->szSetting, "XStatusId"))
+ pcli->pfnClcBroadcast(INTM_STATUSCHANGED, hContact, 0);
+ else if (!strcmp(cws->szSetting, "Timezone"))
+ pcli->pfnClcBroadcast(INTM_TIMEZONECHANGED, hContact, 0);
+ else if (!strcmp(cws->szSetting, "ListeningTo"))
+ pcli->pfnClcBroadcast(INTM_STATUSMSGCHANGED, hContact, 0);
+ else if (!strcmp(cws->szSetting, "Transport") || !strcmp(cws->szSetting, "IsTransported")) {
+ pcli->pfnInvalidateDisplayNameCacheEntry(hContact);
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, hContact, 0);
+ }
+ }
+ }
+ return 0;
+}
+
+static int clcHookDbEventAdded(WPARAM hContact, LPARAM lParam)
+{
+ g_CluiData.t_now = time(NULL);
+ if (hContact && lParam) {
+ DBEVENTINFO dbei = { sizeof(dbei) };
+ db_event_get(lParam, &dbei);
+ if (dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_SENT)) {
+ db_set_dw(hContact, "CList", "mf_lastmsg", dbei.timestamp);
+ ClcCacheEntry *pdnce = pcli->pfnGetCacheEntry(hContact);
+ if (pdnce)
+ pdnce->dwLastMsgTime = dbei.timestamp;
+ }
+ }
+ return 0;
+}
+
+static int clcHookBkgndConfigChanged(WPARAM, LPARAM)
+{
+ pcli->pfnClcOptionsChanged();
+ return 0;
+}
+
+static int clcHookAvatarChanged(WPARAM wParam, LPARAM lParam)
+{
+ if (MirandaExiting()) return 0;
+ pcli->pfnClcBroadcast(INTM_AVATARCHANGED, wParam, lParam);
+ return 0;
+}
+
+static int clcExitDragToScroll()
+{
+ if (!IsDragToScrollMode) return 0;
+ IsDragToScrollMode = 0;
+ ReleaseCapture();
+ return 1;
+}
+
+static int clcProceedDragToScroll(HWND hwnd, int Y)
+{
+ int pos, dy;
+ if (!IsDragToScrollMode) return 0;
+ if (GetCapture() != hwnd) clcExitDragToScroll();
+ dy = StartDragPos - Y;
+ pos = StartScrollPos + dy;
+ if (pos < 0)
+ pos = 0;
+ SendMessage(hwnd, WM_VSCROLL, MAKEWPARAM(SB_THUMBTRACK, pos), 0);
+ return 1;
+}
+
+
+
+static int clcSearchNextContact(HWND hwnd, ClcData *dat, int index, const TCHAR *text, int prefixOk, BOOL fSearchUp)
+{
+ ClcGroup *group = &dat->list;
+ int testlen = (int)mir_tstrlen(text);
+ BOOL fReturnAsFound = FALSE;
+ int nLastFound = -1;
+ if (index == -1) fReturnAsFound = TRUE;
+ 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 found;
+ if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) {
+ found = true;
+ }
+ else if (dat->filterSearch) {
+ TCHAR *lowered_szText = CharLowerW(NEWTSTR_ALLOCA(group->cl.items[group->scanIndex]->szText));
+ TCHAR *lowered_search = CharLowerW(NEWTSTR_ALLOCA(dat->szQuickSearch));
+ found = _tcsstr(lowered_szText, lowered_search) != NULL;
+ }
+ else {
+ found = ((prefixOk && CSTR_EQUAL == CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, text, -1, group->cl.items[group->scanIndex]->szText, testlen)) || (!prefixOk && !mir_tstrcmpi(text, group->cl.items[group->scanIndex]->szText)));
+ }
+ if (found) {
+ ClcGroup *contactGroup = group;
+ int contactScanIndex = group->scanIndex;
+ int foundindex;
+ for (; group; group = group->parent)
+ pcli->pfnSetGroupExpand(hwnd, dat, group, 1);
+ foundindex = pcli->pfnGetRowsPriorTo(&dat->list, contactGroup, contactScanIndex);
+ if (fReturnAsFound)
+ return foundindex;
+ else if (nLastFound != -1 && fSearchUp && foundindex == index)
+ return nLastFound;
+ else if (!fSearchUp && foundindex == index)
+ fReturnAsFound = TRUE;
+ else
+ nLastFound = foundindex;
+ group = contactGroup;
+ group->scanIndex = 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;
+}
+
+static BOOL clcItemNotHiddenOffline(ClcGroup *group, ClcContact *contact)
+{
+ if (g_CluiData.bFilterEffective) return FALSE;
+
+ if (!contact) return FALSE;
+ ClcCacheEntry *pdnce = pcli->pfnGetCacheEntry(contact->hContact);
+ if (!pdnce) return FALSE;
+ if (pdnce->m_bNoHiddenOffline) return TRUE;
+
+ if (!group) return FALSE;
+ if (group->hideOffline) return FALSE;
+
+ if (CLCItems_IsShowOfflineGroup(group)) return TRUE;
+
+ return FALSE;
+}
+
+static LRESULT clcOnCreate(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ dat = (ClcData*)mir_calloc(sizeof(ClcData));
+ SetWindowLongPtr(hwnd, 0, (LONG_PTR)dat);
+ dat->hCheckBoxTheme = xpt_AddThemeHandle(hwnd, L"BUTTON");
+ dat->m_paintCouter = 0;
+ dat->hWnd = hwnd;
+
+ ImageArray_Initialize(&dat->avatar_cache, FALSE, 20); //this array will be used to keep small avatars too
+
+ RowHeights_Initialize(dat);
+
+ dat->needsResort = 1;
+ dat->MetaIgnoreEmptyExtra = db_get_b(NULL, "CLC", "MetaIgnoreEmptyExtra", SETTING_METAIGNOREEMPTYEXTRA_DEFAULT);
+
+ dat->IsMetaContactsEnabled = (!(GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_MANUALUPDATE)) && db_mc_isEnabled();
+
+ dat->expandMeta = db_get_b(NULL, "CLC", "MetaExpanding", SETTING_METAEXPANDING_DEFAULT);
+ dat->useMetaIcon = db_get_b(NULL, "CLC", "Meta", SETTING_USEMETAICON_DEFAULT);
+ dat->drawOverlayedStatus = db_get_b(NULL, "CLC", "DrawOverlayedStatus", SETTING_DRAWOVERLAYEDSTATUS_DEFAULT);
+ g_CluiData.bSortByOrder[0] = db_get_b(NULL, "CList", "SortBy1", SETTING_SORTBY1_DEFAULT);
+ g_CluiData.bSortByOrder[1] = db_get_b(NULL, "CList", "SortBy2", SETTING_SORTBY2_DEFAULT);
+ g_CluiData.bSortByOrder[2] = db_get_b(NULL, "CList", "SortBy3", SETTING_SORTBY3_DEFAULT);
+ g_CluiData.fSortNoOfflineBottom = db_get_b(NULL, "CList", "NoOfflineBottom", SETTING_NOOFFLINEBOTTOM_DEFAULT);
+ dat->menuOwnerID = -1;
+ dat->menuOwnerType = CLCIT_INVALID;
+
+ corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+ LoadCLCOptions(hwnd, dat, TRUE);
+ if (dat->contact_time_show || dat->second_line_type == TEXT_CONTACT_TIME || dat->third_line_type == TEXT_CONTACT_TIME)
+ CLUI_SafeSetTimer(hwnd, TIMERID_INVALIDATE, 5000, NULL);
+ else
+ KillTimer(hwnd, TIMERID_INVALIDATE);
+
+ TRACE("Create New ClistControl TO END\r\n");
+ return 0;
+}
+
+static LRESULT clcOnHitTest(ClcData *, HWND hwnd, UINT, WPARAM wParam, LPARAM lParam)
+{
+ return DefWindowProc(hwnd, WM_NCHITTEST, wParam, lParam);
+}
+
+static LRESULT clcOnCommand(ClcData *dat, HWND hwnd, UINT, WPARAM wParam, LPARAM lParam)
+{
+ ClcContact *contact;
+ int hit = pcli->pfnGetRowByIndex(dat, dat->selection, &contact, NULL);
+ if (hit != -1) {
+ switch (LOWORD(wParam)) {
+ case POPUP_NEWSUBGROUP:
+ if (contact->type == CLCIT_GROUP) {
+ SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~CLS_HIDEEMPTYGROUPS);
+ SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) | CLS_USEGROUPS);
+ CallService(MS_CLIST_GROUPCREATE, contact->groupId, 0);
+ }
+ return 0;
+
+ case POPUP_GROUPSHOWOFFLINE:
+ if (contact->type == CLCIT_GROUP) {
+ CallService(MS_CLIST_GROUPSETFLAGS, contact->groupId, MAKELPARAM(CLCItems_IsShowOfflineGroup(contact->group) ? 0 : GROUPF_SHOWOFFLINE, GROUPF_SHOWOFFLINE));
+ pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0);
+ }
+ return 0;
+ }
+ }
+
+ return corecli.pfnContactListControlWndProc(hwnd, WM_COMMAND, wParam, lParam);
+}
+
+static LRESULT clcOnSize(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ pcli->pfnEndRename(hwnd, dat, 1);
+ KillTimer(hwnd, TIMERID_INFOTIP);
+ KillTimer(hwnd, TIMERID_RENAME);
+ cliRecalcScrollBar(hwnd, dat);
+ if (g_CluiData.fDisableSkinEngine || dat->force_in_dialog) {
+ RECT rc = { 0 };
+ GetClientRect(hwnd, &rc);
+ if (rc.right == 0)
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+
+ rc.bottom = max(dat->row_min_heigh, 1);
+
+ 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 || dat->force_in_dialog) ? 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);
+ }
+ else if (dat->himlHighlight) {
+ ImageList_Destroy(dat->himlHighlight);
+ dat->himlHighlight = NULL;
+ }
+ return 0;
+}
+
+static LRESULT clcOnChar(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (wParam == 27 && dat->szQuickSearch[0] == '\0') { //escape and not quick search
+ // minimize clist
+ CListMod_HideWindow();
+ }
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+}
+static LRESULT clcOnPaint(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (IsWindowVisible(hwnd)) {
+ if (!g_CluiData.fLayered || GetParent(hwnd) != pcli->hwndContactList) {
+ PAINTSTRUCT ps;
+ HDC hdc = BeginPaint(hwnd, &ps);
+ g_clcPainter.cliPaintClc(hwnd, dat, hdc, &ps.rcPaint);
+ EndPaint(hwnd, &ps);
+ }
+ else CallService(MS_SKINENG_INVALIDATEFRAMEIMAGE, (WPARAM)hwnd, 0);
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+static LRESULT clcOnEraseBkGround(ClcData *, HWND, UINT, WPARAM, LPARAM)
+{
+ return 1;
+}
+
+static LRESULT clcOnKeyDown(ClcData *dat, HWND hwnd, UINT, WPARAM wParam, LPARAM lParam)
+{
+ if (wParam == VK_CONTROL)
+ return 0;
+
+ pcli->pfnHideInfoTip(hwnd, dat);
+ KillTimer(hwnd, TIMERID_INFOTIP);
+ KillTimer(hwnd, TIMERID_RENAME);
+
+ if (CallService(MS_CLIST_MENUPROCESSHOTKEY, wParam, MPCF_CONTACTMENU))
+ return 0;
+
+ RECT clRect;
+ GetClientRect(hwnd, &clRect);
+ int pageSize = (dat->rowHeight) ? clRect.bottom / dat->rowHeight : 0;
+ int selMoved = 0;
+ int changeGroupExpand = 0;
+
+ switch (wParam) {
+ case VK_DOWN:
+ case VK_UP:
+ if (dat->szQuickSearch[0] != '\0' && dat->selection != -1) { //get next contact
+ //get next contact
+ int index = clcSearchNextContact(hwnd, dat, dat->selection, dat->szQuickSearch, 1, (wParam == VK_UP));
+ if (index == -1) {
+ MessageBeep(MB_OK);
+ return 0;
+ }
+
+ dat->selection = index;
+ pcli->pfnInvalidateRect(hwnd, NULL, FALSE);
+ pcli->pfnEnsureVisible(hwnd, dat, dat->selection, 0);
+ return 0;
+ }
+
+ if (wParam == VK_DOWN) dat->selection++;
+ if (wParam == 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 = pcli->pfnGetGroupContentsCount(&dat->list, 1) - 1; selMoved = 1; break;
+ case VK_LEFT: changeGroupExpand = 1; break;
+ case VK_RIGHT: changeGroupExpand = 2; break;
+ case VK_RETURN:
+ pcli->pfnDoSelectionDefaultAction(hwnd, dat);
+ SetCapture(hwnd);
+ dat->szQuickSearch[0] = 0;
+ if (dat->filterSearch)
+ pcli->pfnSaveStateAndRebuildList(hwnd, dat);
+ return 0;
+
+ case VK_F2: cliBeginRenameSelection(hwnd, dat); /*SetCapture(hwnd);*/ return 0;
+ case VK_DELETE: pcli->pfnDeleteFromContactList(hwnd, dat); SetCapture(hwnd); return 0;
+ case VK_ESCAPE:
+ if ((dat->dragStage & DRAGSTAGEM_STAGE) == DRAGSTAGE_ACTIVE) {
+ dat->iDragItem = -1;
+ dat->iInsertionMark = -1;
+ dat->dragStage = 0;
+ ReleaseCapture();
+ }
+ 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)) {
+ SetCapture(hwnd);
+ return 0;
+ }
+ }
+
+ if (changeGroupExpand) {
+ ClcContact *contact;
+ ClcGroup *group;
+ int hit = cliGetRowByIndex(dat, dat->selection, &contact, &group);
+ if (hit == -1) {
+ SetCapture(hwnd);
+ return 0;
+ }
+
+ if (contact->type == CLCIT_CONTACT && (contact->isSubcontact || contact->SubAllocated > 0)) {
+ if (contact->isSubcontact && changeGroupExpand == 1) {
+ dat->selection -= contact->isSubcontact;
+ selMoved = 1;
+ }
+ else if (!contact->isSubcontact && contact->SubAllocated > 0) {
+ if (changeGroupExpand == 1 && !contact->SubExpanded) {
+ dat->selection = cliGetRowsPriorTo(&dat->list, group, -1);
+ selMoved = 1;
+ }
+ else if (changeGroupExpand == 1 && contact->SubExpanded) {
+ //Contract
+ ClcContact *ht = NULL;
+ KillTimer(hwnd, TIMERID_SUBEXPAND);
+ contact->SubExpanded = 0;
+ db_set_b(contact->hContact, "CList", "Expanded", 0);
+ ht = contact;
+ dat->needsResort = 1;
+ pcli->pfnSortCLC(hwnd, dat, 1);
+ cliRecalcScrollBar(hwnd, dat);
+ hitcontact = NULL;
+ }
+ else if (changeGroupExpand == 2 && contact->SubExpanded) {
+ dat->selection++;
+ selMoved = 1;
+ }
+ else if (changeGroupExpand == 2 && !contact->SubExpanded && dat->expandMeta) {
+ ClcContact *ht = NULL;
+ KillTimer(hwnd, TIMERID_SUBEXPAND);
+ contact->SubExpanded = 1;
+ db_set_b(contact->hContact, "CList", "Expanded", 1);
+ ht = contact;
+ dat->needsResort = 1;
+ pcli->pfnSortCLC(hwnd, dat, 1);
+ cliRecalcScrollBar(hwnd, dat);
+ if (ht) {
+ ClcContact *contact2;
+ ClcGroup *group2;
+ if (FindItem(hwnd, dat, contact->hContact, &contact2, &group2, NULL, FALSE)) {
+ int i = cliGetRowsPriorTo(&dat->list, group2, GetContactIndex(group2, contact2));
+ pcli->pfnEnsureVisible(hwnd, dat, i + contact->SubAllocated, 0);
+ }
+ }
+ hitcontact = NULL;
+ }
+ }
+ }
+ else {
+ if (changeGroupExpand == 1 && contact->type == CLCIT_CONTACT) {
+ if (group == &dat->list) { SetCapture(hwnd); return 0; }
+ dat->selection = cliGetRowsPriorTo(&dat->list, group, -1);
+ selMoved = 1;
+ }
+ else {
+ if (contact->type == CLCIT_GROUP) {
+ if (changeGroupExpand == 1) {
+ if (!contact->group->expanded) {
+ dat->selection--;
+ selMoved = 1;
+ }
+ else pcli->pfnSetGroupExpand(hwnd, dat, contact->group, 0);
+ }
+ else if (changeGroupExpand == 2) {
+ pcli->pfnSetGroupExpand(hwnd, dat, contact->group, 1);
+ dat->selection++;
+ selMoved = 1;
+ }
+ else { SetCapture(hwnd); return 0; }
+ }
+ }
+ }
+ }
+ if (selMoved) {
+ if (dat->selection >= pcli->pfnGetGroupContentsCount(&dat->list, 1))
+ dat->selection = pcli->pfnGetGroupContentsCount(&dat->list, 1) - 1;
+ if (dat->selection < 0) dat->selection = 0;
+ if (dat->bCompactMode)
+ SendMessage(hwnd, WM_SIZE, 0, 0);
+ CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
+ pcli->pfnEnsureVisible(hwnd, dat, dat->selection, 0);
+ UpdateWindow(hwnd);
+ SetCapture(hwnd);
+ return 0;
+ }
+ SetCapture(hwnd);
+ return 0;
+}
+
+void clcSetDelayTimer(UINT_PTR uIDEvent, HWND hwnd, int nDelay)
+{
+ KillTimer(hwnd, uIDEvent);
+ int delay = nDelay;
+ if (delay == -1) {
+ switch (uIDEvent) {
+ case TIMERID_DELAYEDRESORTCLC: delay = 10; break;
+ case TIMERID_RECALCSCROLLBAR: delay = 10; break;
+ case TIMERID_REBUILDAFTER: delay = 50; break;
+ default: delay = 100; break;
+ }
+ }
+ CLUI_SafeSetTimer(hwnd, uIDEvent, delay, NULL);
+}
+
+static LRESULT clcOnTimer(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (wParam) {
+ case TIMERID_INVALIDATE_FULL:
+ KillTimer(hwnd, TIMERID_INVALIDATE_FULL);
+ pcli->pfnRecalcScrollBar(hwnd, dat);
+ pcli->pfnInvalidateRect(hwnd, NULL, 0);
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+
+ case TIMERID_INVALIDATE:
+ {
+ time_t cur_time = (time(NULL) / 60);
+ if (cur_time != dat->last_tick_time) {
+ CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
+ dat->last_tick_time = cur_time;
+ }
+ }
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+
+ case TIMERID_SUBEXPAND:
+ KillTimer(hwnd, TIMERID_SUBEXPAND);
+ {
+ ClcContact *ht = NULL;
+ if (hitcontact && dat->expandMeta) {
+ if (hitcontact->SubExpanded) hitcontact->SubExpanded = 0; else hitcontact->SubExpanded = 1;
+ db_set_b(hitcontact->hContact, "CList", "Expanded", hitcontact->SubExpanded);
+ if (hitcontact->SubExpanded)
+ ht = &(hitcontact->subcontacts[hitcontact->SubAllocated - 1]);
+ }
+
+ dat->needsResort = 1;
+ pcli->pfnSortCLC(hwnd, dat, 1);
+ cliRecalcScrollBar(hwnd, dat);
+ if (ht) {
+ int i = 0;
+ ClcContact *contact;
+ ClcGroup *group;
+ if (FindItem(hwnd, dat, hitcontact->hContact, &contact, &group, NULL, FALSE)) {
+ i = cliGetRowsPriorTo(&dat->list, group, GetContactIndex(group, contact));
+ pcli->pfnEnsureVisible(hwnd, dat, i + hitcontact->SubAllocated, 0);
+ }
+ }
+ hitcontact = NULL;
+ }
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+
+ case TIMERID_DELAYEDRESORTCLC:
+ TRACE("Do sort on Timer\n");
+ KillTimer(hwnd, TIMERID_DELAYEDRESORTCLC);
+ pcli->pfnSortCLC(hwnd, dat, 1);
+ pcli->pfnInvalidateRect(hwnd, NULL, FALSE);
+ return 0;
+
+ case TIMERID_RECALCSCROLLBAR:
+ KillTimer(hwnd, TIMERID_RECALCSCROLLBAR);
+ pcli->pfnRecalcScrollBar(hwnd, dat);
+ return 0;
+
+ default:
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+ }
+}
+
+
+static LRESULT clcOnActivate(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ TRACE("clcOnActivate\n");
+ if (dat->bCompactMode) {
+ cliRecalcScrollBar(hwnd, dat);
+ if (dat->hwndRenameEdit == NULL)
+ PostMessage(hwnd, WM_SIZE, 0, 0);
+ }
+ dat->dragStage |= DRAGSTAGEF_SKIPRENAME;
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+}
+
+static LRESULT clcOnSetCursor(ClcData *, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (!CLUI_IsInMainWindow(hwnd))
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+
+ if (g_CluiData.nBehindEdgeState > 0)
+ CLUI_ShowFromBehindEdge();
+
+ if (g_CluiData.bBehindEdgeSettings)
+ CLUI_UpdateTimer();
+
+ int lResult = CLUI_TestCursorOnBorders();
+ return lResult ? lResult : DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+static LRESULT clcOnLButtonDown(ClcData *dat, HWND hwnd, UINT, WPARAM, LPARAM lParam)
+{
+ POINT pt = { LOWORD(lParam), HIWORD(lParam) };
+ ClientToScreen(hwnd, &pt);
+ int k = CLUI_SizingOnBorder(pt, 0);
+ if (k) {
+ int io = dat->iHotTrack;
+ dat->iHotTrack = 0;
+ if (dat->exStyle & CLS_EX_TRACKSELECT)
+ pcli->pfnInvalidateItem(hwnd, dat, io);
+
+ if (k && GetCapture() == hwnd)
+ SendMessage(GetParent(hwnd), WM_PARENTNOTIFY, WM_LBUTTONDOWN, lParam);
+ return FALSE;
+ }
+
+ fMouseUpped = FALSE;
+ pcli->pfnHideInfoTip(hwnd, dat);
+ KillTimer(hwnd, TIMERID_INFOTIP);
+ KillTimer(hwnd, TIMERID_RENAME);
+ KillTimer(hwnd, TIMERID_SUBEXPAND);
+
+ pcli->pfnEndRename(hwnd, dat, 1);
+ dat->ptDragStart.x = (short)LOWORD(lParam);
+ dat->ptDragStart.y = (short)HIWORD(lParam);
+
+ ClcContact *contact;
+ ClcGroup *group;
+ DWORD hitFlags;
+ int hit = cliHitTest(hwnd, dat, (short)LOWORD(lParam), (short)HIWORD(lParam), &contact, &group, &hitFlags);
+ if (GetFocus() != hwnd)
+ SetFocus(hwnd);
+ if (hit != -1 && !(hitFlags & CLCHT_NOWHERE)) {
+ if (hit == dat->selection && hitFlags & CLCHT_ONITEMLABEL && dat->exStyle & CLS_EX_EDITLABELS) {
+ if (!(dat->dragStage & DRAGSTAGEF_SKIPRENAME)) {
+ SetCapture(hwnd);
+ dat->iDragItem = dat->selection;
+ dat->dragStage = DRAGSTAGE_NOTMOVED | DRAGSTAGEF_MAYBERENAME;
+ dat->dragAutoScrolling = 0;
+ return TRUE;
+ }
+ else {
+ dat->dragStage &= ~DRAGSTAGEF_SKIPRENAME;
+ return TRUE;
+ }
+ }
+ }
+
+ if (hit != -1 && !(hitFlags & CLCHT_NOWHERE) && contact->type == CLCIT_CONTACT && contact->SubAllocated && !contact->isSubcontact)
+ if (hitFlags & CLCHT_ONITEMICON && dat->expandMeta) {
+ hitcontact = contact;
+ HitPoint.x = (short)LOWORD(lParam);
+ HitPoint.y = (short)HIWORD(lParam);
+ fMouseUpped = FALSE;
+ if ((GetKeyState(VK_SHIFT) & 0x8000) || (GetKeyState(VK_CONTROL) & 0x8000) || (GetKeyState(VK_MENU) & 0x8000)) {
+ fMouseUpped = TRUE;
+ hitcontact = contact;
+ KillTimer(hwnd, TIMERID_SUBEXPAND);
+ CLUI_SafeSetTimer(hwnd, TIMERID_SUBEXPAND, 0, NULL);
+ }
+ }
+ else hitcontact = NULL;
+
+ if (hit != -1 && !(hitFlags & CLCHT_NOWHERE) && contact->type == CLCIT_GROUP && (hitFlags & CLCHT_ONITEMICON)) {
+ ClcGroup *selgroup;
+ ClcContact *selcontact;
+ dat->selection = cliGetRowByIndex(dat, dat->selection, &selcontact, &selgroup);
+ pcli->pfnSetGroupExpand(hwnd, dat, contact->group, -1);
+ if (dat->selection != -1) {
+ dat->selection = cliGetRowsPriorTo(&dat->list, selgroup, GetContactIndex(selgroup, selcontact));
+ if (dat->selection == -1)
+ dat->selection = cliGetRowsPriorTo(&dat->list, contact->group, -1);
+ }
+
+ if (dat->bCompactMode)
+ SendMessage(hwnd, WM_SIZE, 0, 0);
+ else {
+ CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
+ UpdateWindow(hwnd);
+ }
+ return TRUE;
+ }
+
+ if (hit != -1 && !(hitFlags & CLCHT_NOWHERE) && (hitFlags & CLCHT_ONITEMCHECK)) {
+ int bNewState = (contact->flags & CONTACTF_CHECKED) == 0; // inversion
+
+ if (contact->type == CLCIT_GROUP)
+ pcli->pfnSetGroupChildCheckboxes(contact->group, bNewState);
+ else
+ pcli->pfnSetContactCheckboxes(contact, bNewState);
+ pcli->pfnRecalculateGroupCheckboxes(hwnd, dat);
+ CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
+
+ NMCLISTCONTROL nm;
+ nm.hdr.code = CLN_CHECKCHANGED;
+ nm.hdr.hwndFrom = hwnd;
+ nm.hdr.idFrom = GetDlgCtrlID(hwnd);
+ nm.flags = 0;
+ nm.hItem = ContactToItemHandle(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;
+ nm.hItem = (hit == -1 || hitFlags & CLCHT_NOWHERE) ? NULL : ContactToItemHandle(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))
+ return FALSE;
+
+ dat->selection = (hitFlags & CLCHT_NOWHERE) ? -1 : hit;
+ CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
+
+ UpdateWindow(hwnd);
+ if (dat->selection != -1 && (contact->type == CLCIT_CONTACT || contact->type == CLCIT_GROUP) && !(hitFlags & (CLCHT_ONITEMEXTRA | CLCHT_ONITEMCHECK | CLCHT_NOWHERE))) {
+ SetCapture(hwnd);
+ dat->iDragItem = dat->selection;
+ dat->dragStage = DRAGSTAGE_NOTMOVED;
+ dat->dragAutoScrolling = 0;
+ }
+
+ if (dat->bCompactMode)
+ SendMessage(hwnd, WM_SIZE, 0, 0);
+
+ if (dat->selection != -1)
+ pcli->pfnEnsureVisible(hwnd, dat, hit, 0);
+ return TRUE;
+}
+
+static LRESULT clcOnCaptureChanged(ClcData *dat, HWND hwnd, UINT, WPARAM, LPARAM lParam)
+{
+ if ((HWND)lParam != hwnd) {
+ if (dat->iHotTrack != -1) {
+ int i;
+ i = dat->iHotTrack;
+ dat->iHotTrack = -1;
+ pcli->pfnInvalidateItem(hwnd, dat, i);
+ pcli->pfnHideInfoTip(hwnd, dat);
+ }
+ }
+ return 0;
+}
+
+static LRESULT clcOnMouseMove(ClcData *dat, HWND hwnd, UINT, WPARAM wParam, LPARAM lParam)
+{
+ BOOL isOutside = FALSE;
+ if (CLUI_IsInMainWindow(hwnd)) {
+ if (g_CluiData.bBehindEdgeSettings)
+ CLUI_UpdateTimer();
+ CLUI_TestCursorOnBorders();
+ }
+
+ if (clcProceedDragToScroll(hwnd, (short)HIWORD(lParam)))
+ return 0;
+
+ if (dat->dragStage & DRAGSTAGEF_MAYBERENAME) {
+ POINT pt = UNPACK_POINT(lParam);
+ if (abs(pt.x - dat->ptDragStart.x) > GetSystemMetrics(SM_CXDOUBLECLK) || abs(pt.y - dat->ptDragStart.y) > GetSystemMetrics(SM_CYDOUBLECLK)) {
+ KillTimer(hwnd, TIMERID_RENAME);
+ dat->dragStage &= (~DRAGSTAGEF_MAYBERENAME);
+ }
+ }
+
+ if (dat->iDragItem == -1) {
+ POINT pt = UNPACK_POINT(lParam);
+ ClientToScreen(hwnd, &pt);
+ HWND window = WindowFromPoint(pt);
+ if (window != hwnd)
+ isOutside = TRUE;
+ }
+
+ if (hitcontact != NULL) {
+ int x = (short)LOWORD(lParam);
+ int y = (short)HIWORD(lParam);
+ int xm = GetSystemMetrics(SM_CXDOUBLECLK);
+ int ym = GetSystemMetrics(SM_CYDOUBLECLK);
+ if (abs(HitPoint.x - x) > xm || abs(HitPoint.y - y) > ym) {
+ if (fMouseUpped) {
+ KillTimer(hwnd, TIMERID_SUBEXPAND);
+ CLUI_SafeSetTimer(hwnd, TIMERID_SUBEXPAND, 0, NULL);
+ fMouseUpped = FALSE;
+ }
+ else {
+ KillTimer(hwnd, TIMERID_SUBEXPAND);
+ hitcontact = NULL;
+ fMouseUpped = FALSE;
+ }
+ }
+ }
+
+ if (dat->iDragItem == -1) {
+ DWORD flag = 0;
+ int iOldHotTrack = dat->iHotTrack;
+
+ if (dat->hwndRenameEdit != NULL || GetKeyState(VK_MENU) & 0x8000 || GetKeyState(VK_F10) & 0x8000)
+ return 0;
+
+ dat->iHotTrack = isOutside ? -1 : cliHitTest(hwnd, dat, (short)LOWORD(lParam), (short)HIWORD(lParam), NULL, NULL, &flag);
+
+ if (flag & CLCHT_NOWHERE)
+ dat->iHotTrack = -1;
+
+ if (iOldHotTrack != dat->iHotTrack || isOutside) {
+ if (iOldHotTrack == -1 && !isOutside)
+ SetCapture(hwnd);
+
+ if (dat->iHotTrack == -1 || isOutside)
+ ReleaseCapture();
+
+ if (dat->exStyle & CLS_EX_TRACKSELECT) {
+ pcli->pfnInvalidateItem(hwnd, dat, iOldHotTrack);
+ pcli->pfnInvalidateItem(hwnd, dat, dat->iHotTrack);
+ }
+
+ pcli->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);
+ CLUI_SafeSetTimer(hwnd, TIMERID_INFOTIP, dat->infoTipTimeout, NULL);
+ }
+ return 0;
+ }
+
+ 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) {
+ RECT clRect;
+ GetClientRect(hwnd, &clRect);
+
+ POINT pt = UNPACK_POINT(lParam);
+ HCURSOR hNewCursor = LoadCursor(NULL, IDC_NO);
+ CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
+ if (dat->dragAutoScrolling) {
+ KillTimer(hwnd, TIMERID_DRAGAUTOSCROLL);
+ dat->dragAutoScrolling = 0;
+ }
+ int target = GetDropTargetInformation(hwnd, dat, pt);
+ if ((dat->dragStage & DRAGSTAGEF_OUTSIDE) && target != DROPTARGET_OUTSIDE) {
+ ClcContact *contact;
+ cliGetRowByIndex(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 = ContactToItemHandle(contact, &nm.flags);
+ SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)&nm);
+ dat->dragStage &= ~DRAGSTAGEF_OUTSIDE;
+ }
+
+ ClcContact *contSour, *contDest;
+
+ switch (target) {
+ case DROPTARGET_ONSELF:
+ break;
+
+ case DROPTARGET_ONCONTACT:
+ cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
+ if (contSour->isChat())
+ break;
+ if (contSour->type == CLCIT_CONTACT && mir_strcmp(contSour->proto, META_PROTO)) {
+ if (!contSour->isSubcontact)
+ hNewCursor = LoadCursor(g_hMirApp, MAKEINTRESOURCE(IDC_DROPUSER)); /// Add to meta
+ else
+ hNewCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_DROPMETA));
+ }
+ break;
+
+ case DROPTARGET_ONMETACONTACT:
+ cliGetRowByIndex(dat, dat->selection, &contDest, NULL);
+ cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
+ if (contSour->isChat() || contDest->isChat())
+ break;
+ if (contSour->type == CLCIT_CONTACT && mir_strcmp(contSour->proto, META_PROTO)) {
+ if (!contSour->isSubcontact)
+ hNewCursor = LoadCursor(g_hMirApp, MAKEINTRESOURCE(IDC_DROPUSER)); /// Add to meta
+ else if (contSour->subcontacts == contDest)
+ hNewCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_DEFAULTSUB)); ///MakeDefault
+ else
+ hNewCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_REGROUP));
+ }
+ break;
+
+ case DROPTARGET_ONSUBCONTACT:
+ cliGetRowByIndex(dat, dat->selection, &contDest, NULL);
+ cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
+ if (contSour->isChat() || contDest->isChat())
+ break;
+ if (contSour->type == CLCIT_CONTACT && mir_strcmp(contSour->proto, META_PROTO)) {
+ if (!contSour->isSubcontact)
+ hNewCursor = LoadCursor(g_hMirApp, MAKEINTRESOURCE(IDC_DROPUSER)); /// Add to meta
+ else if (contDest->subcontacts == contSour->subcontacts)
+ break;
+ else
+ hNewCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_REGROUP));
+ }
+ break;
+
+ case DROPTARGET_ONGROUP:
+ hNewCursor = LoadCursor(g_hMirApp, MAKEINTRESOURCE(IDC_DROPUSER));
+ break;
+
+ case DROPTARGET_INSERTION:
+ hNewCursor = LoadCursor(g_hMirApp, MAKEINTRESOURCE(IDC_DROP));
+ break;
+
+ case DROPTARGET_OUTSIDE:
+ 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) {
+ dat->dragAutoScrolling = (pt.y < 0) ? -1 : 1;
+ CLUI_SafeSetTimer(hwnd, TIMERID_DRAGAUTOSCROLL, dat->scrollTime, NULL);
+ }
+ SendMessage(hwnd, WM_TIMER, TIMERID_DRAGAUTOSCROLL, 0);
+ }
+
+ dat->dragStage |= DRAGSTAGEF_OUTSIDE;
+ {
+ ClcContact *contact;
+ cliGetRowByIndex(dat, dat->iDragItem, &contact, NULL);
+
+ NMCLISTCONTROL nm;
+ nm.hdr.code = CLN_DRAGGING;
+ nm.hdr.hwndFrom = hwnd;
+ nm.hdr.idFrom = GetDlgCtrlID(hwnd);
+ nm.flags = 0;
+ nm.hItem = ContactToItemHandle(contact, &nm.flags);
+ nm.pt = pt;
+ if (SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM)&nm))
+ return 0;
+ }
+ break;
+
+ default:
+ ClcGroup *group = NULL;
+ cliGetRowByIndex(dat, dat->iDragItem, NULL, &group);
+ if (group && group->parent) {
+ cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
+ if (!contSour->isSubcontact)
+ hNewCursor = LoadCursor(g_hMirApp, MAKEINTRESOURCE(IDC_DROPUSER));
+ }
+ break;
+ }
+ SetCursor(hNewCursor);
+ }
+ return 0;
+}
+
+static LRESULT clcOnLButtonUp(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (clcExitDragToScroll())
+ return 0;
+
+ fMouseUpped = TRUE;
+
+ if (hitcontact != NULL && dat->expandMeta) {
+ BYTE doubleClickExpand = db_get_b(NULL, "CLC", "MetaDoubleClick", SETTING_METAAVOIDDBLCLICK_DEFAULT);
+ CLUI_SafeSetTimer(hwnd, TIMERID_SUBEXPAND, GetDoubleClickTime()*doubleClickExpand, NULL);
+ }
+ else if (dat->iHotTrack == -1 && dat->iDragItem == -1)
+ ReleaseCapture();
+
+ if (dat->iDragItem == -1)
+ return 0;
+
+ SetCursor((HCURSOR)GetClassLongPtr(hwnd, GCLP_HCURSOR));
+ if (dat->exStyle & CLS_EX_TRACKSELECT) {
+ DWORD flags;
+ dat->iHotTrack = cliHitTest(hwnd, dat, (short)LOWORD(lParam), (short)HIWORD(lParam), NULL, NULL, &flags);
+ if (dat->iHotTrack == -1)
+ ReleaseCapture();
+ }
+ else if (hitcontact == NULL)
+ ReleaseCapture();
+ KillTimer(hwnd, TIMERID_DRAGAUTOSCROLL);
+ if (dat->dragStage == (DRAGSTAGE_NOTMOVED | DRAGSTAGEF_MAYBERENAME))
+ CLUI_SafeSetTimer(hwnd, TIMERID_RENAME, GetDoubleClickTime(), NULL);
+ else if ((dat->dragStage & DRAGSTAGEM_STAGE) == DRAGSTAGE_ACTIVE) {
+ TCHAR Wording[500];
+ ClcContact *contDest, *contSour;
+ POINT pt = UNPACK_POINT(lParam);
+ int target = GetDropTargetInformation(hwnd, dat, pt);
+ switch (target) {
+ case DROPTARGET_ONSELF:
+ break;
+
+ case DROPTARGET_ONCONTACT:
+ cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
+ cliGetRowByIndex(dat, dat->selection, &contDest, NULL);
+ if (contSour->isChat() || contDest->isChat())
+ break;
+ if (contSour->type == CLCIT_CONTACT) {
+ MCONTACT hcontact = contSour->hContact;
+ if (mir_strcmp(contSour->proto, META_PROTO)) {
+ if (!contSour->isSubcontact) {
+ MCONTACT hDest = contDest->hContact;
+ mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be converted to metacontact and '%s' be added to it?"), contDest->szText, contSour->szText);
+ int res = MessageBox(hwnd, Wording, TranslateT("Converting to metacontact"), MB_OKCANCEL | MB_ICONQUESTION);
+ if (res == 1) {
+ MCONTACT handle = CallService(MS_MC_CONVERTTOMETA, hDest, 0);
+ if (!handle)
+ return 0;
+
+ CallService(MS_MC_ADDTOMETA, hcontact, handle);
+ }
+ }
+ else {
+ hcontact = contSour->hContact;
+ MCONTACT hdest = contDest->hContact;
+ mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be converted to metacontact and '%s' be added to it (remove it from '%s')?"), contDest->szText, contSour->szText, contSour->subcontacts->szText);
+ int res = MessageBox(hwnd, Wording, TranslateT("Converting to metacontact (moving)"), MB_OKCANCEL | MB_ICONQUESTION);
+ if (res == 1) {
+ MCONTACT handle = (MCONTACT)CallService(MS_MC_CONVERTTOMETA, (WPARAM)hdest, 0);
+ if (!handle)
+ return 0;
+
+ CallService(MS_MC_REMOVEFROMMETA, 0, hcontact);
+ CallService(MS_MC_ADDTOMETA, hcontact, handle);
+ }
+ }
+ }
+ }
+ break;
+
+ case DROPTARGET_ONMETACONTACT:
+ cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
+ cliGetRowByIndex(dat, dat->selection, &contDest, NULL);
+ if (contSour->isChat() || contDest->isChat())
+ break;
+ if (contSour->type == CLCIT_CONTACT) {
+ if (!mir_strcmp(contSour->proto, META_PROTO))
+ break;
+ if (!contSour->isSubcontact) {
+ MCONTACT hcontact = contSour->hContact;
+ MCONTACT handle = contDest->hContact;
+ mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be added to metacontact '%s'?"), contSour->szText, contDest->szText);
+ int res = MessageBox(hwnd, Wording, TranslateT("Adding contact to metacontact"), MB_OKCANCEL | MB_ICONQUESTION);
+ if (res == 1) {
+ if (!handle)
+ return 0;
+ CallService(MS_MC_ADDTOMETA, hcontact, handle);
+ }
+ }
+ else if (contSour->subcontacts == contDest) {
+ MCONTACT hsour = contSour->hContact;
+ mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be default?"), contSour->szText);
+ int res = MessageBox(hwnd, Wording, TranslateT("Set default contact"), MB_OKCANCEL | MB_ICONQUESTION);
+ if (res == 1)
+ db_mc_setDefault(contDest->hContact, hsour, true);
+ }
+ else {
+ MCONTACT hcontact = contSour->hContact;
+ MCONTACT handle = contDest->hContact;
+ mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be removed from metacontact '%s' and added to '%s'?"), contSour->szText, contSour->subcontacts->szText, contDest->szText);
+ int res = MessageBox(hwnd, Wording, TranslateT("Changing metacontacts (moving)"), MB_OKCANCEL | MB_ICONQUESTION);
+ if (res == 1) {
+ if (!handle)
+ return 0;
+
+ CallService(MS_MC_REMOVEFROMMETA, 0, hcontact);
+ CallService(MS_MC_ADDTOMETA, hcontact, handle);
+ }
+ }
+ }
+ break;
+
+ case DROPTARGET_ONSUBCONTACT:
+ cliGetRowByIndex(dat, dat->iDragItem, &contSour, NULL);
+ cliGetRowByIndex(dat, dat->selection, &contDest, NULL);
+ if (contSour->isChat() || contDest->isChat())
+ break;
+ if (contSour->type == CLCIT_CONTACT) {
+ if (!mir_strcmp(contSour->proto, META_PROTO))
+ break;
+ if (!contSour->isSubcontact) {
+ MCONTACT hcontact = contSour->hContact;
+ MCONTACT handle = contDest->subcontacts->hContact;
+ mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be added to metacontact '%s'?"), contSour->szText, contDest->subcontacts->szText);
+ int res = MessageBox(hwnd, Wording, TranslateT("Changing metacontacts (moving)"), MB_OKCANCEL | MB_ICONQUESTION);
+ if (res == 1) {
+ if (!handle)
+ return 0;
+
+ CallService(MS_MC_ADDTOMETA, hcontact, handle);
+ }
+ }
+ else if (contSour->subcontacts != contDest->subcontacts) {
+ MCONTACT hcontact = contSour->hContact;
+ MCONTACT handle = contDest->subcontacts->hContact;
+ mir_sntprintf(Wording, TranslateT("Do you want contact '%s' to be removed from metacontact '%s' and added to '%s'?"), contSour->szText, contSour->subcontacts->szText, contDest->subcontacts->szText);
+ int res = MessageBox(hwnd, Wording, TranslateT("Changing metacontacts (moving)"), MB_OKCANCEL | MB_ICONQUESTION);
+ if (res == 1) {
+ if (!handle)
+ return 0;
+
+ CallService(MS_MC_REMOVEFROMMETA, 0, hcontact);
+ CallService(MS_MC_ADDTOMETA, hcontact, handle);
+ }
+ }
+ }
+ break;
+
+ case DROPTARGET_ONGROUP:
+ corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+ break;
+
+ case DROPTARGET_INSERTION:
+ {
+ ClcContact *contact, *destcontact;
+ ClcGroup *group, *destgroup;
+ BOOL NeedRename = FALSE;
+ TCHAR newName[128] = { 0 };
+ pcli->pfnGetRowByIndex(dat, dat->iDragItem, &contact, &group);
+ int i = pcli->pfnGetRowByIndex(dat, dat->iInsertionMark, &destcontact, &destgroup);
+ if (i != -1 && group->groupId != destgroup->groupId) {
+ TCHAR *groupName = mir_tstrdup(pcli->pfnGetGroupName(contact->groupId, 0));
+ TCHAR *shortGroup = NULL;
+ TCHAR *sourceGrName = mir_tstrdup(pcli->pfnGetGroupName(destgroup->groupId, 0));
+ if (groupName) {
+ int len = (int)mir_tstrlen(groupName);
+ do { len--; } while (len >= 0 && groupName[len] != '\\');
+ if (len >= 0) shortGroup = groupName + len + 1;
+ else shortGroup = groupName;
+ }
+ if (shortGroup) {
+ NeedRename = TRUE;
+ if (sourceGrName)
+ mir_sntprintf(newName, _T("%s\\%s"), sourceGrName, shortGroup);
+ else
+ mir_tstrncpy(newName, shortGroup, _countof(newName));
+ }
+ mir_free(groupName);
+ mir_free(sourceGrName);
+ }
+ int newIndex = CallService(MS_CLIST_GROUPMOVEBEFORE, contact->groupId, (destcontact && i != -1) ? destcontact->groupId : 0);
+ newIndex = newIndex ? newIndex : contact->groupId;
+ if (NeedRename) pcli->pfnRenameGroup(newIndex, newName);
+ }
+ break;
+
+ case DROPTARGET_OUTSIDE:
+ corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+ break;
+
+ default:
+ corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+ break;
+ }
+ }
+
+ CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
+ dat->iDragItem = -1;
+ dat->iInsertionMark = -1;
+ return 0;
+}
+
+static LRESULT clcOnLButtonDblClick(ClcData *, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ KillTimer(hwnd, TIMERID_SUBEXPAND);
+ hitcontact = NULL;
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+}
+
+static LRESULT clcOnDestroy(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ for (int i = 0; i <= FONTID_MODERN_MAX; i++) {
+ if (dat->fontModernInfo[i].hFont)
+ DeleteObject(dat->fontModernInfo[i].hFont);
+ dat->fontModernInfo[i].hFont = NULL;
+ }
+ if (dat->hMenuBackground) {
+ DeleteObject(dat->hMenuBackground);
+ dat->hMenuBackground = NULL;
+ }
+ if (dat->hBmpBackground) {
+ DeleteObject(dat->hBmpBackground);
+ dat->hBmpBackground = NULL;
+ }
+
+ ImageArray_Clear(&dat->avatar_cache);
+ DeleteDC(dat->avatar_cache.hdc);
+ ImageArray_Free(&dat->avatar_cache, FALSE);
+ if (dat->himlHighlight) {
+ ImageList_Destroy(dat->himlHighlight);
+ dat->himlHighlight = NULL;
+ }
+
+ RowHeights_Free(dat);
+ corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+ xpt_FreeThemeForWindow(hwnd);
+ return 0;
+}
+
+static LRESULT clcOnIntmGroupChanged(ClcData *dat, HWND hwnd, UINT, WPARAM wParam, LPARAM)
+{
+ WORD iExtraImage[EXTRA_ICON_COUNT];
+ BYTE flags = 0;
+
+ ClcContact *contact;
+ if (!pcli->pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL))
+ memset(iExtraImage, 0xFF, sizeof(iExtraImage));
+ else {
+ memcpy(iExtraImage, contact->iExtraImage, sizeof(iExtraImage));
+ flags = contact->flags;
+ }
+ pcli->pfnDeleteItemFromTree(hwnd, wParam);
+ if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_SHOWHIDDEN || !db_get_b(wParam, "CList", "Hidden", 0)) {
+ NMCLISTCONTROL nm;
+ pcli->pfnAddContactToTree(hwnd, dat, wParam, 1, 1);
+ if (pcli->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);
+ return 0;
+}
+
+static LRESULT clcOnIntmIconChanged(ClcData *dat, HWND hwnd, UINT, WPARAM wParam, LPARAM lParam)
+{
+ ClcContact *contact = NULL;
+ ClcGroup *group = NULL;
+ int recalcScrollBar = 0, shouldShow;
+ BOOL needRepaint = FALSE;
+ int contacticon = corecli.pfnGetContactIcon(wParam);
+ MCONTACT hSelItem = NULL;
+ ClcContact *selcontact = NULL;
+
+ char *szProto = GetContactProto(wParam);
+ WORD status = (szProto == NULL) ? ID_STATUS_OFFLINE : GetContactCachedStatus(wParam);
+ BOOL image_is_special = (LOWORD(contacticon) != (LOWORD(lParam))); //check only base icons
+
+ int nHiddenStatus = CLVM_GetContactHiddenStatus(wParam, szProto, dat);
+
+ DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE);
+ bool isVisiblebyFilter = (((style & CLS_SHOWHIDDEN) && nHiddenStatus != -1) || !nHiddenStatus);
+ bool ifVisibleByClui = !pcli->pfnIsHiddenMode(dat, status);
+ bool isVisible = g_CluiData.bFilterEffective&CLVM_FILTER_STATUS ? TRUE : ifVisibleByClui;
+ bool isIconChanged = cli_GetContactIcon(wParam) != LOWORD(lParam);
+
+ shouldShow = isVisiblebyFilter && (isVisible || isIconChanged);
+
+ // XXX CLVM changed - this means an offline msg is flashing, so the contact should be shown
+
+ if (!pcli->pfnFindItem(hwnd, dat, wParam, &contact, &group, NULL)) {
+ if (shouldShow && CallService(MS_DB_CONTACT_IS, wParam, 0)) {
+ if (dat->selection >= 0 && pcli->pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) != -1)
+ hSelItem = (DWORD_PTR)pcli->pfnContactToHItem(selcontact);
+ pcli->pfnAddContactToTree(hwnd, dat, wParam, (style & CLS_CONTACTLIST) == 0, 0);
+ recalcScrollBar = 1;
+ needRepaint = TRUE;
+ pcli->pfnFindItem(hwnd, dat, wParam, &contact, NULL, NULL);
+ if (contact) {
+ contact->iImage = lParam;
+ contact->image_is_special = image_is_special;
+ pcli->pfnNotifyNewContact(hwnd, wParam);
+ dat->needsResort = 1;
+ }
+ }
+ }
+ else {
+ //item in list already
+ if (contact && contact->iImage == lParam)
+ return 0;
+
+ if (!shouldShow && !(style & CLS_NOHIDEOFFLINE) && (style & CLS_HIDEOFFLINE || group->hideOffline) && clcItemNotHiddenOffline(group, contact))
+ shouldShow = TRUE;
+
+ if (!shouldShow && !(style & CLS_NOHIDEOFFLINE) && ((style & CLS_HIDEOFFLINE) || group->hideOffline || g_CluiData.bFilterEffective)) { // CLVM changed
+ if (dat->selection >= 0 && pcli->pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) != -1)
+ hSelItem = (DWORD_PTR)pcli->pfnContactToHItem(selcontact);
+ pcli->pfnRemoveItemFromGroup(hwnd, group, contact, (style & CLS_CONTACTLIST) == 0);
+ needRepaint = TRUE;
+ recalcScrollBar = 1;
+ dat->needsResort = 1;
+ }
+ else if (contact) {
+ contact->iImage = lParam;
+ if (!pcli->pfnIsHiddenMode(dat, status))
+ contact->flags |= CONTACTF_ONLINE;
+ else
+ contact->flags &= ~CONTACTF_ONLINE;
+ contact->image_is_special = image_is_special;
+ if (!image_is_special) { //Only if it is status changing
+ dat->needsResort = 1;
+ needRepaint = TRUE;
+ }
+ else if (dat->m_paintCouter == contact->lastPaintCounter) //if contacts is visible
+ needRepaint = TRUE;
+ }
+ }
+
+ if (hSelItem) {
+ ClcGroup *selgroup;
+ if (pcli->pfnFindItem(hwnd, dat, hSelItem, &selcontact, &selgroup, NULL))
+ dat->selection = pcli->pfnGetRowsPriorTo(&dat->list, selgroup, List_IndexOf((SortedList*)&selgroup->cl, selcontact));
+ else
+ dat->selection = -1;
+ }
+
+ if (dat->needsResort) {
+ TRACE("Sort required\n");
+ clcSetDelayTimer(TIMERID_DELAYEDRESORTCLC, hwnd);
+ }
+ else if (needRepaint) {
+ if (contact && contact->pos_icon.bottom != 0 && contact->pos_icon.right != 0)
+ CLUI__cliInvalidateRect(hwnd, &(contact->pos_icon), FALSE);
+ else
+ CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
+ //try only needed rectangle
+ }
+
+ return 0;
+}
+
+static LRESULT clcOnIntmAvatarChanged(ClcData *dat, HWND hwnd, UINT, WPARAM hContact, LPARAM)
+{
+ ClcContact *contact;
+ if (FindItem(hwnd, dat, hContact, &contact, NULL, NULL, FALSE))
+ Cache_GetAvatar(dat, contact);
+ else if (hContact == 0)
+ UpdateAllAvatars(dat);
+
+ CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
+ return 0;
+}
+
+static LRESULT clcOnIntmTimeZoneChanged(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ ClcContact *contact;
+ if (!FindItem(hwnd, dat, wParam, &contact, NULL, NULL, FALSE))
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+
+ if (contact) {
+ Cache_GetTimezone(dat, contact->hContact);
+ Cache_GetText(dat, contact, 1);
+ cliRecalcScrollBar(hwnd, dat);
+ }
+ return 0;
+}
+
+static LRESULT clcOnIntmNameChanged(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ int ret = corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+
+ pcli->pfnInvalidateDisplayNameCacheEntry(wParam);
+
+ ClcContact *contact;
+ if (!FindItem(hwnd, dat, wParam, &contact, NULL, NULL, FALSE))
+ return ret;
+
+ if (contact) {
+ mir_tstrncpy(contact->szText, pcli->pfnGetContactDisplayName(wParam, 0), _countof(contact->szText));
+ Cache_GetText(dat, contact, 1);
+ cliRecalcScrollBar(hwnd, dat);
+ }
+
+ dat->needsResort = 1;
+ return ret;
+}
+
+static LRESULT clcOnIntmApparentModeChanged(ClcData *, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+}
+
+static LRESULT clcOnIntmStatusMsgChanged(ClcData *dat, HWND hwnd, UINT msg, WPARAM hContact, LPARAM lParam)
+{
+ if (hContact == NULL || IsHContactInfo(hContact) || IsHContactGroup(hContact))
+ return corecli.pfnContactListControlWndProc(hwnd, msg, hContact, lParam);
+
+ ClcContact *contact;
+ if (!FindItem(hwnd, dat, hContact, &contact, NULL, NULL, FALSE))
+ return corecli.pfnContactListControlWndProc(hwnd, msg, hContact, lParam);
+
+ if (contact) {
+ Cache_GetText(dat, contact, 1);
+ cliRecalcScrollBar(hwnd, dat);
+ PostMessage(hwnd, INTM_INVALIDATE, 0, 0);
+ }
+ return corecli.pfnContactListControlWndProc(hwnd, msg, hContact, lParam);
+}
+
+static LRESULT clcOnIntmNotOnListChanged(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING*)lParam;
+
+ ClcContact *contact;
+ if (!FindItem(hwnd, dat, wParam, &contact, NULL, NULL, TRUE))
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+
+ if (contact->type != CLCIT_CONTACT)
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+
+ if (dbcws->value.type == DBVT_DELETED || dbcws->value.bVal == 0)
+ contact->flags &= ~CONTACTF_NOTONLIST;
+ else
+ contact->flags |= CONTACTF_NOTONLIST;
+
+ CLUI__cliInvalidateRect(hwnd, NULL, FALSE);
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+}
+
+static LRESULT clcOnIntmScrollBarChanged(ClcData *dat, HWND hwnd, UINT, WPARAM, LPARAM)
+{
+ if (GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_CONTACTLIST) {
+ if (dat->noVScrollbar)
+ ShowScrollBar(hwnd, SB_VERT, FALSE);
+ else
+ pcli->pfnRecalcScrollBar(hwnd, dat);
+ }
+ return 0;
+}
+
+static LRESULT clcOnIntmStatusChanged(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ int ret = corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+ if (wParam != 0) {
+ ClcCacheEntry *pdnce = pcli->pfnGetCacheEntry(wParam);
+ if (pdnce && pdnce->m_pszProto) {
+ pdnce->m_iStatus = GetStatusForContact(pdnce->hContact, pdnce->m_pszProto);
+ if (!dat->force_in_dialog && (dat->second_line_show || dat->third_line_show))
+ gtaRenewText(pdnce->hContact);
+ SendMessage(hwnd, INTM_ICONCHANGED, wParam, corecli.pfnGetContactIcon(wParam));
+
+ ClcContact *contact;
+ if (FindItem(hwnd, dat, wParam, &contact, NULL, NULL, TRUE)) {
+ if (contact && contact->type == CLCIT_CONTACT) {
+ if (!contact->image_is_special && pdnce->getStatus() > ID_STATUS_OFFLINE)
+ contact->iImage = corecli.pfnGetContactIcon(wParam);
+ if (contact->isSubcontact && contact->subcontacts && contact->subcontacts->type == CLCIT_CONTACT)
+ pcli->pfnClcBroadcast(INTM_STATUSCHANGED, contact->subcontacts->hContact, 0); //forward status changing to host meta contact
+ }
+ }
+ }
+ }
+
+ if (db_get_b(NULL, "CList", "PlaceOfflineToRoot", SETTING_PLACEOOFLINETOROOT_DEFAULT))
+ pcli->pfnInitAutoRebuild(hwnd);
+ else
+ PostMessage(hwnd, INTM_INVALIDATE, 0, 0);
+
+ return ret;
+}
+
+static LRESULT clcOnIntmReloadOptions(ClcData *dat, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+ pcli->pfnLoadClcOptions(hwnd, dat, FALSE);
+ LoadCLCOptions(hwnd, dat, FALSE);
+ pcli->pfnSaveStateAndRebuildList(hwnd, dat);
+ pcli->pfnSortCLC(hwnd, dat, 1);
+ if (IsWindowVisible(hwnd))
+ pcli->pfnInvalidateRect(GetParent(hwnd), NULL, FALSE);
+ return TRUE;
+}
+
+static int clcHookModulesLoaded(WPARAM, LPARAM)
+{
+ if (MirandaExiting())
+ return 0;
+
+ if (!ServiceExists(MS_AV_GETAVATARBITMAP))
+ MessageBox(NULL,
+ TranslateT("Clist Modern requires AVS plugin to be present. Install it using PluginUpdater or download from http://wiki.miranda-ng.org/Download"),
+ TranslateT("Error loading plugin"), MB_ICONERROR | MB_OK);
+
+ HookEvent(ME_AV_AVATARCHANGED, clcHookAvatarChanged);
+
+ HookEvent(ME_MODERNOPT_INITIALIZE, ModernOptInit);
+ HookEvent(ME_MODERNOPT_INITIALIZE, ModernSkinOptInit);
+
+ HookEvent(ME_FOLDERS_PATH_CHANGED, ReloadSkinFolder);
+ hSkinFolder = FoldersRegisterCustomPathT(LPGEN("Skins"), LPGEN("Modern contact list"), MIRANDA_PATHT _T("\\") _T(DEFAULT_SKIN_FOLDER));
+ FoldersGetCustomPathT(hSkinFolder, SkinsFolder, _countof(SkinsFolder), _T(DEFAULT_SKIN_FOLDER));
+
+ // Get icons
+ TCHAR szMyPath[MAX_PATH];
+ GetModuleFileName(g_hInst, szMyPath, _countof(szMyPath));
+
+ SKINICONDESC sid = { 0 };
+ sid.defaultFile.t = szMyPath;
+ sid.flags = SIDF_PATH_TCHAR;
+
+ sid.section.a = LPGEN("Contact list");
+ sid.description.a = LPGEN("Listening to");
+ sid.pszName = "LISTENING_TO_ICON";
+ sid.iDefaultIndex = -IDI_LISTENING_TO;
+ IcoLib_AddIcon(&sid);
+
+ sid.section.a = LPGEN("Contact list") "/" LPGEN("Avatar overlay");
+ for (int i = 0; i < _countof(g_pAvatarOverlayIcons); i++) {
+ sid.description.a = g_pAvatarOverlayIcons[i].description;
+ sid.pszName = g_pAvatarOverlayIcons[i].name;
+ sid.iDefaultIndex = -g_pAvatarOverlayIcons[i].id;
+ IcoLib_AddIcon(&sid);
+ }
+
+ sid.section.a = LPGEN("Contact list") "/" LPGEN("Status overlay");
+ for (int i = 0; i < _countof(g_pStatusOverlayIcons); i++) {
+ sid.description.a = g_pStatusOverlayIcons[i].description;
+ sid.pszName = g_pStatusOverlayIcons[i].name;
+ sid.iDefaultIndex = -g_pStatusOverlayIcons[i].id;
+ IcoLib_AddIcon(&sid);
+ }
+
+ clcHookIconsChanged(0, 0);
+
+ HookEvent(ME_SKIN2_ICONSCHANGED, clcHookIconsChanged);
+
+ // Register smiley category
+ if (ServiceExists(MS_SMILEYADD_REGISTERCATEGORY)) {
+ SMADD_REGCAT rc;
+ rc.cbSize = sizeof(rc);
+ rc.name = "clist";
+ rc.dispname = Translate("Contact list smileys");
+
+ CallService(MS_SMILEYADD_REGISTERCATEGORY, 0, (LPARAM)&rc);
+
+ HookEvent(ME_SMILEYADD_OPTIONSCHANGED, clcHookSmileyAddOptionsChanged);
+ }
+
+ CallService(MS_BACKGROUNDCONFIG_REGISTER, (WPARAM)(LPGEN("List background")"/CLC"), 0);
+ CallService(MS_BACKGROUNDCONFIG_REGISTER, (WPARAM)(LPGEN("Menu background")"/Menu"), 0);
+ CallService(MS_BACKGROUNDCONFIG_REGISTER, (WPARAM)(LPGEN("Status bar background")"/StatusBar"), 0);
+ CallService(MS_BACKGROUNDCONFIG_REGISTER, (WPARAM)(LPGEN("Frames title bar background")"/FrameTitleBar"), 0);
+
+ HookEvent(ME_BACKGROUNDCONFIG_CHANGED, clcHookBkgndConfigChanged);
+ HookEvent(ME_BACKGROUNDCONFIG_CHANGED, BgStatusBarChange);
+ HookEvent(ME_BACKGROUNDCONFIG_CHANGED, OnFrameTitleBarBackgroundChange);
+ HookEvent(ME_COLOUR_RELOAD, OnFrameTitleBarBackgroundChange);
+
+ AniAva_UpdateOptions();
+ return 0;
+}
+
+HRESULT ClcLoadModule()
+{
+ g_himlCListClc = (HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0);
+
+ HookEvent(ME_MC_SUBCONTACTSCHANGED, clcMetacontactChanged);
+ HookEvent(ME_MC_ENABLED, clcMetaModeChanged);
+ HookEvent(ME_DB_CONTACT_SETTINGCHANGED, clcHookSettingChanged);
+ HookEvent(ME_OPT_INITIALISE, ClcOptInit);
+ HookEvent(ME_PROTO_ACK, clcHookProtoAck);
+ HookEvent(ME_SYSTEM_MODULESLOADED, clcHookModulesLoaded);
+ HookEvent(ME_DB_EVENT_ADDED, clcHookDbEventAdded);
+ return S_OK;
+}
+
+int ClcUnloadModule()
+{
+ if (g_CluiData.bOldUseGroups != (BYTE)-1)
+ db_set_b(NULL, "CList", "UseGroups", (BYTE)g_CluiData.bOldUseGroups);
+ if (g_CluiData.boldHideOffline != (BYTE)-1)
+ db_set_b(NULL, "CList", "HideOffline", (BYTE)g_CluiData.boldHideOffline);
+
+ return 0;
+}
+
+int ClcDoProtoAck(MCONTACT, ACKDATA *ack)
+{
+ if (MirandaExiting()) return 0;
+ if (ack->type == ACKTYPE_STATUS) {
+ if (ack->result == ACKRESULT_SUCCESS) {
+ for (int i = 0; i < pcli->hClcProtoCount; i++) {
+ if (!mir_strcmp(pcli->clcProto[i].szProto, ack->szModule)) {
+ pcli->clcProto[i].dwStatus = (WORD)ack->lParam;
+ if (pcli->clcProto[i].dwStatus >= ID_STATUS_OFFLINE)
+ pcli->pfnTrayIconUpdateBase(pcli->clcProto[i].szProto);
+ return 0;
+ }
+ }
+ }
+ }
+ else if (ack->type == ACKTYPE_AWAYMSG) {
+ if (ack->result == ACKRESULT_SUCCESS && ack->lParam) {
+ if (ack->szModule != NULL)
+ if (db_get_b(ack->hContact, ack->szModule, "ChatRoom", 0) != 0)
+ return 0;
+
+ db_set_ws(ack->hContact, "CList", "StatusMsg", (const TCHAR *)ack->lParam);
+ gtaRenewText(ack->hContact);
+ }
+ else {
+ if (ack->szModule != NULL)
+ if (db_get_b(ack->hContact, ack->szModule, "ChatRoom", 0) != 0)
+ return 0;
+
+ if (ack->hContact) {
+ char *val = db_get_sa(ack->hContact, "CList", "StatusMsg");
+ if (val) {
+ if (mir_strcmpi(val, ""))
+ db_set_s(ack->hContact, "CList", "StatusMsg", "");
+ else
+ gtaRenewText(ack->hContact);
+ mir_free(val);
+ }
+ }
+ }
+ }
+ else if (ack->type == ACKTYPE_EMAIL) {
+ CLUIUnreadEmailCountChanged(0, 0);
+ }
+ return 0;
+}
+
+int ClcGetShortData(ClcData* pData, SHORTDATA *pShortData)
+{
+ if (!pData || !pShortData)
+ return -1;
+
+ pShortData->hWnd = pData->hWnd;
+ pShortData->text_replace_smileys = pData->text_replace_smileys;
+ pShortData->text_smiley_height = pData->text_smiley_height;
+ pShortData->text_use_protocol_smileys = pData->text_use_protocol_smileys;
+ pShortData->contact_time_show_only_if_different = pData->contact_time_show_only_if_different;
+
+ // Second line
+ pShortData->second_line_show = pData->second_line_show;
+ pShortData->second_line_draw_smileys = pData->second_line_draw_smileys;
+ pShortData->second_line_type = pData->second_line_type;
+
+ mir_tstrncpy(pShortData->second_line_text, pData->second_line_text, _countof(pShortData->second_line_text));
+
+ pShortData->second_line_xstatus_has_priority = pData->second_line_xstatus_has_priority;
+ pShortData->second_line_show_status_if_no_away = pData->second_line_show_status_if_no_away;
+ pShortData->second_line_show_listening_if_no_away = pData->second_line_show_listening_if_no_away;
+ pShortData->second_line_use_name_and_message_for_xstatus = pData->second_line_use_name_and_message_for_xstatus;
+
+ // Third line
+ pShortData->third_line_show = pData->third_line_show;
+ pShortData->third_line_draw_smileys = pData->third_line_draw_smileys;
+ pShortData->third_line_type = pData->third_line_type;
+
+ mir_tstrncpy(pShortData->third_line_text, pData->third_line_text, _countof(pShortData->third_line_text));
+
+ pShortData->third_line_xstatus_has_priority = pData->third_line_xstatus_has_priority;
+ pShortData->third_line_show_status_if_no_away = pData->third_line_show_status_if_no_away;
+ pShortData->third_line_show_listening_if_no_away = pData->third_line_show_listening_if_no_away;
+ pShortData->third_line_use_name_and_message_for_xstatus = pData->third_line_use_name_and_message_for_xstatus;
+ return 0;
+}
+
+int ClcEnterDragToScroll(HWND hwnd, int Y)
+{
+ if (IsDragToScrollMode)
+ return 0;
+
+ ClcData *dat = (ClcData*)GetWindowLongPtr(hwnd, 0);
+ if (!dat)
+ return 0;
+
+ StartDragPos = Y;
+ StartScrollPos = dat->yScroll;
+ IsDragToScrollMode = 1;
+ SetCapture(hwnd);
+ return 1;
+}
+
+
+/*
+* Contact list control window procedure
+*/
+LRESULT CALLBACK cli_ContactListControlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+
+#define CASE_MSG_RET(msg, handler) case msg: return handler(dat, hwnd, msg, wParam, lParam);
+
+ ClcData *dat = (ClcData*)GetWindowLongPtr(hwnd, 0);
+
+ if (msg >= CLM_FIRST && msg < CLM_LAST)
+ return cli_ProcessExternalMessages(hwnd, dat, msg, wParam, lParam);
+
+ switch (msg) {
+ CASE_MSG_RET(INTM_GROUPCHANGED, clcOnIntmGroupChanged);
+ CASE_MSG_RET(INTM_ICONCHANGED, clcOnIntmIconChanged);
+ CASE_MSG_RET(INTM_AVATARCHANGED, clcOnIntmAvatarChanged);
+ CASE_MSG_RET(INTM_TIMEZONECHANGED, clcOnIntmTimeZoneChanged);
+ CASE_MSG_RET(INTM_NAMECHANGED, clcOnIntmNameChanged);
+ CASE_MSG_RET(INTM_APPARENTMODECHANGED, clcOnIntmApparentModeChanged);
+ CASE_MSG_RET(INTM_STATUSMSGCHANGED, clcOnIntmStatusMsgChanged);
+ CASE_MSG_RET(INTM_NOTONLISTCHANGED, clcOnIntmNotOnListChanged);
+ CASE_MSG_RET(INTM_SCROLLBARCHANGED, clcOnIntmScrollBarChanged);
+ CASE_MSG_RET(INTM_STATUSCHANGED, clcOnIntmStatusChanged);
+ CASE_MSG_RET(INTM_RELOADOPTIONS, clcOnIntmReloadOptions);
+
+ CASE_MSG_RET(WM_CREATE, clcOnCreate);
+ CASE_MSG_RET(WM_NCHITTEST, clcOnHitTest);
+ CASE_MSG_RET(WM_COMMAND, clcOnCommand);
+ CASE_MSG_RET(WM_SIZE, clcOnSize);
+ CASE_MSG_RET(WM_CHAR, clcOnChar);
+ CASE_MSG_RET(WM_PAINT, clcOnPaint);
+ CASE_MSG_RET(WM_ERASEBKGND, clcOnEraseBkGround);
+ CASE_MSG_RET(WM_KEYDOWN, clcOnKeyDown);
+ CASE_MSG_RET(WM_TIMER, clcOnTimer);
+ CASE_MSG_RET(WM_ACTIVATE, clcOnActivate);
+ CASE_MSG_RET(WM_SETCURSOR, clcOnSetCursor);
+ CASE_MSG_RET(WM_LBUTTONDOWN, clcOnLButtonDown);
+ CASE_MSG_RET(WM_CAPTURECHANGED, clcOnCaptureChanged);
+ CASE_MSG_RET(WM_MOUSEMOVE, clcOnMouseMove);
+ CASE_MSG_RET(WM_LBUTTONUP, clcOnLButtonUp);
+ CASE_MSG_RET(WM_LBUTTONDBLCLK, clcOnLButtonDblClick);
+ CASE_MSG_RET(WM_DESTROY, clcOnDestroy);
+
+ default:
+ return corecli.pfnContactListControlWndProc(hwnd, msg, wParam, lParam);
+ }
+}
diff --git a/plugins/Clist_modern/src/modern_clcitems.cpp b/plugins/Clist_modern/src/modern_clcitems.cpp
index 2a9c992cf6..087d67ab56 100644
--- a/plugins/Clist_modern/src/modern_clcitems.cpp
+++ b/plugins/Clist_modern/src/modern_clcitems.cpp
@@ -1,750 +1,749 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-16 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-08 Miranda ICQ/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 "stdafx.h"
-#include "modern_clc.h"
-#include "modern_clist.h"
-#include "m_metacontacts.h"
-#include "modern_commonprototypes.h"
-
-void AddSubcontacts(ClcData *dat, ClcContact *cont, BOOL showOfflineHereGroup)
-{
- ClcCacheEntry *cacheEntry = pcli->pfnGetCacheEntry(cont->hContact);
- cont->SubExpanded = (db_get_b(cont->hContact, "CList", "Expanded", 0) && (db_get_b(NULL, "CLC", "MetaExpanding", SETTING_METAEXPANDING_DEFAULT)));
- int subcount = db_mc_getSubCount(cont->hContact);
- if (subcount <= 0) {
- cont->isSubcontact = 0;
- cont->subcontacts = NULL;
- cont->SubAllocated = 0;
- return;
- }
-
- cont->isSubcontact = 0;
- mir_free(cont->subcontacts);
- cont->subcontacts = (ClcContact *)mir_calloc(sizeof(ClcContact)*subcount);
- cont->SubAllocated = subcount;
- int i = 0;
- int bHideOffline = db_get_b(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT);
- for (int j = 0; j < subcount; j++) {
- MCONTACT hsub = db_mc_getSub(cont->hContact, j);
- cacheEntry = pcli->pfnGetCacheEntry(hsub);
- WORD wStatus = cacheEntry->getStatus();
-
- if (!showOfflineHereGroup && bHideOffline && !cacheEntry->m_bNoHiddenOffline && wStatus == ID_STATUS_OFFLINE)
- continue;
-
- ClcContact& p = cont->subcontacts[i];
- p.hContact = cacheEntry->hContact;
-
- p.avatar_pos = AVATAR_POS_DONT_HAVE;
- Cache_GetAvatar(dat, &p);
-
- p.iImage = corecli.pfnGetContactIcon(cacheEntry->hContact);
- memset(p.iExtraImage, 0xFF, sizeof(p.iExtraImage));
- p.proto = cacheEntry->m_pszProto;
- p.type = CLCIT_CONTACT;
- p.flags = 0;//CONTACTF_ONLINE;
- p.isSubcontact = i + 1;
- p.lastPaintCounter = 0;
- p.subcontacts = cont;
- p.image_is_special = FALSE;
- //p.status = cacheEntry->status;
- Cache_GetTimezone(dat, (&p)->hContact);
- Cache_GetText(dat, &p, 1);
-
- char *szProto = cacheEntry->m_pszProto;
- if (szProto != NULL && !pcli->pfnIsHiddenMode(dat, wStatus))
- p.flags |= CONTACTF_ONLINE;
- int apparentMode = szProto != NULL ? cacheEntry->ApparentMode : 0;
- if (apparentMode == ID_STATUS_OFFLINE) p.flags |= CONTACTF_INVISTO;
- else if (apparentMode == ID_STATUS_ONLINE) p.flags |= CONTACTF_VISTO;
- else if (apparentMode) p.flags |= CONTACTF_VISTO | CONTACTF_INVISTO;
- if (cacheEntry->NotOnList) p.flags |= CONTACTF_NOTONLIST;
- int idleMode = szProto != NULL ? cacheEntry->IdleTS : 0;
- if (idleMode) p.flags |= CONTACTF_IDLE;
- i++;
- }
-
- cont->SubAllocated = i;
- if (!i && cont->subcontacts != NULL)
- mir_free_and_nil(cont->subcontacts);
-}
-
-int cli_AddItemToGroup(ClcGroup *group, int iAboveItem)
-{
- if (group == NULL)
- return 0;
-
- iAboveItem = corecli.pfnAddItemToGroup(group, iAboveItem);
- ClearRowByIndexCache();
- return iAboveItem;
-}
-
-ClcGroup* cli_AddGroup(HWND hwnd, ClcData *dat, const TCHAR *szName, DWORD flags, int groupId, int calcTotalMembers)
-{
- ClearRowByIndexCache();
- if (!dat->force_in_dialog && !(GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_SHOWHIDDEN))
- if (!mir_tstrcmp(_T("-@-HIDDEN-GROUP-@-"), szName)) { //group is hidden
- ClearRowByIndexCache();
- return NULL;
- }
-
- ClcGroup *result = corecli.pfnAddGroup(hwnd, dat, szName, flags, groupId, calcTotalMembers);
- ClearRowByIndexCache();
- return result;
-}
-
-void cli_FreeContact(ClcContact *p)
-{
- if (p->SubAllocated) {
- if (p->subcontacts && !p->isSubcontact) {
- for (int i = 0; i < p->SubAllocated; i++) {
- p->subcontacts[i].ssText.DestroySmileyList();
- if (p->subcontacts[i].avatar_pos == AVATAR_POS_ANIMATED)
- AniAva_RemoveAvatar(p->subcontacts[i].hContact);
- p->subcontacts[i].avatar_pos = AVATAR_POS_DONT_HAVE;
- }
- mir_free_and_nil(p->subcontacts);
- }
- p->SubAllocated = 0;
- }
-
- p->ssText.DestroySmileyList();
- if (p->avatar_pos == AVATAR_POS_ANIMATED)
- AniAva_RemoveAvatar(p->hContact);
- p->avatar_pos = AVATAR_POS_DONT_HAVE;
- corecli.pfnFreeContact(p);
-}
-
-void cli_FreeGroup(ClcGroup* group)
-{
- corecli.pfnFreeGroup(group);
- ClearRowByIndexCache();
-}
-
-int cli_AddInfoItemToGroup(ClcGroup *group, int flags, const TCHAR *pszText)
-{
- int i = corecli.pfnAddInfoItemToGroup(group, flags, pszText);
- ClearRowByIndexCache();
- return i;
-}
-
-static void _LoadDataToContact(ClcContact *cont, ClcGroup *group, ClcData *dat, MCONTACT hContact)
-{
- if (!cont)
- return;
-
- cont->type = CLCIT_CONTACT;
- cont->SubAllocated = 0;
- cont->isSubcontact = 0;
- cont->subcontacts = NULL;
- cont->szText[0] = 0;
- cont->lastPaintCounter = 0;
- cont->image_is_special = FALSE;
- cont->hContact = hContact;
-
- pcli->pfnInvalidateDisplayNameCacheEntry(hContact);
-
- ClcCacheEntry *cacheEntry = pcli->pfnGetCacheEntry(hContact);
- char *szProto = cacheEntry->m_pszProto;
- cont->proto = szProto;
-
- if (szProto != NULL && !pcli->pfnIsHiddenMode(dat, cacheEntry->m_iStatus))
- cont->flags |= CONTACTF_ONLINE;
-
- WORD apparentMode = szProto != NULL ? cacheEntry->ApparentMode : 0;
- if (apparentMode)
- switch (apparentMode) {
- case ID_STATUS_OFFLINE:
- cont->flags |= CONTACTF_INVISTO;
- break;
- case ID_STATUS_ONLINE:
- cont->flags |= CONTACTF_VISTO;
- break;
- default:
- cont->flags |= CONTACTF_VISTO | CONTACTF_INVISTO;
- }
-
- if (cacheEntry->NotOnList)
- cont->flags |= CONTACTF_NOTONLIST;
-
- DWORD idleMode = szProto != NULL ? cacheEntry->IdleTS : 0;
- if (idleMode)
- cont->flags |= CONTACTF_IDLE;
-
- // Add subcontacts
- if (szProto)
- if (dat->IsMetaContactsEnabled && mir_strcmp(cont->proto, META_PROTO) == 0)
- AddSubcontacts(dat, cont, CLCItems_IsShowOfflineGroup(group));
-
- cont->lastPaintCounter = 0;
- cont->avatar_pos = AVATAR_POS_DONT_HAVE;
- Cache_GetAvatar(dat, cont);
- Cache_GetText(dat, cont, 1);
- Cache_GetTimezone(dat, cont->hContact);
- cont->iImage = corecli.pfnGetContactIcon(hContact);
- cont->bContactRate = db_get_b(hContact, "CList", "Rate", 0);
-}
-
-static ClcContact* AddContactToGroup(ClcData *dat, ClcGroup *group, ClcCacheEntry *cacheEntry)
-{
- if (cacheEntry == NULL || group == NULL || dat == NULL)
- return NULL;
-
- MCONTACT hContact = cacheEntry->hContact;
- dat->needsResort = 1;
- int i;
- for (i = group->cl.count - 1; i >= 0; i--)
- if (group->cl.items[i]->type != CLCIT_INFO || !(group->cl.items[i]->flags & CLCIIF_BELOWCONTACTS))
- break;
- i = cli_AddItemToGroup(group, i + 1);
-
- _LoadDataToContact(group->cl.items[i], group, dat, hContact);
- cacheEntry = pcli->pfnGetCacheEntry(hContact);
- ClearRowByIndexCache();
- return group->cl.items[i];
-}
-
-void* AddTempGroup(HWND hwnd, ClcData *dat, const TCHAR *szName)
-{
- if (wildcmp(_T2A(szName), "-@-HIDDEN-GROUP-@-"))
- return NULL;
-
- int i;
- DWORD groupFlags;
- for (i = 1;; i++) {
- TCHAR *szGroupName = pcli->pfnGetGroupName(i, &groupFlags);
- if (szGroupName == NULL)
- break;
- if (!mir_tstrcmpi(szGroupName, szName))
- return NULL;
- }
-
- char buf[20];
- _itoa_s(i - 1, buf, 10);
-
- TCHAR b2[255];
- mir_sntprintf(b2, _T("#%s"), szName);
- b2[0] = 1 | GROUPF_EXPANDED;
- db_set_ts(NULL, "CListGroups", buf, b2);
- pcli->pfnGetGroupName(i, &groupFlags);
- return cli_AddGroup(hwnd, dat, szName, groupFlags, i, 0);
-}
-
-void cli_AddContactToTree(HWND hwnd, ClcData *dat, MCONTACT hContact, int updateTotalCount, int checkHideOffline)
-{
- ClcCacheEntry *cacheEntry = pcli->pfnGetCacheEntry(hContact);
- if (dat->IsMetaContactsEnabled && cacheEntry && cacheEntry->m_bIsSub)
- return; //contact should not be added
-
- if (!dat->IsMetaContactsEnabled && cacheEntry && !mir_strcmp(cacheEntry->m_pszProto, META_PROTO))
- return;
-
- corecli.pfnAddContactToTree(hwnd, dat, hContact, updateTotalCount, checkHideOffline);
-
- ClcGroup *group;
- ClcContact *cont;
- if (FindItem(hwnd, dat, hContact, &cont, &group, NULL, FALSE))
- _LoadDataToContact(cont, group, dat, hContact);
-}
-
-void cli_DeleteItemFromTree(HWND hwnd, MCONTACT hContact)
-{
- ClcData *dat = (ClcData *)GetWindowLongPtr(hwnd, 0);
- ClearRowByIndexCache();
- corecli.pfnDeleteItemFromTree(hwnd, hContact);
-
- // check here contacts are not resorting
- if (hwnd == pcli->hwndContactTree) {
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (ñ) 2012-16 Miranda NG project (http://miranda-ng.org),
+Copyright (c) 2000-08 Miranda ICQ/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 "stdafx.h"
+#include "modern_clc.h"
+#include "modern_clist.h"
+#include "m_metacontacts.h"
+#include "modern_commonprototypes.h"
+
+void AddSubcontacts(ClcData *dat, ClcContact *cont, BOOL showOfflineHereGroup)
+{
+ ClcCacheEntry *cacheEntry = pcli->pfnGetCacheEntry(cont->hContact);
+ cont->SubExpanded = (db_get_b(cont->hContact, "CList", "Expanded", 0) && (db_get_b(NULL, "CLC", "MetaExpanding", SETTING_METAEXPANDING_DEFAULT)));
+ int subcount = db_mc_getSubCount(cont->hContact);
+ if (subcount <= 0) {
+ cont->isSubcontact = 0;
+ cont->subcontacts = NULL;
+ cont->SubAllocated = 0;
+ return;
+ }
+
+ cont->isSubcontact = 0;
+ mir_free(cont->subcontacts);
+ cont->subcontacts = (ClcContact *)mir_calloc(sizeof(ClcContact)*subcount);
+ cont->SubAllocated = subcount;
+ int i = 0;
+ int bHideOffline = db_get_b(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT);
+ for (int j = 0; j < subcount; j++) {
+ MCONTACT hsub = db_mc_getSub(cont->hContact, j);
+ cacheEntry = pcli->pfnGetCacheEntry(hsub);
+ WORD wStatus = cacheEntry->getStatus();
+
+ if (!showOfflineHereGroup && bHideOffline && !cacheEntry->m_bNoHiddenOffline && wStatus == ID_STATUS_OFFLINE)
+ continue;
+
+ ClcContact& p = cont->subcontacts[i];
+ p.hContact = cacheEntry->hContact;
+
+ p.avatar_pos = AVATAR_POS_DONT_HAVE;
+ Cache_GetAvatar(dat, &p);
+
+ p.iImage = corecli.pfnGetContactIcon(cacheEntry->hContact);
+ memset(p.iExtraImage, 0xFF, sizeof(p.iExtraImage));
+ p.proto = cacheEntry->m_pszProto;
+ p.type = CLCIT_CONTACT;
+ p.flags = 0;//CONTACTF_ONLINE;
+ p.isSubcontact = i + 1;
+ p.lastPaintCounter = 0;
+ p.subcontacts = cont;
+ p.image_is_special = FALSE;
+ //p.status = cacheEntry->status;
+ Cache_GetTimezone(dat, (&p)->hContact);
+ Cache_GetText(dat, &p, 1);
+
+ char *szProto = cacheEntry->m_pszProto;
+ if (szProto != NULL && !pcli->pfnIsHiddenMode(dat, wStatus))
+ p.flags |= CONTACTF_ONLINE;
+ int apparentMode = szProto != NULL ? cacheEntry->ApparentMode : 0;
+ if (apparentMode == ID_STATUS_OFFLINE) p.flags |= CONTACTF_INVISTO;
+ else if (apparentMode == ID_STATUS_ONLINE) p.flags |= CONTACTF_VISTO;
+ else if (apparentMode) p.flags |= CONTACTF_VISTO | CONTACTF_INVISTO;
+ if (cacheEntry->NotOnList) p.flags |= CONTACTF_NOTONLIST;
+ int idleMode = szProto != NULL ? cacheEntry->IdleTS : 0;
+ if (idleMode) p.flags |= CONTACTF_IDLE;
+ i++;
+ }
+
+ cont->SubAllocated = i;
+ if (!i && cont->subcontacts != NULL)
+ mir_free_and_nil(cont->subcontacts);
+}
+
+int cli_AddItemToGroup(ClcGroup *group, int iAboveItem)
+{
+ if (group == NULL)
+ return 0;
+
+ iAboveItem = corecli.pfnAddItemToGroup(group, iAboveItem);
+ ClearRowByIndexCache();
+ return iAboveItem;
+}
+
+ClcGroup* cli_AddGroup(HWND hwnd, ClcData *dat, const TCHAR *szName, DWORD flags, int groupId, int calcTotalMembers)
+{
+ ClearRowByIndexCache();
+ if (!dat->force_in_dialog && !(GetWindowLongPtr(hwnd, GWL_STYLE) & CLS_SHOWHIDDEN))
+ if (!mir_tstrcmp(_T("-@-HIDDEN-GROUP-@-"), szName)) { //group is hidden
+ ClearRowByIndexCache();
+ return NULL;
+ }
+
+ ClcGroup *result = corecli.pfnAddGroup(hwnd, dat, szName, flags, groupId, calcTotalMembers);
+ ClearRowByIndexCache();
+ return result;
+}
+
+void cli_FreeContact(ClcContact *p)
+{
+ if (p->SubAllocated) {
+ if (p->subcontacts && !p->isSubcontact) {
+ for (int i = 0; i < p->SubAllocated; i++) {
+ p->subcontacts[i].ssText.DestroySmileyList();
+ if (p->subcontacts[i].avatar_pos == AVATAR_POS_ANIMATED)
+ AniAva_RemoveAvatar(p->subcontacts[i].hContact);
+ p->subcontacts[i].avatar_pos = AVATAR_POS_DONT_HAVE;
+ }
+ mir_free_and_nil(p->subcontacts);
+ }
+ p->SubAllocated = 0;
+ }
+
+ p->ssText.DestroySmileyList();
+ if (p->avatar_pos == AVATAR_POS_ANIMATED)
+ AniAva_RemoveAvatar(p->hContact);
+ p->avatar_pos = AVATAR_POS_DONT_HAVE;
+ corecli.pfnFreeContact(p);
+}
+
+void cli_FreeGroup(ClcGroup* group)
+{
+ corecli.pfnFreeGroup(group);
+ ClearRowByIndexCache();
+}
+
+int cli_AddInfoItemToGroup(ClcGroup *group, int flags, const TCHAR *pszText)
+{
+ int i = corecli.pfnAddInfoItemToGroup(group, flags, pszText);
+ ClearRowByIndexCache();
+ return i;
+}
+
+static void _LoadDataToContact(ClcContact *cont, ClcGroup *group, ClcData *dat, MCONTACT hContact)
+{
+ if (!cont)
+ return;
+
+ cont->type = CLCIT_CONTACT;
+ cont->SubAllocated = 0;
+ cont->isSubcontact = 0;
+ cont->subcontacts = NULL;
+ cont->szText[0] = 0;
+ cont->lastPaintCounter = 0;
+ cont->image_is_special = FALSE;
+ cont->hContact = hContact;
+
+ pcli->pfnInvalidateDisplayNameCacheEntry(hContact);
+
+ ClcCacheEntry *cacheEntry = pcli->pfnGetCacheEntry(hContact);
+ char *szProto = cacheEntry->m_pszProto;
+ cont->proto = szProto;
+
+ if (szProto != NULL && !pcli->pfnIsHiddenMode(dat, cacheEntry->m_iStatus))
+ cont->flags |= CONTACTF_ONLINE;
+
+ WORD apparentMode = szProto != NULL ? cacheEntry->ApparentMode : 0;
+ if (apparentMode)
+ switch (apparentMode) {
+ case ID_STATUS_OFFLINE:
+ cont->flags |= CONTACTF_INVISTO;
+ break;
+ case ID_STATUS_ONLINE:
+ cont->flags |= CONTACTF_VISTO;
+ break;
+ default:
+ cont->flags |= CONTACTF_VISTO | CONTACTF_INVISTO;
+ }
+
+ if (cacheEntry->NotOnList)
+ cont->flags |= CONTACTF_NOTONLIST;
+
+ DWORD idleMode = szProto != NULL ? cacheEntry->IdleTS : 0;
+ if (idleMode)
+ cont->flags |= CONTACTF_IDLE;
+
+ // Add subcontacts
+ if (szProto)
+ if (dat->IsMetaContactsEnabled && mir_strcmp(cont->proto, META_PROTO) == 0)
+ AddSubcontacts(dat, cont, CLCItems_IsShowOfflineGroup(group));
+
+ cont->lastPaintCounter = 0;
+ cont->avatar_pos = AVATAR_POS_DONT_HAVE;
+ Cache_GetAvatar(dat, cont);
+ Cache_GetText(dat, cont, 1);
+ Cache_GetTimezone(dat, cont->hContact);
+ cont->iImage = corecli.pfnGetContactIcon(hContact);
+ cont->bContactRate = db_get_b(hContact, "CList", "Rate", 0);
+}
+
+static ClcContact* AddContactToGroup(ClcData *dat, ClcGroup *group, ClcCacheEntry *cacheEntry)
+{
+ if (cacheEntry == NULL || group == NULL || dat == NULL)
+ return NULL;
+
+ MCONTACT hContact = cacheEntry->hContact;
+ dat->needsResort = 1;
+ int i;
+ for (i = group->cl.count - 1; i >= 0; i--)
+ if (group->cl.items[i]->type != CLCIT_INFO || !(group->cl.items[i]->flags & CLCIIF_BELOWCONTACTS))
+ break;
+ i = cli_AddItemToGroup(group, i + 1);
+
+ _LoadDataToContact(group->cl.items[i], group, dat, hContact);
+ cacheEntry = pcli->pfnGetCacheEntry(hContact);
+ ClearRowByIndexCache();
+ return group->cl.items[i];
+}
+
+void* AddTempGroup(HWND hwnd, ClcData *dat, const TCHAR *szName)
+{
+ if (wildcmp(_T2A(szName), "-@-HIDDEN-GROUP-@-"))
+ return NULL;
+
+ int i;
+ DWORD groupFlags;
+ for (i = 1;; i++) {
+ TCHAR *szGroupName = pcli->pfnGetGroupName(i, &groupFlags);
+ if (szGroupName == NULL)
+ break;
+ if (!mir_tstrcmpi(szGroupName, szName))
+ return NULL;
+ }
+
+ char buf[20];
+ _itoa_s(i - 1, buf, 10);
+
+ TCHAR b2[255];
+ mir_sntprintf(b2, _T("#%s"), szName);
+ b2[0] = 1 | GROUPF_EXPANDED;
+ db_set_ts(NULL, "CListGroups", buf, b2);
+ pcli->pfnGetGroupName(i, &groupFlags);
+ return cli_AddGroup(hwnd, dat, szName, groupFlags, i, 0);
+}
+
+void cli_AddContactToTree(HWND hwnd, ClcData *dat, MCONTACT hContact, int updateTotalCount, int checkHideOffline)
+{
+ ClcCacheEntry *cacheEntry = pcli->pfnGetCacheEntry(hContact);
+ if (dat->IsMetaContactsEnabled && cacheEntry && cacheEntry->m_bIsSub)
+ return; //contact should not be added
+
+ if (!dat->IsMetaContactsEnabled && cacheEntry && !mir_strcmp(cacheEntry->m_pszProto, META_PROTO))
+ return;
+
+ corecli.pfnAddContactToTree(hwnd, dat, hContact, updateTotalCount, checkHideOffline);
+
+ ClcGroup *group;
+ ClcContact *cont;
+ if (FindItem(hwnd, dat, hContact, &cont, &group, NULL, FALSE))
+ _LoadDataToContact(cont, group, dat, hContact);
+}
+
+void cli_DeleteItemFromTree(HWND hwnd, MCONTACT hContact)
+{
+ ClcData *dat = (ClcData *)GetWindowLongPtr(hwnd, 0);
+ ClearRowByIndexCache();
+ corecli.pfnDeleteItemFromTree(hwnd, hContact);
+
+ // check here contacts are not resorting
+ if (hwnd == pcli->hwndContactTree) {
int idx = clistCache.getIndex((ClcCacheEntry*)&hContact);
if (idx != -1) {
- pcli->pfnFreeCacheItem(clistCache[idx]);
- clistCache.remove(idx);
- }
- }
-
- dat->needsResort = 1;
- ClearRowByIndexCache();
-}
-
-bool CLCItems_IsShowOfflineGroup(ClcGroup *group)
-{
- if (!group) return false;
- if (group->hideOffline) return false;
-
- DWORD groupFlags = 0;
- pcli->pfnGetGroupName(group->groupId, &groupFlags);
- return (groupFlags & GROUPF_SHOWOFFLINE) != 0;
-}
-
-MCONTACT SaveSelection(ClcData *dat)
-{
- ClcContact *selcontact = NULL;
- if (pcli->pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) == -1)
- return NULL;
-
- return (DWORD_PTR)pcli->pfnContactToHItem(selcontact);
-}
-
-int RestoreSelection(ClcData *dat, MCONTACT hSelected)
-{
- ClcContact *selcontact = NULL;
- ClcGroup *selgroup = NULL;
-
- if (!hSelected || !pcli->pfnFindItem(dat->hWnd, dat, hSelected, &selcontact, &selgroup, NULL)) {
- dat->selection = -1;
- return dat->selection;
- }
-
- if (!selcontact->isSubcontact)
- dat->selection = pcli->pfnGetRowsPriorTo(&dat->list, selgroup, List_IndexOf((SortedList*)&selgroup->cl, selcontact));
- else {
- dat->selection = pcli->pfnGetRowsPriorTo(&dat->list, selgroup, List_IndexOf((SortedList*)&selgroup->cl, selcontact->subcontacts));
-
- if (dat->selection != -1)
- dat->selection += selcontact->isSubcontact;
- }
- return dat->selection;
-}
-
-void cliRebuildEntireList(HWND hwnd, ClcData *dat)
-{
- DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE);
- ClcGroup *group = NULL;
- static int rebuildCounter = 0;
-
- BOOL PlaceOfflineToRoot = db_get_b(NULL, "CList", "PlaceOfflineToRoot", SETTING_PLACEOFFLINETOROOT_DEFAULT);
- KillTimer(hwnd, TIMERID_REBUILDAFTER);
+ pcli->pfnFreeCacheItem(clistCache[idx]);
+ clistCache.remove(idx);
+ }
+ }
+
+ dat->needsResort = 1;
+ ClearRowByIndexCache();
+}
+
+bool CLCItems_IsShowOfflineGroup(ClcGroup *group)
+{
+ if (!group) return false;
+ if (group->hideOffline) return false;
+
+ DWORD groupFlags = 0;
+ pcli->pfnGetGroupName(group->groupId, &groupFlags);
+ return (groupFlags & GROUPF_SHOWOFFLINE) != 0;
+}
+
+MCONTACT SaveSelection(ClcData *dat)
+{
+ ClcContact *selcontact = NULL;
+ if (pcli->pfnGetRowByIndex(dat, dat->selection, &selcontact, NULL) == -1)
+ return NULL;
+
+ return (DWORD_PTR)pcli->pfnContactToHItem(selcontact);
+}
+
+int RestoreSelection(ClcData *dat, MCONTACT hSelected)
+{
+ ClcContact *selcontact = NULL;
+ ClcGroup *selgroup = NULL;
+
+ if (!hSelected || !pcli->pfnFindItem(dat->hWnd, dat, hSelected, &selcontact, &selgroup, NULL)) {
+ dat->selection = -1;
+ return dat->selection;
+ }
+
+ if (!selcontact->isSubcontact)
+ dat->selection = pcli->pfnGetRowsPriorTo(&dat->list, selgroup, List_IndexOf((SortedList*)&selgroup->cl, selcontact));
+ else {
+ dat->selection = pcli->pfnGetRowsPriorTo(&dat->list, selgroup, List_IndexOf((SortedList*)&selgroup->cl, selcontact->subcontacts));
+
+ if (dat->selection != -1)
+ dat->selection += selcontact->isSubcontact;
+ }
+ return dat->selection;
+}
+
+void cliRebuildEntireList(HWND hwnd, ClcData *dat)
+{
+ DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE);
+ ClcGroup *group = NULL;
+ static int rebuildCounter = 0;
+
+ BOOL PlaceOfflineToRoot = db_get_b(NULL, "CList", "PlaceOfflineToRoot", SETTING_PLACEOFFLINETOROOT_DEFAULT);
+ KillTimer(hwnd, TIMERID_REBUILDAFTER);
pcli->bAutoRebuild = false;
-
- ClearRowByIndexCache();
- ImageArray_Clear(&dat->avatar_cache);
- RowHeights_Clear(dat);
- RowHeights_GetMaxRowHeight(dat, hwnd);
- TRACEVAR("Rebuild Entire List %d times\n", ++rebuildCounter);
-
- dat->list.expanded = 1;
- dat->list.hideOffline = db_get_b(NULL, "CLC", "HideOfflineRoot", SETTING_HIDEOFFLINEATROOT_DEFAULT) && style&CLS_USEGROUPS;
- dat->list.cl.count = dat->list.cl.limit = 0;
- dat->list.cl.increment = 50;
- dat->needsResort = 1;
-
- MCONTACT hSelected = SaveSelection(dat);
- dat->selection = -1;
- dat->HiLightMode = db_get_b(NULL, "CLC", "HiLightMode", SETTING_HILIGHTMODE_DEFAULT);
-
- for (int i = 1;; i++) {
- DWORD groupFlags;
- TCHAR *szGroupName = pcli->pfnGetGroupName(i, &groupFlags); //UNICODE
- if (szGroupName == NULL)
- break;
- cli_AddGroup(hwnd, dat, szGroupName, groupFlags, i, 0);
- }
-
- for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) {
- ClcContact *cont = NULL;
- ClcCacheEntry *cacheEntry = pcli->pfnGetCacheEntry(hContact);
-
- int nHiddenStatus = CLVM_GetContactHiddenStatus(hContact, NULL, dat);
- if ((style & CLS_SHOWHIDDEN && nHiddenStatus != -1) || !nHiddenStatus) {
- if (mir_tstrlen(cacheEntry->tszGroup) == 0)
- group = &dat->list;
- else
- group = cli_AddGroup(hwnd, dat, cacheEntry->tszGroup, (DWORD)-1, 0, 0);
-
- if (group != NULL) {
- if (cacheEntry->m_iStatus == ID_STATUS_OFFLINE && PlaceOfflineToRoot)
- group = &dat->list;
-
- group->totalMembers++;
-
- if (!(style & CLS_NOHIDEOFFLINE) && (style & CLS_HIDEOFFLINE || group->hideOffline)) {
- if (cacheEntry->m_pszProto == NULL) {
- if (!pcli->pfnIsHiddenMode(dat, ID_STATUS_OFFLINE) || cacheEntry->m_bNoHiddenOffline || CLCItems_IsShowOfflineGroup(group))
- cont = AddContactToGroup(dat, group, cacheEntry);
- }
- else if (!pcli->pfnIsHiddenMode(dat, cacheEntry->m_iStatus) || cacheEntry->m_bNoHiddenOffline || CLCItems_IsShowOfflineGroup(group))
- cont = AddContactToGroup(dat, group, cacheEntry);
- }
- else cont = AddContactToGroup(dat, group, cacheEntry);
- }
- }
- if (cont) {
- cont->SubAllocated = 0;
- if (cont->proto && dat->IsMetaContactsEnabled && mir_strcmp(cont->proto, META_PROTO) == 0)
- AddSubcontacts(dat, cont, CLCItems_IsShowOfflineGroup(group));
- }
- }
-
- 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 = pcli->pfnRemoveItemFromGroup(hwnd, group, group->cl.items[group->scanIndex], 0);
- else {
- group = group->cl.items[group->scanIndex]->group;
- group->scanIndex = 0;
- }
- continue;
- }
- group->scanIndex++;
- }
- }
-
- pcli->pfnSortCLC(hwnd, dat, 0);
-
- RestoreSelection(dat, hSelected);
-}
-
-void cli_SortCLC(HWND hwnd, ClcData *dat, int useInsertionSort)
-{
- MCONTACT hSelected = SaveSelection(dat);
- corecli.pfnSortCLC(hwnd, dat, useInsertionSort);
- RestoreSelection(dat, hSelected);
-}
-
-int GetNewSelection(ClcGroup *group, int selection, int direction)
-{
- if (selection < 0)
- return 0;
-
- int lastcount = 0, count = 0;
-
- group->scanIndex = 0;
- for (;;) {
- if (group->scanIndex == group->cl.count) {
- group = group->parent;
- if (group == NULL) break;
- group->scanIndex++;
- continue;
- }
-
- if (count >= selection)
- return count;
-
- lastcount = count;
- count++;
- if (!direction && count > selection)
- return lastcount;
-
- if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP && (group->cl.items[group->scanIndex]->group->expanded)) {
- group = group->cl.items[group->scanIndex]->group;
- group->scanIndex = 0;
- continue;
- }
- group->scanIndex++;
- }
- return lastcount;
-}
-
-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;
-};
-
-BOOL LOCK_RECALC_SCROLLBAR = FALSE;
-void cli_SaveStateAndRebuildList(HWND hwnd, ClcData *dat)
-{
- LOCK_RECALC_SCROLLBAR = TRUE;
-
- NMCLISTCONTROL nm;
- int i, j;
- OBJLIST<SavedGroupState_t> savedGroup(4);
- OBJLIST<SavedContactState_t> savedContact(4);
- OBJLIST<SavedInfoState_t> savedInfo(4);
-
- ClcGroup *group;
- ClcContact *contact;
-
- pcli->pfnHideInfoTip(hwnd, dat);
- KillTimer(hwnd, TIMERID_INFOTIP);
- KillTimer(hwnd, TIMERID_RENAME);
- pcli->pfnEndRename(hwnd, dat, 1);
-
- 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;
- savedGroup.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;
- savedContact.insert(p);
- }
- else if (group->cl.items[group->scanIndex]->type == CLCIT_INFO) {
- SavedInfoState_t *p = new SavedInfoState_t;
- memset(p, 0, sizeof(SavedInfoState_t));
- if (group->parent == NULL)
- p->parentId = -1;
- else
- p->parentId = group->groupId;
- p->contact = *group->cl.items[group->scanIndex];
- savedInfo.insert(p);
- }
- group->scanIndex++;
- }
-
- pcli->pfnFreeGroup(&dat->list);
- pcli->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;
- for (i = 0; i < savedGroup.getCount(); i++)
- if (savedGroup[i].groupId == group->groupId) {
- group->expanded = savedGroup[i].expanded;
- break;
- }
- continue;
- }
- else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT) {
- for (i = 0; i < savedContact.getCount(); i++)
- if (savedContact[i].hContact == group->cl.items[group->scanIndex]->hContact) {
- memcpy(group->cl.items[group->scanIndex]->iExtraImage, savedContact[i].iExtraImage, sizeof(contact->iExtraImage));
- if (savedContact[i].checked)
- group->cl.items[group->scanIndex]->flags |= CONTACTF_CHECKED;
- break;
- }
- }
- group->scanIndex++;
- }
-
- for (i = 0; i < savedInfo.getCount(); i++) {
- if (savedInfo[i].parentId == -1)
- group = &dat->list;
- else {
- if (!pcli->pfnFindItem(hwnd, dat, savedInfo[i].parentId | HCONTACT_ISGROUP, &contact, NULL, NULL))
- continue;
- group = contact->group;
- }
- j = pcli->pfnAddInfoItemToGroup(group, savedInfo[i].contact.flags, _T(""));
- *group->cl.items[j] = savedInfo[i].contact;
- }
-
- LOCK_RECALC_SCROLLBAR = FALSE;
- pcli->pfnRecalculateGroupCheckboxes(hwnd, dat);
-
- pcli->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);
-}
-
-ClcContact* cliCreateClcContact()
-{
- ClcContact* contact = (ClcContact*)mir_calloc(sizeof(ClcContact));
- memset(contact->iExtraImage, 0xFF, sizeof(contact->iExtraImage));
- return contact;
-}
-
-ClcCacheEntry* cliCreateCacheItem(MCONTACT hContact)
-{
- ClcCacheEntry *p = (ClcCacheEntry *)mir_calloc(sizeof(ClcCacheEntry));
- if (p == NULL)
- return NULL;
-
- p->hContact = hContact;
- p->m_pszProto = GetContactProto(hContact);
+
+ ClearRowByIndexCache();
+ ImageArray_Clear(&dat->avatar_cache);
+ RowHeights_Clear(dat);
+ RowHeights_GetMaxRowHeight(dat, hwnd);
+ TRACEVAR("Rebuild Entire List %d times\n", ++rebuildCounter);
+
+ dat->list.expanded = 1;
+ dat->list.hideOffline = db_get_b(NULL, "CLC", "HideOfflineRoot", SETTING_HIDEOFFLINEATROOT_DEFAULT) && style&CLS_USEGROUPS;
+ dat->list.cl.count = dat->list.cl.limit = 0;
+ dat->list.cl.increment = 50;
+ dat->needsResort = 1;
+
+ MCONTACT hSelected = SaveSelection(dat);
+ dat->selection = -1;
+ dat->HiLightMode = db_get_b(NULL, "CLC", "HiLightMode", SETTING_HILIGHTMODE_DEFAULT);
+
+ for (int i = 1;; i++) {
+ DWORD groupFlags;
+ TCHAR *szGroupName = pcli->pfnGetGroupName(i, &groupFlags); //UNICODE
+ if (szGroupName == NULL)
+ break;
+ cli_AddGroup(hwnd, dat, szGroupName, groupFlags, i, 0);
+ }
+
+ for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) {
+ ClcContact *cont = NULL;
+ ClcCacheEntry *cacheEntry = pcli->pfnGetCacheEntry(hContact);
+
+ int nHiddenStatus = CLVM_GetContactHiddenStatus(hContact, NULL, dat);
+ if ((style & CLS_SHOWHIDDEN && nHiddenStatus != -1) || !nHiddenStatus) {
+ if (mir_tstrlen(cacheEntry->tszGroup) == 0)
+ group = &dat->list;
+ else
+ group = cli_AddGroup(hwnd, dat, cacheEntry->tszGroup, (DWORD)-1, 0, 0);
+
+ if (group != NULL) {
+ if (cacheEntry->m_iStatus == ID_STATUS_OFFLINE && PlaceOfflineToRoot)
+ group = &dat->list;
+
+ group->totalMembers++;
+
+ if (!(style & CLS_NOHIDEOFFLINE) && (style & CLS_HIDEOFFLINE || group->hideOffline)) {
+ if (cacheEntry->m_pszProto == NULL) {
+ if (!pcli->pfnIsHiddenMode(dat, ID_STATUS_OFFLINE) || cacheEntry->m_bNoHiddenOffline || CLCItems_IsShowOfflineGroup(group))
+ cont = AddContactToGroup(dat, group, cacheEntry);
+ }
+ else if (!pcli->pfnIsHiddenMode(dat, cacheEntry->m_iStatus) || cacheEntry->m_bNoHiddenOffline || CLCItems_IsShowOfflineGroup(group))
+ cont = AddContactToGroup(dat, group, cacheEntry);
+ }
+ else cont = AddContactToGroup(dat, group, cacheEntry);
+ }
+ }
+ if (cont) {
+ cont->SubAllocated = 0;
+ if (cont->proto && dat->IsMetaContactsEnabled && mir_strcmp(cont->proto, META_PROTO) == 0)
+ AddSubcontacts(dat, cont, CLCItems_IsShowOfflineGroup(group));
+ }
+ }
+
+ 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 = pcli->pfnRemoveItemFromGroup(hwnd, group, group->cl.items[group->scanIndex], 0);
+ else {
+ group = group->cl.items[group->scanIndex]->group;
+ group->scanIndex = 0;
+ }
+ continue;
+ }
+ group->scanIndex++;
+ }
+ }
+
+ pcli->pfnSortCLC(hwnd, dat, 0);
+
+ RestoreSelection(dat, hSelected);
+}
+
+void cli_SortCLC(HWND hwnd, ClcData *dat, int useInsertionSort)
+{
+ MCONTACT hSelected = SaveSelection(dat);
+ corecli.pfnSortCLC(hwnd, dat, useInsertionSort);
+ RestoreSelection(dat, hSelected);
+}
+
+int GetNewSelection(ClcGroup *group, int selection, int direction)
+{
+ if (selection < 0)
+ return 0;
+
+ int lastcount = 0, count = 0;
+
+ group->scanIndex = 0;
+ for (;;) {
+ if (group->scanIndex == group->cl.count) {
+ group = group->parent;
+ if (group == NULL) break;
+ group->scanIndex++;
+ continue;
+ }
+
+ if (count >= selection)
+ return count;
+
+ lastcount = count;
+ count++;
+ if (!direction && count > selection)
+ return lastcount;
+
+ if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP && (group->cl.items[group->scanIndex]->group->expanded)) {
+ group = group->cl.items[group->scanIndex]->group;
+ group->scanIndex = 0;
+ continue;
+ }
+ group->scanIndex++;
+ }
+ return lastcount;
+}
+
+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;
+};
+
+BOOL LOCK_RECALC_SCROLLBAR = FALSE;
+void cli_SaveStateAndRebuildList(HWND hwnd, ClcData *dat)
+{
+ LOCK_RECALC_SCROLLBAR = TRUE;
+
+ NMCLISTCONTROL nm;
+ int i, j;
+ OBJLIST<SavedGroupState_t> savedGroup(4);
+ OBJLIST<SavedContactState_t> savedContact(4);
+ OBJLIST<SavedInfoState_t> savedInfo(4);
+
+ ClcGroup *group;
+ ClcContact *contact;
+
+ pcli->pfnHideInfoTip(hwnd, dat);
+ KillTimer(hwnd, TIMERID_INFOTIP);
+ KillTimer(hwnd, TIMERID_RENAME);
+ pcli->pfnEndRename(hwnd, dat, 1);
+
+ 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;
+ savedGroup.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;
+ savedContact.insert(p);
+ }
+ else if (group->cl.items[group->scanIndex]->type == CLCIT_INFO) {
+ SavedInfoState_t *p = new SavedInfoState_t;
+ memset(p, 0, sizeof(SavedInfoState_t));
+ if (group->parent == NULL)
+ p->parentId = -1;
+ else
+ p->parentId = group->groupId;
+ p->contact = *group->cl.items[group->scanIndex];
+ savedInfo.insert(p);
+ }
+ group->scanIndex++;
+ }
+
+ pcli->pfnFreeGroup(&dat->list);
+ pcli->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;
+ for (i = 0; i < savedGroup.getCount(); i++)
+ if (savedGroup[i].groupId == group->groupId) {
+ group->expanded = savedGroup[i].expanded;
+ break;
+ }
+ continue;
+ }
+ else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT) {
+ for (i = 0; i < savedContact.getCount(); i++)
+ if (savedContact[i].hContact == group->cl.items[group->scanIndex]->hContact) {
+ memcpy(group->cl.items[group->scanIndex]->iExtraImage, savedContact[i].iExtraImage, sizeof(contact->iExtraImage));
+ if (savedContact[i].checked)
+ group->cl.items[group->scanIndex]->flags |= CONTACTF_CHECKED;
+ break;
+ }
+ }
+ group->scanIndex++;
+ }
+
+ for (i = 0; i < savedInfo.getCount(); i++) {
+ if (savedInfo[i].parentId == -1)
+ group = &dat->list;
+ else {
+ if (!pcli->pfnFindItem(hwnd, dat, savedInfo[i].parentId | HCONTACT_ISGROUP, &contact, NULL, NULL))
+ continue;
+ group = contact->group;
+ }
+ j = pcli->pfnAddInfoItemToGroup(group, savedInfo[i].contact.flags, _T(""));
+ *group->cl.items[j] = savedInfo[i].contact;
+ }
+
+ LOCK_RECALC_SCROLLBAR = FALSE;
+ pcli->pfnRecalculateGroupCheckboxes(hwnd, dat);
+
+ pcli->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);
+}
+
+ClcContact* cliCreateClcContact()
+{
+ ClcContact* contact = (ClcContact*)mir_calloc(sizeof(ClcContact));
+ memset(contact->iExtraImage, 0xFF, sizeof(contact->iExtraImage));
+ return contact;
+}
+
+ClcCacheEntry* cliCreateCacheItem(MCONTACT hContact)
+{
+ ClcCacheEntry *p = (ClcCacheEntry *)mir_calloc(sizeof(ClcCacheEntry));
+ if (p == NULL)
+ return NULL;
+
+ p->hContact = hContact;
+ p->m_pszProto = GetContactProto(hContact);
p->dwLastMsgTime = -1;
p->bIsHidden = -1;
p->m_bNoHiddenOffline = -1;
p->IdleTS = -1;
p->NotOnList = -1;
p->IsExpanded = -1;
- return p;
-}
-
-void cliInvalidateDisplayNameCacheEntry(MCONTACT hContact)
-{
- if (hContact == INVALID_CONTACT_ID)
- corecli.pfnInvalidateDisplayNameCacheEntry(INVALID_CONTACT_ID);
- else {
- ClcCacheEntry *p = pcli->pfnGetCacheEntry(hContact);
- if (p)
+ return p;
+}
+
+void cliInvalidateDisplayNameCacheEntry(MCONTACT hContact)
+{
+ if (hContact == INVALID_CONTACT_ID)
+ corecli.pfnInvalidateDisplayNameCacheEntry(INVALID_CONTACT_ID);
+ else {
+ ClcCacheEntry *p = pcli->pfnGetCacheEntry(hContact);
+ if (p)
p->m_iStatus = 0;
- }
-}
-
-void cli_SetContactCheckboxes(ClcContact *cc, int checked)
-{
- corecli.pfnSetContactCheckboxes(cc, checked);
-
- for (int i = 0; i < cc->SubAllocated; i++)
- corecli.pfnSetContactCheckboxes(&cc->subcontacts[i], checked);
-}
-
-TCHAR* cli_GetGroupCountsText(ClcData *dat, ClcContact *contact)
-{
- return corecli.pfnGetGroupCountsText(dat, contact);
-}
-
-int cliGetGroupContentsCount(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 & 0x01) || group->cl.items[group->scanIndex]->group->expanded)) {
- group = group->cl.items[group->scanIndex]->group;
- group->scanIndex = 0;
- count += group->cl.count;
- continue;
- }
- else if ((group->cl.items[group->scanIndex]->type == CLCIT_CONTACT) &&
- (group->cl.items[group->scanIndex]->subcontacts != NULL) &&
- ((group->cl.items[group->scanIndex]->SubExpanded || (!visibleOnly)))) {
- count += group->cl.items[group->scanIndex]->SubAllocated;
- }
- group->scanIndex++;
- }
- return count;
-}
-
-/*
-* checks the currently active view mode filter and returns true, if the contact should be hidden
-* if no view mode is active, it returns the CList/Hidden setting
-* also cares about sub contacts (if meta is active)
-*/
-
-int __fastcall CLVM_GetContactHiddenStatus(MCONTACT hContact, char *szProto, ClcData *dat)
-{
- int dbHidden = db_get_b(hContact, "CList", "Hidden", 0); // default hidden state, always respect it.
- int filterResult = 1;
- int searchResult = 0;
- DBVARIANT dbv = { 0 };
- char szTemp[64];
- TCHAR szGroupMask[256];
- DWORD dwLocalMask;
- ClcCacheEntry *pdnce = pcli->pfnGetCacheEntry(hContact);
- // always hide subcontacts (but show them on embedded contact lists)
-
- if (dat != NULL && dat->IsMetaContactsEnabled && db_mc_isSub(hContact))
- return -1; //subcontact
- if (pdnce && pdnce->m_bIsUnknown && dat != NULL && !dat->force_in_dialog)
- return 1; //'Unknown Contact'
- if (dat != NULL && dat->filterSearch && pdnce && pdnce->tszName) {
- // search filtering
- TCHAR *lowered_name = CharLowerW(NEWTSTR_ALLOCA(pdnce->tszName));
- TCHAR *lowered_search = CharLowerW(NEWTSTR_ALLOCA(dat->szQuickSearch));
- searchResult = _tcsstr(lowered_name, lowered_search) ? 0 : 1;
- }
- if (pdnce && g_CluiData.bFilterEffective && dat != NULL && !dat->force_in_dialog) {
- if (szProto == NULL)
- szProto = GetContactProto(hContact);
- // check stickies first (priority), only if we really have stickies defined (CLVM_STICKY_CONTACTS is set).
- if (g_CluiData.bFilterEffective & CLVM_STICKY_CONTACTS) {
- if ((dwLocalMask = db_get_dw(hContact, CLVM_MODULE, g_CluiData.current_viewmode, 0)) != 0) {
- if (g_CluiData.bFilterEffective & CLVM_FILTER_STICKYSTATUS) {
- WORD wStatus = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE);
- return !((1 << (wStatus - ID_STATUS_OFFLINE)) & HIWORD(dwLocalMask)) | searchResult;
- }
- return 0 | searchResult;
- }
- }
- // check the proto, use it as a base filter result for all further checks
- if (g_CluiData.bFilterEffective & CLVM_FILTER_PROTOS) {
- mir_snprintf(szTemp, "%s|", szProto);
- filterResult = strstr(g_CluiData.protoFilter, szTemp) ? 1 : 0;
- }
- if (g_CluiData.bFilterEffective & CLVM_FILTER_GROUPS) {
- if (!db_get_ts(hContact, "CList", "Group", &dbv)) {
- mir_sntprintf(szGroupMask, _T("%s|"), &dbv.ptszVal[0]);
- filterResult = (g_CluiData.filterFlags & CLVM_PROTOGROUP_OP) ? (filterResult | (_tcsstr(g_CluiData.groupFilter, szGroupMask) ? 1 : 0)) : (filterResult & (_tcsstr(g_CluiData.groupFilter, szGroupMask) ? 1 : 0));
- mir_free(dbv.ptszVal);
- }
- else if (g_CluiData.filterFlags & CLVM_INCLUDED_UNGROUPED)
- filterResult = (g_CluiData.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 1;
- else
- filterResult = (g_CluiData.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 0;
- }
- if (g_CluiData.bFilterEffective & CLVM_FILTER_STATUS) {
- WORD wStatus = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE);
- filterResult = (g_CluiData.filterFlags & CLVM_GROUPSTATUS_OP) ? ((filterResult | ((1 << (wStatus - ID_STATUS_OFFLINE)) & g_CluiData.statusMaskFilter ? 1 : 0))) : (filterResult & ((1 << (wStatus - ID_STATUS_OFFLINE)) & g_CluiData.statusMaskFilter ? 1 : 0));
- }
- if (g_CluiData.bFilterEffective & CLVM_FILTER_LASTMSG) {
- if (pdnce->dwLastMsgTime != -1) {
- DWORD now = g_CluiData.t_now;
- now -= g_CluiData.lastMsgFilter;
- if (g_CluiData.bFilterEffective & CLVM_FILTER_LASTMSG_OLDERTHAN)
- filterResult = filterResult & (pdnce->dwLastMsgTime < now);
- else if (g_CluiData.bFilterEffective & CLVM_FILTER_LASTMSG_NEWERTHAN)
- filterResult = filterResult & (pdnce->dwLastMsgTime > now);
- }
- }
- return (dbHidden | !filterResult | searchResult);
- }
-
- return dbHidden | searchResult;
-}
+ }
+}
+
+void cli_SetContactCheckboxes(ClcContact *cc, int checked)
+{
+ corecli.pfnSetContactCheckboxes(cc, checked);
+
+ for (int i = 0; i < cc->SubAllocated; i++)
+ corecli.pfnSetContactCheckboxes(&cc->subcontacts[i], checked);
+}
+
+TCHAR* cli_GetGroupCountsText(ClcData *dat, ClcContact *contact)
+{
+ return corecli.pfnGetGroupCountsText(dat, contact);
+}
+
+int cliGetGroupContentsCount(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 & 0x01) || group->cl.items[group->scanIndex]->group->expanded)) {
+ group = group->cl.items[group->scanIndex]->group;
+ group->scanIndex = 0;
+ count += group->cl.count;
+ continue;
+ }
+ else if ((group->cl.items[group->scanIndex]->type == CLCIT_CONTACT) &&
+ (group->cl.items[group->scanIndex]->subcontacts != NULL) &&
+ ((group->cl.items[group->scanIndex]->SubExpanded || (!visibleOnly)))) {
+ count += group->cl.items[group->scanIndex]->SubAllocated;
+ }
+ group->scanIndex++;
+ }
+ return count;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// checks the currently active view mode filter and returns true, if the contact should be hidden
+// if no view mode is active, it returns the CList/Hidden setting
+// also cares about sub contacts (if meta is active)
+//
+int __fastcall CLVM_GetContactHiddenStatus(MCONTACT hContact, char *szProto, ClcData *dat)
+{
+ int dbHidden = db_get_b(hContact, "CList", "Hidden", 0); // default hidden state, always respect it.
+ int filterResult = 1;
+ int searchResult = 0;
+ DBVARIANT dbv = { 0 };
+ char szTemp[64];
+ TCHAR szGroupMask[256];
+ DWORD dwLocalMask;
+ ClcCacheEntry *pdnce = pcli->pfnGetCacheEntry(hContact);
+ // always hide subcontacts (but show them on embedded contact lists)
+
+ if (dat != NULL && dat->IsMetaContactsEnabled && db_mc_isSub(hContact))
+ return -1; //subcontact
+ if (pdnce && pdnce->m_bIsUnknown && dat != NULL && !dat->force_in_dialog)
+ return 1; //'Unknown Contact'
+ if (dat != NULL && dat->filterSearch && pdnce && pdnce->tszName) {
+ // search filtering
+ TCHAR *lowered_name = CharLowerW(NEWTSTR_ALLOCA(pdnce->tszName));
+ TCHAR *lowered_search = CharLowerW(NEWTSTR_ALLOCA(dat->szQuickSearch));
+ searchResult = _tcsstr(lowered_name, lowered_search) ? 0 : 1;
+ }
+ if (pdnce && g_CluiData.bFilterEffective && dat != NULL && !dat->force_in_dialog) {
+ if (szProto == NULL)
+ szProto = GetContactProto(hContact);
+ // check stickies first (priority), only if we really have stickies defined (CLVM_STICKY_CONTACTS is set).
+ if (g_CluiData.bFilterEffective & CLVM_STICKY_CONTACTS) {
+ if ((dwLocalMask = db_get_dw(hContact, CLVM_MODULE, g_CluiData.current_viewmode, 0)) != 0) {
+ if (g_CluiData.bFilterEffective & CLVM_FILTER_STICKYSTATUS) {
+ WORD wStatus = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE);
+ return !((1 << (wStatus - ID_STATUS_OFFLINE)) & HIWORD(dwLocalMask)) | searchResult;
+ }
+ return 0 | searchResult;
+ }
+ }
+ // check the proto, use it as a base filter result for all further checks
+ if (g_CluiData.bFilterEffective & CLVM_FILTER_PROTOS) {
+ mir_snprintf(szTemp, "%s|", szProto);
+ filterResult = strstr(g_CluiData.protoFilter, szTemp) ? 1 : 0;
+ }
+ if (g_CluiData.bFilterEffective & CLVM_FILTER_GROUPS) {
+ if (!db_get_ts(hContact, "CList", "Group", &dbv)) {
+ mir_sntprintf(szGroupMask, _T("%s|"), &dbv.ptszVal[0]);
+ filterResult = (g_CluiData.filterFlags & CLVM_PROTOGROUP_OP) ? (filterResult | (_tcsstr(g_CluiData.groupFilter, szGroupMask) ? 1 : 0)) : (filterResult & (_tcsstr(g_CluiData.groupFilter, szGroupMask) ? 1 : 0));
+ mir_free(dbv.ptszVal);
+ }
+ else if (g_CluiData.filterFlags & CLVM_INCLUDED_UNGROUPED)
+ filterResult = (g_CluiData.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 1;
+ else
+ filterResult = (g_CluiData.filterFlags & CLVM_PROTOGROUP_OP) ? filterResult : filterResult & 0;
+ }
+ if (g_CluiData.bFilterEffective & CLVM_FILTER_STATUS) {
+ WORD wStatus = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE);
+ filterResult = (g_CluiData.filterFlags & CLVM_GROUPSTATUS_OP) ? ((filterResult | ((1 << (wStatus - ID_STATUS_OFFLINE)) & g_CluiData.statusMaskFilter ? 1 : 0))) : (filterResult & ((1 << (wStatus - ID_STATUS_OFFLINE)) & g_CluiData.statusMaskFilter ? 1 : 0));
+ }
+ if (g_CluiData.bFilterEffective & CLVM_FILTER_LASTMSG) {
+ if (pdnce->dwLastMsgTime != -1) {
+ DWORD now = g_CluiData.t_now;
+ now -= g_CluiData.lastMsgFilter;
+ if (g_CluiData.bFilterEffective & CLVM_FILTER_LASTMSG_OLDERTHAN)
+ filterResult = filterResult & (pdnce->dwLastMsgTime < now);
+ else if (g_CluiData.bFilterEffective & CLVM_FILTER_LASTMSG_NEWERTHAN)
+ filterResult = filterResult & (pdnce->dwLastMsgTime > now);
+ }
+ }
+ return (dbHidden | !filterResult | searchResult);
+ }
+
+ return dbHidden | searchResult;
+}
diff --git a/plugins/Clist_modern/src/modern_clcmsgs.cpp b/plugins/Clist_modern/src/modern_clcmsgs.cpp
index eec91381b3..6748c9eaa4 100644
--- a/plugins/Clist_modern/src/modern_clcmsgs.cpp
+++ b/plugins/Clist_modern/src/modern_clcmsgs.cpp
@@ -26,8 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "modern_clc.h"
#include "modern_commonprototypes.h"
+/////////////////////////////////////////////////////////////////////////////////////////
//processing of all the CLM_ messages incoming
-
+//
LRESULT cli_ProcessExternalMessages(HWND hwnd, ClcData *dat, UINT msg, WPARAM wParam, LPARAM lParam)
{
ClcContact *contact = NULL;
diff --git a/plugins/Clist_modern/src/modern_clcpaint.cpp b/plugins/Clist_modern/src/modern_clcpaint.cpp
index 4638fad9f8..cfaa374d46 100644
--- a/plugins/Clist_modern/src/modern_clcpaint.cpp
+++ b/plugins/Clist_modern/src/modern_clcpaint.cpp
@@ -553,8 +553,11 @@ MODERNMASK* CLCPaint::_GetCLCContactRowBackModernMask(ClcGroup *group, ClcContac
switch (Drawing->type) {
case CLCIT_GROUP:
_AddParamShort(mpModernMask, hi_Type, hi_Group);
- _AddParamShort(mpModernMask, hi_Open, (Drawing->group && Drawing->group->expanded) ? hi_True : hi_False);
- _AddParamShort(mpModernMask, hi_IsEmpty, (Drawing->group->cl.count == 0) ? hi_True : hi_False);
+ if (Drawing->group)
+ {
+ _AddParamShort(mpModernMask, hi_Open, Drawing->group->expanded ? hi_True : hi_False);
+ _AddParamShort(mpModernMask, hi_IsEmpty, (Drawing->group->cl.count == 0) ? hi_True : hi_False);
+ }
break;
case CLCIT_CONTACT:
@@ -1413,6 +1416,7 @@ void CLCPaint::_PaintRowItemsEx(HWND hwnd, HDC hdcMem, ClcData *dat, ClcContact
}
}
}
+ break;
case TC_TIME:
TCHAR szResult[80];
diff --git a/plugins/Clist_modern/src/modern_skinselector.cpp b/plugins/Clist_modern/src/modern_skinselector.cpp
index 89e7f970a2..26fd11ec91 100644
--- a/plugins/Clist_modern/src/modern_skinselector.cpp
+++ b/plugins/Clist_modern/src/modern_skinselector.cpp
@@ -57,7 +57,7 @@ DWORD mod_CalcHash(const char *szStr)
return hash;
}
-int AddModernMaskToList(MODERNMASK *mm, LISTMODERNMASK * mmTemplateList)
+static int AddModernMaskToList(MODERNMASK *mm, LISTMODERNMASK * mmTemplateList)
{
if (!mmTemplateList || !mm) return -1;
mmTemplateList->pl_Masks = (MODERNMASK *)mir_realloc(mmTemplateList->pl_Masks, sizeof(MODERNMASK)*(mmTemplateList->dwMaskCnt + 1));
@@ -77,7 +77,7 @@ int ClearMaskList(LISTMODERNMASK * mmTemplateList)
return 0;
}
-int DeleteMaskByItID(DWORD mID, LISTMODERNMASK *mmTemplateList)
+static int DeleteMaskByItID(DWORD mID, LISTMODERNMASK *mmTemplateList)
{
if (!mmTemplateList) return -1;
if (mID >= mmTemplateList->dwMaskCnt) return -1;
@@ -103,7 +103,7 @@ int DeleteMaskByItID(DWORD mID, LISTMODERNMASK *mmTemplateList)
}
-int ExchangeMasksByID(DWORD mID1, DWORD mID2, LISTMODERNMASK * mmTemplateList)
+static int ExchangeMasksByID(DWORD mID1, DWORD mID2, LISTMODERNMASK * mmTemplateList)
{
if (!mmTemplateList) return 0;
if (mID1 >= mmTemplateList->dwMaskCnt) return 0;
@@ -232,7 +232,7 @@ static BOOL _GetParamValue(char *szText, unsigned int &start, unsigned int lengt
return (value || param);
}
-int ParseToModernMask(MODERNMASK *mm, char *szText)
+static int ParseToModernMask(MODERNMASK *mm, char *szText)
{
if (!mm || !szText) return -1;
@@ -279,7 +279,7 @@ int ParseToModernMask(MODERNMASK *mm, char *szText)
return 0;
};
-BOOL CompareModernMask(MODERNMASK *mmValue, MODERNMASK *mmTemplate)
+static BOOL CompareModernMask(MODERNMASK *mmValue, MODERNMASK *mmTemplate)
{
//TODO
BOOL res = TRUE;
diff --git a/plugins/Clist_modern/src/modern_skinselector.h b/plugins/Clist_modern/src/modern_skinselector.h
index c145595c9d..e0cc3606c7 100644
--- a/plugins/Clist_modern/src/modern_skinselector.h
+++ b/plugins/Clist_modern/src/modern_skinselector.h
@@ -65,18 +65,11 @@ struct LISTMODERNMASK
};
/// PROTOTYPES
-int AddModernMaskToList(MODERNMASK *mm, LISTMODERNMASK *mmTemplateList);
int AddStrModernMaskToList(DWORD maskID, char *szStr, char *objectName, LISTMODERNMASK *mmTemplateList);
int SortMaskList(LISTMODERNMASK *mmList);
-
-int DeleteMaskByItID(DWORD mID, LISTMODERNMASK *mmTemplateList);
int ClearMaskList(LISTMODERNMASK *mmTemplateList);
-int ExchangeMasksByID(DWORD mID1, DWORD mID2, LISTMODERNMASK *mmTemplateList);
-int ParseToModernMask(MODERNMASK *mm, char *szText);
-BOOL CompareModernMask(MODERNMASK *mmValue, MODERNMASK *mmTemplate);
BOOL CompareStrWithModernMask(char * szValue, MODERNMASK *mmTemplate);
-MODERNMASK * FindMaskByStr(char * szValue, LISTMODERNMASK * mmTemplateList);
DWORD mod_CalcHash(const char * a);
int RegisterObjectByParce(char * ObjectName, char *Params);
SKINOBJECTDESCRIPTOR* skin_FindObjectByRequest(char *szValue, LISTMODERNMASK *mmTemplateList);