From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/mwclist/clc.c | 292 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 plugins/mwclist/clc.c (limited to 'plugins/mwclist/clc.c') 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; +} -- cgit v1.2.3