File: sort-automation-menus.patch

package info (click to toggle)
aegisub 3.2.2%2Bdfsg-7
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 22,904 kB
  • sloc: cpp: 57,067; ansic: 16,457; asm: 3,618; sh: 3,525; makefile: 409; python: 350; perl: 274; cs: 205; xml: 196; objc: 47
file content (109 lines) | stat: -rw-r--r-- 3,426 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
From d0296618a67bffff8014fd92ce557d9c0635e721 Mon Sep 17 00:00:00 2001
From: Niels Martin Hansen <nielsm@indvikleren.dk>
Date: Sun, 25 Jan 2015 00:35:42 +0100
Subject: [PATCH] Sort Automation menu items by display name

---
 src/menu.cpp | 65 ++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 50 insertions(+), 15 deletions(-)

diff --git a/src/menu.cpp b/src/menu.cpp
index 5b4cef151..4c3848e50 100644
--- a/src/menu.cpp
+++ b/src/menu.cpp
@@ -39,6 +39,7 @@
 #include <algorithm>
 #include <boost/algorithm/string/case_conv.hpp>
 #include <boost/range/algorithm_ext/push_back.hpp>
+#include <boost/locale/collator.hpp>
 #include <vector>
 #include <wx/frame.h>
 #include <wx/menu.h>
@@ -395,6 +396,47 @@ class AutomationMenu final : public wxMenu {
 	agi::signal::Connection local_slot;
 	std::vector<wxMenuItem *> all_items;
 
+	struct WorkItem {
+		std::string displayname;
+		cmd::Command *command;
+		std::vector<WorkItem> subitems;
+
+		WorkItem(std::string const &displayname, cmd::Command *command = nullptr)
+		: displayname(displayname), command(command) { }
+
+		WorkItem *FindOrMakeSubitem(std::string const &name) {
+			auto sub = std::find_if(subitems.begin(), subitems.end(), [&](WorkItem const &item) { return item.displayname == name; });
+			if (sub != subitems.end()) return &*sub;
+			
+			subitems.emplace_back(name);
+			return &subitems.back();
+		}
+
+		void Sort() {
+			if (command) return;
+			for (auto &sub : subitems)
+				sub.Sort();
+			auto comp = boost::locale::comparator<std::string::value_type>();
+			std::sort(subitems.begin(), subitems.end(), [&](WorkItem const &a, WorkItem const &b){
+				return comp(a.displayname, b.displayname);
+			});
+		}
+
+		void GenerateMenu(wxMenu *parent, AutomationMenu *am) {
+			for (auto item : subitems) {
+				if (item.command) {
+					am->cm->AddCommand(item.command, parent, item.displayname);
+					am->all_items.push_back(parent->GetMenuItems().back());
+				}
+				else {
+					auto submenu = new wxMenu;
+					parent->AppendSubMenu(submenu, to_wx(item.displayname));
+					item.GenerateMenu(submenu, am);
+				}
+			}
+		}
+	};
+
 	void Regenerate() {
 		for (auto item : all_items)
 			cm->Remove(item);
@@ -411,30 +453,23 @@ class AutomationMenu final : public wxMenu {
 			return;
 		}
 
-		std::map<std::string, wxMenu *> submenus;
-
+		WorkItem top("");
 		for (auto macro : macros) {
 			const auto name = from_wx(macro->StrMenu(c));
-			wxMenu *parent = this;
+			WorkItem *parent = &top;
 			for (auto section : agi::Split(name, wxS('/'))) {
+				std::string sectionname(section.begin(), section.end());
+
 				if (section.end() == name.end()) {
-					cm->AddCommand(macro, parent, wxString::FromUTF8Unchecked(&*section.begin(), section.size()));
-					all_items.push_back(parent->GetMenuItems().back());
-					break;
+					parent->subitems.emplace_back(sectionname, macro);
 				}
-
-				std::string prefix(name.begin(), section.end());
-				auto it = submenus.find(prefix);
-				if (it != submenus.end())
-					parent = it->second;
 				else {
-					auto menu = new wxMenu;
-					parent->AppendSubMenu(menu, wxString::FromUTF8Unchecked(&*section.begin(), section.size()));
-					submenus[prefix] = menu;
-					parent = menu;
+					parent = parent->FindOrMakeSubitem(sectionname);
 				}
 			}
 		}
+		top.Sort();
+		top.GenerateMenu(this, this);
 	}
 public:
 	AutomationMenu(agi::Context *c, CommandManager *cm)