diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2015-08-04 13:57:51 -0400 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2016-02-22 15:31:23 -0500 |
commit | e13322e7f5bb1d7f31a867fa10b5b1ef0b8ea804 (patch) | |
tree | df1fd4f53e1a042433ba6fc024d955a92ff24a59 /libs/gtkmm2ext | |
parent | a13a8da8ac977b247b7c8d8b4f2cfcddfc8996e7 (diff) |
bindings: prevent double registration and double signal connection, and provide get_all_actions() methods
Diffstat (limited to 'libs/gtkmm2ext')
-rw-r--r-- | libs/gtkmm2ext/bindings.cc | 146 | ||||
-rw-r--r-- | libs/gtkmm2ext/gtkmm2ext/bindings.h | 18 |
2 files changed, 137 insertions, 27 deletions
diff --git a/libs/gtkmm2ext/bindings.cc b/libs/gtkmm2ext/bindings.cc index 6ef2e29196..83e2dcf5b5 100644 --- a/libs/gtkmm2ext/bindings.cc +++ b/libs/gtkmm2ext/bindings.cc @@ -611,6 +611,89 @@ Bindings::load (const XMLNode& node) } } +void +Bindings::get_all_actions (std::vector<std::string>& names, + std::vector<std::string>& paths, + std::vector<std::string>& tooltips, + std::vector<std::string>& keys, + std::vector<KeyboardKey>& bindings) +{ + if (!action_map) { + return; + } + + /* build a reverse map from actions to bindings */ + + typedef map<Glib::RefPtr<Gtk::Action>,KeyboardKey> ReverseMap; + ReverseMap rmap; + + for (KeybindingMap::const_iterator k = press_bindings.begin(); k != press_bindings.end(); ++k) { + rmap.insert (make_pair (k->second, k->first)); + } + + /* get a list of all actions */ + + ActionMap::Actions actions; + action_map->get_actions (actions); + + for (ActionMap::Actions::const_iterator act = actions.begin(); act != actions.end(); ++act) { + names.push_back ((*act)->get_name()); + paths.push_back ((*act)->get_accel_path()); + tooltips.push_back ((*act)->get_tooltip()); + + ReverseMap::iterator r = rmap.find (*act); + if (r != rmap.end()) { + keys.push_back (gtk_accelerator_get_label (r->second.key(), (GdkModifierType) r->second.state())); + bindings.push_back (r->second); + } else { + keys.push_back (string()); + bindings.push_back (KeyboardKey::null_key()); + } + } +} + +void +Bindings::get_all_actions (std::vector<std::string>& groups, + std::vector<std::string>& paths, + std::vector<std::string>& tooltips, + std::vector<KeyboardKey>& bindings) +{ + /* build a reverse map from actions to bindings */ + + typedef map<Glib::RefPtr<Gtk::Action>,KeyboardKey> ReverseMap; + ReverseMap rmap; + + for (KeybindingMap::const_iterator k = press_bindings.begin(); k != press_bindings.end(); ++k) { + rmap.insert (make_pair (k->second, k->first)); + } + + /* get a list of all actions */ + + ActionMap::Actions actions; + action_map->get_actions (actions); + + for (ActionMap::Actions::const_iterator act = actions.begin(); act != actions.end(); ++act) { + groups.push_back ((*act)->get_name()); + paths.push_back ((*act)->get_accel_path()); + tooltips.push_back ((*act)->get_tooltip()); + + ReverseMap::iterator r = rmap.find (*act); + if (r != rmap.end()) { + bindings.push_back (r->second); + } else { + bindings.push_back (KeyboardKey::null_key()); + } + } +} + +void +ActionMap::get_actions (ActionMap::Actions& acts) +{ + for (_ActionMap::iterator a = actions.begin(); a != actions.end(); ++a) { + acts.push_back (a->second); + } +} + RefPtr<Action> ActionMap::find_action (const string& name) { @@ -647,10 +730,13 @@ ActionMap::register_action (RefPtr<ActionGroup> group, const char* name, const c fullpath += '/'; fullpath += name; - actions.insert (_ActionMap::value_type (fullpath, act)); - group->add (act); - - return act; + if (actions.insert (_ActionMap::value_type (fullpath, act)).second) { + group->add (act); + return act; + } + + /* already registered */ + return RefPtr<Action> (); } RefPtr<Action> @@ -661,16 +747,17 @@ ActionMap::register_action (RefPtr<ActionGroup> group, RefPtr<Action> act = Action::create (name, label); - act->signal_activate().connect (sl); - fullpath = group->get_name(); fullpath += '/'; fullpath += name; - actions.insert (_ActionMap::value_type (fullpath, act)); - group->add (act, sl); + if (actions.insert (_ActionMap::value_type (fullpath, act)).second) { + group->add (act, sl); + return act; + } - return act; + /* already registered */ + return RefPtr<Action>(); } RefPtr<Action> @@ -684,15 +771,17 @@ ActionMap::register_radio_action (RefPtr<ActionGroup> group, RefPtr<Action> act = RadioAction::create (rgroup, name, label); RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act); - act->signal_activate().connect (sl); - fullpath = group->get_name(); fullpath += '/'; fullpath += name; - actions.insert (_ActionMap::value_type (fullpath, act)); - group->add (act, sl); - return act; + if (actions.insert (_ActionMap::value_type (fullpath, act)).second) { + group->add (act, sl); + return act; + } + + /* already registered */ + return RefPtr<Action>(); } RefPtr<Action> @@ -708,15 +797,18 @@ ActionMap::register_radio_action (RefPtr<ActionGroup> group, RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act); ract->property_value() = value; - act->signal_activate().connect (sigc::bind (sl, act->gobj())); - fullpath = group->get_name(); fullpath += '/'; fullpath += name; - actions.insert (_ActionMap::value_type (fullpath, act)); - group->add (act, sigc::bind (sl, act->gobj())); - return act; + if (actions.insert (_ActionMap::value_type (fullpath, act)).second) { + group->add (act, sigc::bind (sl, act->gobj())); + return act; + } + + /* already registered */ + + return RefPtr<Action>(); } RefPtr<Action> @@ -725,17 +817,19 @@ ActionMap::register_toggle_action (RefPtr<ActionGroup> group, { string fullpath; - RefPtr<Action> act = ToggleAction::create (name, label); - - act->signal_activate().connect (sl); - fullpath = group->get_name(); fullpath += '/'; fullpath += name; - actions.insert (_ActionMap::value_type (fullpath, act)); - group->add (act, sl); - return act; + RefPtr<Action> act = ToggleAction::create (name, label); + + if (actions.insert (_ActionMap::value_type (fullpath, act)).second) { + group->add (act, sl); + return act; + } + + /* already registered */ + return RefPtr<Action>(); } std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey const & k) { diff --git a/libs/gtkmm2ext/gtkmm2ext/bindings.h b/libs/gtkmm2ext/gtkmm2ext/bindings.h index 7685d8cf32..8dff6d2372 100644 --- a/libs/gtkmm2ext/gtkmm2ext/bindings.h +++ b/libs/gtkmm2ext/gtkmm2ext/bindings.h @@ -23,6 +23,8 @@ class LIBGTKMM2EXT_API KeyboardKey KeyboardKey (uint32_t state, uint32_t keycode); + static KeyboardKey null_key() { return KeyboardKey (0, 0); } + uint32_t state() const { return _val >> 32; } uint32_t key() const { return _val & 0xffff; } @@ -96,6 +98,9 @@ class LIBGTKMM2EXT_API ActionMap { Glib::RefPtr<Gtk::Action> find_action (const std::string& name); + typedef std::vector<Glib::RefPtr<Gtk::Action> > Actions; + void get_actions (Actions&); + private: typedef std::map<std::string, Glib::RefPtr<Gtk::Action> > _ActionMap; _ActionMap actions; @@ -129,12 +134,23 @@ class LIBGTKMM2EXT_API Bindings { void save (XMLNode& root); void set_action_map (ActionMap&); - + static void set_ignored_state (int mask) { _ignored_state = mask; } static uint32_t ignored_state() { return _ignored_state; } + void get_all_actions (std::vector<std::string>& names, + std::vector<std::string>& paths, + std::vector<std::string>& tooltips, + std::vector<std::string>& keys, + std::vector<KeyboardKey>& bindings); + + void get_all_actions (std::vector<std::string>& groups, + std::vector<std::string>& paths, + std::vector<std::string>& tooltips, + std::vector<KeyboardKey>& bindings); + private: typedef std::map<KeyboardKey,Glib::RefPtr<Gtk::Action> > KeybindingMap; |