X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fgtkmm2ext%2Factions.cc;h=840c9dc4a29012285b62468f8907b813e5f9163a;hb=c8c6bca6587450ff64303dbc994a4cd28d6ce7aa;hp=3fc9def399974f20484b42b6429f0b77662e1784;hpb=b9ff443085b0513d95c867cce81595b9509b2dff;p=ardour.git diff --git a/libs/gtkmm2ext/actions.cc b/libs/gtkmm2ext/actions.cc index 3fc9def399..840c9dc4a2 100644 --- a/libs/gtkmm2ext/actions.cc +++ b/libs/gtkmm2ext/actions.cc @@ -21,21 +21,27 @@ #include #include #include +#include #include +#include + #include #include #include +#include #include #include +#include + #include "pbd/error.h" #include "gtkmm2ext/actions.h" #include "gtkmm2ext/utils.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace std; using namespace Gtk; @@ -47,107 +53,24 @@ using namespace Gtkmm2ext; RefPtr ActionManager::ui_manager; string ActionManager::unbound_string = "--"; +struct ActionState { + GtkAction* action; + bool sensitive; + ActionState (GtkAction* a, bool s) : action (a), sensitive (s) {} +}; -RefPtr -ActionManager::register_action (RefPtr group, const char * name, const char * label, slot sl) -{ - RefPtr act; - - act = Action::create (name, label); - group->add (act, sl); - - return act; -} - -RefPtr -ActionManager::register_action (RefPtr group, const char * name, const char * label) -{ - RefPtr act; - - act = Action::create (name, label); - group->add (act); - - return act; -} - - -RefPtr -ActionManager::register_radio_action (RefPtr group, RadioAction::Group& rgroup, const char * name, const char * label, slot sl) -{ - RefPtr act; - - act = RadioAction::create (rgroup, name, label); - group->add (act, sl); - - return act; -} - -RefPtr -ActionManager::register_radio_action ( - RefPtr group, RadioAction::Group& rgroup, string const & name, string const & label, string const & tooltip, slot sl - ) -{ - RefPtr act; - - act = RadioAction::create (rgroup, name, label, tooltip); - group->add (act, sl); - - return act; -} - -RefPtr -ActionManager::register_toggle_action (RefPtr group, const char * name, const char * label, slot sl) -{ - RefPtr act; - - act = ToggleAction::create (name, label); - group->add (act, sl); - - return act; -} - -RefPtr -ActionManager::register_toggle_action (RefPtr group, string const & name, string const & label, string const & tooltip, slot sl) -{ - RefPtr act; - - act = ToggleAction::create (name, label, tooltip); - group->add (act, sl); - - return act; -} - -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)); - } +typedef std::vector ActionStates; - return known; -} - -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; - } -}; +static ActionStates action_states_to_restore; +static bool actions_disabled = false; void -ActionManager::get_all_actions (vector& groups, vector& names, vector& tooltips, vector& bindings) +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 (ui_manager->gobj()); + GList* list = gtk_ui_manager_get_action_groups (ActionManager::ui_manager->gobj()); GList* node; GList* acts; @@ -155,86 +78,46 @@ ActionManager::get_all_actions (vector& groups, vector& names, v GtkActionGroup* group = (GtkActionGroup*) node->data; - /* first pass: collect them all */ - - typedef std::list > 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)); - tooltips.push_back ((*a)->get_tooltip ()); - - AccelKey key; - lookup_entry (accel_path, key); - bindings.push_back (AccelKey (key.get_key(), Gdk::ModifierType (key.get_mod()))); + action_states_to_restore.push_back (ActionState (action, gtk_action_get_sensitive (action))); } } } void -ActionManager::get_all_actions (vector& names, vector& paths, vector& tooltips, vector& keys, vector& bindings) +ActionManager::enable_active_actions () { - /* 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 > 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) { - - ustring const label = (*a)->property_label (); - string const accel_path = (*a)->get_accel_path (); - - names.push_back (label); - paths.push_back (accel_path); - tooltips.push_back ((*a)->get_tooltip ()); + if (!actions_disabled) { + return ; + } - AccelKey key; - keys.push_back (get_key_representation (accel_path, key)); - bindings.push_back (AccelKey (key.get_key(), Gdk::ModifierType (key.get_mod()))); + 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::add_action_group (RefPtr grp) +ActionManager::disable_active_actions () { - ui_manager->insert_action_group (grp); + 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; } Widget* @@ -250,25 +133,31 @@ ActionManager::get_action (const char* path) return RefPtr(); } - char copy[strlen(path)+1]; + /* Skip / in path */ - if (*path == '/') { - const char* cslash = strchr (path, '/'); - if (!cslash) { - return RefPtr (); - } - strcpy (copy, cslash+1); - } else { - strcpy (copy, 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++; } - char* slash = strchr (copy, '/'); + vector copy(len+1); + strcpy (©[0], path); + char* slash = strchr (©[0], '/'); if (!slash) { return RefPtr (); } *slash = '\0'; - return get_action (copy, ++slash); - + + return get_action (©[0], ++slash); + } RefPtr @@ -278,7 +167,7 @@ ActionManager::get_action (const char* group_name, const char* action_name) gtkmm2.6, so we fall back to the C level. */ - if (ui_manager == 0) { + if (! ui_manager) { return RefPtr (); } @@ -298,56 +187,60 @@ ActionManager::get_action (const char* group_name, const char* action_name) act = Glib::wrap (_act, true); break; } + + break; } } return act; } -RefPtr -ActionManager::get_action_from_name (const char* name) +void +ActionManager::set_sensitive (vector >& actions, bool state) { - /* 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); + // 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; + } } } } - - return RefPtr(); } void -ActionManager::set_sensitive (vector >& actions, bool state) +ActionManager::check_toggleaction (string n) { - for (vector >::iterator i = actions.begin(); i != actions.end(); ++i) { - (*i)->set_sensitive (state); - } + 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; } @@ -360,10 +253,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; } @@ -371,20 +264,6 @@ ActionManager::uncheck_toggleaction (string n) delete [] group_name; } -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; -} - void ActionManager::do_action (const char* group, const char*action) { @@ -405,4 +284,3 @@ ActionManager::set_toggle_action (const char* group, const char*action, bool yn) } } } -