Sort Automation menu items by display name
This commit is contained in:
parent
0f3bca016e
commit
d0296618a6
1 changed files with 51 additions and 16 deletions
67
src/menu.cpp
67
src/menu.cpp
|
@ -39,6 +39,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <boost/algorithm/string/case_conv.hpp>
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
#include <boost/range/algorithm_ext/push_back.hpp>
|
#include <boost/range/algorithm_ext/push_back.hpp>
|
||||||
|
#include <boost/locale/collator.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wx/frame.h>
|
#include <wx/frame.h>
|
||||||
#include <wx/menu.h>
|
#include <wx/menu.h>
|
||||||
|
@ -395,6 +396,47 @@ class AutomationMenu final : public wxMenu {
|
||||||
agi::signal::Connection local_slot;
|
agi::signal::Connection local_slot;
|
||||||
std::vector<wxMenuItem *> all_items;
|
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() {
|
void Regenerate() {
|
||||||
for (auto item : all_items)
|
for (auto item : all_items)
|
||||||
cm->Remove(item);
|
cm->Remove(item);
|
||||||
|
@ -411,30 +453,23 @@ class AutomationMenu final : public wxMenu {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, wxMenu *> submenus;
|
WorkItem top("");
|
||||||
|
|
||||||
for (auto macro : macros) {
|
for (auto macro : macros) {
|
||||||
const auto name = from_wx(macro->StrMenu(c));
|
const auto name = from_wx(macro->StrMenu(c));
|
||||||
wxMenu *parent = this;
|
WorkItem *parent = ⊤
|
||||||
for (auto section : agi::Split(name, wxS('/'))) {
|
for (auto section : agi::Split(name, wxS('/'))) {
|
||||||
if (section.end() == name.end()) {
|
std::string sectionname(section.begin(), section.end());
|
||||||
cm->AddCommand(macro, parent, wxString::FromUTF8Unchecked(&*section.begin(), section.size()));
|
|
||||||
all_items.push_back(parent->GetMenuItems().back());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string prefix(name.begin(), section.end());
|
if (section.end() == name.end()) {
|
||||||
auto it = submenus.find(prefix);
|
parent->subitems.emplace_back(sectionname, macro);
|
||||||
if (it != submenus.end())
|
}
|
||||||
parent = it->second;
|
|
||||||
else {
|
else {
|
||||||
auto menu = new wxMenu;
|
parent = parent->FindOrMakeSubitem(sectionname);
|
||||||
parent->AppendSubMenu(menu, wxString::FromUTF8Unchecked(&*section.begin(), section.size()));
|
|
||||||
submenus[prefix] = menu;
|
|
||||||
parent = menu;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
top.Sort();
|
||||||
|
top.GenerateMenu(this, this);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
AutomationMenu(agi::Context *c, CommandManager *cm)
|
AutomationMenu(agi::Context *c, CommandManager *cm)
|
||||||
|
|
Loading…
Reference in a new issue