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.
This commit is contained in:
Thomas Goyne 2011-01-17 23:53:46 +00:00
parent cd4b032c25
commit 04a4c074b0
6 changed files with 79 additions and 60 deletions

View file

@ -26,6 +26,8 @@
#include <memory>
#endif
#include <tuple>
#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<const json::String&>(obj["key"]).Value());
combo->Enable(static_cast<const json::Boolean&>(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<HotkeyMap::const_iterator, HotkeyMap::const_iterator> 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<std::string> Hotkey::GetHotkeys(const std::string &context, const std::string &command) const {
std::vector<std::string> 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());

View file

@ -22,6 +22,8 @@
#include <math.h>
#include <memory>
#include <string>
#include <vector>
#endif
#include <libaegisub/cajun/elements.h>
@ -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<std::string> GetHotkeys(const std::string &context, const std::string &command) const;
private:
typedef std::multimap<std::string, Combo*> HotkeyMap; ///< Map to hold Combo instances.
typedef std::pair<std::string, Combo*> 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.

View file

@ -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());

View file

@ -27,8 +27,6 @@
#include <vector>
#endif
#include <libaegisub/io.h>
#include <libaegisub/json.h>
#include <libaegisub/log.h>
#include <libaegisub/hotkey.h>
@ -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<std::string> 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<std::string> strs = get_hotkey_strs(context, command);
return strs.empty() ? "" : strs.front();
}
static inline void set_kc(std::vector<std::string> &vec, int code, std::string const& str) {
if (static_cast<size_t>(code) >= vec.size()) vec.resize(code * 2, "");

View file

@ -25,12 +25,13 @@
#include <memory>
#include <string>
#include <vector>
#endif
#include <libaegisub/cajun/elements.h>
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<std::string> get_hotkey_strs(std::string const& context, std::string const& command);
} // namespace hotkey

View file

@ -28,11 +28,13 @@
#include <wx/menuitem.h>
#endif
#include "include/aegisub/menu.h"
#include <libaegisub/io.h>
#include <libaegisub/json.h>
#include <libaegisub/log.h>
#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;