[LyX/master] Allow to group matters in submenus

Juergen Spitzmueller spitz at lyx.org
Wed Aug 5 04:53:58 UTC 2026


commit 43f51f79bc8fb54ab0c7d1f365a1c2251d169aa4
Author: Juergen Spitzmueller <spitz at lyx.org>
Date:   Wed Aug 5 06:52:48 2026 +0200

    Allow to group matters in submenus
    
    This improves the user interface with many variants (as in KOMA)
---
 lib/doc/Customization.lyx     | 46 ++++++++++++++++++++++++++---
 lib/doc/de/Customization.lyx  | 23 +++++++++++++--
 lib/layouts/memoir.layout     | 15 ++++++----
 lib/layouts/recipebook.layout | 67 ++++++++++++++++++++++++++++++-------------
 lib/layouts/scrbook.layout    | 66 +++++++++++++++++++++++++++++-------------
 po/lyx_pot.py                 |  7 +++++
 src/TextClass.cpp             |  7 +++++
 src/TextClass.h               |  2 ++
 src/frontends/qt/Menus.cpp    | 30 +++++++++++++++++--
 9 files changed, 210 insertions(+), 53 deletions(-)

diff --git a/lib/doc/Customization.lyx b/lib/doc/Customization.lyx
index ed61dd3c52..3f14b3ee02 100644
--- a/lib/doc/Customization.lyx
+++ b/lib/doc/Customization.lyx
@@ -10664,6 +10664,8 @@ status collapsed
 
 \change_inserted -712698321 1785853142
 Matter
+\change_unchanged
+
 \end_layout
 
 \end_inset
@@ -10676,6 +10678,8 @@ status collapsed
 
 \change_inserted -712698321 1785853156
 string
+\change_unchanged
+
 \end_layout
 
 \end_inset
@@ -10690,6 +10694,8 @@ status collapsed
 
 \backslash
 frontmatter
+\change_unchanged
+
 \end_layout
 
 \end_inset
@@ -10705,6 +10711,8 @@ status collapsed
 
 \backslash
 mainmatter
+\change_unchanged
+
 \end_layout
 
 \end_inset
@@ -10720,6 +10728,8 @@ status collapsed
 
 \backslash
 backmatter
+\change_unchanged
+
 \end_layout
 
 \end_inset
@@ -10734,6 +10744,8 @@ status collapsed
 
 \change_inserted -712698321 1785853205
 EndMatter
+\change_unchanged
+
 \end_layout
 
 \end_inset
@@ -10747,7 +10759,7 @@ EndMatter
 \begin_deeper
 \begin_layout Description
 
-\change_inserted -712698321 1785853319
+\change_inserted -712698321 1785905337
 \begin_inset Flex Code
 status open
 
@@ -10765,12 +10777,12 @@ GuiName
 
 \end_inset
 
- The name as shown in the workarea
+ The name as shown in the workarea.
 \end_layout
 
 \begin_layout Description
 
-\change_inserted -712698321 1785853381
+\change_inserted -712698321 1785905336
 \begin_inset Flex Code
 status collapsed
 
@@ -10788,7 +10800,29 @@ MenuString
 
 \end_inset
 
- The string shown in the menu including accelerators
+ The string shown in the menu including accelerators.
+\end_layout
+
+\begin_layout Description
+
+\change_inserted -712698321 1785905491
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1785905234
+SubMenu
+\begin_inset space ~
+\end_inset
+
+<string>
+\end_layout
+
+\end_inset
+
+ Put the function in a submenu with the given label.
+ Use this if you have many variants of a matter.
 \end_layout
 
 \begin_layout Description
@@ -10814,6 +10848,8 @@ status collapsed
 
 \emph on
 0
+\change_unchanged
+
 \end_layout
 
 \end_inset
@@ -10830,6 +10866,8 @@ status collapsed
 
 \change_inserted -712698321 1785853402
 1
+\change_unchanged
+
 \end_layout
 
 \end_inset
diff --git a/lib/doc/de/Customization.lyx b/lib/doc/de/Customization.lyx
index fc63830b1e..81620c87ed 100644
--- a/lib/doc/de/Customization.lyx
+++ b/lib/doc/de/Customization.lyx
@@ -9261,7 +9261,7 @@ GuiName
 \end_inset
 
  Der Name,
- der im Arbeitsbereich angezeigt wird
+ der im Arbeitsbereich angezeigt wird.
 \end_layout
 
 \begin_layout Description
@@ -9280,7 +9280,26 @@ MenuString
 
  Die Zeichenklette,
  die im Menü erscheint (inkl.
- Tastenkürzel)
+ Tastenkürzel).
+\end_layout
+
+\begin_layout Description
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+SubMenu
+\begin_inset space ~
+\end_inset
+
+<string>
+\end_layout
+
+\end_inset
+
+ Verschiebt die Funktion in ein Untermenü mit der angegebenen Bezeichnung.
+ Verwenden Sie dies,
+ wenn die Klasse viele Varianten von Strukturierungsbefehlen bietet.
 \end_layout
 
 \begin_layout Description
diff --git a/lib/layouts/memoir.layout b/lib/layouts/memoir.layout
index 938f314caa..273096eb74 100644
--- a/lib/layouts/memoir.layout
+++ b/lib/layouts/memoir.layout
@@ -42,29 +42,34 @@ End
 
 Matter frontmatter
 	GuiName "Front Matter"
-	MenuString "Front Matter|F"
+	SubMenu "Front Matter|F"
+	MenuString "Default|D"
 EndMatter
 
 Matter frontmatter*
 	GuiName "Front Matter (Continuous Pagination)"
-	MenuString "Front Matter (Continuous Pagination)|r"
+	SubMenu "Front Matter|F"
+	MenuString "Continuous Pagination|C"
 EndMatter
 
 Matter mainmatter
 	GuiName "Main Matter"
-	MenuString "Main Matter|M"
+	SubMenu "Main Matter|M"
+	MenuString "Default|D"
 	UseCounters 1
 EndMatter
 
 Matter mainmatter*
 	GuiName "Main Matter (Continuous Pagination)"
-	MenuString "Main Matter (Continuous Pagination)|a"
+	SubMenu "Main Matter|M"
+	MenuString "Continuous Pagination|C"
 	UseCounters 1
 EndMatter
 
 Matter backmatter
 	GuiName "Back Matter"
-	MenuString "Back Matter|B"
+	SubMenu "Back Matter|B"
+	MenuString "Default|D"
 EndMatter
 
 
diff --git a/lib/layouts/recipebook.layout b/lib/layouts/recipebook.layout
index 7dc2ea2ee0..7edd8456d2 100644
--- a/lib/layouts/recipebook.layout
+++ b/lib/layouts/recipebook.layout
@@ -43,111 +43,138 @@ DocBookRoot		book
 
 Matter frontmatter
 	GuiName "Front Matter"
-	MenuString "Front Matter|F"
+	SubMenu "Front Matter|F"
+	MenuString "Default|D"
 EndMatter
 
 Matter frontmatter*
 	GuiName "Front Matter (Continuous Pagination)"
-	MenuString "Front Matter (Continuous Pagination)|r"
+	SubMenu "Front Matter|F"
+	MenuString "Continuous Pagination|C"
 EndMatter
 
 Matter frontmatter[arabic]
 	GuiName "Front Matter (Arabic Pagination)"
-	MenuString "Front Matter (Arabic Pagination)|o"
+	SubMenu "Front Matter|F"
+	MenuString "Arabic Pagination|A"
 EndMatter
 
 Matter frontmatter[roman]
 	GuiName "Front Matter (Lowercase Roman Pagination)"
-	MenuString "Front Matter (Lowercase Roman Pagination)|n"
+	SubMenu "Front Matter|F"
+	MenuString "Lowercase Roman Pagination|o"
 EndMatter
 
 Matter frontmatter[Roman]
 	GuiName "Front Matter (Uppercase Roman Pagination)"
-	MenuString "Front Matter (Uppercase Roman Pagination)|t"
+	SubMenu "Front Matter|F"
+	MenuString "Uppercase Roman Pagination|R"
 EndMatter
 
 Matter frontmatter[alph]
 	GuiName "Front Matter (Lowercase Alphabetic Pagination)"
-	MenuString "Front Matter (Lowercase Alphabetic Pagination)|L"
+	SubMenu "Front Matter|F"
+	MenuString "Lowercase Alphabetic Pagination|p"
 EndMatter
 
 Matter frontmatter[Alph]
 	GuiName "Front Matter (Uppercase Alphabetic Pagination)"
-	MenuString "Front Matter (Uppercase Alphabetic Pagination)|U"
+	SubMenu "Front Matter|F"
+	MenuString "Uppercase Alphabetic Pagination|b"
 EndMatter
 
 Matter mainmatter
 	GuiName "Main Matter"
-	MenuString "Main Matter|M"
+	SubMenu "Main Matter|M"
+	MenuString "Default|D"
 	UseCounters 1
 EndMatter
 
 Matter mainmatter*
 	GuiName "Main Matter (Continuous Pagination)"
-	MenuString "Main Matter (Continuous Pagination)|a"
+	SubMenu "Main Matter|M"
+	MenuString "Continuous Pagination|C"
 	UseCounters 1
 EndMatter
 
 Matter frontmatter[arabic]
 	GuiName "Main Matter (Arabic Pagination)"
-	MenuString "Main Matter (Arabic Pagination)|i"
+	SubMenu "Main Matter|M"
+	MenuString "Arabic Pagination|A"
 	UseCounters 1
 EndMatter
 
 Matter mainmatter[roman]
 	GuiName "Main Matter (Lowercase Roman Pagination)"
-	MenuString "Main Matter (Lowercase Roman Pagination)|w"
+	SubMenu "Main Matter|M"
+	MenuString "Lowercase Roman Pagination|o"
 	UseCounters 1
 EndMatter
 
 Matter mainmatter[Roman]
 	GuiName "Main Matter (Uppercase Roman Pagination)"
-	MenuString "Main Matter (Uppercase Roman Pagination)|c"
+	SubMenu "Main Matter|M"
+	MenuString "Uppercase Roman Pagination|R"
 	UseCounters 1
 EndMatter
 
 Matter mainmatter[alph]
 	GuiName "Main Matter (Lowercase Alphabetic Pagination)"
-	MenuString "Main Matter (Lowercase Alphabetic Pagination)|s"
+	SubMenu "Main Matter|M"
+	MenuString "Lowercase Alphabetic Pagination|p"
 	UseCounters 1
 EndMatter
 
 Matter mainmatter[Alph]
 	GuiName "Main Matter (Uppercase Alphabetic Pagination)"
-	MenuString "Main Matter (Uppercase Alphabetic Pagination)|p"
+	SubMenu "Main Matter|M"
+	MenuString "Uppercase Alphabetic Pagination|b"
 	UseCounters 1
 EndMatter
 
 Matter backmatter
 	GuiName "Back Matter"
-	MenuString "Back Matter|B"
+	SubMenu "Back Matter|B"
+	MenuString "Default|D"
+EndMatter
+
+Matter backmatter*
+	GuiName "Back Matter (Continuous Pagination)"
+	SubMenu "Back Matter|B"
+	MenuString "Continuous Pagination|C"
 EndMatter
 
 Matter backmatter[arabic]
 	GuiName "Back Matter (Arabic Pagination)"
-	MenuString "Back Matter (Arabic Pagination)|k"
+	SubMenu "Back Matter|B"
+	MenuString "Arabic Pagination|A"
 EndMatter
 
 Matter backmatter[roman]
 	GuiName "Back Matter (Lowercase Roman Pagination)"
-	MenuString "Back Matter (Lowercase Roman Pagination)|e"
+	SubMenu "Back Matter|B"
+	MenuString "Lowercase Roman Pagination|o"
 EndMatter
 
 Matter backmatter[Roman]
 	GuiName "Back Matter (Uppercase Roman Pagination)"
-	MenuString "Back Matter (Uppercase Roman Pagination)|g"
+	SubMenu "Back Matter|B"
+	MenuString "Uppercase Roman Pagination|R"
 EndMatter
 
 Matter backmatter[alph]
 	GuiName "Back Matter (Lowercase Alphabetic Pagination)"
-	MenuString "Back Matter (Lowercase Alphabetic Pagination)|h"
+	SubMenu "Back Matter|B"
+	MenuString "Lowercase Alphabetic Pagination|p"
 EndMatter
 
 Matter backmatter[Alph]
 	GuiName "Back Matter (Uppercase Alphabetic Pagination)"
-	MenuString "Back Matter (Uppercase Alphabetic Pagination)"
+	SubMenu "Back Matter|B"
+	MenuString "Uppercase Alphabetic Pagination|b"
 EndMatter
 
+
 # There is no abstract environment in scrbook.cls
 NoStyle Abstract
 
diff --git a/lib/layouts/scrbook.layout b/lib/layouts/scrbook.layout
index 80798c478a..2441703668 100644
--- a/lib/layouts/scrbook.layout
+++ b/lib/layouts/scrbook.layout
@@ -21,109 +21,135 @@ NoStyle Abstract
 
 Matter frontmatter
 	GuiName "Front Matter"
-	MenuString "Front Matter|F"
+	SubMenu "Front Matter|F"
+	MenuString "Default|D"
 EndMatter
 
 Matter frontmatter*
 	GuiName "Front Matter (Continuous Pagination)"
-	MenuString "Front Matter (Continuous Pagination)|r"
+	SubMenu "Front Matter|F"
+	MenuString "Continuous Pagination|C"
 EndMatter
 
 Matter frontmatter[arabic]
 	GuiName "Front Matter (Arabic Pagination)"
-	MenuString "Front Matter (Arabic Pagination)|o"
+	SubMenu "Front Matter|F"
+	MenuString "Arabic Pagination|A"
 EndMatter
 
 Matter frontmatter[roman]
 	GuiName "Front Matter (Lowercase Roman Pagination)"
-	MenuString "Front Matter (Lowercase Roman Pagination)|n"
+	SubMenu "Front Matter|F"
+	MenuString "Lowercase Roman Pagination|o"
 EndMatter
 
 Matter frontmatter[Roman]
 	GuiName "Front Matter (Uppercase Roman Pagination)"
-	MenuString "Front Matter (Uppercase Roman Pagination)|t"
+	SubMenu "Front Matter|F"
+	MenuString "Uppercase Roman Pagination|R"
 EndMatter
 
 Matter frontmatter[alph]
 	GuiName "Front Matter (Lowercase Alphabetic Pagination)"
-	MenuString "Front Matter (Lowercase Alphabetic Pagination)|L"
+	SubMenu "Front Matter|F"
+	MenuString "Lowercase Alphabetic Pagination|p"
 EndMatter
 
 Matter frontmatter[Alph]
 	GuiName "Front Matter (Uppercase Alphabetic Pagination)"
-	MenuString "Front Matter (Uppercase Alphabetic Pagination)|U"
+	SubMenu "Front Matter|F"
+	MenuString "Uppercase Alphabetic Pagination|b"
 EndMatter
 
 Matter mainmatter
 	GuiName "Main Matter"
-	MenuString "Main Matter|M"
+	SubMenu "Main Matter|M"
+	MenuString "Default|D"
 	UseCounters 1
 EndMatter
 
 Matter mainmatter*
 	GuiName "Main Matter (Continuous Pagination)"
-	MenuString "Main Matter (Continuous Pagination)|a"
+	SubMenu "Main Matter|M"
+	MenuString "Continuous Pagination|C"
 	UseCounters 1
 EndMatter
 
 Matter frontmatter[arabic]
 	GuiName "Main Matter (Arabic Pagination)"
-	MenuString "Main Matter (Arabic Pagination)|i"
+	SubMenu "Main Matter|M"
+	MenuString "Arabic Pagination|A"
 	UseCounters 1
 EndMatter
 
 Matter mainmatter[roman]
 	GuiName "Main Matter (Lowercase Roman Pagination)"
-	MenuString "Main Matter (Lowercase Roman Pagination)|w"
+	SubMenu "Main Matter|M"
+	MenuString "Lowercase Roman Pagination|o"
 	UseCounters 1
 EndMatter
 
 Matter mainmatter[Roman]
 	GuiName "Main Matter (Uppercase Roman Pagination)"
-	MenuString "Main Matter (Uppercase Roman Pagination)|c"
+	SubMenu "Main Matter|M"
+	MenuString "Uppercase Roman Pagination|R"
 	UseCounters 1
 EndMatter
 
 Matter mainmatter[alph]
 	GuiName "Main Matter (Lowercase Alphabetic Pagination)"
-	MenuString "Main Matter (Lowercase Alphabetic Pagination)|s"
+	SubMenu "Main Matter|M"
+	MenuString "Lowercase Alphabetic Pagination|p"
 	UseCounters 1
 EndMatter
 
 Matter mainmatter[Alph]
 	GuiName "Main Matter (Uppercase Alphabetic Pagination)"
-	MenuString "Main Matter (Uppercase Alphabetic Pagination)|p"
+	SubMenu "Main Matter|M"
+	MenuString "Uppercase Alphabetic Pagination|b"
 	UseCounters 1
 EndMatter
 
 Matter backmatter
 	GuiName "Back Matter"
-	MenuString "Back Matter|B"
+	SubMenu "Back Matter|B"
+	MenuString "Default|D"
+EndMatter
+
+Matter backmatter*
+	GuiName "Back Matter (Continuous Pagination)"
+	SubMenu "Back Matter|B"
+	MenuString "Continuous Pagination|C"
 EndMatter
 
 Matter backmatter[arabic]
 	GuiName "Back Matter (Arabic Pagination)"
-	MenuString "Back Matter (Arabic Pagination)|k"
+	SubMenu "Back Matter|B"
+	MenuString "Arabic Pagination|A"
 EndMatter
 
 Matter backmatter[roman]
 	GuiName "Back Matter (Lowercase Roman Pagination)"
-	MenuString "Back Matter (Lowercase Roman Pagination)|e"
+	SubMenu "Back Matter|B"
+	MenuString "Lowercase Roman Pagination|o"
 EndMatter
 
 Matter backmatter[Roman]
 	GuiName "Back Matter (Uppercase Roman Pagination)"
-	MenuString "Back Matter (Uppercase Roman Pagination)|g"
+	SubMenu "Back Matter|B"
+	MenuString "Uppercase Roman Pagination|R"
 EndMatter
 
 Matter backmatter[alph]
 	GuiName "Back Matter (Lowercase Alphabetic Pagination)"
-	MenuString "Back Matter (Lowercase Alphabetic Pagination)|h"
+	SubMenu "Back Matter|B"
+	MenuString "Lowercase Alphabetic Pagination|p"
 EndMatter
 
 Matter backmatter[Alph]
 	GuiName "Back Matter (Uppercase Alphabetic Pagination)"
-	MenuString "Back Matter (Uppercase Alphabetic Pagination)"
+	SubMenu "Back Matter|B"
+	MenuString "Uppercase Alphabetic Pagination|b"
 EndMatter
 
 
diff --git a/po/lyx_pot.py b/po/lyx_pot.py
index 13c6f0c7b6..dbec87886c 100755
--- a/po/lyx_pot.py
+++ b/po/lyx_pot.py
@@ -88,6 +88,7 @@ def layouts_l10n(input_files, output, base, layouttranslations):
     # match LabelString, EndLabelString, LabelStringAppendix and maybe others but no comments
     LabelString = re.compile(r'^[^#]*LabelString\S*\s+(.*\S)\s*$', re.IGNORECASE)
     MenuString = re.compile(r'^[^#]*MenuString\S*\s+(.*\S)\s*$', re.IGNORECASE)
+    SubMenu = re.compile(r'^[^#]*SubMenu\S*\s+(.*\S)\s*$', re.IGNORECASE)
     OutlinerName = re.compile(r'^[^#]*OutlinerName\s+(\S+|\"[^\"]*\")\s+\"([^\"]*)\"', re.IGNORECASE)
     Tooltip = re.compile(r'^\s*Tooltip\S*\s+(.*\S)\s*$', re.IGNORECASE)
     GuiName = re.compile(r'^\s*GuiName\s+(.*\S)\s*$', re.IGNORECASE)
@@ -265,6 +266,12 @@ def layouts_l10n(input_files, output, base, layouttranslations):
                     writeString(out, src, base, lineno, string)
                 continue
             res = MenuString.search(line)
+            if res != None:
+                string = res.group(1)
+                if not layouttranslations:
+                    writeString(out, src, base, lineno, string)
+                continue
+            res = SubMenu.search(line)
             if res != None:
                 string = res.group(1)
                 if not layouttranslations:
diff --git a/src/TextClass.cpp b/src/TextClass.cpp
index e9c1bf3a39..bb7bf8d754 100644
--- a/src/TextClass.cpp
+++ b/src/TextClass.cpp
@@ -1078,6 +1078,8 @@ void TextClass::readMatter(Lexer & lexrc)
 		///
 		MATTER_MENU_STRING,
 		///
+		MATTER_SUBMENU,
+		///
 		MATTER_USE_COUNTERS,
 		///
 		MATTER_END
@@ -1087,6 +1089,7 @@ void TextClass::readMatter(Lexer & lexrc)
 		{ "endmatter",  MATTER_END },
 		{ "guiname",  MATTER_GUI_NAME },
 		{ "menustring", MATTER_MENU_STRING },
+		{ "submenu", MATTER_SUBMENU },
 		{ "usecounters", MATTER_USE_COUNTERS }
 	};
 
@@ -1114,6 +1117,10 @@ void TextClass::readMatter(Lexer & lexrc)
 			lexrc.next();
 			matter.menustring = rtrim(lexrc.getDocString());
 			break;
+		case MATTER_SUBMENU:
+			lexrc.next();
+			matter.submenu = rtrim(lexrc.getDocString());
+			break;
 		case MATTER_USE_COUNTERS:
 			lexrc.next();
 			matter.use_counters = lexrc.getBool();
diff --git a/src/TextClass.h b/src/TextClass.h
index 4e28d8fa9b..e7ec8b6b77 100644
--- a/src/TextClass.h
+++ b/src/TextClass.h
@@ -218,6 +218,8 @@ public:
 		///
 		docstring menustring;
 		///
+		docstring submenu;
+		///
 		bool use_counters;
 	};
 	/// Does this class provide \forntmatter, \mainmatter, and \backmatter?
diff --git a/src/frontends/qt/Menus.cpp b/src/frontends/qt/Menus.cpp
index 4170ee16c7..8e62a0bc75 100644
--- a/src/frontends/qt/Menus.cpp
+++ b/src/frontends/qt/Menus.cpp
@@ -2024,10 +2024,36 @@ void MenuDefinition::expandDocMatters(Buffer const * buf)
 		return;
 
 	DocumentClass const & dc = buf->params().documentClass();
+	vector<MenuDefinition> submenus;
 	for (auto const & m : dc.getMatters()) {
 		docstring const gui = m.menustring.empty() ? m.guiname : m.menustring;
-		add(MenuItem(MenuItem::Command, toqstr(translateIfPossible(gui)),
-			     FuncRequest(LFUN_MATTER, from_ascii(m.name))));
+		if (m.submenu.empty())
+			add(MenuItem(MenuItem::Command, toqstr(translateIfPossible(gui)),
+				     FuncRequest(LFUN_MATTER, from_ascii(m.name))));
+		else {
+			QString sname = toqstr(m.submenu);
+			bool have_submenu = false;
+			for (auto & sm : submenus) {
+				if (sm.name() == sname) {
+					sm.add(MenuItem(MenuItem::Command, toqstr(translateIfPossible(gui)),
+						       FuncRequest(LFUN_MATTER, from_ascii(m.name))));
+					have_submenu = true;
+					break;
+				}
+			}
+			if (!have_submenu) {
+				MenuDefinition md(sname);
+				md.add(MenuItem(MenuItem::Command, toqstr(translateIfPossible(gui)),
+						FuncRequest(LFUN_MATTER, from_ascii(m.name))));
+				submenus.push_back(md);
+			}
+		}
+	}
+	// append submenus
+	for (auto const & sm : submenus) {
+		MenuItem item(MenuItem::Submenu, qt_(sm.name()));
+		item.setSubmenu(sm);
+		add(item);
 	}
 }
 


More information about the lyx-cvs mailing list