summaryrefslogtreecommitdiff
path: root/libs
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
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')
-rw-r--r--libs/gtkmm2ext/actions.cc78
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/actions.h5
2 files changed, 83 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)
{
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__ */