From 725f68b6808a8a30778f58223fac75386f082785 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Fri, 18 May 2012 22:10:43 +0000 Subject: plugins folders renaming git-svn-id: http://svn.miranda-ng.org/main/trunk@61 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Modernb/modern_clcitems.cpp | 826 ++++++++++++++++++++++++++++++++++++ 1 file changed, 826 insertions(+) create mode 100644 plugins/Modernb/modern_clcitems.cpp (limited to 'plugins/Modernb/modern_clcitems.cpp') diff --git a/plugins/Modernb/modern_clcitems.cpp b/plugins/Modernb/modern_clcitems.cpp new file mode 100644 index 0000000000..36ab3bca7a --- /dev/null +++ b/plugins/Modernb/modern_clcitems.cpp @@ -0,0 +1,826 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2008 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 "hdr/modern_commonheaders.h" +#include "m_clc.h" +#include "hdr/modern_clc.h" +#include "hdr/modern_clist.h" +#include "m_metacontacts.h" +#include "hdr/modern_commonprototypes.h" + +void AddSubcontacts(struct ClcData *dat, struct ClcContact * cont, BOOL showOfflineHereGroup) +{ + int subcount,i,j; + HANDLE hsub; + pdisplayNameCacheEntry cacheEntry; + cacheEntry=(pdisplayNameCacheEntry)pcli->pfnGetCacheEntry(cont->hContact); + cont->SubExpanded=(ModernGetSettingByte(cont->hContact,"CList","Expanded",0) && (ModernGetSettingByte(NULL,"CLC","MetaExpanding",SETTING_METAEXPANDING_DEFAULT))); + subcount=(int)CallService(MS_MC_GETNUMCONTACTS,(WPARAM)cont->hContact,0); + + if (subcount <= 0) { + cont->isSubcontact=0; + cont->subcontacts=NULL; + cont->SubAllocated=0; + return; + } + + cont->isSubcontact=0; + mir_free(cont->subcontacts); + cont->subcontacts=(struct ClcContact *) mir_calloc(sizeof(struct ClcContact)*subcount); + cont->SubAllocated=subcount; + i=0; + for (j=0; jhContact,j); + cacheEntry=(pdisplayNameCacheEntry)pcli->pfnGetCacheEntry(hsub); + wStatus=pdnce___GetStatus( cacheEntry ); + if (showOfflineHereGroup||(!(ModernGetSettingByte(NULL,"CLC","MetaHideOfflineSub",SETTING_METAHIDEOFFLINESUB_DEFAULT) && ModernGetSettingByte(NULL,"CList","HideOffline",SETTING_HIDEOFFLINE_DEFAULT) ) || + wStatus!=ID_STATUS_OFFLINE ) + //&& + //(!cacheEntry->Hidden || style&CLS_SHOWHIDDEN) + ) + + { + cont->subcontacts[i].hContact=cacheEntry->m_cache_hContact; + + cont->subcontacts[i].avatar_pos = AVATAR_POS_DONT_HAVE; + Cache_GetAvatar(dat, &cont->subcontacts[i]); + + cont->subcontacts[i].iImage=CallService(MS_CLIST_GETCONTACTICON,(WPARAM)cacheEntry->m_cache_hContact,1); + memset(cont->subcontacts[i].iExtraImage,0xFF,sizeof(cont->subcontacts[i].iExtraImage)); + memset((void*)cont->subcontacts[i].iWideExtraImage,0xFF,sizeof(cont->subcontacts[i].iWideExtraImage)); + cont->subcontacts[i].proto=cacheEntry->m_cache_cszProto; + cont->subcontacts[i].type=CLCIT_CONTACT; + cont->subcontacts[i].flags=0;//CONTACTF_ONLINE; + cont->subcontacts[i].isSubcontact=i+1; + cont->subcontacts[i].lastPaintCounter=0; + cont->subcontacts[i].subcontacts=cont; + cont->subcontacts[i].image_is_special=FALSE; + //cont->subcontacts[i].status=cacheEntry->status; + Cache_GetTimezone(dat, (&cont->subcontacts[i])->hContact); + Cache_GetText(dat, &cont->subcontacts[i],1); + + { + int apparentMode; + char *szProto; + int idleMode; + szProto=cacheEntry->m_cache_cszProto; + if(szProto!=NULL && !pcli->pfnIsHiddenMode(dat,wStatus)) + cont->subcontacts[i].flags|=CONTACTF_ONLINE; + apparentMode=szProto!=NULL?cacheEntry->ApparentMode:0; + apparentMode=szProto!=NULL?cacheEntry->ApparentMode:0; + if(apparentMode==ID_STATUS_OFFLINE) cont->subcontacts[i].flags|=CONTACTF_INVISTO; + else if(apparentMode==ID_STATUS_ONLINE) cont->subcontacts[i].flags|=CONTACTF_VISTO; + else if(apparentMode) cont->subcontacts[i].flags|=CONTACTF_VISTO|CONTACTF_INVISTO; + if(cacheEntry->NotOnList) cont->subcontacts[i].flags|=CONTACTF_NOTONLIST; + idleMode=szProto!=NULL?cacheEntry->IdleTS:0; + if (idleMode) cont->subcontacts[i].flags|=CONTACTF_IDLE; + } + i++; + } } + + cont->SubAllocated=i; + if (!i && cont->subcontacts != NULL) mir_free_and_nill(cont->subcontacts); +} + +int cli_AddItemToGroup(struct ClcGroup *group,int iAboveItem) +{ + if ( group == NULL ) return 0; + + iAboveItem = corecli.pfnAddItemToGroup( group, iAboveItem ); + ClearRowByIndexCache(); + return iAboveItem; +} + +struct ClcGroup *cli_AddGroup(HWND hwnd,struct ClcData *dat,const TCHAR *szName,DWORD flags,int groupId,int calcTotalMembers) +{ + struct ClcGroup* result; + ClearRowByIndexCache(); + if (!dat->force_in_dialog && !(GetWindowLong(hwnd, GWL_STYLE) & CLS_SHOWHIDDEN)) + if (!lstrcmp(_T("-@-HIDDEN-GROUP-@-"),szName)) //group is hidden + { + ClearRowByIndexCache(); + return NULL; + } + result = corecli.pfnAddGroup( hwnd, dat, szName, flags, groupId, calcTotalMembers); + /* ToDo: fix some times valid contact with valid group are placed to root + if ( result == NULL ) + { + result = &dat->list; + } + */ + ClearRowByIndexCache(); + return result; +} + +void cli_FreeContact(struct ClcContact *p) +{ + if ( p->SubAllocated) { + if ( p->subcontacts && !p->isSubcontact) { + int i; + for ( 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_nill(p->subcontacts); + } } + + 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( struct ClcGroup* group ) +{ + corecli.pfnFreeGroup( group ); + ClearRowByIndexCache(); +} + +int cli_AddInfoItemToGroup(struct ClcGroup *group,int flags,const TCHAR *pszText) +{ + int i = corecli.pfnAddInfoItemToGroup( group, flags, pszText ); + ClearRowByIndexCache(); + return i; +} + +static void _LoadDataToContact(struct ClcContact * cont, struct ClcGroup *group, struct ClcData *dat, HANDLE hContact) +{ + pdisplayNameCacheEntry cacheEntry=NULL; + WORD apparentMode; + DWORD idleMode; + char * szProto; + + 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); + cacheEntry=(pdisplayNameCacheEntry)pcli->pfnGetCacheEntry(hContact); + + szProto=cacheEntry->m_cache_cszProto; + cont->proto=szProto; + + if(szProto!=NULL&&!pcli->pfnIsHiddenMode(dat,pdnce___GetStatus( cacheEntry ))) + cont->flags |= CONTACTF_ONLINE; + + 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; + idleMode=szProto!=NULL?cacheEntry->IdleTS:0; + + if (idleMode) + cont->flags|=CONTACTF_IDLE; + + + //Add subcontacts + if (szProto) + { + if ( g_szMetaModuleName && dat->IsMetaContactsEnabled && mir_strcmp(cont->proto,g_szMetaModuleName)==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=CallService(MS_CLIST_GETCONTACTICON,(WPARAM)hContact,1); + cont->bContactRate=ModernGetSettingByte(hContact, "CList", "Rate",0); +} + +static struct ClcContact * AddContactToGroup(struct ClcData *dat,struct ClcGroup *group, pdisplayNameCacheEntry cacheEntry) +{ + HANDLE hContact; + int i; + if (cacheEntry==NULL) return NULL; + if (group==NULL) return NULL; + if (dat==NULL) return NULL; + hContact=cacheEntry->m_cache_hContact; + dat->NeedResort=1; + 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=(pdisplayNameCacheEntry)pcli->pfnGetCacheEntry(hContact); + ClearRowByIndexCache(); + return group->cl.items[i]; +} + +void * AddTempGroup(HWND hwnd,struct ClcData *dat,const TCHAR *szName,DWORD flags,int groupId,int calcTotalMembers) +{ + int i=0; + int f=0; + TCHAR * szGroupName; + DWORD groupFlags; +#ifdef UNICODE + char *mbuf=mir_u2a((TCHAR *)szName); +#else + char *mbuf=mir_strdup((char *)szName); +#endif + if (wildcmp(mbuf,"-@-HIDDEN-GROUP-@-",0)) + { + mir_free_and_nill(mbuf); + return NULL; + } + mir_free_and_nill(mbuf); + for(i=1;;i++) + { + szGroupName = pcli->pfnGetGroupName(i,&groupFlags); + if(szGroupName==NULL) break; + if (!mir_tstrcmpi(szGroupName,szName)) f=1; + } + if (!f) + { + char buf[20]; + TCHAR b2[255]; + void * res=NULL; + mir_snprintf(buf,SIZEOF(buf),"%d",(i-1)); + mir_sntprintf(b2,SIZEOF(b2),_T("#%s"),szName); + b2[0]=1|GROUPF_EXPANDED; + ModernWriteSettingTString(NULL,"CListGroups",buf,b2); + pcli->pfnGetGroupName(i,&groupFlags); + res=cli_AddGroup(hwnd,dat,szName,groupFlags,i,0); + return res; + } + return NULL; +} + +void cli_AddContactToTree(HWND hwnd,struct ClcData *dat,HANDLE hContact,int updateTotalCount,int checkHideOffline) +{ + struct ClcGroup *group; + struct ClcContact * cont; + pdisplayNameCacheEntry cacheEntry=(pdisplayNameCacheEntry)pcli->pfnGetCacheEntry(hContact); + if(dat->IsMetaContactsEnabled && cacheEntry && cacheEntry->m_cache_nHiddenSubcontact) return; //contact should not be added + if(!dat->IsMetaContactsEnabled && cacheEntry && g_szMetaModuleName && !mir_strcmp(cacheEntry->m_cache_cszProto,g_szMetaModuleName)) return; + corecli.pfnAddContactToTree(hwnd,dat,hContact,updateTotalCount,checkHideOffline); + if (FindItem(hwnd,dat,hContact,&cont,&group,NULL,FALSE)) + _LoadDataToContact(cont, group, dat, hContact); + return; +} + +void cli_DeleteItemFromTree(HWND hwnd,HANDLE hItem) +{ + struct ClcData *dat = (struct ClcData *) GetWindowLongPtr(hwnd, 0); + ClearRowByIndexCache(); + corecli.pfnDeleteItemFromTree(hwnd, hItem); + + //check here contacts are not resorting + if (hwnd==pcli->hwndContactTree) + pcli->pfnFreeCacheItem(pcli->pfnGetCacheEntry(hItem)); + dat->NeedResort=1; + ClearRowByIndexCache(); +} + + +__inline BOOL CLCItems_IsShowOfflineGroup(struct ClcGroup* group) +{ + DWORD groupFlags=0; + if (!group) return FALSE; + if (group->hideOffline) return FALSE; + pcli->pfnGetGroupName(group->groupId,&groupFlags); + return (groupFlags&GROUPF_SHOWOFFLINE)!=0; +} + +HANDLE SaveSelection( struct ClcData *dat ) +{ + ClcContact * selcontact = NULL; + + if ( pcli->pfnGetRowByIndex( dat, dat->selection, &selcontact, NULL ) == -1 ) + return NULL; + else + return pcli->pfnContactToHItem( selcontact ); +} + +int RestoreSelection( struct ClcData *dat, HANDLE 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, li.List_IndexOf((SortedList*)&selgroup->cl, selcontact ) ); + } + else + { + dat->selection = pcli->pfnGetRowsPriorTo(&dat->list, selgroup, li.List_IndexOf((SortedList*)&selgroup->cl, selcontact->subcontacts ) ); + + if (dat->selection != -1 ) + dat->selection += selcontact->isSubcontact; + } + return dat->selection; + +} + +void cliRebuildEntireList(HWND hwnd,struct ClcData *dat) +{ + DWORD style=GetWindowLong(hwnd,GWL_STYLE); + HANDLE hContact; + struct ClcContact * cont; + struct ClcGroup *group; + static int rebuildCounter=0; + + BOOL PlaceOfflineToRoot=ModernGetSettingByte(NULL,"CList","PlaceOfflineToRoot",SETTING_PLACEOFFLINETOROOT_DEFAULT); + KillTimer(hwnd,TIMERID_REBUILDAFTER); + + 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=ModernGetSettingByte(NULL,"CLC","HideOfflineRoot",SETTING_HIDEOFFLINEATROOT_DEFAULT) && style&CLS_USEGROUPS; + dat->list.cl.count = dat->list.cl.limit = 0; + dat->list.cl.increment = 50; + dat->NeedResort=1; + + HANDLE hSelected = SaveSelection( dat ); + dat->selection=-1; + dat->HiLightMode=ModernGetSettingByte(NULL,"CLC","HiLightMode",SETTING_HILIGHTMODE_DEFAULT); + { + int i; + TCHAR *szGroupName; + DWORD groupFlags; + + for(i=1;;i++) { + szGroupName=pcli->pfnGetGroupName(i,&groupFlags); //UNICODE + if(szGroupName==NULL) break; + cli_AddGroup(hwnd,dat,szGroupName,groupFlags,i,0); + } + } + + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + while(hContact) + { + pdisplayNameCacheEntry cacheEntry=NULL; + int nHiddenStatus; + cont=NULL; + cacheEntry=(pdisplayNameCacheEntry)pcli->pfnGetCacheEntry(hContact); + + nHiddenStatus=CLVM_GetContactHiddenStatus(hContact, NULL, dat); + if ( (style&CLS_SHOWHIDDEN && nHiddenStatus!=-1) || !nHiddenStatus) + { + + if(lstrlen(cacheEntry->m_cache_tcsGroup)==0) + group=&dat->list; + else { + group=cli_AddGroup(hwnd,dat,cacheEntry->m_cache_tcsGroup,(DWORD)-1,0,0); + } + if(group!=NULL) + { + WORD wStatus=pdnce___GetStatus( cacheEntry ); + if (wStatus==ID_STATUS_OFFLINE) + if (PlaceOfflineToRoot) + group=&dat->list; + group->totalMembers++; + + if(!(style&CLS_NOHIDEOFFLINE) && (style&CLS_HIDEOFFLINE || group->hideOffline)) + { + if(cacheEntry->m_cache_cszProto==NULL) { + if(!pcli->pfnIsHiddenMode(dat,ID_STATUS_OFFLINE)||cacheEntry->m_cache_nNoHiddenOffline || CLCItems_IsShowOfflineGroup(group)) + cont=AddContactToGroup(dat,group,cacheEntry); + } + else + if(!pcli->pfnIsHiddenMode(dat,wStatus)||cacheEntry->m_cache_nNoHiddenOffline || CLCItems_IsShowOfflineGroup(group)) + cont=AddContactToGroup(dat,group,cacheEntry); + } + else cont=AddContactToGroup(dat,group,cacheEntry); + } + } + if (cont) + { + cont->SubAllocated=0; + if (cont->proto && g_szMetaModuleName && dat->IsMetaContactsEnabled && strcmp(cont->proto,g_szMetaModuleName)==0) + AddSubcontacts(dat,cont,CLCItems_IsShowOfflineGroup(group)); + } + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0); + } + + 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, struct ClcData *dat, int useInsertionSort ) +{ + HANDLE hSelected = SaveSelection( dat ); + + corecli.pfnSortCLC(hwnd,dat,useInsertionSort); + + RestoreSelection( dat, hSelected ); +} + +int GetNewSelection(struct ClcGroup *group, int selection, int direction) +{ + int lastcount=0, count=0;//group->cl.count; + if (selection<0) { + return 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) { + if (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 { + HANDLE hContact; + BYTE iExtraImage[MAXEXTRACOLUMNS]; + WORD iWideExtraImage[MAXEXTRACOLUMNS]; + int checked; +}; + +struct SavedGroupState_t { + int groupId,expanded; +}; + +struct SavedInfoState_t { + int parentId; + struct ClcContact contact; +}; + +BOOL LOCK_RECALC_SCROLLBAR=FALSE; +void cli_SaveStateAndRebuildList(HWND hwnd, struct ClcData *dat) +{ + LOCK_RECALC_SCROLLBAR=TRUE; + + NMCLISTCONTROL nm; + int i, j; + OBJLIST savedGroup( 4 ); + OBJLIST savedContact( 4 ); + OBJLIST savedInfo( 4 ); + + struct ClcGroup *group; + struct ClcContact *contact; + + pcli->pfnHideInfoTip(hwnd, dat); + KillTimer(hwnd, TIMERID_INFOTIP); + KillTimer(hwnd, TIMERID_RENAME); + pcli->pfnEndRename(hwnd, dat, 1); + + dat->NeedResort = 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; + CopyMemory(p->iExtraImage, group->cl.items[group->scanIndex]->iExtraImage, + sizeof(group->cl.items[group->scanIndex]->iExtraImage)); + + CopyMemory((void*)p->iWideExtraImage, (void*)group->cl.items[group->scanIndex]->iWideExtraImage, + sizeof(group->cl.items[group->scanIndex]->iWideExtraImage)); + + 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) { + CopyMemory(group->cl.items[group->scanIndex]->iExtraImage, savedContact[i].iExtraImage, + sizeof(group->cl.items[group->scanIndex]->iExtraImage)); + + CopyMemory((void*)group->cl.items[group->scanIndex]->iWideExtraImage, (void*)savedContact[i].iWideExtraImage, + sizeof(group->cl.items[group->scanIndex]->iWideExtraImage)); + + if (savedContact[i].checked) + group->cl.items[group->scanIndex]->flags |= CONTACTF_CHECKED; + break; + } + } + group->scanIndex++; + } + savedGroup.destroy(); + savedContact.destroy(); + + for (i = 0; i < savedInfo.getCount(); i++) { + if (savedInfo[i].parentId == -1) + group = &dat->list; + else { + if (!pcli->pfnFindItem(hwnd, dat, (HANDLE) (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; + } + savedInfo.destroy(); + + 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); +} + + +WORD pdnce___GetStatus(pdisplayNameCacheEntry pdnce) +{ + if (!pdnce) + return ID_STATUS_OFFLINE; + else + return pdnce->m_cache_nStatus; + /* + // this stub will replace direct usage of m_cache_nStatus and will be substituted by getting info from DB directrly + if (!pdnce) return ID_STATUS_OFFLINE; + if (!pdnce->m_cache_cszProto) return ID_STATUS_OFFLINE; + if (!pdnce->m_cache_hContact) return ID_STATUS_OFFLINE; + return DBGetContactSettingWord( pdnce->m_cache_hContact, pdnce->m_cache_cszProto, "Status" , ID_STATUS_OFFLINE ); + */ +} + + +void pdnce___SetStatus( pdisplayNameCacheEntry pdnce, WORD wStatus ) +{ + if (pdnce) pdnce->m_cache_nStatus=wStatus; +} +struct ClcContact* cliCreateClcContact( void ) +{ + struct ClcContact* contact=(struct ClcContact*)mir_calloc(sizeof( struct ClcContact ) ); + memset((void*)contact->iWideExtraImage,0xFF,sizeof(contact->iWideExtraImage)); + return contact; +} + +ClcCacheEntryBase* cliCreateCacheItem( HANDLE hContact ) +{ + pdisplayNameCacheEntry p = (pdisplayNameCacheEntry)mir_calloc(sizeof( displayNameCacheEntry )); + if ( p ) + { + memset(p,0,sizeof( displayNameCacheEntry )); + p->m_cache_hContact = hContact; + InvalidateDNCEbyPointer(hContact,p,0); + p->szSecondLineText=NULL; + p->szThirdLineText=NULL; + p->ssSecondLine.plText=NULL; + p->ssThirdLine.plText=NULL; + } + return (ClcCacheEntryBase*)p; +} + + + +void cliInvalidateDisplayNameCacheEntry(HANDLE hContact) +{ + pdisplayNameCacheEntry p; + p = (pdisplayNameCacheEntry) pcli->pfnGetCacheEntry(hContact); + if (p) InvalidateDNCEbyPointer(hContact,p,0); + return; +} + +char* cli_GetGroupCountsText(struct ClcData *dat, struct ClcContact *contact) +{ + char * res; + + res=corecli.pfnGetGroupCountsText(dat, contact); + + return res; +} + +int cliGetGroupContentsCount(struct ClcGroup *group, int visibleOnly) +{ + int count = group->cl.count; + struct 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(HANDLE hContact, char *szProto, struct ClcData *dat) +{ + int dbHidden = ModernGetSettingByte(hContact, "CList", "Hidden", 0); // default hidden state, always respect it. + int filterResult = 1; + DBVARIANT dbv = {0}; + char szTemp[64]; + TCHAR szGroupMask[256]; + DWORD dwLocalMask; + PDNCE pdnce=(PDNCE)pcli->pfnGetCacheEntry(hContact); + BOOL fEmbedded=dat->force_in_dialog; + // always hide subcontacts (but show them on embedded contact lists) + + if(g_CluiData.bMetaAvail && dat != NULL && dat->IsMetaContactsEnabled && g_szMetaModuleName && ModernGetSettingByte(hContact, g_szMetaModuleName, "IsSubcontact", 0)) + return -1; //subcontact + if (pdnce && pdnce->isUnknown && !fEmbedded) + return 1; //'Unknown Contact' + if(pdnce && g_CluiData.bFilterEffective && !fEmbedded) + { + if(szProto == NULL) + szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + // 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 = ModernGetSettingDword(hContact, CLVM_MODULE, g_CluiData.current_viewmode, 0)) != 0) { + if(g_CluiData.bFilterEffective & CLVM_FILTER_STICKYSTATUS) + { + WORD wStatus = ModernGetSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE); + return !((1 << (wStatus - ID_STATUS_OFFLINE)) & HIWORD(dwLocalMask)); + } + return 0; + } + } + // check the proto, use it as a base filter result for all further checks + if(g_CluiData.bFilterEffective & CLVM_FILTER_PROTOS) { + mir_snprintf(szTemp, SIZEOF(szTemp), "%s|", szProto); + filterResult = strstr(g_CluiData.protoFilter, szTemp) ? 1 : 0; + } + if(g_CluiData.bFilterEffective & CLVM_FILTER_GROUPS) { + if(!ModernGetSettingTString(hContact, "CList", "Group", &dbv)) { + mir_sntprintf(szGroupMask, SIZEOF(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 = ModernGetSettingWord(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) + { + DWORD now; + PDNCE pdnce=(PDNCE)pcli->pfnGetCacheEntry(hContact); + if (pdnce) + { + 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); + } + else + return dbHidden; +} -- cgit v1.2.3