summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2015-12-09 22:25:09 +0000
committerGeorge Hazan <george.hazan@gmail.com>2015-12-09 22:25:09 +0000
commit4e2b6ee4835543e3fa34075a853f2357c5fd4d9c (patch)
tree35c4840de6340c1e84a90fcdcf9badd317236af8
parent80fc8a06568a0fe4e6f483ec79e537f30e3d1442 (diff)
- correct menu serialization;
- custom menu items root introduced git-svn-id: http://svn.miranda-ng.org/main/trunk@15835 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--src/mir_app/src/genmenu.h5
-rw-r--r--src/mir_app/src/menu_options.cpp39
-rw-r--r--src/mir_app/src/menu_utils.cpp185
3 files changed, 164 insertions, 65 deletions
diff --git a/src/mir_app/src/genmenu.h b/src/mir_app/src/genmenu.h
index 0a73caa036..2465612a10 100644
--- a/src/mir_app/src/genmenu.h
+++ b/src/mir_app/src/genmenu.h
@@ -37,6 +37,9 @@ struct TMO_LinkedList
TMO_IntMenuItem
*first, // first element of submenu, or NULL
*last; // last element of submenu, or NULL
+
+ void insert(TMO_IntMenuItem*);
+ void remove(TMO_IntMenuItem*);
};
struct TMO_IntMenuItem
@@ -117,6 +120,8 @@ TMO_IntMenuItem *MO_RecursiveWalkMenu(TMO_IntMenuItem*, pfnWalkFunc, void*);
int InitGenMenu();
int UninitGenMenu();
+int Menu_LoadFromDatabase(TMO_IntMenuItem *pimi, void *param);
+
TMO_IntMenuItem * GetMenuItemByGlobalID(int globalMenuID);
BOOL FindMenuHanleByGlobalID(HMENU hMenu, int globalID, struct _MenuItemHandles * dat); //GenMenu.c
diff --git a/src/mir_app/src/menu_options.cpp b/src/mir_app/src/menu_options.cpp
index f3c89cf9ad..8f7599c41f 100644
--- a/src/mir_app/src/menu_options.cpp
+++ b/src/mir_app/src/menu_options.cpp
@@ -91,7 +91,13 @@ class CGenMenuOptionsPage : public CDlgBase
else
ptszCustomName = _T("");
- CMString tszValue(FORMAT, _T("%d;%d;%s"), visible, runtimepos, ptszCustomName);
+ char pszParent[33];
+ if (pimi->mi.root == NULL)
+ pszParent[0] = 0;
+ else
+ bin2hex(&pimi->mi.root->mi.uid, sizeof(MUUID), pszParent);
+
+ CMString tszValue(FORMAT, _T("%d;%d;%S;%s"), visible, runtimepos, pszParent, ptszCustomName);
db_set_ts(NULL, szModule, menuItemName, tszValue);
if (pimi->mi.flags & CMIF_CUSTOM)
@@ -153,7 +159,7 @@ class CGenMenuOptionsPage : public CDlgBase
BuildTree(MenuObjectID, true);
}
- void BuildTreeInternal(const char *pszModule, bool bReread, HGENMENU pFirst, HTREEITEM hRoot)
+ void BuildTreeInternal(const char *pszModule, bool bReread, TMO_IntMenuItem *pFirst, HTREEITEM hRoot)
{
LIST<MenuItemOptData> arItems(10, SortMenuItems);
@@ -162,32 +168,12 @@ class CGenMenuOptionsPage : public CDlgBase
if (p->mi.flags & CMIF_SYSTEM)
continue;
- TCHAR customName[201]; customName[0] = 0;
- int visible = 1, pos = 0;
- if (!equalUUID(p->mi.uid, miid_last)) {
- char menuItemName[256];
- bin2hex(&p->mi.uid, sizeof(p->mi.uid), menuItemName);
- ptrT tszSettings(db_get_tsa(NULL, pszModule, menuItemName));
- if (tszSettings == NULL)
- pos = p->mi.position;
- else if (_stscanf(tszSettings, _T("%d;%d;%200s"), &visible, &pos, customName) < 2)
- continue;
- }
-
MenuItemOptData *PD = new MenuItemOptData();
- if (customName[0] != 0)
- PD->name = mir_tstrdup(customName);
- else
- PD->name = mir_tstrdup(GetMenuItemText(p));
-
PD->pimi = p;
PD->defname = mir_tstrdup(GetMenuItemText(p));
- PD->bShow = visible != 0;
- if (bReread)
- PD->pos = pos;
- else
- PD->pos = (PD->pimi) ? PD->pimi->originalPosition : 0;
-
+ PD->name = mir_tstrdup((p->CustomName != NULL) ? p->CustomName : PD->defname);
+ PD->bShow = (p->mi.flags & CMIF_HIDDEN) == 0;
+ PD->pos = (bReread) ? p->mi.position : p->originalPosition;
PD->id = p->iCommand;
arItems.insert(PD);
}
@@ -247,6 +233,9 @@ class CGenMenuOptionsPage : public CDlgBase
char szModule[256];
mir_snprintf(szModule, "%s_Items", pmo->pszName);
+ if (bReread) // no need to reread database on reset
+ MO_RecursiveWalkMenu(pmo->m_items.first, Menu_LoadFromDatabase, szModule);
+
bRebuild = true;
m_menuItems.SendMsg(WM_SETREDRAW, FALSE, 0);
m_menuItems.DeleteAllItems();
diff --git a/src/mir_app/src/menu_utils.cpp b/src/mir_app/src/menu_utils.cpp
index 266d67b7aa..4d4d6735d3 100644
--- a/src/mir_app/src/menu_utils.cpp
+++ b/src/mir_app/src/menu_utils.cpp
@@ -86,7 +86,7 @@ LPTSTR GetMenuItemText(TMO_IntMenuItem *pimi)
TMO_IntMenuItem* MO_RecursiveWalkMenu(TMO_IntMenuItem *parent, pfnWalkFunc func, void* param)
{
if (parent == NULL)
- return FALSE;
+ return NULL;
TMO_IntMenuItem *pnext;
for (TMO_IntMenuItem *pimi = parent; pimi != NULL; pimi = pnext) {
@@ -102,7 +102,7 @@ TMO_IntMenuItem* MO_RecursiveWalkMenu(TMO_IntMenuItem *parent, pfnWalkFunc func,
}
}
- return FALSE;
+ return NULL;
}
///////////////////////////////////////////////////////////////////////////////
@@ -749,11 +749,7 @@ MIR_APP_DLL(HGENMENU) Menu_AddItem(int hMenuObject, TMO_MenuItem *pmi, void *pUs
}
else p->owner = &pmo->m_items;
- if (!p->owner->first)
- p->owner->first = p;
- if (p->owner->last)
- p->owner->last->next = p;
- p->owner->last = p;
+ p->owner->insert(p);
return p;
}
@@ -896,8 +892,14 @@ static int sttDumpItem(TMO_IntMenuItem *pmi, void *szModule)
int visible = (pmi->mi.flags & CMIF_HIDDEN) == 0;
TCHAR *ptszName = (pmi->CustomName != NULL) ? pmi->CustomName : _T("");
+
+ char szRootUid[33];
+ if (pmi->mi.root == NULL)
+ szRootUid[0] = 0;
+ else
+ bin2hex(&pmi->mi.root->mi.uid, sizeof(MUUID), szRootUid);
- CMString szNewValue(FORMAT, _T("%d;%d;%s"), visible, pmi->mi.position, ptszName);
+ CMString szNewValue(FORMAT, _T("%d;%d;%S;%s"), visible, pmi->mi.position, szRootUid, ptszName);
db_set_ts(NULL, (char*)szModule, menuItemName, szNewValue);
Netlib_Logf(NULL, "MENU[%s] => %s, %d, %d", menuItemName, pmi->UniqName, visible, pmi->mi.position);
@@ -918,14 +920,36 @@ static INT_PTR sttUpdateMenuService(WPARAM wParam, LPARAM)
char szModule[256];
mir_snprintf(szModule, "%s_Items", pmo->pszName);
- // read old settings first
- MO_RecursiveWalkMenu(pmo->m_items.first, sttReadOldItem, szModule);
-
- // wipe out old trash, write new data & compatibility flag
- CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)szModule);
- db_set_b(NULL, szModule, "MenuFormat", true);
+ // was a menu converted?
+ if (db_get_b(NULL, szModule, "MenuFormat", 0) == 0) { // no
+ // read old settings
+ MO_RecursiveWalkMenu(pmo->m_items.first, sttReadOldItem, szModule);
- MO_RecursiveWalkMenu(pmo->m_items.first, sttDumpItem, szModule);
+ // wipe out old trash, write new data & compatibility flag
+ CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)szModule);
+ db_set_b(NULL, szModule, "MenuFormat", true);
+ MO_RecursiveWalkMenu(pmo->m_items.first, sttDumpItem, szModule);
+ }
+ else { // yes, menu is already converted, simply load its data
+ for (int i = 0;; i++) {
+ char szSetting[100];
+ mir_snprintf(szSetting, "Custom%d", i);
+ ptrA szCustomMenu(db_get_sa(NULL, szModule, szSetting));
+ if (mir_strlen(szCustomMenu) != 32)
+ break;
+
+ TMO_MenuItem mi = {};
+ mi.flags = CMIF_CUSTOM;
+ mi.name.a = LPGEN("New submenu");
+ mi.position = 500050000;
+ BYTE *p = (BYTE*)&mi.uid;
+ for (int i = 0; i < 16; i++)
+ sscanf(&szCustomMenu[i*2], "%02x", &p[i]);
+ Menu_AddItem(pmo->id, &mi, NULL);
+ }
+
+ MO_RecursiveWalkMenu(pmo->m_items.first, Menu_LoadFromDatabase, szModule);
+ }
}
return 0;
}
@@ -934,12 +958,87 @@ static INT_PTR sttUpdateMenuService(WPARAM wParam, LPARAM)
void ScheduleMenuUpdate()
{
- // already converted
- if (db_get_b(NULL, "MainMenu_Items", "MenuFormat", 0) == 0) {
- HANDLE hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
- CreateServiceFunction(MS_MENU_UPDATE, sttUpdateMenuService);
- CallService(MS_SYSTEM_WAITONHANDLE, (WPARAM)hEvent, (LPARAM)MS_MENU_UPDATE);
+ HANDLE hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
+ CreateServiceFunction(MS_MENU_UPDATE, sttUpdateMenuService);
+ CallService(MS_SYSTEM_WAITONHANDLE, (WPARAM)hEvent, (LPARAM)MS_MENU_UPDATE);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static int sttFindMenuItemByUid(TMO_IntMenuItem *pimi, void *pUid)
+{
+ return memcmp(&pimi->mi.uid, pUid, sizeof(MUUID)) == 0;
+}
+
+int Menu_LoadFromDatabase(TMO_IntMenuItem *pimi, void *szModule)
+{
+ if ((pimi->mi.flags & CMIF_SYSTEM) || equalUUID(pimi->mi.uid, miid_last))
+ return 0;
+
+ char menuItemName[256];
+ bin2hex(&pimi->mi.uid, sizeof(pimi->mi.uid), menuItemName);
+
+ TIntMenuObject *pmo = pimi->parent;
+ ptrT szValue(db_get_tsa(NULL, (char*)szModule, menuItemName));
+ if (szValue == NULL)
+ return 0;
+
+ TCHAR *ptszToken = szValue, *pDelim = _tcschr(szValue, ';');
+ int visible = true, pos = 0;
+ TCHAR tszCustomName[201]; tszCustomName[0] = 0;
+ char szCustomRoot[33]; szCustomRoot[0] = 0;
+ for (int i = 0; i < 4; i++) {
+ if (pDelim)
+ *pDelim = 0;
+
+ switch (i) {
+ case 0: visible = _ttoi(ptszToken); break;
+ case 1: pos = _ttoi(ptszToken); break;
+ case 2: strncpy_s(szCustomRoot, _T2A(ptszToken), _TRUNCATE); break;
+ }
+
+ ptszToken = pDelim + 1;
+ if ((pDelim = _tcschr(ptszToken, ';')) == NULL) {
+ if (i == 2 && *ptszToken != 0)
+ _tcsncpy_s(tszCustomName, ptszToken, _TRUNCATE); break;
+ break;
+ }
}
+
+ pimi->mi.position = pos;
+ if (visible)
+ pimi->mi.flags &= ~CMIF_HIDDEN;
+ else
+ pimi->mi.flags |= CMIF_HIDDEN;
+
+ if (tszCustomName[0])
+ replaceStrT(pimi->CustomName, tszCustomName);
+
+ if (szCustomRoot[0]) {
+ char szCurrentUid[33];
+ if (pimi->mi.root == NULL)
+ szCurrentUid[0] = 0;
+ else
+ bin2hex(&pimi->mi.root->mi.uid, sizeof(pimi->mi.root->mi.uid), szCurrentUid);
+
+ if (0 != strcmp(szCurrentUid, szCustomRoot)) { // need to move menu item to another root
+ TMO_LinkedList *pNew;
+ if (szCustomRoot[0] != 0) {
+ TMO_IntMenuItem *p = MO_RecursiveWalkMenu(pmo->m_items.first, sttFindMenuItemByUid, &szCustomRoot);
+ if (p == NULL)
+ return NULL;
+
+ pNew = &p->submenu;
+ }
+ else pNew = &pmo->m_items;
+
+ // relink menu item
+ pimi->owner->remove(pimi);
+ pNew->insert(pimi);
+ }
+ }
+
+ return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -976,26 +1075,6 @@ static HMENU BuildRecursiveMenu(HMENU hMenu, TMO_IntMenuItem *pRootMenu, WPARAM
continue;
}
- // if we have to check & apply database settings
- if (!(mi->flags & CMIF_SYSTEM) && pmo->m_bUseUserDefinedItems) {
- char menuItemName[256];
- int visible = true, pos = 0;
-
- if (!equalUUID(mi->uid, miid_last)) {
- bin2hex(&mi->uid, sizeof(mi->uid), menuItemName);
- ptrT szValue(db_get_tsa(NULL, szModule, menuItemName));
- if (szValue != NULL) {
- TCHAR tszCustomName[201]; tszCustomName[0] = 0;
- if (_stscanf(szValue, _T("%d;%d;%200s"), &visible, &pos, tszCustomName) >= 2)
- mi->position = pos;
- if (tszCustomName[0])
- replaceStrT(pmi->CustomName, tszCustomName);
- }
- }
- if (!visible)
- continue;
- }
-
int i = WhereToPlace(hMenu, mi);
MENUITEMINFO mii = { 0 };
@@ -1257,3 +1336,29 @@ void TIntMenuObject::freeItem(TMO_IntMenuItem *p)
if (p->hBmp) DeleteObject(p->hBmp);
mir_free(p);
}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void TMO_LinkedList::insert(TMO_IntMenuItem *pItem)
+{
+ pItem->owner = this;
+ if (!first)
+ first = pItem;
+ if (last)
+ last->next = pItem;
+ last = pItem;
+}
+
+void TMO_LinkedList::remove(TMO_IntMenuItem *pItem)
+{
+ TMO_IntMenuItem *pPrev = NULL;
+ for (TMO_IntMenuItem *p = first; p != NULL; p = p->next) {
+ if (p == pItem) {
+ if (first == pItem) first = pItem->next;
+ if (last == pItem) last = pPrev;
+ pItem->next = NULL;
+ return;
+ }
+ pPrev = p;
+ }
+}