diff options
author | George Hazan <ghazan@miranda.im> | 2018-12-07 20:29:02 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2018-12-07 20:29:02 +0300 |
commit | 8e52da65d2cfa36bf23fa7be0577e420f3cf0480 (patch) | |
tree | e6af6fbb59a385187294fd045b74486616d27361 /src | |
parent | 3f09ad4929d58a73005361cb8bb5b8aa0b41f605 (diff) |
fixes #1653 (recursive removal of embedded groups)
Diffstat (limited to 'src')
-rw-r--r-- | src/mir_app/src/clistgroups.cpp | 91 | ||||
-rw-r--r-- | src/mir_app/src/contact.cpp | 2 |
2 files changed, 49 insertions, 44 deletions
diff --git a/src/mir_app/src/clistgroups.cpp b/src/mir_app/src/clistgroups.cpp index c49f028d62..b8917f02be 100644 --- a/src/mir_app/src/clistgroups.cpp +++ b/src/mir_app/src/clistgroups.cpp @@ -36,7 +36,7 @@ struct CGroupInternal { mir_free(groupName);
}
- int groupId;
+ int groupId, oldId;
wchar_t *groupName;
void save()
@@ -135,7 +135,7 @@ static INT_PTR CreateGroupInternal(MGROUP hParent, const wchar_t *ptszName) Clist_GroupAdded(newId + 1);
- CLISTGROUPCHANGE grpChg = { sizeof(grpChg), nullptr, newName };
+ CLISTGROUPCHANGE grpChg = { nullptr, newName };
NotifyEventHooks(hGroupChangeEvent, 0, (LPARAM)&grpChg);
return newId + 1;
@@ -176,6 +176,20 @@ MIR_APP_DLL(wchar_t*) Clist_GroupGetName(MGROUP hGroup, DWORD *pdwFlags) /////////////////////////////////////////////////////////////////////////////////////////
+static bool isParentOf(const CMStringW &pParent, const wchar_t *p)
+{
+ if (mir_wstrncmp(pParent, p, pParent.GetLength()))
+ return false;
+
+ switch (p[pParent.GetLength()]) {
+ case '\\':
+ case 0:
+ return true;
+ default:
+ return false;
+ }
+}
+
MIR_APP_DLL(int) Clist_GroupDelete(MGROUP hGroup)
{
// get the name
@@ -194,67 +208,58 @@ MIR_APP_DLL(int) Clist_GroupDelete(MGROUP hGroup) // must remove setting from all child contacts too
// children are demoted to the next group up, not deleted.
- wchar_t *szNewParent = NEWWSTR_ALLOCA(pGroup->groupName+1);
+ CMStringW wszOldName(pGroup->groupName + 1), wszNewParent;
{
- wchar_t *pszLastBackslash = wcsrchr(szNewParent, '\\');
- if (pszLastBackslash)
- pszLastBackslash[0] = '\0';
- else
- szNewParent[0] = '\0';
+ int idx = wszOldName.ReverseFind('\\');
+ if (idx != -1)
+ wszNewParent = wszOldName.Left(idx);
}
for (auto &hContact : Contacts()) {
ptrW tszGroupName(db_get_wsa(hContact, "CList", "Group"));
- if (mir_wstrcmp(tszGroupName, pGroup->groupName+1))
+ if (!tszGroupName || !isParentOf(wszOldName, tszGroupName))
continue;
- CLISTGROUPCHANGE grpChg = { sizeof(grpChg), nullptr, nullptr };
- grpChg.pszOldName = pGroup->groupName+1;
- if (szNewParent[0]) {
- db_set_ws(hContact, "CList", "Group", szNewParent);
- grpChg.pszNewName = szNewParent;
- }
- else {
- db_unset(hContact, "CList", "Group");
- grpChg.pszNewName = nullptr;
+ CLISTGROUPCHANGE grpChg = { wszOldName, 0 };
+ if (!wszNewParent.IsEmpty()) {
+ db_set_ws(hContact, "CList", "Group", wszNewParent);
+ grpChg.pszNewName = wszNewParent;
}
+ else db_unset(hContact, "CList", "Group");
NotifyEventHooks(hGroupChangeEvent, hContact, (LPARAM)&grpChg);
}
// shuffle list of groups up to fill gap
- arByIds.remove(pGroup);
- arByName.remove(pGroup);
+ for (auto &it : arByIds)
+ it->oldId = it->groupId;
- for (int i = hGroup-1; i < arByIds.getCount(); i++) {
- CGroupInternal *p = arByIds[i];
- p->groupId--;
- p->save();
+ int iGap = 0;
+ for (auto &it : arByIds.rev_iter()) {
+ if (!isParentOf(wszOldName, it->groupName + 1))
+ continue;
+
+ iGap++;
+ arByName.remove(it);
+ arByIds.remove(arByIds.indexOf(&it));
}
- char idstr[33];
- _itoa(arByIds.getCount(), idstr, 10);
- db_unset(0, "CListGroups", idstr);
-
- // rename subgroups
- wchar_t szNewName[256];
- size_t len = mir_wstrlen(pGroup->groupName+1);
- for (int i = 0; i < arByIds.getCount(); i++) {
- CGroupInternal *p = arByIds[i];
-
- if (!wcsncmp(pGroup->groupName+1, p->groupName+1, len) && p->groupName[len+1] == '\\' && wcschr(p->groupName + len + 2, '\\') == nullptr) {
- if (szNewParent[0])
- mir_snwprintf(szNewName, L"%s\\%s", szNewParent, p->groupName + len + 2);
- else
- mir_wstrncpy(szNewName, p->groupName + len + 2, _countof(szNewName));
- Clist_GroupRename(i + 1, szNewName);
- }
+ for (auto &it : arByIds) {
+ it->groupId = arByIds.indexOf(&it);
+ if (it->groupId != it->oldId)
+ it->save();
+ }
+
+ for (int i = 0; i < iGap; i++) {
+ char idstr[33];
+ _itoa(arByIds.getCount()+i, idstr, 10);
+ db_unset(0, "CListGroups", idstr);
}
SetCursor(LoadCursor(nullptr, IDC_ARROW));
Clist_LoadContactTree();
- const CLISTGROUPCHANGE grpChg = { sizeof(grpChg), pGroup->groupName+1, nullptr };
+ const CLISTGROUPCHANGE grpChg = { wszOldName, nullptr };
NotifyEventHooks(hGroupChangeEvent, 0, (LPARAM)&grpChg);
delete(pGroup);
@@ -381,7 +386,7 @@ static int RenameGroupWithMove(int groupId, const wchar_t *szName, int move) }
}
- const CLISTGROUPCHANGE grpChg = { sizeof(grpChg), oldName, (wchar_t*)szName };
+ const CLISTGROUPCHANGE grpChg = { oldName, szName };
NotifyEventHooks(hGroupChangeEvent, 0, (LPARAM)&grpChg);
return 0;
}
diff --git a/src/mir_app/src/contact.cpp b/src/mir_app/src/contact.cpp index 141a02f6a1..e822b9d8eb 100644 --- a/src/mir_app/src/contact.cpp +++ b/src/mir_app/src/contact.cpp @@ -40,7 +40,7 @@ MIR_APP_DLL(void) Clist_LoadContactTree(void) MIR_APP_DLL(int) Clist_ContactChangeGroup(MCONTACT hContact, MGROUP hGroup) { - CLISTGROUPCHANGE grpChg = { sizeof(CLISTGROUPCHANGE), nullptr, nullptr }; + CLISTGROUPCHANGE grpChg = {}; if (hGroup == 0) db_unset(hContact, "CList", "Group"); |