From e13322e7f5bb1d7f31a867fa10b5b1ef0b8ea804 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 4 Aug 2015 13:57:51 -0400 Subject: bindings: prevent double registration and double signal connection, and provide get_all_actions() methods --- libs/gtkmm2ext/bindings.cc | 146 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 120 insertions(+), 26 deletions(-) (limited to 'libs/gtkmm2ext/bindings.cc') 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& names, + std::vector& paths, + std::vector& tooltips, + std::vector& keys, + std::vector& bindings) +{ + if (!action_map) { + return; + } + + /* build a reverse map from actions to bindings */ + + typedef map,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& groups, + std::vector& paths, + std::vector& tooltips, + std::vector& bindings) +{ + /* build a reverse map from actions to bindings */ + + typedef map,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 ActionMap::find_action (const string& name) { @@ -647,10 +730,13 @@ ActionMap::register_action (RefPtr 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 (); } RefPtr @@ -661,16 +747,17 @@ ActionMap::register_action (RefPtr group, RefPtr 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(); } RefPtr @@ -684,15 +771,17 @@ ActionMap::register_radio_action (RefPtr group, RefPtr act = RadioAction::create (rgroup, name, label); RefPtr ract = RefPtr::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(); } RefPtr @@ -708,15 +797,18 @@ ActionMap::register_radio_action (RefPtr group, RefPtr ract = RefPtr::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(); } RefPtr @@ -725,17 +817,19 @@ ActionMap::register_toggle_action (RefPtr group, { string fullpath; - RefPtr 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 act = ToggleAction::create (name, label); + + if (actions.insert (_ActionMap::value_type (fullpath, act)).second) { + group->add (act, sl); + return act; + } + + /* already registered */ + return RefPtr(); } std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey const & k) { -- cgit v1.2.3