2 Copyright (C) 2001-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <gdk/gdkkeysyms.h>
22 #include <pbd/error.h>
25 #include "keyboard_target.h"
31 KeyboardTarget::ActionMap KeyboardTarget::actions;
33 KeyboardTarget::KeyboardTarget (Gtk::Window& win, string name)
37 Keyboard::the_keyboard().register_target (this);
40 KeyboardTarget::~KeyboardTarget ()
46 KeyboardTarget::key_release_event (GdkEventKey *event, Keyboard::State& state)
52 KeyboardTarget::key_press_event (GdkEventKey *event, Keyboard::State& state, bool& handled)
54 KeyMap::iterator result;
56 if ((result = keymap.find (state)) != keymap.end()) {
63 KeyboardTarget::add_binding (string keystring, string action)
65 KeyMap::iterator existing;
66 Keyboard::State state;
69 state = Keyboard::translate_key_name (keystring);
71 if (keystring.length() == 0) {
72 error << _("KeyboardTarget: empty string passed to add_binding.")
77 if (state.size() == 0) {
78 error << string_compose(_("KeyboardTarget: no translation found for \"%1\""), keystring) << endmsg;
82 if (find_action (action, key_action)) {
83 error << string_compose(_("KeyboardTarget: unknown action \"%1\""), action) << endmsg;
87 /* remove any existing binding */
89 if ((existing = keymap.find (state)) != keymap.end()) {
90 keymap.erase (existing);
93 keymap.insert (pair<Keyboard::State,KeyAction> (state, key_action));
94 bindings.insert (pair<string,string> (keystring, action));
99 KeyboardTarget::get_binding (string name)
101 BindingMap::iterator i;
103 for (i = bindings.begin(); i != bindings.end(); ++i) {
105 if (i->second == name) {
107 /* convert keystring to GTK format */
109 string str = i->first;
115 if ((p = str.find ('-')) == string::npos || (p == str.length() - 1)) {
120 gtkstr += str.substr (0, p);
123 str = str.substr (p+1);
129 if (gtkstr.length() == 0) {
140 KeyboardTarget::show_all_actions ()
142 ActionMap::iterator i;
144 for (i = actions.begin(); i != actions.end(); ++i) {
145 cout << i->first << endl;
150 KeyboardTarget::add_action (string name, KeyAction action)
152 pair<string,KeyAction> newpair;
153 pair<ActionMap::iterator,bool> result;
154 newpair.first = name;
155 newpair.second = action;
157 result = actions.insert (newpair);
158 return result.second ? 0 : -1;
162 KeyboardTarget::find_action (string name, KeyAction& action)
164 map<string,KeyAction>::iterator i;
166 if ((i = actions.find (name)) != actions.end()) {
175 KeyboardTarget::remove_action (string name)
177 map<string,KeyAction>::iterator i;
179 if ((i = actions.find (name)) != actions.end()) {
188 KeyboardTarget::get_binding_state () const
190 XMLNode *node = new XMLNode ("context");
191 BindingMap::const_iterator i;
193 node->add_property ("name", _name);
195 for (i = bindings.begin(); i != bindings.end(); ++i) {
198 child = new XMLNode ("binding");
199 child->add_property ("keys", i->first);
200 child->add_property ("action", i->second);
201 node->add_child_nocopy (*child);
208 KeyboardTarget::set_binding_state (const XMLNode& node)
210 XMLNodeList nlist = node.children();
211 XMLNodeConstIterator niter;
217 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
220 if (child_node->name() == "context") {
223 if ((prop = child_node->property ("name")) != 0) {
224 if (prop->value() == _name) {
225 return load_bindings (*child_node);
235 KeyboardTarget::load_bindings (const XMLNode& node)
237 XMLNodeList nlist = node.children();
238 XMLNodeConstIterator niter;
240 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
244 keys = (*niter)->property ("keys");
245 action = (*niter)->property ("action");
247 if (!keys || !action) {
248 error << _("misformed binding node - ignored") << endmsg;
252 add_binding (keys->value(), action->value());