From 951bdb6a6296837838b87125b41bf2e7a976b773 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 13 Apr 2016 18:37:10 +0000 Subject: simple but effective clist group cache git-svn-id: http://svn.miranda-ng.org/main/trunk@16649 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- include/m_clist.h | 9 -- src/mir_app/src/clistmod.cpp | 2 + src/mir_app/src/groups.cpp | 252 ++++++++++++++++++++++++------------------- 3 files changed, 144 insertions(+), 119 deletions(-) diff --git a/include/m_clist.h b/include/m_clist.h index 61b4f13322..a66e48cf45 100644 --- a/include/m_clist.h +++ b/include/m_clist.h @@ -411,17 +411,8 @@ __forceinline HANDLE Clist_CreateGroup(HANDLE hParent, LPCTSTR ptszGroupName) // & isExpanded can be NULL if you don't want to know if the group is expanded or not. #define MS_CLIST_GROUPGETNAME "CList/GroupGetName" -///////////////////////////////////////////////////////////////////////////////////////// -// get the name of a group -// wParam = (WPARAM)(HANDLE)hGroup -// lParam = (LPARAM)(DWORD*)&flags -// returns a static buffer pointing to the name of the group -// returns NULL if hGroup is invalid. -// this buffer is only valid until the next call to this service -// & flags can be NULL if you don't want any of that info. #define GROUPF_EXPANDED 0x04 #define GROUPF_HIDEOFFLINE 0x08 -#define MS_CLIST_GROUPGETNAME2 "CList/GroupGetName2" ///////////////////////////////////////////////////////////////////////////////////////// // move a group to directly before another group diff --git a/src/mir_app/src/clistmod.cpp b/src/mir_app/src/clistmod.cpp index 2f9b3bd220..1987c9db6f 100644 --- a/src/mir_app/src/clistmod.cpp +++ b/src/mir_app/src/clistmod.cpp @@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. INT_PTR ContactChangeGroup(WPARAM wParam, LPARAM lParam); int InitCListEvents(void); void UninitCListEvents(void); +void UninitGroupServices(void); int ContactSettingChanged(WPARAM wParam, LPARAM lParam); int ContactAdded(WPARAM wParam, LPARAM lParam); int ContactDeleted(WPARAM wParam, LPARAM lParam); @@ -474,5 +475,6 @@ void UnloadContactListModule() } ImageList_Destroy(hCListImages); UninitCListEvents(); + UninitGroupServices(); DestroyHookableEvent(hContactDoubleClicked); } diff --git a/src/mir_app/src/groups.cpp b/src/mir_app/src/groups.cpp index 0ed7df4f18..d01bcb8074 100644 --- a/src/mir_app/src/groups.cpp +++ b/src/mir_app/src/groups.cpp @@ -27,35 +27,65 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. HANDLE hGroupChangeEvent; -static INT_PTR RenameGroup(WPARAM wParam, LPARAM lParam); -static INT_PTR MoveGroupBefore(WPARAM wParam, LPARAM lParam); +struct CGroupInternal +{ + CGroupInternal(const TCHAR *_name, int _id) : + groupId(_id), + groupName(mir_tstrdup(_name)) + {} -static int CountGroups(void) + int groupId; + TCHAR *groupName; +}; + +static int CompareGrpByName(const CGroupInternal *p1, const CGroupInternal *p2) +{ return mir_tstrcmp(p1->groupName, p2->groupName); +} +static LIST arByName(20, CompareGrpByName); + +static LIST arByIds(20, NumericKeySortT); + +static void BuildGroupList() { for (int i = 0;; i++) { - char str[33]; + char str[32]; _itoa(i, str, 10); - ptrT grpName(db_get_tsa(NULL, "CListGroups", str)); - if (grpName == NULL) - return i; + ptrT tszGroup(db_get_tsa(NULL, "CListGroups", str)); + if (tszGroup == NULL) + break; + + if (tszGroup[0] & 0x80) { + tszGroup[0] &= 0x7f; + db_set_ts(NULL, "CListGroups", str, tszGroup); + } + + CGroupInternal *p = new CGroupInternal((TCHAR*)tszGroup + 1, i); + arByIds.insert(p); + arByName.insert(p); } } -static int GroupNameExists(const TCHAR *name, int skipGroup) +static void WipeGroupList() { - for (int i = 0;; i++) { - if (i == skipGroup) - continue; + for (int i = 0; i < arByIds.getCount(); i++) { + mir_free(arByIds[i]->groupName); + delete arByIds[i]; + } + arByIds.destroy(); + arByName.destroy(); +} - char idstr[33]; - _itoa(i, idstr, 10); - ptrT grpName(db_get_tsa(NULL, "CListGroups", idstr)); - if (grpName == NULL) - break; +static int CountGroups(void) +{ + return arByIds.getCount(); +} - if (!mir_tstrcmp((TCHAR*)grpName + 1, name)) - return i + 1; - } +static int GroupNameExists(const TCHAR *name, int skipGroup) +{ + CGroupInternal *tmp = (CGroupInternal*)_alloca(sizeof(CGroupInternal)); + tmp->groupName = (TCHAR*)name; + if (tmp = arByName.find(tmp)) + return (skipGroup == tmp->groupId) ? 0 : tmp->groupId + 1; return 0; } @@ -69,12 +99,11 @@ static INT_PTR GroupExists(WPARAM, LPARAM lParam) static INT_PTR CreateGroupInternal(INT_PTR iParent, const TCHAR *ptszName) { - int newId = CountGroups(); TCHAR newBaseName[127], newName[128]; char str[33]; int i; - const TCHAR* grpName = ptszName ? ptszName : TranslateT("New group"); + const TCHAR *grpName = ptszName ? ptszName : TranslateT("New group"); if (iParent) { _itoa(iParent - 1, str, 10); DBVARIANT dbv; @@ -86,6 +115,7 @@ static INT_PTR CreateGroupInternal(INT_PTR iParent, const TCHAR *ptszName) } else mir_tstrncpy(newBaseName, grpName, _countof(newBaseName)); + int newId = CountGroups(); _itoa(newId, str, 10); mir_tstrncpy(newName + 1, newBaseName, _countof(newName) - 1); if (ptszName) { @@ -185,6 +215,7 @@ static INT_PTR DeleteGroup(WPARAM wParam, LPARAM) _itoa(wParam - 1, str, 10); if (db_get_ts(NULL, "CListGroups", str, &dbv)) return 1; + mir_tstrncpy(name, dbv.ptszVal + 1, _countof(name)); db_free(&dbv); if (db_get_b(NULL, "CList", "ConfirmDelete", SETTING_CONFIRMDELETE_DEFAULT)) { @@ -194,8 +225,9 @@ static INT_PTR DeleteGroup(WPARAM wParam, LPARAM) return 1; } SetCursor(LoadCursor(NULL, IDC_WAIT)); - //must remove setting from all child contacts too - //children are demoted to the next group up, not deleted. + + // must remove setting from all child contacts too + // children are demoted to the next group up, not deleted. mir_tstrcpy(szNewParent, name); pszLastBackslash = _tcsrchr(szNewParent, '\\'); if (pszLastBackslash) @@ -222,7 +254,8 @@ static INT_PTR DeleteGroup(WPARAM wParam, LPARAM) NotifyEventHooks(hGroupChangeEvent, hContact, (LPARAM)&grpChg); } - //shuffle list of groups up to fill gap + + // shuffle list of groups up to fill gap for (i = wParam - 1;; i++) { _itoa(i + 1, str, 10); if (db_get_utf(NULL, "CListGroups", str, &dbv)) @@ -233,7 +266,8 @@ static INT_PTR DeleteGroup(WPARAM wParam, LPARAM) } _itoa(i, str, 10); db_unset(NULL, "CListGroups", str); - //rename subgroups + + // rename subgroups { TCHAR szNewName[256]; size_t len = mir_tstrlen(name); @@ -251,6 +285,10 @@ static INT_PTR DeleteGroup(WPARAM wParam, LPARAM) db_free(&dbv); } } + + WipeGroupList(); + BuildGroupList(); + SetCursor(LoadCursor(NULL, IDC_ARROW)); cli.pfnLoadContactTree(); @@ -259,6 +297,71 @@ static INT_PTR DeleteGroup(WPARAM wParam, LPARAM) return 0; } +static INT_PTR MoveGroupBefore(WPARAM wParam, LPARAM lParam) +{ + int i, shuffleFrom, shuffleTo, shuffleDir; + char str[33]; + TCHAR *szMoveName; + DBVARIANT dbv; + + if (wParam == 0 || (LPARAM)wParam == lParam) + return 0; + _itoa(wParam - 1, str, 10); + if (db_get_ts(NULL, "CListGroups", str, &dbv)) + return 0; + szMoveName = dbv.ptszVal; + //shuffle list of groups up to fill gap + if (lParam == 0) { + shuffleFrom = wParam - 1; + shuffleTo = -1; + shuffleDir = -1; + } + else { + if ((LPARAM)wParam < lParam) { + shuffleFrom = wParam - 1; + shuffleTo = lParam - 2; + shuffleDir = -1; + } + else { + shuffleFrom = wParam - 1; + shuffleTo = lParam - 1; + shuffleDir = 1; + } + } + if (shuffleDir == -1) { + for (i = shuffleFrom; i != shuffleTo; i++) { + _itoa(i + 1, str, 10); + if (db_get_utf(NULL, "CListGroups", str, &dbv)) { + shuffleTo = i; + break; + } + _itoa(i, str, 10); + db_set_utf(NULL, "CListGroups", str, dbv.pszVal); + db_free(&dbv); + } + } + else { + for (i = shuffleFrom; i != shuffleTo; i--) { + _itoa(i - 1, str, 10); + if (db_get_utf(NULL, "CListGroups", str, &dbv)) { + mir_free(szMoveName); + return 1; + } //never happens + _itoa(i, str, 10); + db_set_utf(NULL, "CListGroups", str, dbv.pszVal); + db_free(&dbv); + } + } + _itoa(shuffleTo, str, 10); + db_set_ts(NULL, "CListGroups", str, szMoveName); + mir_free(szMoveName); + + WipeGroupList(); + BuildGroupList(); + + return shuffleTo + 1; +} + static int RenameGroupWithMove(int groupId, const TCHAR *szName, int move) { char idstr[33]; @@ -291,7 +394,7 @@ static int RenameGroupWithMove(int groupId, const TCHAR *szName, int move) } } - //rename subgroups + // rename subgroups { TCHAR szNewName[256]; size_t len = mir_tstrlen(oldName); @@ -309,16 +412,13 @@ static int RenameGroupWithMove(int groupId, const TCHAR *szName, int move) } } - //finally must make sure it's after any parent items + // finally must make sure it's after any parent items if (move) { - TCHAR *pszLastBackslash; - int i; - mir_tstrncpy(str, szName, _countof(str)); - pszLastBackslash = _tcsrchr(str, '\\'); + TCHAR *pszLastBackslash = _tcsrchr(str, '\\'); if (pszLastBackslash != NULL) { *pszLastBackslash = '\0'; - for (i = 0;; i++) { + for (int i = 0;; i++) { _itoa(i, idstr, 10); if (db_get_ts(NULL, "CListGroups", idstr, &dbv)) break; @@ -331,6 +431,9 @@ static int RenameGroupWithMove(int groupId, const TCHAR *szName, int move) db_free(&dbv); } } + + WipeGroupList(); + BuildGroupList(); } const CLISTGROUPCHANGE grpChg = { sizeof(grpChg), oldName, (TCHAR*)szName }; @@ -387,67 +490,6 @@ static INT_PTR SetGroupFlags(WPARAM wParam, LPARAM lParam) return 0; } -static INT_PTR MoveGroupBefore(WPARAM wParam, LPARAM lParam) -{ - int i, shuffleFrom, shuffleTo, shuffleDir; - char str[33]; - TCHAR *szMoveName; - DBVARIANT dbv; - - if (wParam == 0 || (LPARAM)wParam == lParam) - return 0; - _itoa(wParam - 1, str, 10); - if (db_get_ts(NULL, "CListGroups", str, &dbv)) - return 0; - szMoveName = dbv.ptszVal; - //shuffle list of groups up to fill gap - if (lParam == 0) { - shuffleFrom = wParam - 1; - shuffleTo = -1; - shuffleDir = -1; - } - else { - if ((LPARAM)wParam < lParam) { - shuffleFrom = wParam - 1; - shuffleTo = lParam - 2; - shuffleDir = -1; - } - else { - shuffleFrom = wParam - 1; - shuffleTo = lParam - 1; - shuffleDir = 1; - } - } - if (shuffleDir == -1) { - for (i = shuffleFrom; i != shuffleTo; i++) { - _itoa(i + 1, str, 10); - if (db_get_utf(NULL, "CListGroups", str, &dbv)) { - shuffleTo = i; - break; - } - _itoa(i, str, 10); - db_set_utf(NULL, "CListGroups", str, dbv.pszVal); - db_free(&dbv); - } - } - else { - for (i = shuffleFrom; i != shuffleTo; i--) { - _itoa(i - 1, str, 10); - if (db_get_utf(NULL, "CListGroups", str, &dbv)) { - mir_free(szMoveName); - return 1; - } //never happens - _itoa(i, str, 10); - db_set_utf(NULL, "CListGroups", str, dbv.pszVal); - db_free(&dbv); - } - } - _itoa(shuffleTo, str, 10); - db_set_ts(NULL, "CListGroups", str, szMoveName); - mir_free(szMoveName); - return shuffleTo + 1; -} - static INT_PTR BuildGroupMenu(WPARAM, LPARAM) { char idstr[33]; @@ -532,9 +574,8 @@ static INT_PTR BuildGroupMenu(WPARAM, LPARAM) mii.dwItemData = groupId + 1; } InsertMenuItem(hThisMenu, menuId, TRUE, &mii); - if (pNextField) { + if (pNextField) hThisMenu = mii.hSubMenu; - } } } while (pNextField); @@ -545,32 +586,23 @@ static INT_PTR BuildGroupMenu(WPARAM, LPARAM) int InitGroupServices(void) { - for (int i = 0;; i++) { - char str[32]; - _itoa(i, str, 10); - - DBVARIANT dbv; - if (db_get_utf(NULL, "CListGroups", str, &dbv)) - break; - if (dbv.pszVal[0] & 0x80) { - dbv.pszVal[0] &= 0x7f; - db_set_utf(NULL, "CListGroups", str, dbv.pszVal); - } - db_free(&dbv); - } + BuildGroupList(); CreateServiceFunction(MS_CLIST_GROUPEXISTS, GroupExists); CreateServiceFunction(MS_CLIST_GROUPCREATE, CreateGroup); CreateServiceFunction(MS_CLIST_GROUPDELETE, DeleteGroup); CreateServiceFunction(MS_CLIST_GROUPRENAME, RenameGroup); CreateServiceFunction(MS_CLIST_GROUPGETNAME, GetGroupName); - CreateServiceFunction(MS_CLIST_GROUPGETNAME2, GetGroupName2); CreateServiceFunction(MS_CLIST_GROUPSETEXPANDED, SetGroupExpandedState); CreateServiceFunction(MS_CLIST_GROUPSETFLAGS, SetGroupFlags); CreateServiceFunction(MS_CLIST_GROUPMOVEBEFORE, MoveGroupBefore); CreateServiceFunction(MS_CLIST_GROUPBUILDMENU, BuildGroupMenu); hGroupChangeEvent = CreateHookableEvent(ME_CLIST_GROUPCHANGE); - return 0; } + +void UninitGroupServices(void) +{ + WipeGroupList(); +} -- cgit v1.2.3