summaryrefslogtreecommitdiff
path: root/plugins/mwclist/clc.c
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
commit48540940b6c28bb4378abfeb500ec45a625b37b6 (patch)
tree2ef294c0763e802f91d868bdef4229b6868527de /plugins/mwclist/clc.c
parent5c350913f011e119127baeb32a6aedeb4f0d33bc (diff)
initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/mwclist/clc.c')
-rw-r--r--plugins/mwclist/clc.c292
1 files changed, 292 insertions, 0 deletions
diff --git a/plugins/mwclist/clc.c b/plugins/mwclist/clc.c
new file mode 100644
index 0000000000..831e4e5eb6
--- /dev/null
+++ b/plugins/mwclist/clc.c
@@ -0,0 +1,292 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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"
+
+int DefaultImageListColorDepth=ILC_COLOR32;
+
+HIMAGELIST himlCListClc;
+
+static HANDLE hSettingChanged1;
+
+int BgStatusBarChange(WPARAM wParam,LPARAM lParam);
+
+int BgClcChange(WPARAM wParam,LPARAM lParam);
+int OnFrameTitleBarBackgroundChange(WPARAM wParam,LPARAM lParam);
+
+void InitDisplayNameCache(SortedList *list);
+void FreeDisplayNameCache(SortedList *list);
+void LoadExtraImageFunc( void );
+
+void LoadExtraImageFunc( void );
+void UnloadCLUIModule( void );
+
+extern int sortByStatus;
+struct ClcContact * hitcontact=NULL;
+
+extern LRESULT ( CALLBACK *saveContactListControlWndProc )(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+static int stopStatusUpdater = 0;
+void StatusUpdaterThread(HWND hwndDlg)
+{
+ int i,curdelay,lastcheck=0;
+ HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+
+ SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_LOWEST);
+
+ while (!stopStatusUpdater) {
+ curdelay=DBGetContactSettingByte(hContact,"CList","StatusMsgAutoDelay",15000);
+ if (curdelay<5000) curdelay=5000;
+
+ if ((int)(GetTickCount()-lastcheck)>curdelay)
+ {
+ lastcheck=GetTickCount();
+ if (DBGetContactSettingByte(hContact,"CList","StatusMsgAuto",0)) {
+ for (i=0; i<5; i++) {
+ if (hContact!=NULL) {
+ pdisplayNameCacheEntry pdnce =(pdisplayNameCacheEntry)pcli->pfnGetCacheEntry((HANDLE)hContact);
+ if (pdnce && !pdnce->protoNotExists && pdnce->szProto)
+ {
+ CallContactService(hContact, PSS_GETAWAYMSG, 0, 0);
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+ if (hContact==NULL) {
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ if (hContact==NULL) break;
+ }
+ Sleep(500);
+ }
+ }
+ }
+ //Sleep(DBGetContactSettingByte(hContact,"CList","StatusMsgAutoDelay",100));
+ Sleep(200);
+ }
+}
+
+HMENU BuildGroupPopupMenu( struct ClcGroup* group )
+{
+ return (HMENU)CallService(MS_CLIST_MENUBUILDSUBGROUP,(WPARAM)group,0);
+}
+
+void SortClcByTimer (HWND hwnd)
+{
+ KillTimer(hwnd,TIMERID_DELAYEDRESORTCLC);
+ SetTimer(hwnd,TIMERID_DELAYEDRESORTCLC,DBGetContactSettingByte(NULL,"CLUI","DELAYEDTIMER",200),NULL);
+}
+
+static int ClcSettingChanged(WPARAM wParam, LPARAM lParam)
+{
+ DBCONTACTWRITESETTING *cws=(DBCONTACTWRITESETTING*)lParam;
+
+ if ((HANDLE)wParam != NULL && !strcmp(cws->szModule,"MetaContacts") && !strcmp(cws->szSetting,"Handle"))
+ pcli->pfnClcBroadcast( INTM_NAMEORDERCHANGED, 0, 0 );
+
+ if ((HANDLE)wParam!=NULL&&!strcmp(cws->szModule,"CList")) {
+ if( !strcmp( cws->szSetting, "noOffline" ))
+ pcli->pfnClcBroadcast( INTM_NAMEORDERCHANGED, wParam, lParam );
+ else if(!strcmp(cws->szSetting,"StatusMsg"))
+ pcli->pfnClcBroadcast( INTM_STATUSMSGCHANGED, wParam, lParam );
+ }
+ return 0;
+}
+
+static int ClcModulesLoaded(WPARAM wParam,LPARAM lParam)
+{
+ CallService(MS_BACKGROUNDCONFIG_REGISTER,(WPARAM)"StatusBar Background/StatusBar",0);
+ CallService(MS_BACKGROUNDCONFIG_REGISTER,(WPARAM)"List Background/CLC",0);
+ CallService(MS_BACKGROUNDCONFIG_REGISTER,(WPARAM)"Frames TitleBar BackGround/FrameTitleBar",0);
+ HookEvent(ME_BACKGROUNDCONFIG_CHANGED,BgClcChange);
+ HookEvent(ME_BACKGROUNDCONFIG_CHANGED,BgStatusBarChange);
+ HookEvent(ME_BACKGROUNDCONFIG_CHANGED,OnFrameTitleBarBackgroundChange);
+ return 0;
+}
+
+static int ClcShutdown(WPARAM wParam, LPARAM lParam)
+{
+ UnhookEvent(hSettingChanged1);
+ UnloadCLUIModule();
+ return 0;
+}
+
+LRESULT CALLBACK ContactListControlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct ClcData *dat = (struct ClcData*)GetWindowLongPtr(hwnd,0);
+ if ( msg >= CLM_FIRST && msg < CLM_LAST )
+ return pcli->pfnProcessExternalMessages(hwnd,dat,msg,wParam,lParam);
+
+ switch (msg) {
+ case WM_CREATE:
+ dat = (struct ClcData*)mir_calloc( sizeof(struct ClcData));
+ SetWindowLong(hwnd,0,(LPARAM)dat);
+ InitDisplayNameCache(&dat->lCLCContactsCache);
+ break;
+
+ case INTM_ICONCHANGED:
+ { struct ClcContact *contact=NULL;
+ struct ClcGroup *group=NULL;
+ int recalcScrollBar=0,shouldShow;
+ HANDLE hSelItem=NULL;
+ struct ClcContact *selcontact=NULL;
+ pdisplayNameCacheEntry cacheEntry = GetContactFullCacheEntry((HANDLE)wParam);
+
+ WORD status;
+ int NeedResort=0;
+
+ char *szProto = cacheEntry->szProto;
+ if(szProto==NULL) status=ID_STATUS_OFFLINE;
+ else status=cacheEntry->status;
+
+ shouldShow=(GetWindowLong(hwnd,GWL_STYLE)&CLS_SHOWHIDDEN || !cacheEntry->Hidden) && (!pcli->pfnIsHiddenMode(dat,status)||cacheEntry->noHiddenOffline || CallService(MS_CLIST_GETCONTACTICON,wParam,0)!=LOWORD(lParam)); //this means an offline msg is flashing, so the contact should be shown
+ if(!FindItem(hwnd,dat,(HANDLE)wParam,&contact,&group,NULL)) {
+ if(shouldShow && CallService(MS_DB_CONTACT_IS, wParam, 0)) {
+ if(dat->selection>=0 && GetRowByIndex(dat,dat->selection,&selcontact,NULL)!=-1)
+ hSelItem=pcli->pfnContactToHItem(selcontact);
+ AddContactToTree(hwnd,dat,(HANDLE)wParam,0,0);
+ NeedResort=1;
+ recalcScrollBar=1;
+ FindItem(hwnd,dat,(HANDLE)wParam,&contact,NULL,NULL);
+ if (contact) {
+ contact->iImage=(WORD)lParam;
+ pcli->pfnNotifyNewContact(hwnd,(HANDLE)wParam);
+ dat->NeedResort=1;
+ }
+ }
+ }
+ else {
+ //item in list already
+ DWORD style=GetWindowLong(hwnd,GWL_STYLE);
+ if(contact->iImage== (WORD)lParam) break;
+ if (sortByStatus) dat->NeedResort=1;
+
+ if(!shouldShow && !(style&CLS_NOHIDEOFFLINE) && (style&CLS_HIDEOFFLINE || group->hideOffline)) {
+ if(dat->selection>=0 && GetRowByIndex(dat,dat->selection,&selcontact,NULL)!=-1)
+ hSelItem=pcli->pfnContactToHItem(selcontact);
+ RemoveItemFromGroup(hwnd,group,contact,0);
+ recalcScrollBar=1;
+ dat->NeedResort=1;
+ }
+ else {
+ int oldflags;
+ contact->iImage=(WORD)lParam;
+ oldflags=contact->flags;
+ if(!pcli->pfnIsHiddenMode(dat,status)||cacheEntry->noHiddenOffline) contact->flags|=CONTACTF_ONLINE;
+ else contact->flags&=~CONTACTF_ONLINE;
+ if (oldflags!=contact->flags)
+ dat->NeedResort=1;
+ } }
+ if(hSelItem) {
+ struct ClcGroup *selgroup;
+ if(FindItem(hwnd,dat,hSelItem,&selcontact,&selgroup,NULL))
+ dat->selection=GetRowsPriorTo(&dat->list,selgroup,li.List_IndexOf((SortedList*)&selgroup->cl, selcontact));
+ else
+ dat->selection=-1;
+ }
+
+ SortClcByTimer(hwnd);
+ if(recalcScrollBar) RecalcScrollBar(hwnd,dat);
+ goto LBL_Exit;
+ }
+ case INTM_STATUSMSGCHANGED:
+ { struct ClcContact *contact=NULL;
+ struct ClcGroup *group=NULL;
+ DBVARIANT dbv;
+
+ if (!(dat->style&CLS_SHOWSTATUSMESSAGES)) break;
+ if(FindItem(hwnd,dat,(HANDLE)wParam,&contact,&group,NULL) && contact!=NULL) {
+ contact->flags &= ~CONTACTF_STATUSMSG;
+ if (!DBGetContactSettingTString((HANDLE)wParam, "CList", "StatusMsg", &dbv)) {
+ int j;
+ if (dbv.ptszVal==NULL||_tcslen(dbv.ptszVal)==0) break;
+ lstrcpyn(contact->szStatusMsg, dbv.ptszVal, SIZEOF(contact->szStatusMsg));
+ for (j=(int)_tcslen(contact->szStatusMsg)-1;j>=0;j--) {
+ if (contact->szStatusMsg[j]=='\r' || contact->szStatusMsg[j]=='\n' || contact->szStatusMsg[j]=='\t') {
+ contact->szStatusMsg[j] = ' ';
+ }
+ }
+ DBFreeVariant(&dbv);
+ if (_tcslen(contact->szStatusMsg)>0) {
+ contact->flags |= CONTACTF_STATUSMSG;
+ dat->NeedResort=TRUE;
+ }
+ }
+ }
+
+ InvalidateRect(hwnd,NULL,TRUE);
+
+ SortClcByTimer(hwnd);
+ RecalcScrollBar(hwnd,dat);
+ goto LBL_Exit;
+ }
+ case WM_TIMER:
+ if (wParam==TIMERID_DELAYEDREPAINT) {
+ KillTimer(hwnd,TIMERID_DELAYEDREPAINT);
+ InvalidateRect(hwnd,NULL,FALSE);
+ break;
+ }
+
+ if ( wParam == TIMERID_SUBEXPAND) {
+ KillTimer(hwnd,TIMERID_SUBEXPAND);
+ if (hitcontact) {
+ if (hitcontact->SubExpanded) hitcontact->SubExpanded=0; else hitcontact->SubExpanded=1;
+ DBWriteContactSettingByte(hitcontact->hContact,"CList","Expanded",hitcontact->SubExpanded);
+ }
+ hitcontact=NULL;
+ dat->NeedResort=1;
+ SortCLC(hwnd,dat,1);
+ RecalcScrollBar(hwnd,dat);
+ break;
+ }
+ break;
+
+ case WM_DESTROY:
+ FreeDisplayNameCache(&dat->lCLCContactsCache);
+ stopStatusUpdater = 1;
+ break;
+ }
+
+ { LRESULT res = saveContactListControlWndProc(hwnd, msg, wParam, lParam);
+ switch (msg) {
+ case WM_CREATE:
+ mir_forkthread(StatusUpdaterThread,0);
+ break;
+ }
+ return res;
+ }
+
+LBL_Exit:
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+int LoadCLCModule(void)
+{
+ LoadCLUIFramesModule();
+ LoadExtraImageFunc();
+
+ himlCListClc=(HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST,0,0);
+
+ HookEvent(ME_SYSTEM_MODULESLOADED,ClcModulesLoaded);
+ hSettingChanged1=HookEvent(ME_DB_CONTACT_SETTINGCHANGED,ClcSettingChanged);
+ HookEvent(ME_OPT_INITIALISE,ClcOptInit);
+ HookEvent(ME_SYSTEM_SHUTDOWN,ClcShutdown);
+ return 0;
+}