diff --git a/libs/gtkmm2ext/actions.cc b/libs/gtkmm2ext/actions.cc index 200308a254..f4159c71e2 100644 --- a/libs/gtkmm2ext/actions.cc +++ b/libs/gtkmm2ext/actions.cc @@ -21,8 +21,11 @@ #include #include #include +#include #include +#include + #include #include #include @@ -232,6 +235,81 @@ ActionManager::get_all_actions (vector& names, vector& paths, ve } } +struct ActionState { + GtkAction* action; + bool sensitive; + ActionState (GtkAction* a, bool s) : action (a), sensitive (s) {} +}; + +typedef std::vector ActionStates; + +static std::stack > state_stack; + +static boost::shared_ptr +get_action_state () +{ + boost::shared_ptr state = boost::shared_ptr(new ActionStates); + + /* 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; + + /* 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; + + state->push_back (ActionState (action, gtk_action_get_sensitive (action))); + } + } + + return state; +} + +void +ActionManager::push_action_state () +{ + state_stack.push (get_action_state()); +} + +void +ActionManager::pop_action_state () +{ + if (state_stack.empty()) { + warning << string_compose (_("programming error: %1"), X_("ActionManager::pop_action_state called with empty stack")) << endmsg; + return; + } + + boost::shared_ptr as = state_stack.top (); + state_stack.pop (); + + for (ActionStates::iterator i = as->begin(); i != as->end(); ++i) { + gtk_action_set_sensitive ((*i).action, (*i).sensitive); + } +} + +void +ActionManager::disable_all_actions () +{ + push_action_state (); + boost::shared_ptr as = state_stack.top (); + + for (ActionStates::iterator i = as->begin(); i != as->end(); ++i) { + gtk_action_set_sensitive ((*i).action, false); + } +} + void ActionManager::add_action_group (RefPtr grp) { diff --git a/libs/gtkmm2ext/gtkmm2ext/actions.h b/libs/gtkmm2ext/gtkmm2ext/actions.h index d92f85bb6e..536bd326be 100644 --- a/libs/gtkmm2ext/gtkmm2ext/actions.h +++ b/libs/gtkmm2ext/gtkmm2ext/actions.h @@ -91,6 +91,11 @@ namespace ActionManager { LIBGTKMM2EXT_API extern void check_toggleaction (std::string); LIBGTKMM2EXT_API extern void uncheck_toggleaction (std::string); LIBGTKMM2EXT_API extern void set_toggleaction_state (std::string, bool); + + + LIBGTKMM2EXT_API extern void push_action_state (); + LIBGTKMM2EXT_API extern void pop_action_state (); + LIBGTKMM2EXT_API extern void disable_all_actions (); }; #endif /* __libgtkmm2ext_actions_h__ */