summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/delphi/m_clist.inc4
-rw-r--r--include/m_import.h1
-rw-r--r--plugins/Import/src/import.cpp50
-rw-r--r--plugins/Import/src/miranda.cpp4
-rw-r--r--plugins/Import/src/stdafx.h1
-rw-r--r--plugins/RemovePersonalSettings/src/rps.cpp3
-rw-r--r--plugins/Utils.pas/mirutils.pas33
-rw-r--r--plugins/mRadio/i_optdlg.inc7
-rw-r--r--src/mir_app/src/clc.cpp61
-rw-r--r--src/mir_app/src/clc.h14
-rw-r--r--src/mir_app/src/clistgroups.cpp202
-rw-r--r--src/mir_app/src/movetogroup.cpp19
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<MImportGroup> *pArray = (OBJLIST<MImportGroup>*)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<MImportGroup> 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<char> 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<char> &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('<Root Group>'));
- 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<CGroupInternal> arByName(20, CompareGrpByName);
/////////////////////////////////////////////////////////////////////////////////////////
-struct CGroupList : public LIST<CGroupInternal>
+LIST<CGroupInternal> arByIds(20, NumericKeySortT);
+
+static CGroupInternal* FindGroup(int key)
+{
+ return arByIds.find((CGroupInternal *)&key);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static CTimer *g_pTimer;
+
+struct CGroupImpl
{
- CGroupList() :
- LIST<CGroupInternal>(20, NumericKeySortT)
- {}
+ void OnTimer(CTimer *)
+ {
+ g_pTimer->Stop();
- __inline CGroupInternal* find(int key)
- { return LIST<CGroupInternal>::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<HANDLE> 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<CGroupInternal> arByIds;
+
static int OnContactMenuBuild(WPARAM wParam, LPARAM)
{
OBJLIST<GroupItemSort> 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);