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 = ⊤
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)
|