From 9238c4e3aa9df5d0726cf3a03e632bc3d3969711 Mon Sep 17 00:00:00 2001
From: George Hazan <george.hazan@gmail.com>
Date: Thu, 2 Jul 2015 13:15:30 +0000
Subject: two new flags of TMO_MenuItem: - CMIF_SYSTEM: filters a menu item out
 of options' editor; - CMIF_UNMOVABLE: denies attempts to change the item's
 position; - CMIF_SYSTEM applied to frames' menu; - CMIF_UNMOVABLE applied to
 Jabber protocol menu items;

git-svn-id: http://svn.miranda-ng.org/main/trunk@14468 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
---
 src/mir_app/res/resource.rc    |  2 +-
 src/mir_app/src/clistmenus.cpp |  3 +-
 src/mir_app/src/framesmenu.cpp |  4 +--
 src/mir_app/src/genmenuopt.cpp | 74 ++++++++++++++++++++++++++++--------------
 4 files changed, 54 insertions(+), 29 deletions(-)

(limited to 'src/mir_app')

diff --git a/src/mir_app/res/resource.rc b/src/mir_app/res/resource.rc
index 7b86ad92ea..ef4583b099 100644
--- a/src/mir_app/res/resource.rc
+++ b/src/mir_app/res/resource.rc
@@ -487,7 +487,7 @@ BEGIN
     GROUPBOX        "Menu objects",IDC_STATIC,5,2,140,94
     LISTBOX         IDC_MENUOBJECTS,11,13,128,79,WS_VSCROLL | WS_TABSTOP
     GROUPBOX        "Menu items",IDC_STATIC,149,2,161,248
-    CONTROL         "Tree1",IDC_MENUITEMS,"SysTreeView32",TVS_SHOWSELALWAYS | WS_DISABLED | WS_BORDER | WS_HSCROLL | WS_TABSTOP,156,13,148,212
+    CONTROL         "Tree1",IDC_MENUITEMS,"SysTreeView32",TVS_SHOWSELALWAYS | TVS_HASLINES | WS_DISABLED | WS_BORDER | WS_HSCROLL | WS_TABSTOP,156,13,148,212
     GROUPBOX        "Protocol menus",IDC_STATIC,5,100,140,37
     CONTROL         "Move to the main menu",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON,11,111,128,8
     CONTROL         "Move to the status bar",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,11,123,130,8
diff --git a/src/mir_app/src/clistmenus.cpp b/src/mir_app/src/clistmenus.cpp
index fe6499c42f..596a5e3116 100644
--- a/src/mir_app/src/clistmenus.cpp
+++ b/src/mir_app/src/clistmenus.cpp
@@ -1106,7 +1106,7 @@ void InitCustomMenus(void)
 	CreateServiceFunction("StatusMenuExecService", StatusMenuExecService);
 	CreateServiceFunction("StatusMenuCheckService", StatusMenuCheckService);
 
-	//free services
+	// free services
 	CreateServiceFunction("CLISTMENUS/FreeOwnerDataMainMenu", FreeOwnerDataMainMenu);
 	CreateServiceFunction("CLISTMENUS/FreeOwnerDataContactMenu", FreeOwnerDataContactMenu);
 	CreateServiceFunction("CLISTMENUS/FreeOwnerDataStatusMenu", FreeOwnerDataStatusMenu);
@@ -1165,7 +1165,6 @@ void InitCustomMenus(void)
 	HookEvent(ME_HOTKEYS_CHANGED, sttRebuildHotkeys);
 
 	// add exit command to menu
-
 	CMenuItem mi;
 	mi.position = 0x7fffffff;
 	mi.pszService = "CloseAction";
diff --git a/src/mir_app/src/framesmenu.cpp b/src/mir_app/src/framesmenu.cpp
index 98f7da0cdd..4d904620df 100644
--- a/src/mir_app/src/framesmenu.cpp
+++ b/src/mir_app/src/framesmenu.cpp
@@ -34,7 +34,7 @@ static HANDLE hPreBuildFrameMenuEvent;
 // also used in checkservice
 struct FrameMenuExecParam
 {
-	ptrA    szServiceName;
+	ptrA szServiceName;
 };
 
 INT_PTR FreeOwnerDataFrameMenu(WPARAM, LPARAM lParam)
@@ -65,7 +65,7 @@ INT_PTR FrameMenuExecService(WPARAM wParam, LPARAM lParam)
 	return 0;
 }
 
-//true - ok,false ignore
+// true - ok,false ignore
 INT_PTR FrameMenuCheckService(WPARAM wParam, LPARAM)
 {
 	TCheckProcParam *pcpp = (TCheckProcParam*)wParam;
diff --git a/src/mir_app/src/genmenuopt.cpp b/src/mir_app/src/genmenuopt.cpp
index cd2653227f..6e57e67f9d 100644
--- a/src/mir_app/src/genmenuopt.cpp
+++ b/src/mir_app/src/genmenuopt.cpp
@@ -141,29 +141,23 @@ class CGenMenuOptionsPage : public CDlgBase
 			BuildTree(MenuObjectID, true);
 	}
 
-	bool BuildTree(int MenuObjectId, bool bReread)
+	void BuildTreeInternal(const char *pszModule, bool bReread, HGENMENU pFirst, HTREEITEM hRoot)
 	{
-		FreeTreeData();
-
-		TIntMenuObject *pmo = GetMenuObjbyId(MenuObjectId);
-		if (pmo == NULL || pmo->m_items.first == NULL)
-			return false;
-
-		char menuItemName[256], MenuNameItems[256];
-		mir_snprintf(MenuNameItems, _countof(MenuNameItems), "%s_Items", pmo->pszName);
-
 		LIST<MenuItemOptData> arItems(10, SortMenuItems);
 
-		for (TMO_IntMenuItem *p = pmo->m_items.first; p != NULL; p = p->next) {
-			if (p->mi.root != (HGENMENU)-1 && p->mi.root != NULL)
+		for (TMO_IntMenuItem *p = pFirst; p != NULL; p = p->next) {
+			// filter out items whose presence & position might not be changed
+			if (p->mi.flags & CMIF_SYSTEM)
 				continue;
 
+			char menuItemName[256];
+			GetMenuItemName(p, menuItemName, _countof(menuItemName));
+
 			MenuItemOptData *PD = new MenuItemOptData();
-			GetMenuItemName(p, menuItemName, sizeof(menuItemName));
 
 			char buf[256];
 			mir_snprintf(buf, "%s_name", menuItemName);
-			ptrT tszName(db_get_tsa(NULL, MenuNameItems, buf));
+			ptrT tszName(db_get_tsa(NULL, pszModule, buf));
 			if (tszName != 0)
 				PD->name = tszName.detach();
 			else
@@ -173,11 +167,11 @@ class CGenMenuOptionsPage : public CDlgBase
 			PD->defname = mir_tstrdup(GetMenuItemText(p));
 
 			mir_snprintf(buf, "%s_visible", menuItemName);
-			PD->bShow = db_get_b(NULL, MenuNameItems, buf, 1) != 0;
+			PD->bShow = db_get_b(NULL, pszModule, buf, 1) != 0;
 
 			if (bReread) {
 				mir_snprintf(buf, "%s_pos", menuItemName);
-				PD->pos = db_get_dw(NULL, MenuNameItems, buf, 1);
+				PD->pos = db_get_dw(NULL, pszModule, buf, 1);
 			}
 			else PD->pos = (PD->pimi) ? PD->pimi->originalPosition : 0;
 
@@ -189,17 +183,13 @@ class CGenMenuOptionsPage : public CDlgBase
 			arItems.insert(PD);
 		}
 
-		bRebuild = true;
-		m_menuItems.SendMsg(WM_SETREDRAW, FALSE, 0);
-		m_menuItems.DeleteAllItems();
-
 		int lastpos = 0;
 		bool bIsFirst = TRUE;
 
 		TVINSERTSTRUCT tvis;
-		tvis.hParent = NULL;
+		tvis.hParent = hRoot;
 		tvis.hInsertAfter = TVI_LAST;
-		tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+		tvis.item.mask = TVIF_PARAM | TVIF_CHILDREN | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
 
 		for (int i = 0; i < arItems.getCount(); i++) {
 			MenuItemOptData *PD = arItems[i];
@@ -212,21 +202,47 @@ class CGenMenuOptionsPage : public CDlgBase
 				tvis.item.lParam = (LPARAM)sep;
 				tvis.item.pszText = sep->name;
 				tvis.item.iImage = tvis.item.iSelectedImage = 1;
+				tvis.item.cChildren = 0;
 				m_menuItems.InsertItem(&tvis);
 			}
 
 			tvis.item.lParam = (LPARAM)PD;
 			tvis.item.pszText = PD->name;
 			tvis.item.iImage = tvis.item.iSelectedImage = PD->bShow;
+			tvis.item.cChildren = PD->pimi->submenu.first != NULL;
 
 			HTREEITEM hti = m_menuItems.InsertItem(&tvis);
 			if (bIsFirst) {
-				m_menuItems.SelectItem(hti);
+				if (hRoot == NULL)
+					m_menuItems.SelectItem(hti);
 				bIsFirst = false;
 			}
 
+			if (PD->pimi->submenu.first != NULL) {
+				BuildTreeInternal(pszModule, bReread, PD->pimi->submenu.first, hti);
+				m_menuItems.Expand(hti, TVE_EXPAND);
+			}
+
 			lastpos = PD->pos;
 		}
+	}
+
+	bool BuildTree(int MenuObjectId, bool bReread)
+	{
+		FreeTreeData();
+
+		TIntMenuObject *pmo = GetMenuObjbyId(MenuObjectId);
+		if (pmo == NULL || pmo->m_items.first == NULL)
+			return false;
+
+		char MenuNameItems[256];
+		mir_snprintf(MenuNameItems, _countof(MenuNameItems), "%s_Items", pmo->pszName);
+
+		bRebuild = true;
+		m_menuItems.SendMsg(WM_SETREDRAW, FALSE, 0);
+		m_menuItems.DeleteAllItems();
+
+		BuildTreeInternal(MenuNameItems, bReread, pmo->m_items.first, NULL);
 
 		m_menuItems.SendMsg(WM_SETREDRAW, TRUE, 0);
 		bRebuild = false;
@@ -280,6 +296,7 @@ public:
 
 		m_menuItems.SetFlags(MTREE_CHECKBOX | MTREE_DND | MTREE_MULTISELECT);
 		m_menuItems.OnSelChanged = Callback(this, &CGenMenuOptionsPage::onMenuItemChanged);
+		m_menuItems.OnBeginDrag = Callback(this, &CGenMenuOptionsPage::onMenuItemDrag);
 
 		m_customName.SetSilent();
 		m_service.SetSilent();
@@ -289,7 +306,7 @@ public:
 	virtual void OnInitDialog()
 	{
 		iInitMenuValue = db_get_b(NULL, "CList", "MoveProtoMenus", TRUE);
-
+		
 		HIMAGELIST himlCheckBoxes = ImageList_Create(g_iIconSX, g_iIconSY, ILC_COLOR32 | ILC_MASK, 2, 2);
 		ImageList_AddIcon_IconLibLoaded(himlCheckBoxes, SKINICON_OTHER_NOTICK);
 		ImageList_AddIcon_IconLibLoaded(himlCheckBoxes, SKINICON_OTHER_TICK);
@@ -459,6 +476,15 @@ public:
 		m_btnSet.Enable(true);
 		m_customName.Enable(true);
 	}
+
+	void onMenuItemDrag(CCtrlTreeView::TEventInfo *evt)
+	{
+		MenuItemOptData *p = (MenuItemOptData*)evt->nmtv->itemNew.lParam;
+		if (p->pimi == NULL)
+			evt->nmhdr->code = 0; // reject an attempt to move a separator
+		else if (p->pimi->mi.flags & CMIF_UNMOVABLE)
+			evt->nmhdr->code = 0; // reject an attempt to change item's position
+	}
 };
 
 int GenMenuOptInit(WPARAM wParam, LPARAM)
-- 
cgit v1.2.3