initial compilable version of saving key bindings with "new" scheme
[ardour.git] / libs / gtkmm2ext / bindings.cc
index 6ef2e2919685a8ff1e4f35f624881144584c8648..8803edc540e2adb938b2e6904ee052591f49eb73 100644 (file)
@@ -43,6 +43,7 @@ using namespace Gtkmm2ext;
 using namespace PBD;
 
 uint32_t Bindings::_ignored_state = 0;
+map<string,Bindings*> Bindings::bindings_for_state;
 
 MouseButton::MouseButton (uint32_t state, uint32_t keycode)
 {
@@ -227,6 +228,9 @@ Bindings::Bindings ()
 
 Bindings::~Bindings()
 {
+       if (!_name.empty()) {
+               remove_bindings_for_state (_name, *this);
+       }
 }
 
 bool
@@ -507,6 +511,10 @@ Bindings::load (string const & name)
                error << string_compose (_("No keyboard binding information when loading bindings for \"%1\""), name) << endmsg;
                return false;
         }
+
+        if (!_name.empty()) {
+               remove_bindings_for_state (_name, *this);
+        }
         
         const XMLNodeList& children (node->children());
         bool found = false;
@@ -543,6 +551,9 @@ Bindings::load (string const & name)
                load (**i);
         }
 
+        add_bindings_for_state (_name, *this);
+        _name = name;
+        
         return true;
 }
 
@@ -611,6 +622,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 +741,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 +758,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 +782,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 +808,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 +828,31 @@ 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>();
+}
+
+void
+Bindings::add_bindings_for_state (std::string const& name, Bindings& bindings)
+{
+       bindings_for_state.insert (make_pair (name, &bindings));
+}
+
+void
+Bindings::remove_bindings_for_state (std::string const& name, Bindings& bindings)
+{
+       bindings_for_state.erase (name);
 }
 
 std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey const & k) {