ardour/gtk2_ardour/keyboard_target.cc
Paul Davis 4c50965622 fix compose mess, and a number of 64 bit printf specs
git-svn-id: svn://localhost/trunk/ardour2@51 d708f5d6-7413-0410-9779-e7cbd77b26cf
2005-10-06 19:10:57 +00:00

259 lines
5.1 KiB
C++

/*
Copyright (C) 2001-2002 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id$
*/
#include <gdk/gdkkeysyms.h>
#include <pbd/error.h>
#include "keyboard.h"
#include "keyboard_target.h"
#include "i18n.h"
using std::pair;
KeyboardTarget::ActionMap KeyboardTarget::actions;
KeyboardTarget::KeyboardTarget (Gtk::Window& win, string name)
: _window (win)
{
_name = name;
Keyboard::the_keyboard().register_target (this);
}
KeyboardTarget::~KeyboardTarget ()
{
GoingAway ();
}
void
KeyboardTarget::key_release_event (GdkEventKey *event, Keyboard::State& state)
{
// relax
}
void
KeyboardTarget::key_press_event (GdkEventKey *event, Keyboard::State& state, bool& handled)
{
KeyMap::iterator result;
if ((result = keymap.find (state)) != keymap.end()) {
(*result).second ();
handled = true;
}
}
int
KeyboardTarget::add_binding (string keystring, string action)
{
KeyMap::iterator existing;
Keyboard::State state;
KeyAction key_action;
state = Keyboard::translate_key_name (keystring);
if (keystring.length() == 0) {
error << _("KeyboardTarget: empty string passed to add_binding.")
<< endmsg;
return -1;
}
if (state.size() == 0) {
error << string_compose(_("KeyboardTarget: no translation found for \"%1\""), keystring) << endmsg;
return -1;
}
if (find_action (action, key_action)) {
error << string_compose(_("KeyboardTarget: unknown action \"%1\""), action) << endmsg;
return -1;
}
/* remove any existing binding */
if ((existing = keymap.find (state)) != keymap.end()) {
keymap.erase (existing);
}
keymap.insert (pair<Keyboard::State,KeyAction> (state, key_action));
bindings.insert (pair<string,string> (keystring, action));
return 0;
}
string
KeyboardTarget::get_binding (string name)
{
BindingMap::iterator i;
for (i = bindings.begin(); i != bindings.end(); ++i) {
if (i->second == name) {
/* convert keystring to GTK format */
string str = i->first;
string gtkstr;
string::size_type p;
while (1) {
if ((p = str.find ('-')) == string::npos || (p == str.length() - 1)) {
break;
}
gtkstr += '<';
gtkstr += str.substr (0, p);
gtkstr += '>';
str = str.substr (p+1);
}
gtkstr += str;
if (gtkstr.length() == 0) {
return i->first;
}
return gtkstr;
}
}
return string ();
}
void
KeyboardTarget::show_all_actions ()
{
ActionMap::iterator i;
for (i = actions.begin(); i != actions.end(); ++i) {
cout << i->first << endl;
}
}
int
KeyboardTarget::add_action (string name, KeyAction action)
{
pair<string,KeyAction> newpair;
pair<ActionMap::iterator,bool> result;
newpair.first = name;
newpair.second = action;
result = actions.insert (newpair);
return result.second ? 0 : -1;
}
int
KeyboardTarget::find_action (string name, KeyAction& action)
{
map<string,KeyAction>::iterator i;
if ((i = actions.find (name)) != actions.end()) {
action = i->second;
return 0;
} else {
return -1;
}
}
int
KeyboardTarget::remove_action (string name)
{
map<string,KeyAction>::iterator i;
if ((i = actions.find (name)) != actions.end()) {
actions.erase (i);
return 0;
} else {
return -1;
}
}
XMLNode&
KeyboardTarget::get_binding_state () const
{
XMLNode *node = new XMLNode ("context");
BindingMap::const_iterator i;
node->add_property ("name", _name);
for (i = bindings.begin(); i != bindings.end(); ++i) {
XMLNode *child;
child = new XMLNode ("binding");
child->add_property ("keys", i->first);
child->add_property ("action", i->second);
node->add_child_nocopy (*child);
}
return *node;
}
int
KeyboardTarget::set_binding_state (const XMLNode& node)
{
XMLNodeList nlist = node.children();
XMLNodeConstIterator niter;
XMLNode *child_node;
bindings.clear ();
keymap.clear ();
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
child_node = *niter;
if (child_node->name() == "context") {
XMLProperty *prop;
if ((prop = child_node->property ("name")) != 0) {
if (prop->value() == _name) {
return load_bindings (*child_node);
}
}
}
}
return 0;
}
int
KeyboardTarget::load_bindings (const XMLNode& node)
{
XMLNodeList nlist = node.children();
XMLNodeConstIterator niter;
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
XMLProperty *keys;
XMLProperty *action;
keys = (*niter)->property ("keys");
action = (*niter)->property ("action");
if (!keys || !action) {
error << _("misformed binding node - ignored") << endmsg;
continue;
}
add_binding (keys->value(), action->value());
}
return 0;
}