From cb4a46e7fbe62d788e66ed6121c717a2d22a4d7c Mon Sep 17 00:00:00 2001 From: watcherhd Date: Thu, 21 Apr 2011 14:14:52 +0000 Subject: svn.miranda.im is moving to a new home! git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@7 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- miranda-wine/src/modules/clist/contact.c | 185 +++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 miranda-wine/src/modules/clist/contact.c (limited to 'miranda-wine/src/modules/clist/contact.c') diff --git a/miranda-wine/src/modules/clist/contact.c b/miranda-wine/src/modules/clist/contact.c new file mode 100644 index 0000000..be14573 --- /dev/null +++ b/miranda-wine/src/modules/clist/contact.c @@ -0,0 +1,185 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2006 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 "commonheaders.h" +#include "clc.h" + +extern HANDLE hContactIconChangedEvent; + +int sortByStatus; +int sortByProto; +struct { + int status,order; +} statusModeOrder[]={ + {ID_STATUS_OFFLINE,500}, + {ID_STATUS_ONLINE,0}, + {ID_STATUS_AWAY,200}, + {ID_STATUS_DND,400}, + {ID_STATUS_NA,450}, + {ID_STATUS_OCCUPIED,100}, + {ID_STATUS_FREECHAT,50}, + {ID_STATUS_INVISIBLE,20}, + {ID_STATUS_ONTHEPHONE,150}, + {ID_STATUS_OUTTOLUNCH,425}}; + +static int GetContactStatus(HANDLE hContact) +{ + char* szProto = ( char* )CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if (szProto == NULL) + return ID_STATUS_OFFLINE; + return DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE); +} + +void fnChangeContactIcon(HANDLE hContact, int iIcon, int add) +{ + CallService(add ? MS_CLUI_CONTACTADDED : MS_CLUI_CONTACTSETICON, (WPARAM) hContact, iIcon); + NotifyEventHooks(hContactIconChangedEvent, (WPARAM) hContact, iIcon); +} + +int GetStatusModeOrdering(int statusMode) +{ + int i; + for (i = 0; i < SIZEOF(statusModeOrder); i++) + if (statusModeOrder[i].status == statusMode) + return statusModeOrder[i].order; + return 1000; +} + +void fnLoadContactTree(void) +{ + HANDLE hContact; + int i, status, hideOffline; + + CallService(MS_CLUI_LISTBEGINREBUILD, 0, 0); + for (i = 1;; i++) { + if ( cli.pfnGetGroupName(i, NULL) == NULL) + break; + CallService(MS_CLUI_GROUPADDED, i, 0); + } + + hideOffline = DBGetContactSettingByte(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT); + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) { + status = GetContactStatus(hContact); + if ((!hideOffline || status != ID_STATUS_OFFLINE) && !DBGetContactSettingByte(hContact, "CList", "Hidden", 0)) + cli.pfnChangeContactIcon(hContact, cli.pfnIconFromStatusMode((char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0), status, hContact), 1); + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + sortByStatus = DBGetContactSettingByte(NULL, "CList", "SortByStatus", SETTING_SORTBYSTATUS_DEFAULT); + sortByProto = DBGetContactSettingByte(NULL, "CList", "SortByProto", SETTING_SORTBYPROTO_DEFAULT); + CallService(MS_CLUI_SORTLIST, 0, 0); + CallService(MS_CLUI_LISTENDREBUILD, 0, 0); +} + +int fnCompareContacts(const struct ClcContact* c1, const struct ClcContact* c2) +{ + HANDLE a = c1->hContact, b = c2->hContact; + TCHAR namea[128], *nameb; + int statusa, statusb; + int rc; + + statusa = DBGetContactSettingWord((HANDLE) a, c1->proto, "Status", ID_STATUS_OFFLINE); + statusb = DBGetContactSettingWord((HANDLE) b, c2->proto, "Status", ID_STATUS_OFFLINE); + + if (sortByProto) { + /* deal with statuses, online contacts have to go above offline */ + if ((statusa == ID_STATUS_OFFLINE) != (statusb == ID_STATUS_OFFLINE)) { + return 2 * (statusa == ID_STATUS_OFFLINE) - 1; + } + /* both are online, now check protocols */ + rc = lstrcmpA( c1->proto, c2->proto); + if (rc != 0 && (c1->proto != NULL && c2->proto != NULL)) + return rc; + /* protocols are the same, order by display name */ + } + + if (sortByStatus) { + int ordera, orderb; + ordera = GetStatusModeOrdering(statusa); + orderb = GetStatusModeOrdering(statusb); + if (ordera != orderb) + return ordera - orderb; + } + else { + //one is offline: offline goes below online + if ((statusa == ID_STATUS_OFFLINE) != (statusb == ID_STATUS_OFFLINE)) { + return 2 * (statusa == ID_STATUS_OFFLINE) - 1; + } + } + + nameb = cli.pfnGetContactDisplayName( a, 0); + _tcsncpy(namea, nameb, SIZEOF(namea)); + namea[ SIZEOF(namea)-1 ] = 0; + nameb = cli.pfnGetContactDisplayName( b, 0); + + //otherwise just compare names + return _tcsicmp(namea, nameb); +} + +static int resortTimerId = 0; +static VOID CALLBACK SortContactsTimer(HWND hwnd, UINT message, UINT idEvent, DWORD dwTime) +{ + KillTimer(NULL, resortTimerId); + resortTimerId = 0; + CallService(MS_CLUI_SORTLIST, 0, 0); +} + +void fnSortContacts(void) +{ + //avoid doing lots of resorts in quick succession + sortByStatus = DBGetContactSettingByte(NULL, "CList", "SortByStatus", SETTING_SORTBYSTATUS_DEFAULT); + sortByProto = DBGetContactSettingByte(NULL, "CList", "SortByProto", SETTING_SORTBYPROTO_DEFAULT); + if (resortTimerId) + KillTimer(NULL, resortTimerId); + // setting this to a higher delay causes shutdown waits. + resortTimerId = SetTimer(NULL, 0, 500, SortContactsTimer); +} + +int ContactChangeGroup(WPARAM wParam, LPARAM lParam) +{ + CallService(MS_CLUI_CONTACTDELETED, wParam, 0); + if ((HANDLE) lParam == NULL) + DBDeleteContactSetting((HANDLE) wParam, "CList", "Group"); + else + DBWriteContactSettingTString((HANDLE) wParam, "CList", "Group", cli.pfnGetGroupName(lParam, NULL)); + CallService(MS_CLUI_CONTACTADDED, wParam, + cli.pfnIconFromStatusMode((char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0), GetContactStatus((HANDLE) wParam), (HANDLE) wParam)); + return 0; +} + +int fnSetHideOffline(WPARAM wParam, LPARAM lParam) +{ + switch ((int) wParam) { + case 0: + DBWriteContactSettingByte(NULL, "CList", "HideOffline", 0); + break; + case 1: + DBWriteContactSettingByte(NULL, "CList", "HideOffline", 1); + break; + case -1: + DBWriteContactSettingByte(NULL, "CList", "HideOffline", + (BYTE) ! DBGetContactSettingByte(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT)); + break; + } + cli.pfnLoadContactTree(); + return 0; +} -- cgit v1.2.3