Logo Search packages:      
Sourcecode: ardour version File versions  Download package

keyboard_target.cc

/*
    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: keyboard_target.cc,v 1.27 2005/07/18 23:22:48 sampo Exp $
*/

#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 = 0;

      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 << compose(_("KeyboardTarget: no translation found for \"%1\""), keystring) << endmsg;
            return -1;
      }

      if (find_action (action, key_action)) {
            error << 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;
}


Generated by  Doxygen 1.6.0   Back to index