X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fgtkmm2ext%2Factions.cc;h=9471067de9d48602f20d60cee37b528a626045e9;hb=22b07e0233a29d9633ffa825a79503befaf2e16e;hp=1380d49ae8631ee94eb682e9c351e59d7583f9b1;hpb=4cca76853396f5c4090c3be547b0df4b5f0d02d0;p=ardour.git diff --git a/libs/gtkmm2ext/actions.cc b/libs/gtkmm2ext/actions.cc index 1380d49ae8..9471067de9 100644 --- a/libs/gtkmm2ext/actions.cc +++ b/libs/gtkmm2ext/actions.cc @@ -21,15 +21,21 @@ #include #include #include +#include #include +#include + #include #include #include +#include #include #include +#include + #include "pbd/error.h" #include "gtkmm2ext/actions.h" @@ -133,11 +139,11 @@ ActionManager::lookup_entry (const ustring accel_path, Gtk::AccelKey& key) } struct SortActionsByLabel { - bool operator() (Glib::RefPtr a, Glib::RefPtr b) { - ustring astr = a->get_accel_path(); - ustring bstr = b->get_accel_path(); - return astr < bstr; - } + bool operator() (Glib::RefPtr a, Glib::RefPtr b) { + ustring astr = a->get_accel_path(); + ustring bstr = b->get_accel_path(); + return astr < bstr; + } }; void @@ -231,6 +237,117 @@ ActionManager::get_all_actions (vector& names, vector& paths, ve } } +void +ActionManager::enable_accelerators () +{ + /* 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; + string ui_string = ""; + + /* get all actions, build a string describing them all as + */ + + for (node = list; node; node = g_list_next (node)) { + + GtkActionGroup* group = (GtkActionGroup*) node->data; + + for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) { + ui_string += "data); + + ui_string += Glib::path_get_basename (fullpath); + ui_string += "\"/>"; + } + } + + ui_string += ""; + + /* and load it */ + + ui_manager->add_ui_from_string (ui_string); +} + +struct ActionState { + GtkAction* action; + bool sensitive; + ActionState (GtkAction* a, bool s) : action (a), sensitive (s) {} +}; + +typedef std::vector ActionStates; + +static ActionStates action_states_to_restore; +static bool actions_disabled = false; + +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 (node = list; node; node = g_list_next (node)) { + + GtkActionGroup* group = (GtkActionGroup*) node->data; + + for (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))); + } + } +} + +void +ActionManager::enable_active_actions () +{ + if (!actions_disabled) { + return ; + } + + for (ActionStates::iterator i = action_states_to_restore.begin(); i != action_states_to_restore.end(); ++i) { + if ((*i).action && (*i).sensitive) { + gtk_action_set_sensitive ((*i).action, true); + } + } + + action_states_to_restore.clear (); + actions_disabled = false; +} + +void +ActionManager::disable_active_actions () +{ + if (actions_disabled == true ) { + return ; + } + // save all action's states to action_states_to_restore + save_action_states (); + + // set all action's states disabled + for (ActionStates::iterator i = action_states_to_restore.begin(); i != action_states_to_restore.end(); ++i) { + if ((*i).sensitive) { + gtk_action_set_sensitive ((*i).action, false); + } + } + actions_disabled = true; +} + void ActionManager::add_action_group (RefPtr grp) { @@ -243,6 +360,40 @@ ActionManager::get_widget (const char * name) return ui_manager->get_widget (name); } +RefPtr +ActionManager::get_action (const char* path) +{ + if (!path) { + return RefPtr(); + } + + /* Skip / in path */ + + int len = strlen (path); + + if (len < 3) { + /* shortest possible path: "a/b" */ + return RefPtr(); + } + + if (len > 10 && !strncmp (path, "/", 10 )) { + path = path+10; + } else if (path[0] == '/') { + path++; + } + + vector copy(len+1); + strcpy (©[0], path); + char* slash = strchr (©[0], '/'); + if (!slash) { + return RefPtr (); + } + *slash = '\0'; + + return get_action (©[0], ++slash); + +} + RefPtr ActionManager::get_action (const char* group_name, const char* action_name) { @@ -276,24 +427,78 @@ ActionManager::get_action (const char* group_name, const char* action_name) return act; } +RefPtr +ActionManager::get_action_from_name (const char* name) +{ + /* 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; + + for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) { + GtkAction* action = (GtkAction*) acts->data; + if (!strcmp (gtk_action_get_name (action), name)) { + return Glib::wrap (action, true); + } + } + } + + return RefPtr(); +} + void ActionManager::set_sensitive (vector >& actions, bool state) { - for (vector >::iterator i = actions.begin(); i != actions.end(); ++i) { - (*i)->set_sensitive (state); + // if actions weren't disabled + if (!actions_disabled) { + for (vector >::iterator i = actions.begin(); i != actions.end(); ++i) { + (*i)->set_sensitive (state); + } } + else { + // actions were disabled + // so we should just set necessary action's states in action_states_to_restore + for (vector >::iterator i = actions.begin(); i != actions.end(); ++i) { + // go through action_states_to_restore and set state of actions + for (ActionStates::iterator j = action_states_to_restore.begin(); j != action_states_to_restore.end(); ++j) { + // all actions should have their individual name, so we can use it for comparison + if (gtk_action_get_name ((*j).action) == (*i)->get_name ()) { + (*j).sensitive = state; + } + } + } + } +} + +void +ActionManager::check_toggleaction (string n) +{ + set_toggleaction_state (n, true); } void ActionManager::uncheck_toggleaction (string n) +{ + set_toggleaction_state (n, false); +} + +void +ActionManager::set_toggleaction_state (string n, bool s) { char const * name = n.c_str (); - + const char *last_slash = strrchr (name, '/'); if (last_slash == 0) { fatal << string_compose ("programmer error: %1 %2", "illegal toggle action name", name) << endmsg; - /*NOTREACHED*/ + abort(); /*NOTREACHED*/ return; } @@ -306,10 +511,10 @@ ActionManager::uncheck_toggleaction (string n) const char* action_name = last_slash + 1; - RefPtr act = get_action (group_name, action_name); + RefPtr act = get_action (group_name, action_name); if (act) { - RefPtr tact = RefPtr::cast_dynamic(act); - tact->set_active (false); + RefPtr tact = RefPtr::cast_dynamic(act); + tact->set_active (s); } else { error << string_compose (_("Unknown action name: %1"), name) << endmsg; } @@ -321,13 +526,13 @@ string ActionManager::get_key_representation (const string& accel_path, AccelKey& key) { bool known = lookup_entry (accel_path, key); - + if (known) { uint32_t k = possibly_translate_legal_accelerator_to_real_key (key.get_key()); key = AccelKey (k, Gdk::ModifierType (key.get_mod())); return ui_manager->get_accel_group()->get_label (key.get_key(), Gdk::ModifierType (key.get_mod())); - } - + } + return unbound_string; }