+bool
+ActionManager::lookup_entry (const ustring accel_path, Gtk::AccelKey& key)
+{
+ GtkAccelKey gkey;
+ bool known = gtk_accel_map_lookup_entry (accel_path.c_str(), &gkey);
+
+ if (known) {
+ key = AccelKey (gkey.accel_key, Gdk::ModifierType (gkey.accel_mods));
+ } else {
+ key = AccelKey (GDK_VoidSymbol, Gdk::ModifierType (0));
+ }
+
+ return known;
+}
+
+struct SortActionsByLabel {
+ bool operator() (Glib::RefPtr<Gtk::Action> a, Glib::RefPtr<Gtk::Action> b) {
+ ustring astr = a->get_accel_path();
+ ustring bstr = b->get_accel_path();
+ return astr < bstr;
+ }
+};
+
+void
+ActionManager::get_all_actions (vector<string>& groups, vector<string>& names, vector<AccelKey>& bindings)
+{
+ /* 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 (ui_manager->gobj());
+ GList* node;
+ GList* acts;
+
+ for (node = list; node; node = g_list_next (node)) {
+
+ GtkActionGroup* group = (GtkActionGroup*) node->data;
+
+ /* first pass: collect them all */
+
+ typedef std::list<Glib::RefPtr<Gtk::Action> > action_list;
+ action_list the_acts;
+
+ for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
+ GtkAction* action = (GtkAction*) acts->data;
+ the_acts.push_back (Glib::wrap (action, true));
+ }
+
+ /* now sort by label */
+
+ SortActionsByLabel cmp;
+ the_acts.sort (cmp);
+
+ for (action_list::iterator a = the_acts.begin(); a != the_acts.end(); ++a) {
+
+ string accel_path = (*a)->get_accel_path ();
+
+ groups.push_back (gtk_action_group_get_name(group));
+ names.push_back (accel_path.substr (accel_path.find_last_of ('/') + 1));
+
+ AccelKey key;
+ lookup_entry (accel_path, key);
+ bindings.push_back (AccelKey (key.get_key(), Gdk::ModifierType (key.get_mod())));
+ }
+ }
+}
+
+void
+ActionManager::get_all_actions (vector<string>& names, vector<string>& paths, vector<string>& keys, vector<AccelKey>& bindings)
+{
+ /* 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 (ui_manager->gobj());
+ GList* node;
+ GList* acts;
+
+ for (node = list; node; node = g_list_next (node)) {
+
+ GtkActionGroup* group = (GtkActionGroup*) node->data;
+
+ /* first pass: collect them all */
+
+ typedef std::list<Glib::RefPtr<Gtk::Action> > action_list;
+ action_list the_acts;
+
+ for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
+ GtkAction* action = (GtkAction*) acts->data;
+ the_acts.push_back (Glib::wrap (action, true));
+ }
+
+ /* now sort by label */
+
+ SortActionsByLabel cmp;
+ the_acts.sort (cmp);
+
+ for (action_list::iterator a = the_acts.begin(); a != the_acts.end(); ++a) {
+
+ string accel_path = (*a)->get_accel_path ();
+ ustring label = (*a)->property_label();
+
+ names.push_back (label);
+ paths.push_back (accel_path);
+
+ AccelKey key;
+ bool known = lookup_entry (accel_path, key);
+
+ if (known) {
+ keys.push_back (ui_manager->get_accel_group()->name (key.get_key(), Gdk::ModifierType (key.get_mod())));
+ } else {
+ keys.push_back (unbound_string);
+ }
+
+ bindings.push_back (AccelKey (key.get_key(), Gdk::ModifierType (key.get_mod())));
+ }
+ }
+}
+
+void
+ActionManager::add_action_group (RefPtr<ActionGroup> grp)
+{
+ ui_manager->insert_action_group (grp);
+}
+
+Widget*
+ActionManager::get_widget (const char * name)
+{
+ return ui_manager->get_widget (name);
+}