consolidate ActionMap and ActionManager APIs into a single namespace

This commit is contained in:
Paul Davis 2018-12-10 08:22:10 -05:00
parent efd75b7152
commit ad002d0de0
5 changed files with 363 additions and 516 deletions

View file

@ -50,8 +50,13 @@ using namespace sigc;
using namespace PBD;
using namespace Gtkmm2ext;
typedef std::map<std::string, Glib::RefPtr<Gtk::Action> > ActionMap;
static ActionMap actions;
typedef std::vector<Glib::RefPtr<Gtk::ActionGroup> > ActionGroups;
static ActionGroups groups;
RefPtr<UIManager> ActionManager::ui_manager;
string ActionManager::unbound_string = "--";
string ActionManager::unbound_string = X_("--");
struct ActionState {
GtkAction* action;
@ -64,21 +69,24 @@ typedef std::vector<ActionState> ActionStates;
static ActionStates action_states_to_restore;
static bool actions_disabled = false;
void
ActionManager::init ()
{
ui_manager = UIManager::create ();
}
void
ActionManager::save_action_states ()
{
for (ActionGroups::iterator g = groups.begin(); g != groups.end(); ++g) {
/* 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 = (*g)->gobj();
GtkActionGroup* group = (GtkActionGroup*) node->data;
for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
for (GList* 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)));
}
@ -126,75 +134,6 @@ ActionManager::get_widget (const char * name)
return ui_manager->get_widget (name);
}
RefPtr<Action>
ActionManager::get_action (const char* path)
{
if (!path) {
return RefPtr<Action>();
}
/* Skip <Actions>/ in path */
int len = strlen (path);
if (len < 3) {
/* shortest possible path: "a/b" */
return RefPtr<Action>();
}
if (len > 10 && !strncmp (path, "<Actions>/", 10 )) {
path = path+10;
} else if (path[0] == '/') {
path++;
}
vector<char> copy(len+1);
strcpy (&copy[0], path);
char* slash = strchr (&copy[0], '/');
if (!slash) {
return RefPtr<Action> ();
}
*slash = '\0';
return get_action (&copy[0], ++slash);
}
RefPtr<Action>
ActionManager::get_action (const char* group_name, const char* action_name)
{
/* the C++ API for functions used here appears to be broken in
gtkmm2.6, so we fall back to the C level.
*/
if (! ui_manager) {
return RefPtr<Action> ();
}
GList* list = gtk_ui_manager_get_action_groups (ui_manager->gobj());
GList* node;
RefPtr<Action> act;
for (node = list; node; node = g_list_next (node)) {
GtkActionGroup* _ag = (GtkActionGroup*) node->data;
if (strcmp (group_name, gtk_action_group_get_name (_ag)) == 0) {
GtkAction* _act;
if ((_act = gtk_action_group_get_action (_ag, action_name)) != 0) {
act = Glib::wrap (_act, true);
break;
}
break;
}
}
return act;
}
void
ActionManager::set_sensitive (vector<RefPtr<Action> >& actions, bool state)
{
@ -262,7 +201,7 @@ ActionManager::set_toggleaction_state (const string& n, bool s)
bool
ActionManager::set_toggleaction_state (const char* group_name, const char* action_name, bool s)
{
RefPtr<Action> act = get_action (group_name, action_name);
RefPtr<Action> act = find_action (group_name, action_name);
if (act) {
RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
if (tact) {
@ -276,7 +215,7 @@ ActionManager::set_toggleaction_state (const char* group_name, const char* actio
void
ActionManager::do_action (const char* group, const char*action)
{
Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (group, action);
Glib::RefPtr<Gtk::Action> act = ActionManager::find_action (group, action);
if (act) {
act->activate ();
}
@ -285,11 +224,275 @@ ActionManager::do_action (const char* group, const char*action)
void
ActionManager::set_toggle_action (const char* group, const char*action, bool yn)
{
Glib::RefPtr<Gtk::Action> act = ActionManager::get_action (group, action);
if (act) {
Glib::RefPtr<Gtk::ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
if (tact) {
Glib::RefPtr<Gtk::ToggleAction> tact = ActionManager::find_toggle_action (group, action);
tact->set_active (yn);
}
RefPtr<Action>
ActionManager::find_action (const string& name, bool or_die)
{
ActionMap::const_iterator a = actions.find (name);
if (a != actions.end()) {
return a->second;
}
if (or_die) {
::abort ();
}
cerr << "Failed to find action: [" << name << ']' << endl;
return RefPtr<Action>();
}
RefPtr<ToggleAction>
ActionManager::find_toggle_action (const string& name, bool or_die)
{
RefPtr<Action> act = find_action (name, or_die);
if (!act) {
return RefPtr<ToggleAction>();
}
return Glib::RefPtr<ToggleAction>::cast_dynamic (act);
}
RefPtr<RadioAction>
ActionManager::find_radio_action (const string& name, bool or_die)
{
RefPtr<Action> act = find_action (name, or_die);
if (!act) {
return RefPtr<RadioAction>();
}
return Glib::RefPtr<RadioAction>::cast_dynamic (act);
}
RefPtr<Action>
ActionManager::find_action (char const * group_name, char const * action_name, bool or_die)
{
string fullpath (group_name);
fullpath += '/';
fullpath += action_name;
ActionMap::const_iterator a = actions.find (fullpath);
if (a != actions.end()) {
return a->second;
}
if (or_die) {
::abort ();
}
cerr << "Failed to find action (2): [" << fullpath << ']' << endl;
return RefPtr<Action>();
}
RefPtr<ToggleAction>
ActionManager::find_toggle_action (char const * group_name, char const * action_name, bool or_die)
{
RefPtr<Action> act = find_action (group_name, action_name, or_die);
if (!act) {
return RefPtr<ToggleAction>();
}
return Glib::RefPtr<ToggleAction>::cast_dynamic (act);
}
RefPtr<RadioAction>
ActionManager::find_radio_action (char const * group_name, char const * action_name, bool or_die)
{
RefPtr<Action> act = find_action (group_name, action_name, or_die);
if (!act) {
return RefPtr<RadioAction>();
}
return Glib::RefPtr<RadioAction>::cast_dynamic (act);
}
RefPtr<ActionGroup>
ActionManager::create_action_group (string const & name)
{
for (ActionGroups::iterator g = groups.begin(); g != groups.end(); ++g) {
if ((*g)->get_name () == name) {
return *g;
}
}
RefPtr<ActionGroup> g = ActionGroup::create (name);
groups.push_back (g);
/* this is one of the places where our own Action management code
has to touch the GTK one, because we want the GtkUIManager to
be able to create widgets (particularly Menus) from our actions.
This is a a necessary step for that to happen.
*/
if (g) {
ActionManager::ui_manager->insert_action_group (g);
}
return g;
}
RefPtr<Action>
ActionManager::register_action (RefPtr<ActionGroup> group, const char* name, const char* label)
{
string fullpath;
RefPtr<Action> act = Action::create (name, label);
fullpath = group->get_name();
fullpath += '/';
fullpath += name;
if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
group->add (act);
return act;
}
/* already registered */
return RefPtr<Action> ();
}
RefPtr<Action>
ActionManager::register_action (RefPtr<ActionGroup> group,
const char* name, const char* label, sigc::slot<void> sl)
{
string fullpath;
RefPtr<Action> act = Action::create (name, label);
fullpath = group->get_name();
fullpath += '/';
fullpath += name;
if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
group->add (act, sl);
return act;
}
/* already registered */
return RefPtr<Action>();
}
RefPtr<Action>
ActionManager::register_radio_action (RefPtr<ActionGroup> group,
Gtk::RadioAction::Group& rgroup,
const char* name, const char* label,
sigc::slot<void> sl)
{
string fullpath;
RefPtr<Action> act = RadioAction::create (rgroup, name, label);
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
fullpath = group->get_name();
fullpath += '/';
fullpath += name;
if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
group->add (act, sl);
return act;
}
/* already registered */
return RefPtr<Action>();
}
RefPtr<Action>
ActionManager::register_radio_action (RefPtr<ActionGroup> group,
Gtk::RadioAction::Group& rgroup,
const char* name, const char* label,
sigc::slot<void,GtkAction*> sl,
int value)
{
string fullpath;
RefPtr<Action> act = RadioAction::create (rgroup, name, label);
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
ract->property_value() = value;
fullpath = group->get_name();
fullpath += '/';
fullpath += name;
if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
group->add (act, sigc::bind (sl, act->gobj()));
return act;
}
/* already registered */
return RefPtr<Action>();
}
RefPtr<Action>
ActionManager::register_toggle_action (RefPtr<ActionGroup> group,
const char* name, const char* label, sigc::slot<void> sl)
{
string fullpath;
fullpath = group->get_name();
fullpath += '/';
fullpath += name;
RefPtr<Action> act = ToggleAction::create (name, label);
if (actions.insert (ActionMap::value_type (fullpath, act)).second) {
group->add (act, sl);
return act;
}
/* already registered */
return RefPtr<Action>();
}
void
ActionManager::get_all_actions (std::vector<std::string>& paths,
std::vector<std::string>& labels,
std::vector<std::string>& tooltips,
std::vector<std::string>& keys,
std::vector<RefPtr<Action> >& acts)
{
for (ActionMap::const_iterator a = actions.begin(); a != actions.end(); ++a) {
Glib::RefPtr<Action> act = a->second;
paths.push_back (act->get_accel_path());
labels.push_back (act->get_label());
tooltips.push_back (act->get_tooltip());
acts.push_back (act);
/* foreach binding */
#if 0
Bindings* bindings = (*map)->bindings();
if (bindings) {
KeyboardKey key;
Bindings::Operation op;
key = bindings->get_binding_for_action (*act, op);
if (key == KeyboardKey::null_key()) {
keys.push_back (string());
} else {
keys.push_back (key.display_label());
}
} else {
keys.push_back (string());
}
}
#endif
}
}

View file

@ -44,7 +44,6 @@ using namespace Gtkmm2ext;
using namespace PBD;
list<Bindings*> Bindings::bindings; /* global. Gulp */
list<ActionMap*> ActionMap::action_maps; /* global. Gulp */
PBD::Signal1<void,Bindings*> Bindings::BindingsChanged;
template <typename IteratorValueType>
@ -373,7 +372,6 @@ KeyboardKey::make_key (const string& str, KeyboardKey& k)
/*================================= Bindings =================================*/
Bindings::Bindings (std::string const& name)
: _name (name)
, _action_map (0)
{
bindings.push_back (this);
}
@ -409,8 +407,8 @@ Bindings::get_binding_for_action (RefPtr<Action> action, Operation& op)
* setup the association while we're here, and return the binding.
*/
if (_action_map && k->second.action_name == action_name) {
k->second.action = _action_map->find_action (action_name);
if (k->second.action_name == action_name) {
k->second.action = ActionManager::find_action (action_name, false);
return k->first;
}
@ -430,8 +428,8 @@ Bindings::get_binding_for_action (RefPtr<Action> action, Operation& op)
* setup the association while we're here, and return the binding.
*/
if (_action_map && k->second.action_name == action_name) {
k->second.action = _action_map->find_action (action_name);
if (k->second.action_name == action_name) {
k->second.action = ActionManager::find_action (action_name, false);
return k->first;
}
@ -441,15 +439,8 @@ Bindings::get_binding_for_action (RefPtr<Action> action, Operation& op)
}
void
Bindings::set_action_map (ActionMap& actions)
Bindings::reassociate ()
{
if (_action_map) {
_action_map->set_bindings (0);
}
_action_map = &actions;
_action_map->set_bindings (this);
dissociate ();
associate ();
}
@ -497,9 +488,7 @@ Bindings::activate (KeyboardKey kb, Operation op)
if (k->second.action) {
action = k->second.action;
} else {
if (_action_map) {
action = _action_map->find_action (k->second.action_name);
}
action = ActionManager::find_action (k->second.action_name, false);
}
if (action) {
@ -518,32 +507,28 @@ Bindings::associate ()
{
KeybindingMap::iterator k;
if (!_action_map) {
return;
}
for (k = press_bindings.begin(); k != press_bindings.end(); ++k) {
k->second.action = _action_map->find_action (k->second.action_name);
k->second.action = ActionManager::find_action (k->second.action_name, false);
if (k->second.action) {
push_to_gtk (k->first, k->second.action);
} else {
cerr << _name << " didn't find " << k->second.action_name << " in " << _action_map->name() << endl;
cerr << _name << " didn't find " << k->second.action_name << endl;
}
}
for (k = release_bindings.begin(); k != release_bindings.end(); ++k) {
k->second.action = _action_map->find_action (k->second.action_name);
k->second.action = ActionManager::find_action (k->second.action_name, false);
/* no working support in GTK for release bindings */
}
MouseButtonBindingMap::iterator b;
for (b = button_press_bindings.begin(); b != button_press_bindings.end(); ++b) {
b->second.action = _action_map->find_action (b->second.action_name);
b->second.action = ActionManager::find_action (b->second.action_name, false);
}
for (b = button_release_bindings.begin(); b != button_release_bindings.end(); ++b) {
b->second.action = _action_map->find_action (b->second.action_name);
b->second.action = ActionManager::find_action (b->second.action_name, false);
}
}
@ -597,10 +582,6 @@ Bindings::push_to_gtk (KeyboardKey kb, RefPtr<Action> what)
bool
Bindings::replace (KeyboardKey kb, Operation op, string const & action_name, bool can_save)
{
if (!_action_map) {
return false;
}
if (is_registered(op, action_name)) {
remove (op, action_name, can_save);
}
@ -681,9 +662,7 @@ Bindings::activate (MouseButton bb, Operation op)
if (b->second.action) {
action = b->second.action;
} else {
if (_action_map) {
action = _action_map->find_action (b->second.action_name);
}
action = ActionManager::find_action (b->second.action_name, false);
}
if (action) {
@ -818,7 +797,7 @@ Bindings::save_all_bindings_as_html (ostream& ostr)
vector<string> keys;
vector<Glib::RefPtr<Gtk::Action> > actions;
Gtkmm2ext::ActionMap::get_all_actions (paths, labels, tooltips, keys, actions);
ActionManager::get_all_actions (paths, labels, tooltips, keys, actions);
vector<string>::iterator k;
vector<string>::iterator p;
@ -902,9 +881,7 @@ Bindings::save_as_html (ostream& ostr, bool categorize) const
if ((*k)->second.action) {
action = (*k)->second.action;
} else {
if (_action_map) {
action = _action_map->find_action ((*k)->second.action_name);
}
action = ActionManager::find_action ((*k)->second.action_name, false);
}
if (!action) {
@ -1028,10 +1005,6 @@ Bindings::get_all_actions (std::vector<std::string>& paths,
std::vector<std::string>& keys,
std::vector<RefPtr<Action> >& actions)
{
if (!_action_map) {
return;
}
/* build a reverse map from actions to bindings */
typedef map<Glib::RefPtr<Gtk::Action>,KeyboardKey> ReverseMap;
@ -1041,10 +1014,12 @@ Bindings::get_all_actions (std::vector<std::string>& paths,
rmap.insert (make_pair (k->second.action, k->first));
}
/* get a list of all actions */
#if 0
/* get a list of all actions XXX relevant for these bindings */
ActionMap::Actions all_actions;
_action_map->get_actions (all_actions);
ActionManager::get_actions (all_actions);
for (ActionMap::Actions::const_iterator act = all_actions.begin(); act != all_actions.end(); ++act) {
@ -1062,14 +1037,15 @@ Bindings::get_all_actions (std::vector<std::string>& paths,
actions.push_back (*act);
}
#endif
}
Bindings*
Bindings::get_bindings (string const& name, ActionMap& map)
Bindings::get_bindings (string const& name)
{
for (list<Bindings*>::iterator b = bindings.begin(); b != bindings.end(); b++) {
if ((*b)->name() == name) {
(*b)->set_action_map (map);
(*b)->reassociate (); // XXX important side-effects, wierd to call it here
return *b;
}
}
@ -1146,295 +1122,6 @@ Bindings::get_mousemap (Operation op)
}
}
/*==========================================ACTION MAP =========================================*/
ActionMap::ActionMap (string const & name)
: _name (name)
, _bindings (0)
{
action_maps.push_back (this);
}
ActionMap::~ActionMap ()
{
action_maps.remove (this);
}
void
ActionMap::set_bindings (Bindings* b)
{
_bindings = b;
}
void
ActionMap::get_actions (ActionMap::Actions& acts)
{
for (_ActionMap::iterator a = _actions.begin(); a != _actions.end(); ++a) {
acts.push_back (a->second);
}
}
RefPtr<Action>
ActionMap::find_action (const string& name)
{
_ActionMap::iterator a = _actions.find (name);
if (a != _actions.end()) {
return a->second;
}
cerr << "Failed to find action: [" << name << ']' << endl;
return RefPtr<Action>();
}
RefPtr<ToggleAction>
ActionMap::find_toggle_action (const string& name)
{
RefPtr<Action> act = find_action (name);
if (!act) {
return RefPtr<ToggleAction>();
}
return Glib::RefPtr<ToggleAction>::cast_dynamic (act);
}
RefPtr<RadioAction>
ActionMap::find_radio_action (const string& name)
{
RefPtr<Action> act = find_action (name);
if (!act) {
return RefPtr<RadioAction>();
}
return Glib::RefPtr<RadioAction>::cast_dynamic (act);
}
RefPtr<Action>
ActionMap::find_action (char const * group_name, char const * action_name)
{
string fullpath (group_name);
fullpath += '/';
fullpath += action_name;
_ActionMap::iterator a = _actions.find (fullpath);
if (a != _actions.end()) {
return a->second;
}
cerr << "Failed to find action (2): [" << fullpath << ']' << endl;
return RefPtr<Action>();
}
RefPtr<ToggleAction>
ActionMap::find_toggle_action (char const * group_name, char const * action_name)
{
RefPtr<Action> act = find_action (group_name, action_name);
if (!act) {
return RefPtr<ToggleAction>();
}
return Glib::RefPtr<ToggleAction>::cast_dynamic (act);
}
RefPtr<RadioAction>
ActionMap::find_radio_action (char const * group_name, char const * action_name)
{
RefPtr<Action> act = find_action (group_name, action_name);
if (!act) {
return RefPtr<RadioAction>();
}
return Glib::RefPtr<RadioAction>::cast_dynamic (act);
}
RefPtr<ActionGroup>
ActionMap::create_action_group (const string& name)
{
Glib::ListHandle<Glib::RefPtr<ActionGroup> > agl = ActionManager::ui_manager->get_action_groups ();
for (Glib::ListHandle<Glib::RefPtr<ActionGroup> >::iterator i = agl.begin (); i != agl.end (); ++i) {
if ((*i)->get_name () == name) {
return *i;
}
}
RefPtr<ActionGroup> g = ActionGroup::create (name);
/* this is one of the places where our own Action management code
has to touch the GTK one, because we want the GtkUIManager to
be able to create widgets (particularly Menus) from our actions.
This is a a necessary step for that to happen.
*/
if (g) {
ActionManager::ui_manager->insert_action_group (g);
}
return g;
}
RefPtr<Action>
ActionMap::register_action (RefPtr<ActionGroup> group, const char* name, const char* label)
{
string fullpath;
RefPtr<Action> act = Action::create (name, label);
fullpath = group->get_name();
fullpath += '/';
fullpath += name;
if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
group->add (act);
return act;
}
/* already registered */
return RefPtr<Action> ();
}
RefPtr<Action>
ActionMap::register_action (RefPtr<ActionGroup> group,
const char* name, const char* label, sigc::slot<void> sl)
{
string fullpath;
RefPtr<Action> act = Action::create (name, label);
fullpath = group->get_name();
fullpath += '/';
fullpath += name;
if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
group->add (act, sl);
return act;
}
/* already registered */
return RefPtr<Action>();
}
RefPtr<Action>
ActionMap::register_radio_action (RefPtr<ActionGroup> group,
Gtk::RadioAction::Group& rgroup,
const char* name, const char* label,
sigc::slot<void> sl)
{
string fullpath;
RefPtr<Action> act = RadioAction::create (rgroup, name, label);
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
fullpath = group->get_name();
fullpath += '/';
fullpath += name;
if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
group->add (act, sl);
return act;
}
/* already registered */
return RefPtr<Action>();
}
RefPtr<Action>
ActionMap::register_radio_action (RefPtr<ActionGroup> group,
Gtk::RadioAction::Group& rgroup,
const char* name, const char* label,
sigc::slot<void,GtkAction*> sl,
int value)
{
string fullpath;
RefPtr<Action> act = RadioAction::create (rgroup, name, label);
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
ract->property_value() = value;
fullpath = group->get_name();
fullpath += '/';
fullpath += name;
if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
group->add (act, sigc::bind (sl, act->gobj()));
return act;
}
/* already registered */
return RefPtr<Action>();
}
RefPtr<Action>
ActionMap::register_toggle_action (RefPtr<ActionGroup> group,
const char* name, const char* label, sigc::slot<void> sl)
{
string fullpath;
fullpath = group->get_name();
fullpath += '/';
fullpath += name;
RefPtr<Action> act = ToggleAction::create (name, label);
if (_actions.insert (_ActionMap::value_type (fullpath, act)).second) {
group->add (act, sl);
return act;
}
/* already registered */
return RefPtr<Action>();
}
void
ActionMap::get_all_actions (std::vector<std::string>& paths,
std::vector<std::string>& labels,
std::vector<std::string>& tooltips,
std::vector<std::string>& keys,
std::vector<RefPtr<Action> >& actions)
{
for (list<ActionMap*>::const_iterator map = action_maps.begin(); map != action_maps.end(); ++map) {
ActionMap::Actions these_actions;
(*map)->get_actions (these_actions);
for (ActionMap::Actions::const_iterator act = these_actions.begin(); act != these_actions.end(); ++act) {
paths.push_back ((*act)->get_accel_path());
labels.push_back ((*act)->get_label());
tooltips.push_back ((*act)->get_tooltip());
actions.push_back (*act);
Bindings* bindings = (*map)->bindings();
if (bindings) {
KeyboardKey key;
Bindings::Operation op;
key = bindings->get_binding_for_action (*act, op);
if (key == KeyboardKey::null_key()) {
keys.push_back (string());
} else {
keys.push_back (key.display_label());
}
} else {
keys.push_back (string());
}
}
these_actions.clear ();
}
}
std::ostream& operator<<(std::ostream& out, Gtkmm2ext::KeyboardKey const & k) {
char const *gdk_name = gdk_keyval_name (k.key());
return out << "Key " << k.key() << " (" << (gdk_name ? gdk_name : "no-key") << ") state "

View file

@ -617,7 +617,7 @@ UI::process_error_message (Transmitter::Channel chn, const char *str)
void
UI::show_errors ()
{
Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-log-window"));
Glib::RefPtr<Action> act = ActionManager::find_action (X_("Editor"), X_("toggle-log-window"));
if (!act) {
return;
}
@ -631,7 +631,7 @@ UI::show_errors ()
void
UI::toggle_errors ()
{
Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-log-window"));
Glib::RefPtr<Action> act = ActionManager::find_action (X_("Editor"), X_("toggle-log-window"));
if (!act) {
return;
}

View file

@ -36,27 +36,70 @@ namespace Gtk {
namespace ActionManager {
/* Why is this a namespace and not a class?
*
* 1) We want it to behave like a singleton without an instance() method. This
* would normally be accomplished by using a set of static methods and member
* variables.
*
* 2) We need to extend the contents of the (class|namespace) in
* gtk2_ardour. We can't do this with a class without inheritance, which is not
* what we're looking for because we want a non-instance singleton.
*
* Hence, we use namespacing to allow us to write ActionManager::foobar() as
* well as the extensions in gtk2_ardour/actions.h
*
*/
LIBGTKMM2EXT_API extern void init ();
LIBGTKMM2EXT_API extern std::string unbound_string; /* the key string returned if an action is not bound */
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::UIManager> ui_manager;
LIBGTKMM2EXT_API extern void set_sensitive (std::vector<Glib::RefPtr<Gtk::Action> >& actions, bool);
LIBGTKMM2EXT_API extern std::string get_key_representation (const std::string& accel_path, Gtk::AccelKey& key);
LIBGTKMM2EXT_API extern Gtk::Widget* get_widget (const char * name);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> get_action (const char* group, const char* name);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> get_action (const char* path);
LIBGTKMM2EXT_API extern void do_action (const char* group, const char* name);
LIBGTKMM2EXT_API extern void set_toggle_action (const char* group, const char* name, bool);
LIBGTKMM2EXT_API extern void check_toggleaction (const std::string&);
LIBGTKMM2EXT_API extern void uncheck_toggleaction (const std::string&);
LIBGTKMM2EXT_API extern void set_toggleaction_state (const std::string&, bool);
LIBGTKMM2EXT_API extern bool set_toggleaction_state (const char*, const char*, bool);
LIBGTKMM2EXT_API extern void save_action_states ();
LIBGTKMM2EXT_API extern void enable_active_actions ();
LIBGTKMM2EXT_API extern void disable_active_actions ();
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::ActionGroup> create_action_group (std::string const & group_name);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group, const char* name, const char* label);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group,
const char* name, const char* label, sigc::slot<void> sl);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
Gtk::RadioAction::Group&,
const char* name, const char* label,
sigc::slot<void,GtkAction*> sl,
int value);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
Gtk::RadioAction::Group&,
const char* name, const char* label,
sigc::slot<void> sl);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> register_toggle_action (Glib::RefPtr<Gtk::ActionGroup> group,
const char* name, const char* label, sigc::slot<void> sl);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> find_action (const std::string& name, bool or_die = true);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::Action> find_action (char const * group_name, char const * action_name, bool or_die = true);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::ToggleAction> find_toggle_action (const std::string& name, bool or_die = true);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::ToggleAction> find_toggle_action (char const * group_name, char const * action_name, bool or_die = true);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::RadioAction> find_radio_action (const std::string& name, bool or_die = true);
LIBGTKMM2EXT_API extern Glib::RefPtr<Gtk::RadioAction> find_radio_action (char const * group_name, char const * action_name, bool or_die = true);
LIBGTKMM2EXT_API extern void get_all_actions (std::vector<std::string>& paths,
std::vector<std::string>& labels,
std::vector<std::string>& tooltips,
std::vector<std::string>& keys,
std::vector<Glib::RefPtr<Gtk::Action> >& actions);
};
#endif /* __libgtkmm2ext_actions_h__ */

View file

@ -81,90 +81,6 @@ class LIBGTKMM2EXT_API MouseButton {
class LIBGTKMM2EXT_API Bindings;
class LIBGTKMM2EXT_API ActionMap {
public:
ActionMap (std::string const& name);
~ActionMap();
std::string name() const { return _name; }
Glib::RefPtr<Gtk::ActionGroup> create_action_group (const std::string& group_name);
Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group, const char* name, const char* label);
Glib::RefPtr<Gtk::Action> register_action (Glib::RefPtr<Gtk::ActionGroup> group,
const char* name, const char* label, sigc::slot<void> sl);
Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
Gtk::RadioAction::Group&,
const char* name, const char* label,
sigc::slot<void,GtkAction*> sl,
int value);
Glib::RefPtr<Gtk::Action> register_radio_action (Glib::RefPtr<Gtk::ActionGroup> group,
Gtk::RadioAction::Group&,
const char* name, const char* label,
sigc::slot<void> sl);
Glib::RefPtr<Gtk::Action> register_toggle_action (Glib::RefPtr<Gtk::ActionGroup> group,
const char* name, const char* label, sigc::slot<void> sl);
Glib::RefPtr<Gtk::Action> find_action (const std::string& name);
Glib::RefPtr<Gtk::Action> find_action (char const * group_name, char const * action_name);
Glib::RefPtr<Gtk::ToggleAction> find_toggle_action (const std::string& name);
Glib::RefPtr<Gtk::ToggleAction> find_toggle_action (char const * group_name, char const * action_name);
Glib::RefPtr<Gtk::RadioAction> find_radio_action (const std::string& name);
Glib::RefPtr<Gtk::RadioAction> find_radio_action (char const * group_name, char const * action_name);
void set_bindings (Bindings*);
Bindings* bindings() const { return _bindings; }
typedef std::vector<Glib::RefPtr<Gtk::Action> > Actions;
void get_actions (Actions&);
static std::list<ActionMap*> action_maps;
/* used by control surface protocols and other UIs */
static void get_all_actions (std::vector<std::string>& paths,
std::vector<std::string>& labels,
std::vector<std::string>& tooltips,
std::vector<std::string>& keys,
std::vector<Glib::RefPtr<Gtk::Action> >& actions);
private:
std::string _name;
/* hash for faster lookup of actions by name */
typedef std::map<std::string, Glib::RefPtr<Gtk::Action> > _ActionMap;
_ActionMap _actions;
/* initialized to null; set after a Bindings object has ::associated()
* itself with this action map.
*/
Bindings* _bindings;
};
class LIBGTKMM2EXT_API ActionMapOwner {
protected:
Gtkmm2ext::ActionMap myactions;
public:
ActionMapOwner (std::string const & map_name) : myactions (map_name) {}
Glib::RefPtr<Gtk::Action> find_action (const std::string& name) { return myactions.find_action (name); }
Glib::RefPtr<Gtk::Action> find_action (char const * group_name, char const * action_name) { return myactions.find_action (group_name, action_name); }
Gtkmm2ext::ActionMap& action_map() { return myactions; }
};
class LIBGTKMM2EXT_API StaticActionMapOwner {
protected:
virtual Gtkmm2ext::ActionMap& my_actions() const = 0;
public:
virtual ~StaticActionMapOwner() {}
Glib::RefPtr<Gtk::Action> find_action (const std::string& name) { return my_actions().find_action (name); }
Glib::RefPtr<Gtk::Action> find_action (char const * group_name, char const * action_name) { return my_actions().find_action (group_name, action_name); }
Gtkmm2ext::ActionMap& action_map() { return my_actions(); }
};
class LIBGTKMM2EXT_API Bindings {
public:
enum Operation {
@ -187,6 +103,7 @@ class LIBGTKMM2EXT_API Bindings {
std::string const& name() const { return _name; }
void reassociate ();
void associate ();
void dissociate ();
@ -230,8 +147,6 @@ class LIBGTKMM2EXT_API Bindings {
*/
static std::string ardour_action_name (Glib::RefPtr<Gtk::Action>);
void set_action_map (ActionMap&);
/* used for editing bindings */
void get_all_actions (std::vector<std::string>& paths,
std::vector<std::string>& labels,
@ -242,7 +157,7 @@ class LIBGTKMM2EXT_API Bindings {
/* all bindings currently in existence, as grouped into Bindings */
static void reset_bindings () { bindings.clear (); }
static std::list<Bindings*> bindings;
static Bindings* get_bindings (std::string const& name, ActionMap&);
static Bindings* get_bindings (std::string const & name);
static void associate_all ();
static void save_all_bindings_as_html (std::ostream&);
@ -250,7 +165,6 @@ class LIBGTKMM2EXT_API Bindings {
private:
std::string _name;
ActionMap* _action_map;
KeybindingMap press_bindings;
KeybindingMap release_bindings;