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/modernb/modern_clcidents.cpp | 300 +++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 plugins/modernb/modern_clcidents.cpp (limited to 'plugins/modernb/modern_clcidents.cpp') diff --git a/plugins/modernb/modern_clcidents.cpp b/plugins/modernb/modern_clcidents.cpp new file mode 100644 index 0000000000..bcbe3af247 --- /dev/null +++ b/plugins/modernb/modern_clcidents.cpp @@ -0,0 +1,300 @@ +/* + +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_commonprototypes.h" + +#define CacheArrSize 255 +struct ClcGroup *CacheIndex[CacheArrSize]={NULL}; +boolean CacheIndexClear=TRUE; + +/* the CLC uses 3 different ways to identify elements in its list, this file +contains routines to convert between them. + +1) struct ClcContact/struct ClcGroup pair. Only ever used within the duration +of a single operation, but used at some point in nearly everything +2) index integer. The 0-based number of the item from the top. Only visible +items are counted (ie not closed groups). Used for saving selection and drag +highlight +3) hItem handle. Either the hContact or (hGroup|HCONTACT_ISGROUP). Used +exclusively externally + +1->2: cliGetRowsPriorTo() +1->3: ContactToHItem() +3->1: FindItem() +2->1: GetRowByIndex() +*/ + +int GetContactIndex(struct ClcGroup *group,struct ClcContact *contact) +{ + int i=0; + for (i=0; icl.count; i++) + if (group->cl.items[i]->hContact==contact->hContact) return i; + return -1; +} + +int cliGetRowsPriorTo(struct ClcGroup *group,struct ClcGroup *subgroup,int contactIndex) +{ + int count=0; + BYTE k; + int subcontactscount=0; + k=ModernGetSettingByte(NULL,"CLC","MetaExpanding",SETTING_METAEXPANDING_DEFAULT); + group->scanIndex=0; + for(;;) { + if(group->scanIndex==group->cl.count) { + group=group->parent; + if(group==NULL) break; + group->scanIndex++; + continue; + } + if(group==subgroup && contactIndex-subcontactscount==group->scanIndex) return count; + count++; + + /* if ((group->cl.items[group->scanIndex]->type==CLCIT_CONTACT) && (group->cl.items[group->scanIndex].flags & CONTACTF_STATUSMSG)) { + count++; + } + */ + if(group->cl.items[group->scanIndex]->type==CLCIT_GROUP) { + if(group->cl.items[group->scanIndex]->group==subgroup && contactIndex==-1) + return count-1; + if(group->cl.items[group->scanIndex]->group->expanded) { + group=group->cl.items[group->scanIndex]->group; + group->scanIndex=0; + subcontactscount=0; + continue; + } + } + if (group==subgroup) + { + if(group->cl.items[group->scanIndex]->type==CLCIT_CONTACT && group->cl.items[group->scanIndex]->SubAllocated) + { + int rows=(group->cl.items[group->scanIndex]->SubAllocated*group->cl.items[group->scanIndex]->SubExpanded*k); + if (group->scanIndex+rows >= contactIndex) + return count+(contactIndex-group->scanIndex)-1; + } + } + if(group->cl.items[group->scanIndex]->type==CLCIT_CONTACT) + { + count+=(group->cl.items[group->scanIndex]->SubAllocated*group->cl.items[group->scanIndex]->SubExpanded*k); + subcontactscount+=(group->cl.items[group->scanIndex]->SubAllocated*group->cl.items[group->scanIndex]->SubExpanded*k); + } + group->scanIndex++; + } + return -1; +} + +int cliFindItem(HWND hwnd,struct ClcData *dat,HANDLE hItem,struct ClcContact **contact,struct ClcGroup **subgroup,int *isVisible) +{ + return FindItem(hwnd,dat, hItem,contact,subgroup,isVisible,FALSE); +} + +int FindItem(HWND hwnd,struct ClcData *dat,HANDLE hItem,struct ClcContact **contact,struct ClcGroup **subgroup,int *isVisible, BOOL isIgnoreSubcontacts) +{ + int index=0, i; + int nowVisible=1; + struct ClcGroup *group; + + group=&dat->list; + + group->scanIndex=0; + group=&dat->list; + + for(;;) { + if(group->scanIndex==group->cl.count) { + struct ClcGroup *tgroup; + group=group->parent; + if(group==NULL) break; + nowVisible=1; + for(tgroup=group;tgroup;tgroup=tgroup->parent) + { + if(!tgroup->expanded) + { + nowVisible=0; + break; + } + } + group->scanIndex++; + continue; + } + if(nowVisible) index++; + if((IsHContactGroup(hItem) && group->cl.items[group->scanIndex]->type==CLCIT_GROUP && ((UINT_PTR)hItem&~HCONTACT_ISGROUP)==group->cl.items[group->scanIndex]->groupId) || + (IsHContactContact(hItem) && group->cl.items[group->scanIndex]->type==CLCIT_CONTACT && group->cl.items[group->scanIndex]->hContact==hItem) || + (IsHContactInfo(hItem) && group->cl.items[group->scanIndex]->type==CLCIT_INFO && group->cl.items[group->scanIndex]->hContact==(HANDLE)((UINT_PTR)hItem&~HCONTACT_ISINFO))) + { + if(isVisible) { + if(!nowVisible) *isVisible=0; + else { + int posy = cliGetRowTopY(dat,index+1); + if(posyyScroll) + *isVisible=0; + else { + RECT clRect; + GetClientRect(hwnd,&clRect); + if(posy>=dat->yScroll+clRect.bottom) *isVisible=0; + else *isVisible=1; + } + } + } + if(contact) *contact=group->cl.items[group->scanIndex]; + if(subgroup) *subgroup=group; + + return 1; + } + if (!isIgnoreSubcontacts && + IsHContactContact(hItem) && + group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && + group->cl.items[group->scanIndex]->SubAllocated > 0) + { + for (i=0; icl.items[group->scanIndex]->SubAllocated; i++) + { + if (group->cl.items[group->scanIndex]->subcontacts[i].hContact == hItem) + { +#ifdef _DEBUG + if (IsBadWritePtr(&group->cl.items[group->scanIndex]->subcontacts[i], sizeof(struct ClcContact))) + { + log1("FindIltem->IsBadWritePtr | 2o [%08x]", &group->cl.items[group->scanIndex]->subcontacts[i]); + PostMessage(hwnd,CLM_AUTOREBUILD,0,0); + + return 0; + } +#endif + if(contact) *contact=&group->cl.items[group->scanIndex]->subcontacts[i]; + if(subgroup) *subgroup=group; + + return 1; + } + } + } + + if(group->cl.items[group->scanIndex]->type==CLCIT_GROUP) { + group=group->cl.items[group->scanIndex]->group; + group->scanIndex=0; + nowVisible&=group->expanded; + continue; + } + group->scanIndex++; + } + + return 0; +} + +void ClearRowByIndexCache() +{ + if (!CacheIndexClear) + { + memset(CacheIndex,0,sizeof(CacheIndex)); + CacheIndexClear=TRUE; + }; +} +int cliGetRowByIndex(struct ClcData *dat,int testindex,struct ClcContact **contact,struct ClcGroup **subgroup) +{ + int index=0,i; + struct ClcGroup *group=&dat->list; + + if (testindex<0) return (-1); + { + group->scanIndex=0; + for(;;) { + if(group->scanIndex==group->cl.count) { + group=group->parent; + if(group==NULL) break; + group->scanIndex++; + continue; + } + if ((index>0) && (indexcl.items[group->scanIndex]; + if(subgroup) *subgroup=group; + return index; + } + + if (group->cl.items[group->scanIndex]->type==CLCIT_CONTACT) + if (group->cl.items[group->scanIndex]->SubAllocated) + if (group->cl.items[group->scanIndex]->SubExpanded && dat->expandMeta) + { + for (i=0;icl.items[group->scanIndex]->SubAllocated;i++) + { + if ((index>0) && (indexcl.items[group->scanIndex]->subcontacts[i]; + (*contact)->subcontacts=group->cl.items[group->scanIndex]; + } + + if(subgroup) *subgroup=group; + return index; + } + } + + } + index++; + 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 -1; +} + +HANDLE ContactToHItem(struct ClcContact *contact) +{ + switch(contact->type) { +case CLCIT_CONTACT: + return contact->hContact; +case CLCIT_GROUP: + return (HANDLE)(contact->groupId|HCONTACT_ISGROUP); +case CLCIT_INFO: + return (HANDLE)((DWORD_PTR)contact->hContact|HCONTACT_ISINFO); + } + return NULL; +} + +HANDLE ContactToItemHandle(struct ClcContact *contact,DWORD *nmFlags) +{ + switch(contact->type) { +case CLCIT_CONTACT: + return contact->hContact; +case CLCIT_GROUP: + if(nmFlags) *nmFlags|=CLNF_ISGROUP; + return (HANDLE)contact->groupId; +case CLCIT_INFO: + if(nmFlags) *nmFlags|=CLNF_ISINFO; + return (HANDLE)((DWORD_PTR)contact->hContact|HCONTACT_ISINFO); + } + return NULL; +} \ No newline at end of file -- cgit v1.2.3