lyx_mirror/src/KeySequence.cpp
Stephan Witt e9d943aeb8 #7292 make the modifiers Option and Control act on there own on mac - adjust the key bindings to apple standards where possible
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37770 a592a061-630c-0410-9148-cb99ea01b6c8
2011-02-23 14:30:41 +00:00

214 lines
3.7 KiB
C++

/**
* \file KeySequence.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Lars Gullik Bjønnes
* \author Jean-Marc Lasgouttes
* \author John Levon
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "KeySequence.h"
#include "KeyMap.h"
#include "support/gettext.h"
#include "frontends/KeySymbol.h"
using namespace std;
namespace lyx {
FuncRequest const & KeySequence::addkey(KeySymbol const & key,
KeyModifier mod, KeyModifier nmod)
{
// adding a key to a deleted sequence
// starts a new sequence
if (deleted_) {
deleted_ = false;
sequence.clear();
modifiers.clear();
}
modifiers.push_back(make_pair(mod, nmod));
sequence.push_back(key);
if (curmap)
return curmap->lookup(key, mod, this);
return FuncRequest::unknown;
}
size_t KeySequence::parse(string const & s)
{
if (s.empty())
return 1;
size_t i = 0;
KeyModifier mod = NoModifier;
KeyModifier nmod = NoModifier;
while (i < s.length()) {
if (s[i] == ' ')
++i;
if (i >= s.length())
break;
if (i + 1 < s.length() && s[i + 1] == '-') {
switch (s[i]) {
case 's': case 'S':
mod |= ShiftModifier;
i += 2;
continue;
case 'c': case 'C':
mod |= ControlModifier;
i += 2;
continue;
case 'm': case 'M':
#if defined(USE_MACOSX_PACKAGING) || defined(USE_META_KEYBINDING)
mod |= MetaModifier;
i += 2;
continue;
#endif
case 'a': case 'A':
mod |= AltModifier;
i += 2;
continue;
default:
return i + 1;
}
} else if (i + 2 < s.length() && s[i] == '~'
&& s[i + 2] == '-') {
switch (s[i + 1]) {
case 's': case 'S':
nmod |= ShiftModifier;
i += 3;
continue;
case 'c': case 'C':
nmod |= ControlModifier;
i += 3;
continue;
case 'm': case 'M':
#if defined(USE_MACOSX_PACKAGING) || defined(USE_META_KEYBINDING)
nmod |= MetaModifier;
i += 3;
continue;
#endif
case 'a': case 'A':
nmod |= AltModifier;
i += 3;
continue;
default:
return i + 2;
}
} else {
string tbuf;
size_t j = i;
for (; j < s.length() && s[j] != ' '; ++j)
tbuf += s[j]; // (!!!check bounds :-)
KeySymbol key;
key.init(tbuf);
if (!key.isOK())
return j;
i = j;
addkey(key, mod, nmod);
mod = NoModifier;
}
}
// empty sequence?
if (sequence.size() == 0)
return 0;
// everything is fine
return string::npos;
}
docstring const KeySequence::print(outputFormat format) const
{
docstring buf;
size_t const length = sequence.size();
for (size_t i = 0; i != length; ++i) {
switch (format) {
case Portable:
buf += sequence[i].print(modifiers[i].first, false);
break;
case ForGui:
buf += sequence[i].print(modifiers[i].first, true);
break;
case BindFile:
KeyModifier mod = modifiers[i].first;
if (mod & ControlModifier)
buf += "C-";
if (mod & AltModifier)
#if defined(USE_MACOSX_PACKAGING) || defined(USE_META_KEYBINDING)
buf += "A-";
if (mod & MetaModifier)
#endif
buf += "M-";
if (mod & ShiftModifier)
buf += "S-";
buf += from_utf8(sequence[i].getSymbolName());
break;
}
// append a blank
if (i + 1 != length)
buf += ' ';
}
return buf;
}
docstring const KeySequence::printOptions(bool forgui) const
{
docstring buf = print(forgui ? ForGui : Portable);
if (!curmap)
return buf;
buf += _(" options: ");
buf += curmap->print(forgui ? ForGui : Portable);
return buf;
}
void KeySequence::reset()
{
deleted_ = true;
curmap = stdmap;
}
void KeySequence::clear()
{
sequence.clear();
reset();
}
void KeySequence::removeKey()
{
if (deleted_)
return;
sequence.pop_back();
modifiers.pop_back();
if (sequence.empty())
deleted_ = true;
}
} // namespace lyx