32 #include <QtCore/QBuffer>
33 #include <QtCore/QFile>
34 #include <QtCore/QFileInfo>
44 #if defined (Q_OS_MAC)
52 : _haveLoadedAll(false)
61 return QString(
"kb-layouts/" + name +
".keytab");
65 QDir dir(
"kb-layouts/");
67 filters <<
"*.keytab";
68 dir.setNameFilters(filters);
69 QStringList list = dir.entryList(filters);
72 list = dir.entryList(filters);
76 QStringListIterator listIter(list);
77 while (listIter.hasNext())
79 QString translatorPath = listIter.next();
81 QString name = QFileInfo(translatorPath).baseName();
104 if ( translator != 0 )
106 else if ( !name.isEmpty() )
107 qWarning() <<
"Unable to load translator" << name;
114 const QString path =
".keytab";
117 qDebug() <<
"Saving translator to" << path;
119 QFile destination(path);
121 if (!destination.open(QIODevice::WriteOnly | QIODevice::Text))
123 qWarning() <<
"Unable to save keyboard translation:"
124 << destination.errorString();
133 QListIterator<KeyboardTranslator::Entry> iter(translator->
entries());
134 while ( iter.hasNext() )
149 if (name.isEmpty() || !source.open(QIODevice::ReadOnly | QIODevice::Text))
160 if (!textBuffer.open(QIODevice::ReadOnly))
190 : _destination(destination)
192 Q_ASSERT( destination && destination->isWritable() );
202 *
_writer <<
"keyboard \"" << description <<
'\"' <<
'\n';
263 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
264 Qt::KeyboardModifiers modifierMask = Qt::NoModifier;
266 int keyCode = Qt::Key_unknown;
281 text = tokens[2].text.toLocal8Bit();
287 qWarning() <<
"Command" << tokens[2].text <<
"not understood.";
312 if ( text.compare(
"erase",Qt::CaseInsensitive) == 0 )
314 else if ( text.compare(
"scrollpageup",Qt::CaseInsensitive) == 0 )
316 else if ( text.compare(
"scrollpagedown",Qt::CaseInsensitive) == 0 )
318 else if ( text.compare(
"scrolllineup",Qt::CaseInsensitive) == 0 )
320 else if ( text.compare(
"scrolllinedown",Qt::CaseInsensitive) == 0 )
322 else if ( text.compare(
"scrolllock",Qt::CaseInsensitive) == 0 )
332 Qt::KeyboardModifiers& modifiers,
333 Qt::KeyboardModifiers& modifierMask,
334 KeyboardTranslator::States& flags,
335 KeyboardTranslator::States& flagMask)
337 bool isWanted =
true;
338 bool endOfItem =
false;
341 Qt::KeyboardModifiers tempModifiers = modifiers;
342 Qt::KeyboardModifiers tempModifierMask = modifierMask;
343 KeyboardTranslator::States tempFlags = flags;
344 KeyboardTranslator::States tempFlagMask = flagMask;
346 for (
int i = 0 ; i < text.count() ; i++ )
348 const QChar& ch = text[i];
349 bool isLastLetter = ( i == text.count()-1 );
352 if ( ch.isLetterOrNumber() )
358 if ( (endOfItem || isLastLetter) && !buffer.isEmpty() )
360 Qt::KeyboardModifier itemModifier = Qt::NoModifier;
366 tempModifierMask |= itemModifier;
369 tempModifiers |= itemModifier;
373 tempFlagMask |= itemFlag;
376 tempFlags |= itemFlag;
379 keyCode = itemKeyCode;
381 qDebug() <<
"Unable to parse key binding item:" << buffer;
390 else if ( ch ==
'-' )
394 modifiers = tempModifiers;
395 modifierMask = tempModifierMask;
397 flagMask = tempFlagMask;
404 if ( item ==
"shift" )
405 modifier = Qt::ShiftModifier;
406 else if ( item ==
"ctrl" || item ==
"control" )
407 modifier = Qt::ControlModifier;
408 else if ( item ==
"alt" )
409 modifier = Qt::AltModifier;
410 else if ( item ==
"meta" )
411 modifier = Qt::MetaModifier;
412 else if ( item ==
"keypad" )
413 modifier = Qt::KeypadModifier;
421 if ( item ==
"appcukeys" )
423 else if ( item ==
"ansi" )
425 else if ( item ==
"newline" )
427 else if ( item ==
"appscreen" )
429 else if ( item ==
"anymod" )
438 QKeySequence sequence = QKeySequence::fromString(item);
439 if ( !sequence.isEmpty() )
441 keyCode = sequence[0];
443 if ( sequence.count() > 1 )
445 qDebug() <<
"Unhandled key codes in sequence: " << item;
449 else if ( item ==
"prior" )
450 keyCode = Qt::Key_PageUp;
451 else if ( item ==
"next" )
452 keyCode = Qt::Key_PageDown;
468 const QString& result )
470 QString entryString(
"keyboard \"temporary\"\nkey ");
471 entryString.append(condition);
472 entryString.append(
" : ");
479 entryString.append(result);
481 entryString.append(
'\"' + result +
'\"');
483 QByteArray array = entryString.toUtf8();
487 QBuffer buffer(&array);
488 buffer.open(QIODevice::ReadOnly);
514 QString
text = line.simplified();
517 static QRegExp comment(
"\\#.*");
519 static QRegExp title(
"keyboard\\s+\"(.*)\"");
522 static QRegExp key(
"key\\s+([\\w\\+\\s\\-]+)\\s*:\\s*(\"(.*)\"|\\w+)");
526 if ( text.isEmpty() || comment.exactMatch(text) )
531 if ( title.exactMatch(text) )
536 list << titleToken << textToken;
538 else if ( key.exactMatch(text) )
543 list << keyToken << sequenceToken;
545 if ( key.capturedTexts()[3].isEmpty() )
549 list << commandToken;
560 qWarning() <<
"Line in keyboard translator file could not be understood:" << text;
578 , _modifiers(Qt::NoModifier)
579 , _modifierMask(Qt::NoModifier)
581 , _stateMask(NoState)
582 , _command(NoCommand)
598 Qt::KeyboardModifiers modifiers,
601 if ( _keyCode != keyCode )
604 if ( (modifiers & _modifierMask) != (_modifiers & _modifierMask) )
608 if ( modifiers != 0 )
611 if ( (state & _stateMask) != (_state & _stateMask) )
616 bool anyModifiersSet = modifiers != 0 && modifiers != Qt::KeypadModifier;
620 if ( (_state & KeyboardTranslator::AnyModifierState) && !anyModifiersSet )
624 if ( !(_state & KeyboardTranslator::AnyModifierState) && anyModifiersSet )
632 QByteArray result(
text(expandWildCards,modifiers));
634 for (
int i = 0 ; i < result.count() ; i++ )
637 char replacement = 0;
641 case 27 : replacement =
'E';
break;
642 case 8 : replacement =
'b';
break;
643 case 12 : replacement =
'f';
break;
644 case 9 : replacement =
't';
break;
645 case 13 : replacement =
'r';
break;
646 case 10 : replacement =
'n';
break;
650 if ( !QChar(ch).isPrint() )
654 if ( replacement ==
'x' )
656 result.replace(i,1,
"\\x"+QByteArray(1,ch).toInt(0, 16));
657 }
else if ( replacement != 0 )
660 result.insert(i,
'\\');
661 result.insert(i+1,replacement);
669 QByteArray result(input);
671 for (
int i = 0 ; i < result.count()-1 ; i++ )
674 QByteRef ch = result[i];
677 char replacement[2] = {0,0};
678 int charsToRemove = 2;
679 bool escapedChar =
true;
681 switch ( result[i+1] )
683 case 'E' : replacement[0] = 27;
break;
684 case 'b' : replacement[0] = 8 ;
break;
685 case 'f' : replacement[0] = 12;
break;
686 case 't' : replacement[0] = 9 ;
break;
687 case 'r' : replacement[0] = 13;
break;
688 case 'n' : replacement[0] = 10;
break;
694 char hexDigits[3] = {0};
696 if ( (i < result.count()-2) && isxdigit(result[i+2]) )
697 hexDigits[0] = result[i+2];
698 if ( (i < result.count()-3) && isxdigit(result[i+3]) )
699 hexDigits[1] = result[i+3];
702 sscanf(hexDigits,
"%x",&charValue);
704 replacement[0] = (
char)charValue;
706 charsToRemove = 2 + strlen(hexDigits);
714 result.replace(i,charsToRemove,replacement);
723 if ( !(modifier & _modifierMask) )
726 if ( modifier & _modifiers )
731 if ( modifier == Qt::ShiftModifier )
733 else if ( modifier == Qt::ControlModifier )
735 else if ( modifier == Qt::AltModifier )
737 else if ( modifier == Qt::MetaModifier )
739 else if ( modifier == Qt::KeypadModifier )
744 if ( !(state & _stateMask) )
747 if ( state & _state )
765 if ( !_text.isEmpty() )
766 return escapedText(expandWildCards,modifiers);
770 return "ScrollPageUp";
772 return "ScrollPageDown";
774 return "ScrollLineUp";
776 return "ScrollLineDown";
784 QString result = QKeySequence(_keyCode).toString();
787 insertModifier( result , Qt::ShiftModifier );
788 insertModifier( result , Qt::ControlModifier );
789 insertModifier( result , Qt::AltModifier );
790 insertModifier( result , Qt::MetaModifier );
831 const int keyCode = entry.
keyCode();
832 _entries.insertMulti(keyCode,entry);
850 QListIterator<Entry> iter(entriesForKey);
852 while (iter.hasNext())
855 if ( next.
matches(keyCode,modifiers,state) )
872 qWarning() <<
"Unable to save translator" << translator->
name()
881 if ( QFile::remove(path) )
888 qWarning() <<
"Failed to remove translator - " << path;
895 return theKeyboardTranslatorManager;
void setKeyCode(int keyCode)
Sets the character code associated with this entry.
QHash< int, Entry > _entries
Scroll the terminal display up one page.
~KeyboardTranslatorManager()
static const char * defaultTranslatorText
bool parseError()
Returns true if an error occurred whilst parsing the input or false if no error occurred.
Command
This enum describes commands which are associated with particular key sequences.
QByteArray escapedText(bool expandWildCards=false, Qt::KeyboardModifiers modifiers=Qt::NoModifier) const
Returns the character sequence associated with this entry, with any non-printable characters replaced...
Echos the operating system specific erase character.
Qt::KeyboardModifiers _modifierMask
QString resultToString(bool expandWildCards=false, Qt::KeyboardModifiers modifiers=Qt::NoModifier) const
Returns this entry's result ( ie.
Command command() const
Returns the commands associated with this entry.
static uint32_t state[624]
void writeHeader(const QString &description)
Writes the header for the keyboard translator.
Entry findEntry(int keyCode, Qt::KeyboardModifiers modifiers, States state=NoState) const
Looks for an entry in this keyboard translator which matches the given key code, keyboard modifiers a...
void insertModifier(QString &item, int modifier) const
void addTranslator(KeyboardTranslator *translator)
Adds a new translator.
bool isNull() const
Returns true if this entry is null.
QString findTranslatorPath(const QString &name)
Entry()
Constructs a new entry for a keyboard translator.
void setModifiers(Qt::KeyboardModifiers modifiers)
See modifiers()
Indicates that no special state is active.
bool deleteTranslator(const QString &name)
Deletes a translator.
bool operator==(const Entry &rhs) const
State
The meaning of a particular key sequence may depend upon the state which the terminal emulation is in...
KeyboardTranslator::Entry nextEntry()
Returns the next entry found in the source stream.
QString description() const
Returns the descriptive name of this keyboard translator.
const KeyboardTranslator * findTranslator(const QString &name)
Returns the keyboard translator with the given name or 0 if no translator with that name exists...
#define K_GLOBAL_STATIC(TYPE, NAME)
void writeEntry(const KeyboardTranslator::Entry &entry)
Writes a translator entry.
static bool parseAsStateFlag(const QString &item, KeyboardTranslator::State &state)
static bool parseAsModifier(const QString &item, Qt::KeyboardModifier &modifier)
void setText(const QByteArray &text)
Sets the character sequence associated with this entry.
KeyboardTranslatorWriter(QIODevice *destination)
Constructs a new writer which saves data into destination.
KeyboardTranslator(const QString &name)
Constructs a new keyboard translator with the given name.
QList< QString > allTranslators()
Returns a list of the names of available keyboard translators.
QList< Entry > entries() const
Returns a list of all entries in the translator.
Manages the keyboard translations available for use by terminal sessions, see KeyboardTranslator.
QString description() const
Returns the description text.
Indicates that the alternate screen ( typically used by interactive programs such as screen or vim ) ...
Indicates that the terminal is in 'Ansi' mode.
bool saveTranslator(const KeyboardTranslator *translator)
void setStateMask(States mask)
See stateMask()
void setDescription(const QString &description)
Sets the descriptive name of this keyboard translator.
QList< Token > tokenize(const QString &)
Indicates that no command is associated with this command sequence.
Scroll the terminal display up one line.
void setCommand(Command command)
Sets the command associated with this entry.
void setName(const QString &name)
Sets the name of this keyboard translator.
const KeyboardTranslator * defaultTranslator()
Returns the default translator for Konsole.
A convertor which maps between key sequences pressed by the user and the character strings which shou...
void setModifierMask(Qt::KeyboardModifiers modifiers)
See modifierMask() and modifiers()
QString conditionToString() const
Returns the key code and modifiers associated with this entry as a QKeySequence.
KeyboardTranslator * loadTranslator(const QString &name)
Scroll the terminal display down one line.
Parses the contents of a Keyboard Translator (.keytab) file and returns the entries found in it...
bool hasNextEntry()
Returns true if there is another entry in the source stream.
QString name() const
Returns the name of this keyboard translator.
void setState(States state)
See state()
KeyboardTranslator::Entry _nextEntry
static bool parseAsCommand(const QString &text, KeyboardTranslator::Command &command)
bool decodeSequence(const QString &, int &keyCode, Qt::KeyboardModifiers &modifiers, Qt::KeyboardModifiers &modifierMask, KeyboardTranslator::States &state, KeyboardTranslator::States &stateFlags)
void replaceEntry(const Entry &existing, const Entry &replacement)
Replaces an entry in the translator.
Represents an association between a key sequence pressed by the user and the character sequence and c...
bool matches(int keyCode, Qt::KeyboardModifiers modifiers, States flags) const
Returns true if this entry matches the given key sequence, specified as a combination of keyCode ...
~KeyboardTranslatorWriter()
Writes a keyboard translation to disk.
KeyboardTranslatorManager()
Constructs a new KeyboardTranslatorManager and loads the list of available keyboard translations...
Indicates that any of the modifier keys is active.
static int input(yyscan_t yyscanner)
static KeyboardTranslator::Entry createEntry(const QString &condition, const QString &result)
Parses a condition and result string for a translator entry and produces a keyboard translator entry...
static bool parseAsKeyCode(const QString &item, int &keyCode)
QByteArray unescape(const QByteArray &text) const
Scroll the terminal display down one page.
QHash< QString, KeyboardTranslator * > _translators
int keyCode() const
Returns the character code ( from the Qt::Key enum ) associated with this entry.
void removeEntry(const Entry &entry)
Removes an entry from the table.
KeyboardTranslatorReader(QIODevice *source)
Constructs a new reader which parses the given source.
Toggles scroll lock mode.
Qt::KeyboardModifiers _modifiers
void insertState(QString &item, int state) const
void addEntry(const Entry &entry)
Adds an entry to this keyboard translator's table.