// Copyright (c) 2010, Amar Takhar // // Permission to use, copy, modify, and distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /// @file hotkey.h /// @brief Hotkey handler /// @ingroup hotkey menu event window #include #include #include #include #include #include #include namespace json { class UnknownElement; typedef std::map Object; } namespace agi { namespace hotkey { /// @class Combo /// A Combo represents a linear sequence of characters set in an std::vector. This makes up /// a single combination, or "Hotkey". class Combo { std::vector key_map; std::string cmd_name; std::string context; public: /// Constructor /// @param ctx Context /// @param cmd Command name Combo(std::string const& ctx, std::string const& cmd, std::vector const& keys) : key_map(keys) , cmd_name(cmd) , context(ctx) { } /// String representation of the Combo std::string Str() const; /// String suitable for usage in a menu. std::string StrMenu() const; /// Get the literal combo map. /// @return ComboMap (std::vector) of linear key sequence. const std::vector& Get() const { return key_map; } /// Command name triggered by the combination. /// @return Command name const std::string& CmdName() const { return cmd_name; } /// Context this Combo is triggered in. const std::string& Context() const { return context; } }; /// @class Hotkey /// Holds the map of Combo instances and handles searching for matching key sequences. class Hotkey { public: /// Map to hold Combo instances typedef std::multimap HotkeyMap; private: HotkeyMap str_map; ///< String representation -> Combo HotkeyMap cmd_map; ///< Command name -> Combo const agi::fs::path config_file; ///< Default user config location. /// Build hotkey map. /// @param context Context being parsed. /// @param object json::Object holding items for context being parsed. void BuildHotkey(std::string const& context, const json::Object& object); /// Insert Combo into HotkeyMap instance. /// @param combo Combo to insert. void ComboInsert(Combo const& combo); /// Write active Hotkey configuration to disk. void Flush(); /// Announce that the loaded hotkeys have been changed agi::signal::Signal<> HotkeysChanged; public: /// Constructor /// @param file Location of user config file. /// @param default_config Default config. Hotkey(agi::fs::path const& file, const std::string &default_config); /// Scan for a matching key. /// @param context Context requested. /// @param str Hyphen separated key sequence. /// @param always Enable the "Always" override context /// @return Name of command or "" if none match std::string Scan(const std::string &context, const std::string &str, bool always) 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; /// Get a string representation of a hotkeys for the given command /// @param context Context requested /// @param command Command name /// @return A hotkey for the given command or "" if there are none std::string GetHotkey(const std::string &context, const std::string &command) const; /// Get the raw command name -> combo map for all registered hotkeys HotkeyMap const& GetHotkeyMap() const { return cmd_map; } /// Replace the loaded hotkeys with a new set void SetHotkeyMap(HotkeyMap const& new_map); DEFINE_SIGNAL_ADDERS(HotkeysChanged, AddHotkeyChangeListener) }; } // namespace hotkey } // namespace agi