GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
KeyboardTranslator.cpp
Go to the documentation of this file.
1/*
2 This source file was part of Konsole, a terminal emulator.
3
4 Copyright (C) 2007, 2013 by Robert Knight <robertknight@gmail.com>
5
6 Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301 USA.
22*/
23
24// Own
26
27// System
28#include <ctype.h>
29#include <stdio.h>
30
31// Qt
32#include <QtCore/QBuffer>
33#include <QtCore/QFile>
34#include <QtCore/QFileInfo>
35#include <QtCore>
36#include <QtGui>
37
38// FIXME: We should not have a special case for Mac here. Instead, we
39// should be loading .keytab files at run time, and ideally, allowing
40// individual keys to be redefined from some preferences menu.
41
42//and this is default now translator - default.keytab from original Konsole
44#if defined (Q_OS_MAC)
46#else
48#endif
49;
50
52 : _haveLoadedAll(false)
53{
54}
56{
57 qDeleteAll(_translators.values());
58}
60{
61 return QString("kb-layouts/" + name + ".keytab");
62}
64{
65 QDir dir("kb-layouts/");
66 QStringList filters;
67 filters << "*.keytab";
68 dir.setNameFilters(filters);
69 QStringList list = dir.entryList(filters); //(".keytab"); // = KGlobal::dirs()->findAllResources("data",
70 // "konsole/*.keytab",
71 // KStandardDirs::NoDuplicates);
72 list = dir.entryList(filters);
73 // add the name of each translator to the list and associated
74 // the name with a null pointer to indicate that the translator
75 // has not yet been loaded from disk
76 QStringListIterator listIter(list);
77 while (listIter.hasNext())
78 {
79 QString translatorPath = listIter.next();
80
81 QString name = QFileInfo(translatorPath).baseName();
82
83 if ( !_translators.contains(name) ) {
84 _translators.insert(name,nullptr);
85 }
86 }
87 _haveLoadedAll = true;
88}
89
91{
92 if ( name.isEmpty() )
93 return defaultTranslator();
94
95 //here was smth wrong in original Konsole source
97
98 if ( _translators.contains(name) && _translators[name] != nullptr ) {
99 return _translators[name];
100 }
101
103
104 if ( translator != nullptr )
105 _translators[name] = translator;
106 else if ( !name.isEmpty() )
107 qWarning() << "Unable to load translator" << name;
108
109 return translator;
110}
111
113{
114 const QString path = ".keytab";// = KGlobal::dirs()->saveLocation("data","konsole/")+translator->name()
115 // +".keytab";
116
117 qDebug() << "Saving translator to" << path;
118
119 QFile destination(path);
120
121 if (!destination.open(QIODevice::WriteOnly | QIODevice::Text))
122 {
123 qWarning() << "Unable to save keyboard translation:"
124 << destination.errorString();
125
126 return false;
127 }
128
129 {
130 KeyboardTranslatorWriter writer(&destination);
131 writer.writeHeader(translator->description());
132
133 QListIterator<KeyboardTranslator::Entry> iter(translator->entries());
134 while ( iter.hasNext() )
135 writer.writeEntry(iter.next());
136 }
137
138 destination.close();
139
140 return true;
141}
142
144{
145 const QString& path = findTranslatorPath(name);
146
147 QFile source(path);
148
149 if (name.isEmpty() || !source.open(QIODevice::ReadOnly | QIODevice::Text))
150 return nullptr;
151
152 return loadTranslator(&source,name);
153}
154
156{
157 QBuffer textBuffer;
159
160 if (!textBuffer.open(QIODevice::ReadOnly))
161 return nullptr;
162
163 return loadTranslator(&textBuffer,"fallback");
164}
165
167{
168 KeyboardTranslator* translator = new KeyboardTranslator(name);
169 KeyboardTranslatorReader reader(source);
170 translator->setDescription( reader.description() );
171
172 while ( reader.hasNextEntry() ) {
173 translator->addEntry(reader.nextEntry());
174 }
175
176 source->close();
177
178 if ( !reader.parseError() )
179 {
180 return translator;
181 }
182 else
183 {
184 delete translator;
185 return nullptr;
186 }
187}
188
190 : _destination(destination)
191{
192 Q_ASSERT( destination && destination->isWritable() );
193
194 _writer = new QTextStream(_destination);
195}
197{
198 delete _writer;
199}
200void KeyboardTranslatorWriter::writeHeader( const QString& description )
201{
202 *_writer << "keyboard \"" << description << '\"' << '\n';
203}
205{
206 QString result;
207
208 if ( entry.command() != KeyboardTranslator::NoCommand )
209 result = entry.resultToString();
210 else
211 result = '\"' + entry.resultToString() + '\"';
212
213 *_writer << "key " << entry.conditionToString() << " : " << result << '\n';
214}
215
216
217// each line of the keyboard translation file is one of:
218//
219// - keyboard "name"
220// - key KeySequence : "characters"
221// - key KeySequence : CommandName
222//
223// KeySequence begins with the name of the key ( taken from the Qt::Key enum )
224// and is followed by the keyboard modifiers and state flags ( with + or - in front
225// of each modifier or flag to indicate whether it is required ). All keyboard modifiers
226// and flags are optional, if a particular modifier or state is not specified it is
227// assumed not to be a part of the sequence. The key sequence may contain whitespace
228//
229// eg: "key Up+Shift : scrollLineUp"
230// "key Next-Shift : "\E[6~"
231//
232// (lines containing only whitespace are ignored, parseLine assumes that comments have
233// already been removed)
234//
235
237 : _source(source)
238 , _hasNext(false)
239{
240 // read input until we find the description
241 while ( _description.isEmpty() && !source->atEnd() )
242 {
243 const QList<Token>& tokens = tokenize( QString(source->readLine()) );
244
245 if ( !tokens.isEmpty() && tokens.first().type == Token::TitleKeyword )
246 {
247 _description = (tokens[1].text.toUtf8());
248 }
249 }
250
251 readNext();
252}
254{
255 // find next entry
256 while ( !_source->atEnd() )
257 {
258 const QList<Token>& tokens = tokenize( QString(_source->readLine()) );
259 if ( !tokens.isEmpty() && tokens.first().type == Token::KeyKeyword )
260 {
261 KeyboardTranslator::States flags = KeyboardTranslator::NoState;
262 KeyboardTranslator::States flagMask = KeyboardTranslator::NoState;
263 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
264 Qt::KeyboardModifiers modifierMask = Qt::NoModifier;
265
266 int keyCode = Qt::Key_unknown;
267
268 decodeSequence(tokens[1].text.toLower(),
269 keyCode,
270 modifiers,
271 modifierMask,
272 flags,
273 flagMask);
274
276 QByteArray text;
277
278 // get text or command
279 if ( tokens[2].type == Token::OutputText )
280 {
281 text = tokens[2].text.toLocal8Bit();
282 }
283 else if ( tokens[2].type == Token::Command )
284 {
285 // identify command
286 if (!parseAsCommand(tokens[2].text,command))
287 qWarning() << "Command" << tokens[2].text << "not understood.";
288 }
289
291 newEntry.setKeyCode( keyCode );
292 newEntry.setState( flags );
293 newEntry.setStateMask( flagMask );
294 newEntry.setModifiers( modifiers );
295 newEntry.setModifierMask( modifierMask );
296 newEntry.setText( text );
297 newEntry.setCommand( command );
298
299 _nextEntry = newEntry;
300
301 _hasNext = true;
302
303 return;
304 }
305 }
306
307 _hasNext = false;
308}
309
311{
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 )
324 else
325 return false;
326
327 return true;
328}
329
331 int& keyCode,
332 Qt::KeyboardModifiers& modifiers,
333 Qt::KeyboardModifiers& modifierMask,
334 KeyboardTranslator::States& flags,
335 KeyboardTranslator::States& flagMask)
336{
337 bool isWanted = true;
338 bool endOfItem = false;
339 QString buffer;
340
341 Qt::KeyboardModifiers tempModifiers = modifiers;
342 Qt::KeyboardModifiers tempModifierMask = modifierMask;
343 KeyboardTranslator::States tempFlags = flags;
344 KeyboardTranslator::States tempFlagMask = flagMask;
345
346 for ( int i = 0 ; i < text.count() ; i++ )
347 {
348 const QChar& ch = text[i];
349 bool isLastLetter = ( i == text.count()-1 );
350
351 endOfItem = true;
352 if ( ch.isLetterOrNumber() )
353 {
354 endOfItem = false;
355 buffer.append(ch);
356 }
357
358 if ( (endOfItem || isLastLetter) && !buffer.isEmpty() )
359 {
360 Qt::KeyboardModifier itemModifier = Qt::NoModifier;
361 int itemKeyCode = 0;
363
364 if ( parseAsModifier(buffer,itemModifier) )
365 {
366 tempModifierMask |= itemModifier;
367
368 if ( isWanted )
369 tempModifiers |= itemModifier;
370 }
371 else if ( parseAsStateFlag(buffer,itemFlag) )
372 {
373 tempFlagMask |= itemFlag;
374
375 if ( isWanted )
376 tempFlags |= itemFlag;
377 }
378 else if ( parseAsKeyCode(buffer,itemKeyCode) )
379 keyCode = itemKeyCode;
380 else
381 qDebug() << "Unable to parse key binding item:" << buffer;
382
383 buffer.clear();
384 }
385
386 // check if this is a wanted / not-wanted flag and update the
387 // state ready for the next item
388 if ( ch == '+' )
389 isWanted = true;
390 else if ( ch == '-' )
391 isWanted = false;
392 }
393
394 modifiers = tempModifiers;
395 modifierMask = tempModifierMask;
396 flags = tempFlags;
397 flagMask = tempFlagMask;
398
399 return true;
400}
401
402bool KeyboardTranslatorReader::parseAsModifier(const QString& item , Qt::KeyboardModifier& modifier)
403{
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;
414 else
415 return false;
416
417 return true;
418}
420{
421 if ( item == "appcukeys" )
423 else if ( item == "ansi" )
425 else if ( item == "newline" )
427 else if ( item == "appscreen" )
429 else if ( item == "anymod" )
431 else
432 return false;
433
434 return true;
435}
436bool KeyboardTranslatorReader::parseAsKeyCode(const QString& item , int& keyCode)
437{
438 QKeySequence sequence = QKeySequence::fromString(item);
439 if ( !sequence.isEmpty() )
440 {
441 keyCode = sequence[0];
442
443 if ( sequence.count() > 1 )
444 {
445 qDebug() << "Unhandled key codes in sequence: " << item;
446 }
447 }
448 // additional cases implemented for backwards compatibility with KDE 3
449 else if ( item == "prior" )
450 keyCode = Qt::Key_PageUp;
451 else if ( item == "next" )
452 keyCode = Qt::Key_PageDown;
453 else
454 return false;
455
456 return true;
457}
458
460{
461 return _description;
462}
464{
465 return _hasNext;
466}
468 const QString& result )
469{
470 QString entryString("keyboard \"temporary\"\nkey ");
471 entryString.append(condition);
472 entryString.append(" : ");
473
474 // if 'result' is the name of a command then the entry result will be that command,
475 // otherwise the result will be treated as a string to echo when the key sequence
476 // specified by 'condition' is pressed
478 if (parseAsCommand(result,command))
479 entryString.append(result);
480 else
481 entryString.append('\"' + result + '\"');
482
483 QByteArray array = entryString.toUtf8();
484
486
487 QBuffer buffer(&array);
488 buffer.open(QIODevice::ReadOnly);
489 KeyboardTranslatorReader reader(&buffer);
490
491 if ( reader.hasNextEntry() )
492 entry = reader.nextEntry();
493
494 return entry;
495}
496
498{
499 Q_ASSERT( _hasNext );
500
501
503
504 readNext();
505
506 return entry;
507}
509{
510 return false;
511}
513{
514 QString text = line.simplified();
515
516 // comment line: # comment
517 static QRegExp comment("\\#.*");
518 // title line: keyboard "title"
519 static QRegExp title("keyboard\\s+\"(.*)\"");
520 // key line: key KeySequence : "output"
521 // key line: key KeySequence : command
522 static QRegExp key("key\\s+([\\w\\+\\s\\-]+)\\s*:\\s*(\"(.*)\"|\\w+)");
523
524 QList<Token> list;
525
526 if ( text.isEmpty() || comment.exactMatch(text) )
527 {
528 return list;
529 }
530
531 if ( title.exactMatch(text) )
532 {
533 Token titleToken = { Token::TitleKeyword , QString() };
534 Token textToken = { Token::TitleText , title.capturedTexts()[1] };
535
536 list << titleToken << textToken;
537 }
538 else if ( key.exactMatch(text) )
539 {
540 Token keyToken = { Token::KeyKeyword , QString() };
541 Token sequenceToken = { Token::KeySequence , key.capturedTexts()[1].remove(' ') };
542
543 list << keyToken << sequenceToken;
544
545 if ( key.capturedTexts()[3].isEmpty() )
546 {
547 // capturedTexts()[2] is a command
548 Token commandToken = { Token::Command , key.capturedTexts()[2] };
549 list << commandToken;
550 }
551 else
552 {
553 // capturedTexts()[3] is the output string
554 Token outputToken = { Token::OutputText , key.capturedTexts()[3] };
555 list << outputToken;
556 }
557 }
558 else
559 {
560 qWarning() << "Line in keyboard translator file could not be understood:" << text;
561 }
562
563 return list;
564}
565
567{
568 if ( !_haveLoadedAll )
569 {
571 }
572
573 return _translators.keys();
574}
575
577 : _keyCode(0)
578 , _modifiers(Qt::NoModifier)
579 , _modifierMask(Qt::NoModifier)
580 , _state(NoState)
581 , _stateMask(NoState)
582 , _command(NoCommand)
583{
584}
585
587{
588 return _keyCode == rhs._keyCode &&
589 _modifiers == rhs._modifiers &&
590 _modifierMask == rhs._modifierMask &&
591 _state == rhs._state &&
592 _stateMask == rhs._stateMask &&
593 _command == rhs._command &&
594 _text == rhs._text;
595}
596
598 Qt::KeyboardModifiers modifiers,
599 States state) const
600{
601 if ( _keyCode != keyCode )
602 return false;
603
604 if ( (modifiers & _modifierMask) != (_modifiers & _modifierMask) )
605 return false;
606
607 // if modifiers is non-zero, the 'any modifier' state is implicit
608 if ( modifiers != 0 )
610
611 if ( (state & _stateMask) != (_state & _stateMask) )
612 return false;
613
614 // special handling for the 'Any Modifier' state, which checks for the presence of
615 // any or no modifiers. In this context, the 'keypad' modifier does not count.
616 bool anyModifiersSet = modifiers != 0 && modifiers != Qt::KeypadModifier;
617 if ( _stateMask & KeyboardTranslator::AnyModifierState )
618 {
619 // test fails if any modifier is required but none are set
620 if ( (_state & KeyboardTranslator::AnyModifierState) && !anyModifiersSet )
621 return false;
622
623 // test fails if no modifier is allowed but one or more are set
624 if ( !(_state & KeyboardTranslator::AnyModifierState) && anyModifiersSet )
625 return false;
626 }
627
628 return true;
629}
630QByteArray KeyboardTranslator::Entry::escapedText(bool expandWildCards,Qt::KeyboardModifiers modifiers) const
631{
632 QByteArray result(text(expandWildCards,modifiers));
633
634 for ( int i = 0 ; i < result.count() ; i++ )
635 {
636 char ch = result[i];
637 char replacement = 0;
638
639 switch ( ch )
640 {
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;
647 default:
648 // any character which is not printable is replaced by an equivalent
649 // \xhh escape sequence (where 'hh' are the corresponding hex digits)
650 if ( !QChar(ch).isPrint() )
651 replacement = 'x';
652 }
653
654 if ( replacement == 'x' )
655 {
656 result.replace(i,1,"\\x"+QByteArray::number(QByteArray(1,ch).toInt(nullptr, 16)));
657 } else if ( replacement != 0 )
658 {
659 result.remove(i,1);
660 result.insert(i,'\\');
661 result.insert(i+1,replacement);
662 }
663 }
664
665 return result;
666}
667QByteArray KeyboardTranslator::Entry::unescape(const QByteArray& input) const
668{
669 QByteArray result(input);
670
671 for ( int i = 0 ; i < result.count()-1 ; i++ )
672 {
673
674 QByteRef ch = result[i];
675 if ( ch == '\\' )
676 {
677 char replacement[2] = {0,0};
678 int charsToRemove = 2;
679 bool escapedChar = true;
680
681 switch ( result[i+1] )
682 {
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;
689 case 'x' :
690 {
691 // format is \xh or \xhh where 'h' is a hexadecimal
692 // digit from 0-9 or A-F which should be replaced
693 // with the corresponding character value
694 char hexDigits[3] = {0};
695
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];
700
701 int charValue = 0;
702 sscanf(hexDigits,"%x",&charValue);
703
704 replacement[0] = (char)charValue;
705
706 charsToRemove = 2 + strlen(hexDigits);
707 }
708 break;
709 default:
710 escapedChar = false;
711 }
712
713 if ( escapedChar )
714 result.replace(i,charsToRemove,replacement);
715 }
716 }
717
718 return result;
719}
720
721void KeyboardTranslator::Entry::insertModifier( QString& item , int modifier ) const
722{
723 if ( !(modifier & _modifierMask) )
724 return;
725
726 if ( modifier & _modifiers )
727 item += '+';
728 else
729 item += '-';
730
731 if ( modifier == Qt::ShiftModifier )
732 item += "Shift";
733 else if ( modifier == Qt::ControlModifier )
734 item += "Ctrl";
735 else if ( modifier == Qt::AltModifier )
736 item += "Alt";
737 else if ( modifier == Qt::MetaModifier )
738 item += "Meta";
739 else if ( modifier == Qt::KeypadModifier )
740 item += "KeyPad";
741}
742void KeyboardTranslator::Entry::insertState( QString& item , int state ) const
743{
744 if ( !(state & _stateMask) )
745 return;
746
747 if ( state & _state )
748 item += '+' ;
749 else
750 item += '-' ;
751
753 item += "AppScreen";
755 item += "NewLine";
757 item += "Ansi";
759 item += "AppCuKeys";
761 item += "AnyMod";
762}
763QString KeyboardTranslator::Entry::resultToString(bool expandWildCards,Qt::KeyboardModifiers modifiers) const
764{
765 if ( !_text.isEmpty() )
766 return escapedText(expandWildCards,modifiers);
767 else if ( _command == EraseCommand )
768 return "Erase";
769 else if ( _command == ScrollPageUpCommand )
770 return "ScrollPageUp";
771 else if ( _command == ScrollPageDownCommand )
772 return "ScrollPageDown";
773 else if ( _command == ScrollLineUpCommand )
774 return "ScrollLineUp";
775 else if ( _command == ScrollLineDownCommand )
776 return "ScrollLineDown";
777 else if ( _command == ScrollLockCommand )
778 return "ScrollLock";
779
780 return QString();
781}
783{
784 QString result = QKeySequence(_keyCode).toString();
785
786 // add modifiers
787 insertModifier( result , Qt::ShiftModifier );
788 insertModifier( result , Qt::ControlModifier );
789 insertModifier( result , Qt::AltModifier );
790 insertModifier( result , Qt::MetaModifier );
791
792 // add states
793 insertState( result , KeyboardTranslator::AlternateScreenState );
794 insertState( result , KeyboardTranslator::NewLineState );
795 insertState( result , KeyboardTranslator::AnsiState );
796 insertState( result , KeyboardTranslator::CursorKeysState );
797 insertState( result , KeyboardTranslator::AnyModifierState );
798
799 return result;
800}
801
803 : _name(name)
804{
805}
806
807void KeyboardTranslator::setDescription(const QString& description)
808{
810}
812{
813 return _description;
814}
816{
817 _name = name;
818}
820{
821 return _name;
822}
823
825{
826 return _entries.values();
827}
828
830{
831 const int keyCode = entry.keyCode();
832 _entries.insert(keyCode,entry);
833}
834void KeyboardTranslator::replaceEntry(const Entry& existing , const Entry& replacement)
835{
836 if ( !existing.isNull() )
837 _entries.remove(existing.keyCode());
838 _entries.insert(replacement.keyCode(),replacement);
839}
841{
842 _entries.remove(entry.keyCode());
843}
844KeyboardTranslator::Entry KeyboardTranslator::findEntry(int keyCode, Qt::KeyboardModifiers modifiers, States state) const
845{
846 if ( _entries.contains(keyCode) )
847 {
848 QList<Entry> entriesForKey = _entries.values(keyCode);
849
850 QListIterator<Entry> iter(entriesForKey);
851
852 while (iter.hasNext())
853 {
854 const Entry& next = iter.next();
855 if ( next.matches(keyCode,modifiers,state) )
856 return next;
857 }
858
859 return Entry(); // entry not found
860 }
861 else
862 {
863 return Entry();
864 }
865
866}
868{
869 _translators.insert(translator->name(),translator);
870
871 if ( !saveTranslator(translator) )
872 qWarning() << "Unable to save translator" << translator->name()
873 << "to disk.";
874}
876{
877 Q_ASSERT( _translators.contains(name) );
878
879 // locate and delete
880 QString path = findTranslatorPath(name);
881 if ( QFile::remove(path) )
882 {
883 _translators.remove(name);
884 return true;
885 }
886 else
887 {
888 qWarning() << "Failed to remove translator - " << path;
889 return false;
890 }
891}
892K_GLOBAL_STATIC( KeyboardTranslatorManager , theKeyboardTranslatorManager )
894{
895 return theKeyboardTranslatorManager;
896}
#define K_GLOBAL_STATIC(TYPE, NAME)
Manages the keyboard translations available for use by terminal sessions, see KeyboardTranslator.
KeyboardTranslatorManager()
Constructs a new KeyboardTranslatorManager and loads the list of available keyboard translations.
static const char * defaultTranslatorText
const KeyboardTranslator * defaultTranslator()
Returns the default translator for Konsole.
QList< QString > allTranslators()
Returns a list of the names of available keyboard translators.
bool saveTranslator(const KeyboardTranslator *translator)
QString findTranslatorPath(const QString &name)
KeyboardTranslator * loadTranslator(const QString &name)
const KeyboardTranslator * findTranslator(const QString &name)
Returns the keyboard translator with the given name or 0 if no translator with that name exists.
QHash< QString, KeyboardTranslator * > _translators
void addTranslator(KeyboardTranslator *translator)
Adds a new translator.
bool deleteTranslator(const QString &name)
Deletes a translator.
Parses the contents of a Keyboard Translator (.keytab) file and returns the entries found in it.
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.
KeyboardTranslatorReader(QIODevice *source)
Constructs a new reader which parses the given source.
static bool parseAsStateFlag(const QString &item, KeyboardTranslator::State &state)
QList< Token > tokenize(const QString &)
static bool parseAsKeyCode(const QString &item, int &keyCode)
bool parseError()
Returns true if an error occurred whilst parsing the input or false if no error occurred.
KeyboardTranslator::Entry _nextEntry
static bool parseAsModifier(const QString &item, Qt::KeyboardModifier &modifier)
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)
bool hasNextEntry()
Returns true if there is another entry in the source stream.
KeyboardTranslator::Entry nextEntry()
Returns the next entry found in the source stream.
QString description() const
Returns the description text.
Writes a keyboard translation to disk.
void writeHeader(const QString &description)
Writes the header for the keyboard translator.
void writeEntry(const KeyboardTranslator::Entry &entry)
Writes a translator entry.
KeyboardTranslatorWriter(QIODevice *destination)
Constructs a new writer which saves data into destination.
Represents an association between a key sequence pressed by the user and the character sequence and c...
void setModifiers(Qt::KeyboardModifiers modifiers)
See modifiers()
QByteArray unescape(const QByteArray &text) const
void insertState(QString &item, int state) const
QString resultToString(bool expandWildCards=false, Qt::KeyboardModifiers modifiers=Qt::NoModifier) const
Returns this entry's result ( ie.
void setText(const QByteArray &text)
Sets the character sequence associated with this entry.
QString conditionToString() const
Returns the key code and modifiers associated with this entry as a QKeySequence.
void setKeyCode(int keyCode)
Sets the character code associated with this entry.
Qt::KeyboardModifiers _modifiers
Command command() const
Returns the commands associated with this entry.
Qt::KeyboardModifiers _modifierMask
int keyCode() const
Returns the character code ( from the Qt::Key enum ) associated with this entry.
bool isNull() const
Returns true if this entry is null.
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 ,...
bool operator==(const Entry &rhs) const
void setStateMask(States mask)
See stateMask()
void setCommand(Command command)
Sets the command associated with this entry.
void insertModifier(QString &item, int modifier) const
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...
void setState(States state)
See state()
void setModifierMask(Qt::KeyboardModifiers modifiers)
See modifierMask() and modifiers()
Entry()
Constructs a new entry for a keyboard translator.
A convertor which maps between key sequences pressed by the user and the character strings which shou...
QString name() const
Returns the name of this keyboard translator.
State
The meaning of a particular key sequence may depend upon the state which the terminal emulation is in...
@ NewLineState
TODO More documentation.
@ NoState
Indicates that no special state is active.
@ AnyModifierState
Indicates that any of the modifier keys is active.
@ AnsiState
Indicates that the terminal is in 'Ansi' mode.
@ AlternateScreenState
Indicates that the alternate screen ( typically used by interactive programs such as screen or vim ) ...
@ CursorKeysState
TODO More documentation.
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...
QString description() const
Returns the descriptive name of this keyboard translator.
Command
This enum describes commands which are associated with particular key sequences.
@ ScrollLineUpCommand
Scroll the terminal display up one line.
@ EraseCommand
Echos the operating system specific erase character.
@ ScrollPageUpCommand
Scroll the terminal display up one page.
@ ScrollPageDownCommand
Scroll the terminal display down one page.
@ NoCommand
Indicates that no command is associated with this command sequence.
@ ScrollLockCommand
Toggles scroll lock mode.
@ ScrollLineDownCommand
Scroll the terminal display down one line.
void replaceEntry(const Entry &existing, const Entry &replacement)
Replaces an entry in the translator.
void setName(const QString &name)
Sets the name of this keyboard translator.
QList< Entry > entries() const
Returns a list of all entries in the translator.
KeyboardTranslator(const QString &name)
Constructs a new keyboard translator with the given name.
QMultiHash< int, Entry > _entries
void setDescription(const QString &description)
Sets the descriptive name of this keyboard translator.
void addEntry(const Entry &entry)
Adds an entry to this keyboard translator's table.
void removeEntry(const Entry &entry)
Removes an entry from the table.
QString path
QString name
static uint32_t state[624]
Definition: randmtzig.cc:192
static uint32_t * next
Definition: randmtzig.cc:191
T::size_type strlen(const typename T::value_type *str)
Definition: oct-string.cc:85
static int input(yyscan_t yyscanner)