From 0408c8952ca633a1ef37e3c4419816fa4ad5c418 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 17 Jan 2024 20:56:37 +0300 Subject: =?UTF-8?q?fixes=20#4109=20(=D0=9F=D1=80=D0=B5=D0=BA=D1=80=D0=B0?= =?UTF-8?q?=D1=82=D0=B8=D1=82=D1=8C=20=D1=85=D1=80=D0=B0=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=B0=20=D0=B3?= =?UTF-8?q?=D1=80=D1=83=D0=BF=D0=BF=20=D0=B2=20=D0=B1=D0=B0=D0=B7=D0=B5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/delphi/m_clist.inc | 4 + include/m_import.h | 1 - plugins/Import/src/import.cpp | 50 ------- plugins/Import/src/miranda.cpp | 4 +- plugins/Import/src/stdafx.h | 1 - plugins/RemovePersonalSettings/src/rps.cpp | 3 - plugins/Utils.pas/mirutils.pas | 33 +---- plugins/mRadio/i_optdlg.inc | 7 +- src/mir_app/src/clc.cpp | 61 ++++----- src/mir_app/src/clc.h | 14 ++ src/mir_app/src/clistgroups.cpp | 202 ++++++++++++++++------------- src/mir_app/src/movetogroup.cpp | 19 +-- 12 files changed, 163 insertions(+), 236 deletions(-) diff --git a/include/delphi/m_clist.inc b/include/delphi/m_clist.inc index 195b19fbc5..35914d09a6 100644 --- a/include/delphi/m_clist.inc +++ b/include/delphi/m_clist.inc @@ -129,4 +129,8 @@ function Clist_GroupCreate(hParentGroup:integer; groupName:PWideChar) : integer; procedure Clist_ContactDoubleClicked(hContact:TMCONTACT); stdcall; external AppDll; +function Clist_GroupBuildMenu(idxfrom:integer=100) : HMENU; stdcall; external AppDll; + +procedure Clist_SetGroup(hContact:TMCONTACT; groupName:PWideChar); stdcall; external AppDll; + {$ENDIF} diff --git a/include/m_import.h b/include/m_import.h index 1616bab127..be46a8b288 100644 --- a/include/m_import.h +++ b/include/m_import.h @@ -42,7 +42,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define IOPT_SYSTEM 0x00000800 #define IOPT_CONTACTS 0x00001000 -#define IOPT_GROUPS 0x00002000 #define IOPT_SYS_SETTINGS 0x00004000 #define IOPT_COMPLETE 0x00007FFE diff --git a/plugins/Import/src/import.cpp b/plugins/Import/src/import.cpp index 16a0736334..1297462e3d 100644 --- a/plugins/Import/src/import.cpp +++ b/plugins/Import/src/import.cpp @@ -517,43 +517,6 @@ int ModulesEnumProc(const char *szModuleName, void *pParam) ///////////////////////////////////////////////////////////////////////////////////////// -struct MImportGroup -{ - MImportGroup(int _n, wchar_t *_nm) : - wszName(_nm), - iNumber(_n) - {} - - int iNumber; - ptrW wszName; -}; - -static int ImportGroup(const char* szSettingName, void *param) -{ - OBJLIST *pArray = (OBJLIST*)param; - wchar_t *wszGroupName = g_pBatch->myGetWs(NULL, "CListGroups", szSettingName); - if (wszGroupName != nullptr) - pArray->insert(new MImportGroup(atoi(szSettingName), wszGroupName)); - return 0; -} - -int CImportBatch::ImportGroups() -{ - OBJLIST arGroups(10, NumericKeySortT); - srcDb->EnumContactSettings(NULL, ImportGroup, "CListGroups", &arGroups); - - for (auto &it : arGroups) { - MGROUP group_id = Clist_GroupCreate(0, it->wszName.get() + 1); - if (group_id <= 0) - continue; - - Clist_GroupSetExpanded(group_id, (it->wszName[0] & GROUPF_EXPANDED)); - } - return arGroups.getCount(); -} - -///////////////////////////////////////////////////////////////////////////////////////// - DBCachedContact* CImportBatch::FindDestMeta(DBCachedContact *ccSrc) { for (MCONTACT hMeta = dstDb->FindFirstContact(META_PROTO); hMeta != 0; hMeta = dstDb->FindNextContact(hMeta, META_PROTO)) { @@ -1023,7 +986,6 @@ void CImportBatch::DoImport() uint32_t dwTimer = time(0); OBJLIST arSkippedAccs(1, CompareModules); - arSkippedAccs.insert(newStr("CListGroups")); if (!ImportAccounts(arSkippedAccs)) { AddMessage(LPGENW("Error mapping accounts, exiting.")); return; @@ -1034,18 +996,6 @@ void CImportBatch::DoImport() srcDb->EnumModuleNames(CopySystemSettings, &arSkippedAccs); arSkippedAccs.destroy(); - // Import Groups - if (m_iOptions & IOPT_GROUPS) { - AddMessage(LPGENW("Importing groups.")); - nGroupsCount = ImportGroups(); - if (nGroupsCount == -1) - AddMessage(LPGENW("Group import failed.")); - - AddMessage(L""); - } - dstDb->Flush(); - // End of Import Groups - // Import Contacts if (m_iOptions & IOPT_CONTACTS) { AddMessage(LPGENW("Importing contacts.")); diff --git a/plugins/Import/src/miranda.cpp b/plugins/Import/src/miranda.cpp index bad7d76c6b..2faf0e03a7 100644 --- a/plugins/Import/src/miranda.cpp +++ b/plugins/Import/src/miranda.cpp @@ -245,7 +245,7 @@ void CMirandaOptionsPageDlg::OnNext() PostMessage(m_hwndParent, WIZM_GOTOPAGE, IDD_PROGRESS, (LPARAM)new CProgressPageDlg()); } else if (IsDlgButtonChecked(m_hwnd, IDC_RADIO_ALL)) { - g_pBatch->m_iOptions = IOPT_HISTORY | IOPT_SYSTEM | IOPT_GROUPS | IOPT_CONTACTS | iFlags; + g_pBatch->m_iOptions = IOPT_HISTORY | IOPT_SYSTEM | IOPT_CONTACTS | iFlags; PostMessage(m_hwndParent, WIZM_GOTOPAGE, IDD_PROGRESS, (LPARAM)new CProgressPageDlg()); } else if (IsDlgButtonChecked(m_hwnd, IDC_RADIO_CONTACTS)) { @@ -309,7 +309,7 @@ void CMirandaAdvOptionsPageDlg::OnNext() g_pBatch->m_iOptions &= IOPT_CHECKDUPS; if (IsDlgButtonChecked(m_hwnd, IDC_CONTACTS)) - g_pBatch->m_iOptions |= IOPT_CONTACTS | IOPT_GROUPS; + g_pBatch->m_iOptions |= IOPT_CONTACTS; if (IsDlgButtonChecked(m_hwnd, IDC_SYSTEM)) g_pBatch->m_iOptions |= IOPT_SYSTEM; diff --git a/plugins/Import/src/stdafx.h b/plugins/Import/src/stdafx.h index 57511c051c..ec15c520db 100644 --- a/plugins/Import/src/stdafx.h +++ b/plugins/Import/src/stdafx.h @@ -275,7 +275,6 @@ class CImportBatch : public MZeroedObject bool ImportAccounts(OBJLIST &arSkippedModules); MCONTACT ImportContact(MCONTACT hSrc); void ImportHistory(MCONTACT hContact, PROTOACCOUNT **protocol, int protoCount); - int ImportGroups(); void ImportMeta(DBCachedContact *ccSrc); MCONTACT MapContact(MCONTACT hSrc); diff --git a/plugins/RemovePersonalSettings/src/rps.cpp b/plugins/RemovePersonalSettings/src/rps.cpp index 4e42c5065b..08fc78ed2c 100644 --- a/plugins/RemovePersonalSettings/src/rps.cpp +++ b/plugins/RemovePersonalSettings/src/rps.cpp @@ -370,9 +370,6 @@ void RemoveUsers() DB::ECPTR pCursor(DB::Events(0)); while (pCursor.FetchNext()) pCursor.DeleteEvent(); - - // Now delete groups - DeleteSettingEx("CListGroups", nullptr); } } diff --git a/plugins/Utils.pas/mirutils.pas b/plugins/Utils.pas/mirutils.pas index fb07550f08..a38e15142e 100644 --- a/plugins/Utils.pas/mirutils.pas +++ b/plugins/Utils.pas/mirutils.pas @@ -28,7 +28,6 @@ function ShowVarHelp(dlg:HWND;id:integer=0):integer; function CreateGroupW(name:PWideChar;hContact:TMCONTACT):integer; -function MakeGroupMenu(idxfrom:integer=100):HMENU; function GetNewGroupName(parent:HWND):PWideChar; const @@ -351,36 +350,6 @@ begin result:=StrCmpW(PWideChar(para1),PWideChar(para2)); end; -function MakeGroupMenu(idxfrom:integer=100):HMENU; -var - sl:TSortedList; - i:integer; - b:array [0..15] of AnsiChar; - p:PWideChar; -begin - result:=CreatePopupMenu; - i:=0; - AppendMenuW(result,MF_STRING,idxfrom,TranslateW('')); - AppendMenuW(result,MF_SEPARATOR,0,nil); - FillChar(sl,SizeOf(sl),0); - sl.increment:=16; - sl.sortFunc:=@MyStrSort; - repeat - p:=DBReadUnicode(0,'CListGroups',IntToStr(b,i),nil); - if p=nil then break; - List_InsertPtr(@sl,p+1); - inc(i); - until false; - inc(idxfrom); - for i:=0 to sl.realCount-1 do - begin - AppendMenuW(result,MF_STRING,idxfrom+i,PWideChar(sl.Items[i])); - p:=PWideChar(sl.Items[i])-1; - mFreeMem(p); - end; - List_Destroy(@sl); -end; - function GetNewGroupName(parent:HWND):PWideChar; var mmenu:HMENU; @@ -389,7 +358,7 @@ var pt:TPoint; begin result:=nil; - mmenu:=MakeGroupMenu(100); + mmenu:=Clist_GroupBuildMenu(100); GetCursorPos(pt); i:=integer(TrackPopupMenu(mmenu,TPM_RETURNCMD+TPM_NONOTIFY,pt.x,pt.y,0,parent,nil)); if i>100 then // no root or cancel diff --git a/plugins/mRadio/i_optdlg.inc b/plugins/mRadio/i_optdlg.inc index fe26a0bf11..983406afe4 100644 --- a/plugins/mRadio/i_optdlg.inc +++ b/plugins/mRadio/i_optdlg.inc @@ -168,12 +168,7 @@ begin DBWriteUnicode(i,PluginName,optStationURL,@buf); } // "changing" station group - dst:=GetNewGroupName(Dialog); - if dst<>nil then - DBWriteUnicode(i,strCList,optGroup,dst) - else - db_unset(i,strCList,optGroup); - + Clist_SetGroup(i, GetNewGroupName(Dialog)); end else if loword(wParam)=IDC_ADD_INI then begin diff --git a/src/mir_app/src/clc.cpp b/src/mir_app/src/clc.cpp index b52c63f672..48a54d8745 100644 --- a/src/mir_app/src/clc.cpp +++ b/src/mir_app/src/clc.cpp @@ -69,15 +69,6 @@ extern bool g_bGroupsLocked; static int ClcSettingChanged(WPARAM hContact, LPARAM lParam) { DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *)lParam; - if (hContact == 0) { - if (!strcmp(cws->szModule, "CListGroups")) { - if (g_bGroupsLocked) - Clist_Broadcast(CLM_AUTOREBUILD, 0, 0); - else - Clist_Broadcast(INTM_GROUPSCHANGED, hContact, lParam); - } - return 0; - } if (!strcmp(cws->szModule, "CList")) { if (!strcmp(cws->szSetting, "MyHandle")) { @@ -361,40 +352,32 @@ LRESULT CALLBACK fnContactListControlWndProc(HWND hwnd, UINT uMsg, WPARAM wParam return (LRESULT)dat->fontInfo[FONTID_CONTACTS].hFont; case INTM_GROUPSCHANGED: - { - DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING *)lParam; - if (dbcws->value.type == DBVT_ASCIIZ || dbcws->value.type == DBVT_UTF8) { - int groupId = atoi(dbcws->szSetting) + 1; - - // check name of group and ignore message if just being expanded/collapsed - if (Clist_FindItem(hwnd, dat, groupId | HCONTACT_ISGROUP, &contact, &group)) { - CMStringW szFullName(contact->szText); - while (group->parent) { - ClcContact *cc = nullptr; - for (auto &it : group->parent->cl) - if (it->group == group) { - cc = it; - break; - } - - if (cc == nullptr) { - szFullName.Empty(); - break; - } - szFullName = CMStringW(cc->szText) + L"\\" + szFullName; - group = group->parent; - } + if (auto *pGroup = (CGroupInternal *)lParam) { + // check name of group and ignore message if just being expanded/collapsed + if (!Clist_FindItem(hwnd, dat, pGroup->groupId | HCONTACT_ISGROUP, &contact, &group)) + break; - int eq; - if (dbcws->value.type == DBVT_ASCIIZ) - eq = !mir_wstrcmp(szFullName, _A2T(dbcws->value.pszVal + 1)); - else - eq = !mir_wstrcmp(szFullName, ptrW(mir_utf8decodeW(dbcws->value.pszVal + 1))); + CMStringW szFullName(contact->szText); + while (group->parent) { + ClcContact *cc = nullptr; + for (auto &it : group->parent->cl) + if (it->group == group) { + cc = it; + break; + } - if (eq && contact->group->bHideOffline == ((dbcws->value.pszVal[0] & GROUPF_HIDEOFFLINE) != 0)) - break; //only expanded has changed: no action reqd + if (cc == nullptr) { + szFullName.Empty(); + break; } + szFullName = CMStringW(cc->szText) + L"\\" + szFullName; + group = group->parent; } + + bool eq = !mir_wstrcmp(szFullName, pGroup->groupName); + if (eq && contact->group->bHideOffline == ((pGroup->flags & GROUPF_HIDEOFFLINE) != 0)) + break; // only expanded has changed: no action reqd + Clist_SaveStateAndRebuildList(hwnd, dat); } break; diff --git a/src/mir_app/src/clc.h b/src/mir_app/src/clc.h index 9231e8cc18..37a54fb0d6 100644 --- a/src/mir_app/src/clc.h +++ b/src/mir_app/src/clc.h @@ -168,3 +168,17 @@ int fnSetHideOffline(int iValue); /* docking.c */ int fnDocking_ProcessWindowMessage(WPARAM wParam, LPARAM lParam); + +// clistgroups.cpp + +struct CGroupInternal +{ + CGroupInternal(int _id, const wchar_t *_name, int _flags); + ~CGroupInternal(); + + int groupId, oldId = -1, flags; + bool bSaveExpanded; + wchar_t *groupName; + + void save(); +}; diff --git a/src/mir_app/src/clistgroups.cpp b/src/mir_app/src/clistgroups.cpp index 174d4a3289..8bc65e137e 100644 --- a/src/mir_app/src/clistgroups.cpp +++ b/src/mir_app/src/clistgroups.cpp @@ -27,30 +27,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MAX_GROUPNAME_LEN 256 -struct CGroupInternal -{ - CGroupInternal(int _id, const wchar_t *_name) : - groupId(_id), - groupName(mir_wstrdup(_name)) - { - bSaveExpanded = (groupName[0] & GROUPF_EXPANDED) != 0; - } - - ~CGroupInternal() - { mir_free(groupName); - } - - int groupId, oldId = -1; - bool bSaveExpanded; - wchar_t *groupName; +HANDLE hGroupChangeEvent; +bool g_bGroupsLocked = false; - void save() - { - char idstr[33]; - itoa(groupId, idstr, 10); - db_set_ws(0, "CListGroups", idstr, groupName); - } -}; +static mir_cs csGroups; ///////////////////////////////////////////////////////////////////////////////////////// @@ -62,25 +42,57 @@ static LIST arByName(20, CompareGrpByName); ///////////////////////////////////////////////////////////////////////////////////////// -struct CGroupList : public LIST +LIST arByIds(20, NumericKeySortT); + +static CGroupInternal* FindGroup(int key) +{ + return arByIds.find((CGroupInternal *)&key); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static CTimer *g_pTimer; + +struct CGroupImpl { - CGroupList() : - LIST(20, NumericKeySortT) - {} + void OnTimer(CTimer *) + { + g_pTimer->Stop(); - __inline CGroupInternal* find(int key) - { return LIST::find((CGroupInternal*)&key); - } -}; + JSONNode root(JSON_ARRAY); + for (auto &it : arByIds) { + JSONNode grp; + grp << INT_PARAM("id", it->groupId) << WCHAR_PARAM("name", it->groupName) << INT_PARAM("flags", it->flags); + root << grp; + } -static CGroupList arByIds; + json2file(root, VARSW(L"%miranda_userdata%\\groups.json")); + } +} +g_impl; ///////////////////////////////////////////////////////////////////////////////////////// +// CGroupInternal members -HANDLE hGroupChangeEvent; -bool g_bGroupsLocked = false; +CGroupInternal::CGroupInternal(int _id, const wchar_t *_name, int _flags) : + flags(_flags), + groupId(_id), + groupName(mir_wstrdup(_name)) +{ + bSaveExpanded = (_flags & GROUPF_EXPANDED) != 0; +} -static mir_cs csGroups; +CGroupInternal::~CGroupInternal() +{ + mir_free(groupName); +} + +void CGroupInternal::save() +{ + Clist_Broadcast(INTM_GROUPSCHANGED, 0, LPARAM(this)); + + g_pTimer->Start(1000); +} ///////////////////////////////////////////////////////////////////////////////////////// @@ -89,11 +101,8 @@ static int GroupNameExists(const wchar_t *ptszGroupName, int skipGroup) if (ptszGroupName == nullptr) return 0; - wchar_t str[256]; - wcsncpy_s(str + 1, _countof(str) - 1, ptszGroupName, _TRUNCATE); - CGroupInternal *tmp = (CGroupInternal*)_alloca(sizeof(CGroupInternal)); - tmp->groupName = (wchar_t*)str; + tmp->groupName = (wchar_t*)ptszGroupName; if (tmp = arByName.find(tmp)) return (skipGroup == tmp->groupId) ? 0 : tmp->groupId + 1; return 0; @@ -112,35 +121,34 @@ static INT_PTR CreateGroupInternal(MGROUP hParent, const wchar_t *ptszName) const wchar_t *grpName = ptszName ? ptszName : TranslateT("New group"); if (hParent) { - CGroupInternal *tmp = arByIds.find(hParent-1); + CGroupInternal *tmp = FindGroup(hParent-1); if (tmp == nullptr) return 0; - mir_snwprintf(newBaseName, L"%s\\%s", tmp->groupName+1, grpName); + mir_snwprintf(newBaseName, L"%s\\%s", tmp->groupName, grpName); } else wcsncpy_s(newBaseName, grpName, _TRUNCATE); - mir_wstrncpy(newName + 1, newBaseName, _countof(newName) - 1); + mir_wstrncpy(newName, newBaseName, _countof(newName) - 1); if (ptszName) { int id = GroupNameExists(newBaseName, -1); if (id) return id; } else { - for (int idCopy = 1; GroupNameExists(newName + 1, -1); idCopy++) - mir_snwprintf(newName + 1, _countof(newName) - 1, L"%s (%d)", newBaseName, idCopy); + for (int idCopy = 1; GroupNameExists(newName, -1); idCopy++) + mir_snwprintf(newName, L"%s (%d)", newBaseName, idCopy); } int newId = arByIds.getCount(); - newName[0] = 1 | GROUPF_EXPANDED; // 1 is required so we never get '\0' - CGroupInternal *pNew = new CGroupInternal(newId, newName); + CGroupInternal *pNew = new CGroupInternal(newId, newName, GROUPF_EXPANDED); arByIds.insert(pNew); arByName.insert(pNew); pNew->save(); Clist_GroupAdded(newId + 1); - CLISTGROUPCHANGE grpChg = { nullptr, newName+1 }; + CLISTGROUPCHANGE grpChg = { nullptr, newName }; NotifyEventHooks(hGroupChangeEvent, 0, (LPARAM)&grpChg); return newId + 1; @@ -170,13 +178,13 @@ MIR_APP_DLL(MGROUP) Clist_GroupCreate(MGROUP hParent, LPCTSTR ptszGroupName) MIR_APP_DLL(wchar_t*) Clist_GroupGetName(MGROUP hGroup, uint32_t *pdwFlags) { - CGroupInternal *p = arByIds.find(hGroup-1); + CGroupInternal *p = FindGroup(hGroup-1); if (p == nullptr) return nullptr; if (pdwFlags != nullptr) - *pdwFlags = p->groupName[0] & ~1; - return p->groupName+1; + *pdwFlags = p->flags; + return p->groupName; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -198,13 +206,13 @@ static bool isParentOf(const CMStringW &pParent, const wchar_t *p) MIR_APP_DLL(int) Clist_GroupDelete(MGROUP hGroup) { // get the name - CGroupInternal *pGroup = arByIds.find(hGroup-1); + CGroupInternal *pGroup = FindGroup(hGroup-1); if (pGroup == nullptr) return 1; if (Clist::ConfirmDelete) { wchar_t szQuestion[256 + 100]; - mir_snwprintf(szQuestion, TranslateT("Are you sure you want to delete group '%s'? This operation cannot be undone."), pGroup->groupName+1); + mir_snwprintf(szQuestion, TranslateT("Are you sure you want to delete group '%s'? This operation cannot be undone."), pGroup->groupName); if (MessageBoxW(g_clistApi.hwndContactList, szQuestion, TranslateT("Delete group"), MB_YESNO | MB_ICONQUESTION) == IDNO) return 1; } @@ -213,7 +221,7 @@ 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. - CMStringW wszOldName(pGroup->groupName + 1), wszNewParent; + CMStringW wszOldName(pGroup->groupName), wszNewParent; { int idx = wszOldName.ReverseFind('\\'); if (idx != -1) @@ -239,7 +247,7 @@ MIR_APP_DLL(int) Clist_GroupDelete(MGROUP hGroup) int iGap = 0; for (auto &it : arByIds.rev_iter()) { - if (!isParentOf(wszOldName, it->groupName + 1)) + if (!isParentOf(wszOldName, it->groupName)) continue; iGap++; @@ -253,12 +261,6 @@ MIR_APP_DLL(int) Clist_GroupDelete(MGROUP hGroup) 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(); @@ -277,7 +279,7 @@ MIR_APP_DLL(int) Clist_GroupMoveBefore(MGROUP hGroup, MGROUP hGroupBefore) return 0; hGroup--; - CGroupInternal *pGroup = arByIds.find(hGroup); + CGroupInternal *pGroup = FindGroup(hGroup); if (pGroup == nullptr) return 0; @@ -290,7 +292,7 @@ MIR_APP_DLL(int) Clist_GroupMoveBefore(MGROUP hGroup, MGROUP hGroupBefore) } else { hGroupBefore--; - CGroupInternal *pDest = arByIds.find(hGroupBefore); + CGroupInternal *pDest = FindGroup(hGroupBefore); if (pDest == nullptr) return 0; @@ -333,17 +335,16 @@ static int RenameGroupWithMove(int groupId, const wchar_t *szName, int move) return 1; } - CGroupInternal *pGroup = arByIds.find(groupId); + CGroupInternal *pGroup = FindGroup(groupId); if (pGroup == nullptr) return 0; // do the change - wchar_t *oldName = NEWWSTR_ALLOCA(pGroup->groupName+1); + wchar_t *oldName = NEWWSTR_ALLOCA(pGroup->groupName); arByName.remove(pGroup); wchar_t str[256]; - str[0] = pGroup->groupName[0]; - mir_wstrncpy(str + 1, szName, _countof(str) - 1); + mir_wstrncpy(str, szName, _countof(str)); replaceStrW(pGroup->groupName, str); pGroup->save(); @@ -365,9 +366,9 @@ static int RenameGroupWithMove(int groupId, const wchar_t *szName, int move) continue; CGroupInternal *p = arByIds[i]; - if (!wcsncmp(p->groupName+1, oldName, len) && p->groupName[len+1] == '\\' && wcschr(p->groupName + len + 2, '\\') == nullptr) { + if (!wcsncmp(p->groupName, oldName, len) && p->groupName[len] == '\\' && wcschr(p->groupName + len + 1, '\\') == nullptr) { wchar_t szNewName[256]; - mir_snwprintf(szNewName, L"%s\\%s", szName, p->groupName + len + 2); + mir_snwprintf(szNewName, L"%s\\%s", szName, p->groupName + len + 1); RenameGroupWithMove(i, szNewName, 0); // luckily, child groups will never need reordering } } @@ -380,7 +381,7 @@ static int RenameGroupWithMove(int groupId, const wchar_t *szName, int move) *pszLastBackslash = '\0'; for (int i = 0; i < arByIds.getCount(); i++) { CGroupInternal *p = arByIds[i]; - if (!mir_wstrcmp(p->groupName+1, str)) { + if (!mir_wstrcmp(p->groupName, str)) { if (i >= groupId) Clist_GroupMoveBefore(groupId + 1, i + 2); break; @@ -404,16 +405,16 @@ MIR_APP_DLL(int) Clist_GroupRename(MGROUP hGroup, const wchar_t *ptszNewName) MIR_APP_DLL(void) Clist_GroupSaveExpanded() { for (auto &it : arByIds) - it->bSaveExpanded = (it->groupName[0] & GROUPF_EXPANDED) != 0; + it->bSaveExpanded = (it->flags & GROUPF_EXPANDED) != 0; } MIR_APP_DLL(void) Clist_GroupRestoreExpanded() { for (auto &it : arByIds) { if (it->bSaveExpanded) - it->groupName[0] |= GROUPF_EXPANDED; + it->flags |= GROUPF_EXPANDED; else - it->groupName[0] &= ~GROUPF_EXPANDED; + it->flags &= ~GROUPF_EXPANDED; it->save(); } } @@ -422,14 +423,14 @@ MIR_APP_DLL(void) Clist_GroupRestoreExpanded() MIR_APP_DLL(int) Clist_GroupSetExpanded(MGROUP hGroup, int iNewState) { - CGroupInternal *pGroup = arByIds.find(hGroup-1); + CGroupInternal *pGroup = FindGroup(hGroup-1); if (pGroup == nullptr) return 1; if (iNewState) - pGroup->groupName[0] |= GROUPF_EXPANDED; + pGroup->flags |= GROUPF_EXPANDED; else - pGroup->groupName[0] &= ~GROUPF_EXPANDED; + pGroup->flags &= ~GROUPF_EXPANDED; pGroup->save(); return 0; } @@ -438,16 +439,16 @@ MIR_APP_DLL(int) Clist_GroupSetExpanded(MGROUP hGroup, int iNewState) MIR_APP_DLL(int) Clist_GroupSetFlags(MGROUP hGroup, LPARAM iNewFlags) { - CGroupInternal *pGroup = arByIds.find(hGroup-1); + CGroupInternal *pGroup = FindGroup(hGroup-1); if (pGroup == nullptr) return 1; int flags = LOWORD(iNewFlags) & HIWORD(iNewFlags); - int oldval = pGroup->groupName[0]; - pGroup->groupName[0] = ((oldval & ~HIWORD(iNewFlags)) | flags) & 0x7f; + int oldval = pGroup->flags; + pGroup->flags = ((oldval & ~HIWORD(iNewFlags)) | flags) & 0x7f; pGroup->save(); - if ((oldval & GROUPF_HIDEOFFLINE) != (pGroup->groupName[0] & GROUPF_HIDEOFFLINE)) + if ((oldval & GROUPF_HIDEOFFLINE) != (pGroup->flags & GROUPF_HIDEOFFLINE)) Clist_LoadContactTree(); return 0; } @@ -479,7 +480,7 @@ MIR_APP_DLL(HMENU) Clist_GroupBuildMenu(int startId) HMENU hRootMenu = CreateMenu(); for (int i = 0; i < arByIds.getCount(); i++) { - const wchar_t *pNextField = arByIds[i]->groupName + 1; + const wchar_t *pNextField = arByIds[i]->groupName; HMENU hThisMenu = hRootMenu; MENUITEMINFO mii = { 0 }; @@ -554,18 +555,38 @@ MIR_APP_DLL(HMENU) Clist_GroupBuildMenu(int startId) return hRootMenu; } +///////////////////////////////////////////////////////////////////////////////////////// +// Module entry point + int InitGroupServices(void) { - for (int i = 0;; i++) { + g_pTimer = new CTimer(Miranda_GetSystemWindow(), UINT_PTR(&g_pTimer)); + g_pTimer->OnEvent = Callback(&g_impl, &CGroupImpl::OnTimer); + + if (!db_get_b(0, "Compatibility", "Groups")) { char str[32]; - _itoa(i, str, 10); - ptrW tszGroup(db_get_wsa(0, "CListGroups", str)); - if (tszGroup == nullptr) - break; - - CGroupInternal *p = new CGroupInternal(i, tszGroup); - arByIds.insert(p); - arByName.insert(p); + for (int i = 0;; i++) { + _itoa(i, str, 10); + ptrW tszGroup(db_get_wsa(0, "CListGroups", str)); + if (tszGroup == nullptr) + break; + + auto *p = new CGroupInternal(i, tszGroup.get() + 1, tszGroup[0] & ~1); + arByIds.insert(p); + arByName.insert(p); + } + db_set_b(0, "Compatibility", "Groups", 1); + db_delete_module(0, "CListGroups"); + } + else { + JSONNode cache; + if (file2json(VARSW(L"%miranda_userdata%\\groups.json"), cache)) { + for (auto &it : cache) { + CGroupInternal *p = new CGroupInternal(it["id"].as_int(), it["name"].as_mstring(), it["flags"].as_int()); + arByIds.insert(p); + arByName.insert(p); + } + } } hGroupChangeEvent = CreateHookableEvent(ME_CLIST_GROUPCHANGE); @@ -574,6 +595,9 @@ int InitGroupServices(void) void UninitGroupServices(void) { + g_pTimer->OnTimer(); + delete g_pTimer; + for (auto &p : arByIds) delete p; diff --git a/src/mir_app/src/movetogroup.cpp b/src/mir_app/src/movetogroup.cpp index 577f46591f..212546b391 100644 --- a/src/mir_app/src/movetogroup.cpp +++ b/src/mir_app/src/movetogroup.cpp @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "stdafx.h" +#include "clc.h" static HGENMENU hMoveToGroupItem = nullptr, hPriorityItem = nullptr, hFloatingItem = nullptr; static LIST lphGroupsItems(5); @@ -85,6 +86,8 @@ static void AddGroupItem(HGENMENU hRoot, wchar_t* name, int pos, WPARAM param, b // wparam - hcontact // lparam .popupposition from TMO_MenuItem +extern LIST arByIds; + static int OnContactMenuBuild(WPARAM wParam, LPARAM) { OBJLIST groups(10, GroupItemSort::compare); @@ -100,19 +103,9 @@ static int OnContactMenuBuild(WPARAM wParam, LPARAM) pos += 100000; // Separator - for (int i = 0;; i++) { - char intname[20]; - _itoa(i, intname, 10); - - DBVARIANT dbv; - if (db_get_ws(0, "CListGroups", intname, &dbv)) - break; - - if (dbv.pwszVal[0]) - groups.insert(new GroupItemSort(dbv.pwszVal + 1, i + 1)); - - mir_free(dbv.pwszVal); - } + for (auto &it : arByIds) + if (it->flags) + groups.insert(new GroupItemSort(it->groupName, it->groupId)); for (auto &p : groups) { bool checked = szContactGroup && !mir_wstrcmp(szContactGroup, p->name); -- cgit v1.2.3