From 04a4c074b05f0ea9a220969581ca668d0bf7e30f Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Mon, 17 Jan 2011 23:53:46 +0000 Subject: [PATCH] Add function to get the string representation of the hotkeys for a command, use it when generating the menu Originally committed to SVN as r5230. --- aegisub/libaegisub/common/hotkey.cpp | 60 +++++++++++-------- .../libaegisub/include/libaegisub/hotkey.h | 13 +++- aegisub/src/frame_main.cpp | 17 +++--- aegisub/src/hotkey.cpp | 13 +++- aegisub/src/include/aegisub/hotkey.h | 7 ++- aegisub/src/menu.cpp | 29 ++++----- 6 files changed, 79 insertions(+), 60 deletions(-) diff --git a/aegisub/libaegisub/common/hotkey.cpp b/aegisub/libaegisub/common/hotkey.cpp index 74b3b52ca..f14874b0c 100644 --- a/aegisub/libaegisub/common/hotkey.cpp +++ b/aegisub/libaegisub/common/hotkey.cpp @@ -26,6 +26,8 @@ #include #endif +#include + #include "libaegisub/hotkey.h" #include "libaegisub/access.h" @@ -35,7 +37,6 @@ #include "libaegisub/json.h" #include "libaegisub/log.h" - namespace agi { namespace hotkey { @@ -54,7 +55,8 @@ std::string Combo::StrMenu() { } void Hotkey::ComboInsert(Combo *combo) { - map.insert(HotkeyMapPair(combo->Str(), combo)); + str_map.insert(make_pair(combo->Str(), combo)); + cmd_map.insert(make_pair(combo->CmdName(), combo)); } Hotkey::~Hotkey() { @@ -68,45 +70,42 @@ Hotkey::Hotkey(const std::string &file, const std::string &default_config): std::istream *stream; - try { + try { stream = agi::io::Open(config_file); } catch (const acs::AcsNotFound&) { stream = new std::istringstream(config_default); - } + } json::UnknownElement hotkey_root; - try { + try { hotkey_root = agi::json_util::parse(stream); } catch (...) { - // There's definatly a better way to do this. - std::istringstream *stream = new std::istringstream(config_default); + // There's definitely a better way to do this. + delete stream; + stream = new std::istringstream(config_default); hotkey_root = agi::json_util::parse(stream); } json::Object object = hotkey_root; - for (json::Object::const_iterator index(object.Begin()); index != object.End(); index++) { const json::Object::Member& member = *index; const json::Object& obj = member.element; BuildHotkey(member.name, obj); - } + } } void Hotkey::BuildHotkey(std::string context, const json::Object& object) { - for (json::Object::const_iterator index(object.Begin()); index != object.End(); index++) { const json::Object::Member& member = *index; - - const json::Array& array = member.element; - for (json::Array::const_iterator arr_index(array.Begin()); arr_index != array.End(); arr_index++) { + for (json::Array::const_iterator arr_index(array.Begin()); arr_index != array.End(); arr_index++) { Combo *combo = new Combo(context, member.name); - const json::Object& obj = *arr_index; + const json::Object& obj = *arr_index; const json::Array& arr_mod = obj["modifiers"]; @@ -117,26 +116,19 @@ void Hotkey::BuildHotkey(std::string context, const json::Object& object) { } // for arr_mod_index } - const json::String& key = obj["key"]; - combo->KeyInsert(key.Value()); - - const json::Boolean& enable = obj["enable"]; - combo->Enable(enable); + combo->KeyInsert(static_cast(obj["key"]).Value()); + combo->Enable(static_cast(obj["enable"]).Value()); ComboInsert(combo); } // for arr_index } // for index } - bool Hotkey::Scan(const std::string &context, const std::string &str, std::string &cmd) const { - HotkeyMap::const_iterator index; - std::pair range; - - range = map.equal_range(str); std::string local, dfault; - for (index = range.first; index != range.second; ++index) { + HotkeyMap::const_iterator index, end; + for (std::tr1::tie(index, end) = str_map.equal_range(str); index != end; ++index) { std::string ctext = index->second->Context(); if (ctext == "Always") { @@ -161,7 +153,23 @@ bool Hotkey::Scan(const std::string &context, const std::string &str, std::strin } return 1; +} +std::vector Hotkey::GetHotkeys(const std::string &context, const std::string &command) const { + std::vector ret; + + HotkeyMap::const_iterator it, end; + for (std::tr1::tie(it, end) = cmd_map.equal_range(command); it != end; ++it) { + std::string ctext = it->second->Context(); + if (ctext == "Always" || ctext == "Default" || ctext == context) { + ret.push_back(it->second->StrMenu()); + } + } + + sort(ret.begin(), ret.end()); + ret.erase(unique(ret.begin(), ret.end()), ret.end()); + + return ret; } void Hotkey::Flush() { @@ -169,7 +177,7 @@ void Hotkey::Flush() { json::Object root; HotkeyMap::iterator index; - for (index = map.begin(); index != map.end(); ++index) { + for (index = str_map.begin(); index != str_map.end(); ++index) { Combo::ComboMap combo_map(index->second->Get()); diff --git a/aegisub/libaegisub/include/libaegisub/hotkey.h b/aegisub/libaegisub/include/libaegisub/hotkey.h index b0f913152..d9e52f534 100644 --- a/aegisub/libaegisub/include/libaegisub/hotkey.h +++ b/aegisub/libaegisub/include/libaegisub/hotkey.h @@ -22,6 +22,8 @@ #include #include +#include +#include #endif #include @@ -30,7 +32,6 @@ namespace agi { namespace hotkey { - class Hotkey; /// Hotkey instance. extern Hotkey *hotkey; @@ -108,10 +109,16 @@ public: /// @param[out] cmd Command found. bool Scan(const std::string &context, const std::string &str, std::string &cmd) const; + /// Get the string representation of the hotkeys for the given command + /// @param context Context requested + /// @param command Command name + /// @return A vector of all hotkeys for that command in the context + std::vector GetHotkeys(const std::string &context, const std::string &command) const; + private: typedef std::multimap HotkeyMap; ///< Map to hold Combo instances. - typedef std::pair HotkeyMapPair; ///< Pair for HotkeyMap. - HotkeyMap map; ///< HotkeyMap Instance. + HotkeyMap str_map; ///< String representation -> Combo + HotkeyMap cmd_map; ///< Command name -> Combo const std::string config_file; ///< Default user config location. const std::string config_default; ///< Default config. diff --git a/aegisub/src/frame_main.cpp b/aegisub/src/frame_main.cpp index a1b5647ca..906c59049 100644 --- a/aegisub/src/frame_main.cpp +++ b/aegisub/src/frame_main.cpp @@ -1010,18 +1010,19 @@ void FrameMain::OnMenuOpen (wxMenuEvent &event) { wxMenu *editMenu = menu::menu->GetMenu("main/edit"); // Undo state - wxMenuItem *item; -//H wxString undo_text = _("&Undo") + wxString(_T(" ")) + ass->GetUndoDescription() + wxString(_T("\t")) + Hotkeys.GetText(_T("Undo")); -// The bottom line needs to be fixed for the new hotkey system - wxString undo_text = _("&Undo") + wxString(_T(" ")) + context->ass->GetUndoDescription() + wxString(_T("\t")) + _T("Undo"); - item = editMenu->FindItem(cmd::id("edit/undo")); + wxString undo_text = wxString::Format("%s %s\t%s", + cmd::get("edit/undo")->StrMenu(), + context->ass->GetUndoDescription(), + hotkey::get_hotkey_str_first("Default", "edit/undo")); + wxMenuItem *item = editMenu->FindItem(cmd::id("edit/undo")); item->SetItemLabel(undo_text); item->Enable(!context->ass->IsUndoStackEmpty()); // Redo state -//H wxString redo_text = _("&Redo") + wxString(_T(" ")) + ass->GetRedoDescription() + wxString(_T("\t")) + Hotkeys.GetText(_T("Redo")); -// Same as above. - wxString redo_text = _("&Redo") + wxString(_T(" ")) + context->ass->GetRedoDescription() + wxString(_T("\t")) + _T("Redo"); + wxString redo_text = wxString::Format("%s %s\t%s", + cmd::get("edit/redo")->StrMenu(), + context->ass->GetRedoDescription(), + hotkey::get_hotkey_str_first("Default", "edit/redo")); item = editMenu->FindItem(cmd::id("edit/redo")); item->SetItemLabel(redo_text); item->Enable(!context->ass->IsRedoStackEmpty()); diff --git a/aegisub/src/hotkey.cpp b/aegisub/src/hotkey.cpp index 1a6a2406d..bb36e9f99 100644 --- a/aegisub/src/hotkey.cpp +++ b/aegisub/src/hotkey.cpp @@ -27,8 +27,6 @@ #include #endif -#include -#include #include #include @@ -59,7 +57,7 @@ std::string const& keycode_name(int code) { return keycode_names[code]; } -void check(std::string context, int key_code, wchar_t key_char, int modifier) { +void check(std::string const& context, int key_code, wchar_t key_char, int modifier) { std::string combo; if ((modifier != wxMOD_NONE)) { if ((modifier & wxMOD_CMD) != 0) combo.append("Ctrl-"); @@ -79,6 +77,15 @@ void check(std::string context, int key_code, wchar_t key_char, int modifier) { } } +std::vector get_hotkey_strs(std::string const& context, std::string const& command) { + return agi::hotkey::hotkey->GetHotkeys(context, command); +} + +std::string get_hotkey_str_first(std::string const& context, std::string const& command) { + std::vector strs = get_hotkey_strs(context, command); + return strs.empty() ? "" : strs.front(); +} + static inline void set_kc(std::vector &vec, int code, std::string const& str) { if (static_cast(code) >= vec.size()) vec.resize(code * 2, ""); diff --git a/aegisub/src/include/aegisub/hotkey.h b/aegisub/src/include/aegisub/hotkey.h index c51f10951..6559b87e3 100644 --- a/aegisub/src/include/aegisub/hotkey.h +++ b/aegisub/src/include/aegisub/hotkey.h @@ -25,12 +25,13 @@ #include #include +#include #endif -#include - namespace hotkey { -void check(std::string context, int key_code, wchar_t key_char, int modifier); +void check(std::string const& context, int key_code, wchar_t key_char, int modifier); +std::string get_hotkey_str_first(std::string const& context, std::string const& command); +std::vector get_hotkey_strs(std::string const& context, std::string const& command); } // namespace hotkey diff --git a/aegisub/src/menu.cpp b/aegisub/src/menu.cpp index 1d5381ef2..a59b65084 100644 --- a/aegisub/src/menu.cpp +++ b/aegisub/src/menu.cpp @@ -28,11 +28,13 @@ #include #endif +#include "include/aegisub/menu.h" + #include #include #include -#include "include/aegisub/menu.h" +#include "include/aegisub/hotkey.h" #include "command/command.h" #include "libresrc/libresrc.h" #include "main.h" @@ -100,39 +102,32 @@ wxMenu* Menu::BuildMenu(std::string name, const json::Array& array, int submenu) std::string name_submenu = name_sub + "/" + command.Value(); - cmd::Command *cmd; - if (type == Menu::Submenu) { - cmd = cmd::get(name_submenu); - } else { - cmd = cmd::get(command.Value()); - } + std::string cmd_name = type == Menu::Submenu ? name_submenu : command.Value(); + cmd::Command *cmd = cmd::get(cmd_name); - wxString display = cmd->StrMenu(); + wxString display = cmd->StrMenu() + "\t" + hotkey::get_hotkey_str_first("Default", cmd_name); wxString descr = cmd->StrHelp(); - - - switch (type) { case Menu::Option: { - wxMenuItem *menu_item = new wxMenuItem(menu, cmd::id(command.Value()), wxString(display), wxString(descr), wxITEM_NORMAL); + wxMenuItem *menu_item = new wxMenuItem(menu, cmd::id(command.Value()), display, descr, wxITEM_NORMAL); menu->Append(menu_item); } break; case Menu::Check: { - menu->AppendCheckItem(cmd::id(command.Value()), wxString(display), wxString(descr)); + menu->AppendCheckItem(cmd::id(command.Value()), display, descr); } break; case Menu::Radio: { - menu->AppendRadioItem(cmd::id(command.Value()), wxString(display), wxString(descr)); + menu->AppendRadioItem(cmd::id(command.Value()), display, descr); } break; case Menu::Recent: { wxMenu *menu_new = new wxMenu(); - wxMenuItem *menu_item = new wxMenuItem(menu, cmd::id(command.Value()), wxString(display), wxString(descr), wxITEM_NORMAL, menu_new); + wxMenuItem *menu_item = new wxMenuItem(menu, cmd::id(command.Value()), display, descr, wxITEM_NORMAL, menu_new); menu->Append(menu_item); map.insert(MTPair(command.Value(), menu_new)); @@ -147,10 +142,10 @@ wxMenu* Menu::BuildMenu(std::string name, const json::Array& array, int submenu) map.insert(MTPair(name_submenu, menu_new)); if (submenu) { - wxMenuItem *menu_item = new wxMenuItem(menu, cmd::id(name_sub), wxString(display), wxString(descr), wxITEM_NORMAL, menu_new); + wxMenuItem *menu_item = new wxMenuItem(menu, cmd::id(name_sub), display, descr, wxITEM_NORMAL, menu_new); menu->Append(menu_item); } else { - main_menu->Append(menu_new, wxString(display)); + main_menu->Append(menu_new, display); } } break;