consolidate ActionMap and ActionManager APIs into a single namespace
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 10 Dec 2018 13:22:10 +0000 (08:22 -0500)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 10 Dec 2018 13:34:01 +0000 (08:34 -0500)
libs/gtkmm2ext/actions.cc
libs/gtkmm2ext/bindings.cc
libs/gtkmm2ext/gtk_ui.cc
libs/gtkmm2ext/gtkmm2ext/actions.h
libs/gtkmm2ext/gtkmm2ext/bindings.h

index 76c6ba043b7e6b212315416a145fcaf19d0b68be..8f6fa139fd3760b7fe68e2aeb2f22e52045a30e1 100644 (file)
@@ -50,8 +50,13 @@ using namespace sigc;
 using namespace PBD;
 using namespace Gtkmm2ext;
 
+typedef std::map<std::string, Glib::RefPtr<Gtk::Action> > ActionMap;
+static ActionMap actions;
+typedef std::vector<Glib::RefPtr<Gtk::ActionGroup> > ActionGroups;
+static ActionGroups groups;
+
 RefPtr<UIManager> ActionManager::ui_manager;
-string ActionManager::unbound_string = "--";
+string ActionManager::unbound_string = X_("--");
 
 struct ActionState {
        GtkAction* action;
@@ -64,21 +69,24 @@ typedef std::vector<ActionState> ActionStates;
 static ActionStates action_states_to_restore;
 static bool actions_disabled = false;
 
+void
+ActionManager::init ()
+{
+       ui_manager = UIManager::create ();
+}
+
 void
 ActionManager::save_action_states ()
 {
-       /* the C++ API for functions used here appears to be broken in
-          gtkmm2.6, so we fall back to the C level.
-       */
-       GList* list = gtk_ui_manager_get_action_groups (ActionManager::ui_manager->gobj());
-       GList* node;
-       GList* acts;
+       for (ActionGroups::iterator g = groups.begin(); g != groups.end(); ++g) {
 
-       for (node = list; node; node = g_list_next (node)) {
+               /* the C++ API for functions used here appears to be broken in
+                  gtkmm2.6, so we fall back to the C level.
+               */
 
-               GtkActionGroup* group = (GtkActionGroup*) node->data;
+               GtkActionGroup* group = (*g)->gobj();
 
-               for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
+               for (GList* acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
                        GtkAction* action = (GtkAction*) acts->data;
                        action_states_to_restore.push_back (ActionState (action, gtk_action_get_sensitive (action)));
                }
@@ -126,75 +134,6 @@ ActionManager::get_widget (const char * name)
        return ui_manager->get_widget (name);
 }
 
-RefPtr<Action>
-ActionManager::get_action (const char* path)
-{
-       if (!path) {
-               return RefPtr<Action>();
-       }
-
-       /* Skip <Actions>/ in path */
-
-       int len = strlen (path);
-
-       if (len < 3) {
-               /* shortest possible path: "a/b" */
-               return RefPtr<Action>();
-       }
-
-       if (len > 10 && !strncmp (path, "<Actions>/", 10 )) {
-               path = path+10;
-       } else if (path[0] == '/') {
-               path++;
-       }
-
-       vector<char> copy(len+1);
-       strcpy (&copy[0], path);
-       char* slash = strchr (&copy[0], '/');
-       if (!slash) {
-               return RefPtr<Action> ();
-       }
-       *slash = '\0';
-
-       return get_action (&copy[0], ++slash);
-
-}
-
-RefPtr<Action>
-ActionManager::get_action (const char* group_name, const char* action_name)
-{
-       /* the C++ API for functions used here appears to be broken in
-          gtkmm2.6, so we fall back to the C level.
-       */
-
-       if (! ui_manager) {
-               return RefPtr<Action> ();
-       }
-
-       GList* list = gtk_ui_manager_get_action_groups (ui_manager->gobj());
-       GList* node;
-       RefPtr<Action> act;
-
-       for (node = list; node; node = g_list_next (node)) {
-
-               GtkActionGroup* _ag = (GtkActionGroup*) node->data;
-
-               if (strcmp (group_name,  gtk_action_group_get_name (_ag)) == 0) {
-
-                       GtkAction* _act;
-
-                       if ((_act = gtk_action_group_get_action (_ag, action_name)) != 0) {
-                               act = Glib::wrap (_act, true);
-                               break;
-                       }
-
-                       break;
-               }
-       }
-
-       return act;
-}
-
 void
 ActionManager::set_sensitive (vector<RefPtr<Action> >& actions, bool state)
 {
@@ -262,7 +201,7 @@ ActionManager::set_toggleaction_state (const string& n, bool s)
 bool
 ActionManager::set_toggleaction_state (const char* group_name, const char* action_name, bool s)
 {
-       RefPtr<Action> act = get_action (group_name, action_name);
+       RefPtr<Action> act = find_action (group_name, action_name);
        if (act) {
                RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
                if (tact) {
@@ -276,7 +215,7 @@ ActionManager::set_toggleaction_state (const char* group_name, const char* actio
 void
 ActionManager::do_action (const char* group, const char*action)
 {
-       Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (group, action);
+       Glib::RefPtr<Gtk::Action> act = ActionManager::find_action (group, action);
        if (act) {
                act->activate ();
        }
@@ -285,11 +224,275 @@ ActionManager::do_action (const char* group, const char*action)
 void
 ActionManager::set_toggle_action (const char* group, const char*action, bool yn)
 {
-       Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (group, action);
-       if (act) {
-               Glib::RefPtr<Gtk::ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
-               if (tact) {
-                       tact->set_active (yn);
+       Glib::RefPtr<Gtk::ToggleAction> tact = ActionManager::find_toggle_action (group, action);
+       tact->set_active (yn);
+}
+
+RefPtr<Action>
+ActionManager::find_action (const string& name, bool or_die)
+{
+       ActionMap::const_iterator a = actions.find (name);
+
+       if (a != actions.end()) {
+               return a->second;
+       }
+
+       if (or_die) {
+               ::abort ();
+       }
+
+       cerr << "Failed to find action: [" << name << ']' << endl;
+       return RefPtr<Action>();
+}
+
+RefPtr<ToggleAction>
+ActionManager::find_toggle_action (const string& name, bool or_die)
+{
+       RefPtr<Action> act = find_action (name, or_die);
+
+       if (!act) {
+               return RefPtr<ToggleAction>();
+       }
+
+       return Glib::RefPtr<ToggleAction>::cast_dynamic (act);
+}
+
+RefPtr<RadioAction>
+ActionManager::find_radio_action (const string& name, bool or_die)
+{
+       RefPtr<Action> act = find_action (name, or_die);
+
+       if (!act) {
+               return RefPtr<RadioAction>();
+       }
+
+       return Glib::RefPtr<RadioAction>::cast_dynamic (act);
+}
+
+RefPtr<Action>
+ActionManager::find_action (char const * group_name, char const * action_name, bool or_die)
+{
+       string fullpath (group_name);
+       fullpath += '/';
+       fullpath += action_name;
+
+       ActionMap::const_iterator a = actions.find (fullpath);
+
+       if (a != actions.end()) {
+               return a->second;
+       }
+
+       if (or_die) {
+               ::abort ();
+       }
+
+       cerr << "Failed to find action (2): [" << fullpath << ']' << endl;
+       return RefPtr<Action>();
+}
+
+RefPtr<ToggleAction>
+ActionManager::find_toggle_action (char const * group_name, char const * action_name, bool or_die)
+{
+       RefPtr<Action> act = find_action (group_name, action_name, or_die);
+
+       if (!act) {
+               return RefPtr<ToggleAction>();
+       }
+
+       return Glib::RefPtr<ToggleAction>::cast_dynamic (act);
+}
+
+RefPtr<RadioAction>
+ActionManager::find_radio_action (char const * group_name, char const * action_name, bool or_die)
+{
+       RefPtr<Action> act = find_action (group_name, action_name, or_die);
+
+       if (!act) {
+               return RefPtr<RadioAction>();
+       }
+
+       return Glib::RefPtr<RadioAction>::cast_dynamic (act);
+}
+
+
+RefPtr<ActionGroup>
+ActionManager::create_action_group (string const & name)
+{
+       for (ActionGroups::iterator g = groups.begin(); g != groups.end(); ++g) {
+               if ((*g)->get_name () == name) {
+                       return *g;
                }
        }
+
+       RefPtr<ActionGroup> g = ActionGroup::create (name);
+
+       groups.push_back (g);
+
+       /* this is one of the places where our own Action management code
+          has to touch the GTK one, because we want the GtkUIManager to
+          be able to create widgets (particularly Menus) from our actions.
+
+          This is a a necessary step for that to happen.
+       */
+
+       if (g) {
+               ActionManager::ui_manager->insert_action_group (g);
+       }
+
+       return g;
+}
+
+RefPtr<Action>
+ActionManager::register_action (RefPtr<ActionGroup> group, const char* name, const char* label)
+{
+       string fullpath;
+
+       RefPtr<Action> act = Action::create (name, label);
+
+       fullpath = group->get_name();
+       fullpath += '/';
+       fullpath += name;
+
+       if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
+               group->add (act);
+               return act;
+       }
+
+       /* already registered */
+       return RefPtr<Action> ();
+}
+
+RefPtr<Action>
+ActionManager::register_action (RefPtr<ActionGroup> group,
+                            const char* name, const char* label, sigc::slot<void> sl)
+{
+       string fullpath;
+
+       RefPtr<Action> act = Action::create (name, label);
+
+       fullpath = group->get_name();
+       fullpath += '/';
+       fullpath += name;
+
+       if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
+               group->add (act, sl);
+               return act;
+       }
+
+       /* already registered */
+       return RefPtr<Action>();
+}
+
+RefPtr<Action>
+ActionManager::register_radio_action (RefPtr<ActionGroup> group,
+                                  Gtk::RadioAction::Group& rgroup,
+                                  const char* name, const char* label,
+                                  sigc::slot<void> sl)
+{
+       string fullpath;
+
+       RefPtr<Action> act = RadioAction::create (rgroup, name, label);
+       RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+
+       fullpath = group->get_name();
+       fullpath += '/';
+       fullpath += name;
+
+       if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
+               group->add (act, sl);
+               return act;
+       }
+
+       /* already registered */
+       return RefPtr<Action>();
+}
+
+RefPtr<Action>
+ActionManager::register_radio_action (RefPtr<ActionGroup> group,
+                                  Gtk::RadioAction::Group& rgroup,
+                                  const char* name, const char* label,
+                                  sigc::slot<void,GtkAction*> sl,
+                                  int value)
+{
+       string fullpath;
+
+       RefPtr<Action> act = RadioAction::create (rgroup, name, label);
+       RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+       ract->property_value() = value;
+
+       fullpath = group->get_name();
+       fullpath += '/';
+       fullpath += name;
+
+       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>
+ActionManager::register_toggle_action (RefPtr<ActionGroup> group,
+                                   const char* name, const char* label, sigc::slot<void> sl)
+{
+       string fullpath;
+
+       fullpath = group->get_name();
+       fullpath += '/';
+       fullpath += name;
+
+       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
+ActionManager::get_all_actions (std::vector<std::string>& paths,
+                            std::vector<std::string>& labels,
+                            std::vector<std::string>& tooltips,
+                            std::vector<std::string>& keys,
+                            std::vector<RefPtr<Action> >& acts)
+{
+       for (ActionMap::const_iterator a = actions.begin(); a != actions.end(); ++a) {
+
+               Glib::RefPtr<Action> act = a->second;
+
+                       paths.push_back (act->get_accel_path());
+                       labels.push_back (act->get_label());
+                       tooltips.push_back (act->get_tooltip());
+                       acts.push_back (act);
+
+                       /* foreach binding */
+
+#if 0
+                       Bindings* bindings = (*map)->bindings();
+
+                       if (bindings) {
+
+                               KeyboardKey key;
+                               Bindings::Operation op;
+
+                               key = bindings->get_binding_for_action (*act, op);
+
+                               if (key == KeyboardKey::null_key()) {
+                                       keys.push_back (string());
+                               } else {
+                                       keys.push_back (key.display_label());
+                               }
+                       } else {
+                               keys.push_back (string());
+                       }
+               }
+#endif
+
+       }
 }
index cf98bbca4dd6b2080411497d00b6a32436951bef..d5d8245099082d3f2d168b77e3c74fbb8409dbcd 100644 (file)
@@ -44,7 +44,6 @@ using namespace Gtkmm2ext;
 using namespace PBD;
 
 list<Bindings*> Bindings::bindings; /* global. Gulp */
-list<ActionMap*> ActionMap::action_maps; /* global. Gulp */
 PBD::Signal1<void,Bindings*> Bindings::BindingsChanged;
 
 template <typename IteratorValueType>
@@ -373,7 +372,6 @@ KeyboardKey::make_key (const string& str, KeyboardKey& k)
 /*================================= Bindings =================================*/
 Bindings::Bindings (std::string const& name)
        : _name (name)
-       , _action_map (0)
 {
        bindings.push_back (this);
 }
@@ -409,8 +407,8 @@ Bindings::get_binding_for_action (RefPtr<Action> action, Operation& op)
                 * setup the association while we're here, and return the binding.
                 */
 
-               if (_action_map && k->second.action_name == action_name) {
-                       k->second.action = _action_map->find_action (action_name);
+               if (k->second.action_name == action_name) {
+                       k->second.action = ActionManager::find_action (action_name, false);
                        return k->first;
                }
 
@@ -430,8 +428,8 @@ Bindings::get_binding_for_action (RefPtr<Action> action, Operation& op)
                 * setup the association while we're here, and return the binding.
                 */
 
-               if (_action_map && k->second.action_name == action_name) {
-                       k->second.action = _action_map->find_action (action_name);
+               if (k->second.action_name == action_name) {
+                       k->second.action = ActionManager::find_action (action_name, false);
                        return k->first;
                }
 
@@ -441,15 +439,8 @@ Bindings::get_binding_for_action (RefPtr<Action> action, Operation& op)
 }
 
 void
-Bindings::set_action_map (ActionMap& actions)
+Bindings::reassociate ()
 {
-       if (_action_map) {
-               _action_map->set_bindings (0);
-       }
-
-       _action_map = &actions;
-       _action_map->set_bindings (this);
-
        dissociate ();
        associate ();
 }
@@ -497,9 +488,7 @@ Bindings::activate (KeyboardKey kb, Operation op)
        if (k->second.action) {
                action = k->second.action;
        } else {
-               if (_action_map) {
-                       action = _action_map->find_action (k->second.action_name);
-               }
+               action = ActionManager::find_action (k->second.action_name, false);
        }
 
        if (action) {
@@ -518,32 +507,28 @@ Bindings::associate ()
 {
        KeybindingMap::iterator k;
 
-       if (!_action_map) {
-               return;
-       }
-
        for (k = press_bindings.begin(); k != press_bindings.end(); ++k) {
-               k->second.action = _action_map->find_action (k->second.action_name);
+               k->second.action = ActionManager::find_action (k->second.action_name, false);
                if (k->second.action) {
                        push_to_gtk (k->first, k->second.action);
                } else {
-                       cerr << _name << " didn't find " << k->second.action_name << " in " << _action_map->name() << endl;
+                       cerr << _name << " didn't find " << k->second.action_name << endl;
                }
        }
 
        for (k = release_bindings.begin(); k != release_bindings.end(); ++k) {
-               k->second.action = _action_map->find_action (k->second.action_name);
+               k->second.action = ActionManager::find_action (k->second.action_name, false);
                /* no working support in GTK for release bindings */
        }
 
        MouseButtonBindingMap::iterator b;
 
        for (b = button_press_bindings.begin(); b != button_press_bindings.end(); ++b) {
-               b->second.action = _action_map->find_action (b->second.action_name);
+               b->second.action = ActionManager::find_action (b->second.action_name, false);
        }
 
        for (b = button_release_bindings.begin(); b != button_release_bindings.end(); ++b) {
-               b->second.action = _action_map->find_action (b->second.action_name);
+               b->second.action = ActionManager::find_action (b->second.action_name, false);
        }
 }
 
@@ -597,10 +582,6 @@ Bindings::push_to_gtk (KeyboardKey kb, RefPtr<Action> what)
 bool
 Bindings::replace (KeyboardKey kb, Operation op, string const & action_name, bool can_save)
 {
-       if (!_action_map) {
-               return false;
-       }
-
        if (is_registered(op, action_name)) {
                remove (op, action_name, can_save);
        }
@@ -681,9 +662,7 @@ Bindings::activate (MouseButton bb, Operation op)
        if (b->second.action) {
                action = b->second.action;
        } else {
-               if (_action_map) {
-                       action = _action_map->find_action (b->second.action_name);
-               }
+               action = ActionManager::find_action (b->second.action_name, false);
        }
 
        if (action) {
@@ -818,7 +797,7 @@ Bindings::save_all_bindings_as_html (ostream& ostr)
                vector<string> keys;
                vector<Glib::RefPtr<Gtk::Action> > actions;
 
-               Gtkmm2ext::ActionMap::get_all_actions (paths, labels, tooltips, keys, actions);
+               ActionManager::get_all_actions (paths, labels, tooltips, keys, actions);
 
                vector<string>::iterator k;
                vector<string>::iterator p;
@@ -902,9 +881,7 @@ Bindings::save_as_html (ostream& ostr, bool categorize) const
                                if ((*k)->second.action) {
                                        action = (*k)->second.action;
                                } else {
-                                       if (_action_map) {
-                                               action = _action_map->find_action ((*k)->second.action_name);
-                                       }
+                                       action = ActionManager::find_action ((*k)->second.action_name, false);
                                }
 
                                if (!action) {
@@ -1028,10 +1005,6 @@ Bindings::get_all_actions (std::vector<std::string>& paths,
                            std::vector<std::string>& keys,
                            std::vector<RefPtr<Action> >& actions)
 {
-       if (!_action_map) {
-               return;
-       }
-
        /* build a reverse map from actions to bindings */
 
        typedef map<Glib::RefPtr<Gtk::Action>,KeyboardKey> ReverseMap;
@@ -1041,10 +1014,12 @@ Bindings::get_all_actions (std::vector<std::string>& paths,
                rmap.insert (make_pair (k->second.action, k->first));
        }
 
-       /* get a list of all actions */
+#if 0
+
+       /* get a list of all actions XXX relevant for these bindings */
 
        ActionMap::Actions all_actions;
-       _action_map->get_actions (all_actions);
+       ActionManager::get_actions (all_actions);
 
        for (ActionMap::Actions::const_iterator act = all_actions.begin(); act != all_actions.end(); ++act) {
 
@@ -1062,14 +1037,15 @@ Bindings::get_all_actions (std::vector<std::string>& paths,
 
                actions.push_back (*act);
        }
+#endif
 }
 
 Bindings*
-Bindings::get_bindings (string const& name, ActionMap& map)
+Bindings::get_bindings (string const& name)
 {
        for (list<Bindings*>::iterator b = bindings.begin(); b != bindings.end(); b++) {
                if ((*b)->name() == name) {
-                       (*b)->set_action_map (map);
+                       (*b)->reassociate (); // XXX important side-effects, wierd to call it here
                        return *b;
                }
        }
@@ -1146,295 +1122,6 @@ Bindings::get_mousemap (Operation op)
        }
 }
 
-/*==========================================ACTION MAP =========================================*/
-
-ActionMap::ActionMap (string const & name)
-       : _name (name)
-       , _bindings (0)
-{
-       action_maps.push_back (this);
-}
-
-ActionMap::~ActionMap ()
-{
-       action_maps.remove (this);
-}
-
-void
-ActionMap::set_bindings (Bindings* b)
-{
-       _bindings = b;
-}
-
-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)
-{
-       _ActionMap::iterator a = _actions.find (name);
-
-       if (a != _actions.end()) {
-               return a->second;
-       }
-
-       cerr << "Failed to find action: [" << name << ']' << endl;
-       return RefPtr<Action>();
-}
-
-RefPtr<ToggleAction>
-ActionMap::find_toggle_action (const string& name)
-{
-       RefPtr<Action> act = find_action (name);
-
-       if (!act) {
-               return RefPtr<ToggleAction>();
-       }
-
-       return Glib::RefPtr<ToggleAction>::cast_dynamic (act);
-}
-
-RefPtr<RadioAction>
-ActionMap::find_radio_action (const string& name)
-{
-       RefPtr<Action> act = find_action (name);
-
-       if (!act) {
-               return RefPtr<RadioAction>();
-       }
-
-       return Glib::RefPtr<RadioAction>::cast_dynamic (act);
-}
-
-RefPtr<Action>
-ActionMap::find_action (char const * group_name, char const * action_name)
-{
-       string fullpath (group_name);
-       fullpath += '/';
-       fullpath += action_name;
-
-       _ActionMap::iterator a = _actions.find (fullpath);
-
-       if (a != _actions.end()) {
-               return a->second;
-       }
-
-       cerr << "Failed to find action (2): [" << fullpath << ']' << endl;
-       return RefPtr<Action>();
-}
-
-RefPtr<ToggleAction>
-ActionMap::find_toggle_action (char const * group_name, char const * action_name)
-{
-       RefPtr<Action> act = find_action (group_name, action_name);
-
-       if (!act) {
-               return RefPtr<ToggleAction>();
-       }
-
-       return Glib::RefPtr<ToggleAction>::cast_dynamic (act);
-}
-
-RefPtr<RadioAction>
-ActionMap::find_radio_action (char const * group_name, char const * action_name)
-{
-       RefPtr<Action> act = find_action (group_name, action_name);
-
-       if (!act) {
-               return RefPtr<RadioAction>();
-       }
-
-       return Glib::RefPtr<RadioAction>::cast_dynamic (act);
-}
-
-
-RefPtr<ActionGroup>
-ActionMap::create_action_group (const string& name)
-{
-       Glib::ListHandle<Glib::RefPtr<ActionGroup> > agl =  ActionManager::ui_manager->get_action_groups ();
-       for (Glib::ListHandle<Glib::RefPtr<ActionGroup> >::iterator i = agl.begin (); i != agl.end (); ++i) {
-               if ((*i)->get_name () == name) {
-                       return *i;
-               }
-       }
-
-       RefPtr<ActionGroup> g = ActionGroup::create (name);
-
-       /* this is one of the places where our own Action management code
-          has to touch the GTK one, because we want the GtkUIManager to
-          be able to create widgets (particularly Menus) from our actions.
-
-          This is a a necessary step for that to happen.
-       */
-
-       if (g) {
-               ActionManager::ui_manager->insert_action_group (g);
-       }
-
-       return g;
-}
-
-RefPtr<Action>
-ActionMap::register_action (RefPtr<ActionGroup> group, const char* name, const char* label)
-{
-       string fullpath;
-
-       RefPtr<Action> act = Action::create (name, label);
-
-       fullpath = group->get_name();
-       fullpath += '/';
-       fullpath += name;
-
-       if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
-               group->add (act);
-               return act;
-       }
-
-       /* already registered */
-       return RefPtr<Action> ();
-}
-
-RefPtr<Action>
-ActionMap::register_action (RefPtr<ActionGroup> group,
-                            const char* name, const char* label, sigc::slot<void> sl)
-{
-       string fullpath;
-
-       RefPtr<Action> act = Action::create (name, label);
-
-       fullpath = group->get_name();
-       fullpath += '/';
-       fullpath += name;
-
-       if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
-               group->add (act, sl);
-               return act;
-       }
-
-       /* already registered */
-       return RefPtr<Action>();
-}
-
-RefPtr<Action>
-ActionMap::register_radio_action (RefPtr<ActionGroup> group,
-                                  Gtk::RadioAction::Group& rgroup,
-                                  const char* name, const char* label,
-                                  sigc::slot<void> sl)
-{
-       string fullpath;
-
-       RefPtr<Action> act = RadioAction::create (rgroup, name, label);
-       RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
-
-       fullpath = group->get_name();
-       fullpath += '/';
-       fullpath += name;
-
-       if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
-               group->add (act, sl);
-               return act;
-       }
-
-       /* already registered */
-       return RefPtr<Action>();
-}
-
-RefPtr<Action>
-ActionMap::register_radio_action (RefPtr<ActionGroup> group,
-                                  Gtk::RadioAction::Group& rgroup,
-                                  const char* name, const char* label,
-                                  sigc::slot<void,GtkAction*> sl,
-                                  int value)
-{
-       string fullpath;
-
-       RefPtr<Action> act = RadioAction::create (rgroup, name, label);
-       RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
-       ract->property_value() = value;
-
-       fullpath = group->get_name();
-       fullpath += '/';
-       fullpath += name;
-
-       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>
-ActionMap::register_toggle_action (RefPtr<ActionGroup> group,
-                                   const char* name, const char* label, sigc::slot<void> sl)
-{
-       string fullpath;
-
-       fullpath = group->get_name();
-       fullpath += '/';
-       fullpath += name;
-
-       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
-ActionMap::get_all_actions (std::vector<std::string>& paths,
-                            std::vector<std::string>& labels,
-                            std::vector<std::string>& tooltips,
-                            std::vector<std::string>& keys,
-                            std::vector<RefPtr<Action> >& actions)
-{
-       for (list<ActionMap*>::const_iterator map = action_maps.begin(); map != action_maps.end(); ++map) {
-
-               ActionMap::Actions these_actions;
-               (*map)->get_actions (these_actions);
-
-               for (ActionMap::Actions::const_iterator act = these_actions.begin(); act != these_actions.end(); ++act) {
-
-                       paths.push_back ((*act)->get_accel_path());
-                       labels.push_back ((*act)->get_label());
-                       tooltips.push_back ((*act)->get_tooltip());
-                       actions.push_back (*act);
-
-                       Bindings* bindings = (*map)->bindings();
-
-                       if (bindings) {
-
-                               KeyboardKey key;
-                               Bindings::Operation op;
-
-                               key = bindings->get_binding_for_action (*act, op);
-
-                               if (key == KeyboardKey::null_key()) {
-                                       keys.push_back (string());
-                               } else {
-                                       keys.push_back (key.display_label());
-                               }
-                       } else {
-                               keys.push_back (string());
-                       }
-               }
-
-               these_actions.clear ();
-       }
-}
-
 std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey const & k) {
        char const *gdk_name = gdk_keyval_name (k.key());
        return out << "Key " << k.key() << " (" << (gdk_name ? gdk_name : "no-key") << ") state "
index c321d94d4fe91493b33eb5a75ad8fd0291c21126..f03c5c5dec98d6f9839771a3d2c2bc28aaf250f8 100644 (file)
@@ -617,7 +617,7 @@ UI::process_error_message (Transmitter::Channel chn, const char *str)
 void
 UI::show_errors ()
 {
-       Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-log-window"));
+       Glib::RefPtr<Action> act = ActionManager::find_action (X_("Editor"), X_("toggle-log-window"));
        if (!act) {
                return;
        }
@@ -631,7 +631,7 @@ UI::show_errors ()
 void
 UI::toggle_errors ()
 {
-       Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-log-window"));
+       Glib::RefPtr<Action> act = ActionManager::find_action (X_("Editor"), X_("toggle-log-window"));
        if (!act) {
                return;
        }
index 2d1c979ed1ba3ae61353fa9b0174879ad214f0b2..698697316916c4e6e800cfac1ff4cc0af8db7c8a 100644 (file)
@@ -36,27 +36,70 @@ namespace Gtk {
 
 namespace ActionManager {
 
+/* Why is this a namespace and not a class?
+ *
+ * 1) We want it to behave like a singleton without an instance() method. This
+ * would normally be accomplished by using a set of static methods and member
+ * variables.
+ *
+ * 2) We need to extend the contents of the (class|namespace) in
+ * gtk2_ardour. We can't do this with a class without inheritance, which is not
+ * what we're looking for because we want a non-instance singleton.
+ *
+ * Hence, we use namespacing to allow us to write ActionManager::foobar() as
+ * well as the extensions in gtk2_ardour/actions.h
+ *
+ */
+
+       LIBGTKMM2EXT_API extern void init ();
+
        LIBGTKMM2EXT_API extern std::string unbound_string;  /* the key string returned if an action is not bound */
        LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::UIManager> ui_manager;
 
        LIBGTKMM2EXT_API extern void set_sensitive (std::vector<Glib::RefPtr<Gtk::Action> >& actions, bool);
        LIBGTKMM2EXT_API extern std::string get_key_representation (const std::string& accel_path, Gtk::AccelKey& key);
-
        LIBGTKMM2EXT_API extern Gtk::Widget* get_widget (const char * name);
-       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> get_action (const char* group, const char* name);
-       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> get_action (const char* path);
-
        LIBGTKMM2EXT_API extern void do_action (const char* group, const char* name);
        LIBGTKMM2EXT_API extern void set_toggle_action (const char* group, const char* name, bool);
-
        LIBGTKMM2EXT_API extern void check_toggleaction (const std::string&);
        LIBGTKMM2EXT_API extern void uncheck_toggleaction (const std::string&);
        LIBGTKMM2EXT_API extern void set_toggleaction_state (const std::string&, bool);
        LIBGTKMM2EXT_API extern bool set_toggleaction_state (const char*, const char*, bool);
-
        LIBGTKMM2EXT_API extern void save_action_states ();
        LIBGTKMM2EXT_API extern void enable_active_actions ();
        LIBGTKMM2EXT_API extern void disable_active_actions ();
+
+       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::ActionGroup> create_action_group (std::string const & group_name);
+
+       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group, const char* name, const char* label);
+       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group,
+                                                                          const char* name, const char* label, sigc::slot<void> sl);
+       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
+                                                        Gtk::RadioAction::Group&,
+                                                        const char* name, const char* label,
+                                                        sigc::slot<void,GtkAction*> sl,
+                                                        int value);
+       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
+                                                        Gtk::RadioAction::Group&,
+                                                        const char* name, const char* label,
+                                                        sigc::slot<void> sl);
+       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_toggle_action (Glib::RefPtr<Gtk::ActionGroup> group,
+                                                         const char* name, const char* label, sigc::slot<void> sl);
+
+       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action>       find_action (const std::string& name, bool or_die = true);
+       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action>       find_action (char const * group_name, char const * action_name, bool or_die = true);
+       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::ToggleAction> find_toggle_action (const std::string& name, bool or_die = true);
+       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::ToggleAction> find_toggle_action (char const * group_name, char const * action_name, bool or_die = true);
+       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::RadioAction>  find_radio_action (const std::string& name, bool or_die = true);
+       LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::RadioAction>  find_radio_action (char const * group_name, char const * action_name, bool or_die = true);
+
+
+       LIBGTKMM2EXT_API extern void get_all_actions (std::vector<std::string>& paths,
+                                    std::vector<std::string>& labels,
+                                    std::vector<std::string>& tooltips,
+                                    std::vector<std::string>& keys,
+                                    std::vector<Glib::RefPtr<Gtk::Action> >& actions);
+
 };
 
 #endif /* __libgtkmm2ext_actions_h__ */
index 329a0bdaa164e3c5ab66583a38509a0453cec85a..f9c3aa75439d79a3691fb4bc423fe63cc819abc6 100644 (file)
@@ -81,90 +81,6 @@ class LIBGTKMM2EXT_API MouseButton {
 
 class LIBGTKMM2EXT_API Bindings;
 
-class LIBGTKMM2EXT_API ActionMap {
-  public:
-       ActionMap (std::string const& name);
-       ~ActionMap();
-
-       std::string name() const { return _name; }
-
-       Glib::RefPtr<Gtk::ActionGroup> create_action_group (const std::string& group_name);
-
-       Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group, const char* name, const char* label);
-       Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group,
-                                                  const char* name, const char* label, sigc::slot<void> sl);
-       Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
-                                                        Gtk::RadioAction::Group&,
-                                                        const char* name, const char* label,
-                                                        sigc::slot<void,GtkAction*> sl,
-                                                        int value);
-       Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
-                                                        Gtk::RadioAction::Group&,
-                                                        const char* name, const char* label,
-                                                        sigc::slot<void> sl);
-       Glib::RefPtr<Gtk::Action> register_toggle_action (Glib::RefPtr<Gtk::ActionGroup> group,
-                                                         const char* name, const char* label, sigc::slot<void> sl);
-
-       Glib::RefPtr<Gtk::Action> find_action (const std::string& name);
-       Glib::RefPtr<Gtk::Action> find_action (char const * group_name, char const * action_name);
-       Glib::RefPtr<Gtk::ToggleAction> find_toggle_action (const std::string& name);
-       Glib::RefPtr<Gtk::ToggleAction> find_toggle_action (char const * group_name, char const * action_name);
-       Glib::RefPtr<Gtk::RadioAction> find_radio_action (const std::string& name);
-       Glib::RefPtr<Gtk::RadioAction> find_radio_action (char const * group_name, char const * action_name);
-
-       void set_bindings (Bindings*);
-       Bindings* bindings() const { return _bindings; }
-
-       typedef std::vector<Glib::RefPtr<Gtk::Action> > Actions;
-       void get_actions (Actions&);
-
-       static std::list<ActionMap*> action_maps;
-
-       /* used by control surface protocols and other UIs */
-       static void get_all_actions (std::vector<std::string>& paths,
-                                    std::vector<std::string>& labels,
-                                    std::vector<std::string>& tooltips,
-                                    std::vector<std::string>& keys,
-                                    std::vector<Glib::RefPtr<Gtk::Action> >& actions);
-
-  private:
-       std::string _name;
-
-       /* hash for faster lookup of actions by name */
-
-       typedef std::map<std::string, Glib::RefPtr<Gtk::Action> > _ActionMap;
-       _ActionMap _actions;
-
-       /* initialized to null; set after a Bindings object has ::associated()
-        * itself with this action map.
-        */
-
-       Bindings* _bindings;
-
-};
-
-class LIBGTKMM2EXT_API ActionMapOwner {
-  protected:
-       Gtkmm2ext::ActionMap myactions;
-  public:
-       ActionMapOwner (std::string const & map_name) : myactions (map_name) {}
-       Glib::RefPtr<Gtk::Action> find_action (const std::string& name) { return myactions.find_action (name); }
-       Glib::RefPtr<Gtk::Action> find_action (char const * group_name, char const * action_name) { return myactions.find_action (group_name, action_name); }
-
-       Gtkmm2ext::ActionMap& action_map() { return myactions; }
-};
-
-class LIBGTKMM2EXT_API StaticActionMapOwner {
-  protected:
-       virtual Gtkmm2ext::ActionMap& my_actions() const = 0;
-  public:
-       virtual ~StaticActionMapOwner() {}
-       Glib::RefPtr<Gtk::Action> find_action (const std::string& name) { return my_actions().find_action (name); }
-       Glib::RefPtr<Gtk::Action> find_action (char const * group_name, char const * action_name) { return my_actions().find_action (group_name, action_name); }
-
-       Gtkmm2ext::ActionMap& action_map() { return my_actions(); }
-};
-
 class LIBGTKMM2EXT_API Bindings {
   public:
        enum Operation {
@@ -187,6 +103,7 @@ class LIBGTKMM2EXT_API Bindings {
 
        std::string const& name() const { return _name; }
 
+       void reassociate ();
        void associate ();
        void dissociate ();
 
@@ -230,8 +147,6 @@ class LIBGTKMM2EXT_API Bindings {
         */
        static std::string ardour_action_name (Glib::RefPtr<Gtk::Action>);
 
-       void set_action_map (ActionMap&);
-
        /* used for editing bindings */
        void get_all_actions (std::vector<std::string>& paths,
                              std::vector<std::string>& labels,
@@ -242,7 +157,7 @@ class LIBGTKMM2EXT_API Bindings {
        /* all bindings currently in existence, as grouped into Bindings */
        static void reset_bindings () { bindings.clear (); }
        static std::list<Bindings*> bindings;
-       static Bindings* get_bindings (std::string const& name, ActionMap&);
+       static Bindings* get_bindings (std::string const & name);
        static void associate_all ();
        static void save_all_bindings_as_html (std::ostream&);
 
@@ -250,7 +165,6 @@ class LIBGTKMM2EXT_API Bindings {
 
   private:
        std::string  _name;
-       ActionMap*   _action_map;
        KeybindingMap press_bindings;
        KeybindingMap release_bindings;