summaryrefslogtreecommitdiff
path: root/libs/gtkmm2ext/actions.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2014-06-24 09:56:08 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2014-06-24 09:56:16 -0400
commitf147846863c27dfa13ef83b696f198a5092721fa (patch)
treef52baa144cf760138c862f7cdc4ab8fd80a1159d /libs/gtkmm2ext/actions.cc
parentdae3b26f188c17b1e74c17284539979a92ea630f (diff)
add ability to save current action sensitivities and restore them, and to disable all action sensitivity.
This is needed to be able to lock the application fully on OS X, where the global menu bar would still allow interaction even when a modal dialog is displayed.
Diffstat (limited to 'libs/gtkmm2ext/actions.cc')
-rw-r--r--libs/gtkmm2ext/actions.cc78
1 files changed, 78 insertions, 0 deletions
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 <vector>
#include <string>
#include <list>
+#include <stack>
#include <stdint.h>
+#include <boost/shared_ptr.hpp>
+
#include <gtk/gtkaccelmap.h>
#include <gtk/gtkuimanager.h>
#include <gtk/gtkactiongroup.h>
@@ -232,6 +235,81 @@ ActionManager::get_all_actions (vector<string>& names, vector<string>& paths, ve
}
}
+struct ActionState {
+ GtkAction* action;
+ bool sensitive;
+ ActionState (GtkAction* a, bool s) : action (a), sensitive (s) {}
+};
+
+typedef std::vector<ActionState> ActionStates;
+
+static std::stack<boost::shared_ptr<ActionStates> > state_stack;
+
+static boost::shared_ptr<ActionStates>
+get_action_state ()
+{
+ boost::shared_ptr<ActionStates> state = boost::shared_ptr<ActionStates>(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<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;
+
+ 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<ActionStates> 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<ActionStates> 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<ActionGroup> grp)
{