GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
KeyboardTranslator.h
Go to the documentation of this file.
1/*
2 This source file is 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#ifndef KEYBOARDTRANSLATOR_H
25#define KEYBOARDTRANSLATOR_H
26
27// Qt
28#include <QtCore/QHash>
29#include <QtCore/QMultiHash>
30#include <QtCore/QList>
31#include <QKeySequence>
32#include <QtCore/QMetaType>
33#include <QtCore/QVarLengthArray>
34#include <QtCore>
35
36#if QT_VERSION >= 0x050100
37# define K_GLOBAL_STATIC Q_GLOBAL_STATIC
38#else
39
40typedef void (*CleanUpFunction)();
41
42/**
43 * @internal
44 *
45 * Helper class for K_GLOBAL_STATIC to clean up the object on library unload or application
46 * shutdown.
47 */
49{
50 public:
52
53 inline ~CleanUpGlobalStatic() { func(); }
54};
55
56
57//these directives are taken from the heart of kdecore
58
59# define K_GLOBAL_STATIC_STRUCT_NAME(NAME)
60
61#if QT_VERSION < 0x040400
62# define Q_BASIC_ATOMIC_INITIALIZER Q_ATOMIC_INIT
63# define testAndSetOrdered testAndSet
64#endif
65
66#define K_GLOBAL_STATIC(TYPE, NAME) K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ())
67
68#define K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \
69static QBasicAtomicPointer<TYPE > _k_static_##NAME = Q_BASIC_ATOMIC_INITIALIZER(0); \
70static bool _k_static_##NAME##_destroyed; \
71static struct K_GLOBAL_STATIC_STRUCT_NAME(NAME) \
72{ \
73 bool isDestroyed() \
74 { \
75 return _k_static_##NAME##_destroyed; \
76 } \
77 inline operator TYPE*() \
78 { \
79 return operator->(); \
80 } \
81 inline TYPE *operator->() \
82 { \
83 if (!_k_static_##NAME) { \
84 if (isDestroyed()) { \
85 qFatal("Fatal Error: Accessed global static '%s *%s()' after destruction. " \
86 "Defined at %s:%d", #TYPE, #NAME, __FILE__, __LINE__); \
87 } \
88 TYPE *x = new TYPE ARGS; \
89 if (!_k_static_##NAME.testAndSetOrdered(0, x) \
90 && _k_static_##NAME != x ) { \
91 delete x; \
92 } else { \
93 static CleanUpGlobalStatic cleanUpObject = { destroy }; \
94 } \
95 } \
96 return _k_static_##NAME; \
97 } \
98 inline TYPE &operator*() \
99 { \
100 return *operator->(); \
101 } \
102 static void destroy() \
103 { \
104 _k_static_##NAME##_destroyed = true; \
105 TYPE *x = _k_static_##NAME; \
106 _k_static_##NAME = 0; \
107 delete x; \
108 } \
109} NAME;
110
111#endif
112
113class QIODevice;
114class QTextStream;
115
116/**
117 * A convertor which maps between key sequences pressed by the user and the
118 * character strings which should be sent to the terminal and commands
119 * which should be invoked when those character sequences are pressed.
120 *
121 * Konsole supports multiple keyboard translators, allowing the user to
122 * specify the character sequences which are sent to the terminal
123 * when particular key sequences are pressed.
124 *
125 * A key sequence is defined as a key code, associated keyboard modifiers
126 * (Shift,Ctrl,Alt,Meta etc.) and state flags which indicate the state
127 * which the terminal must be in for the key sequence to apply.
128 */
130{
131public:
132 /**
133 * The meaning of a particular key sequence may depend upon the state which
134 * the terminal emulation is in. Therefore findEntry() may return a different
135 * Entry depending upon the state flags supplied.
136 *
137 * This enum describes the states which may be associated with with a particular
138 * entry in the keyboard translation entry.
139 */
140 enum State
141 {
142 /** Indicates that no special state is active */
144 /**
145 * TODO More documentation
146 */
148 /**
149 * Indicates that the terminal is in 'Ansi' mode.
150 * TODO: More documentation
151 */
153 /**
154 * TODO More documentation
155 */
157 /**
158 * Indicates that the alternate screen ( typically used by interactive programs
159 * such as screen or vim ) is active
160 */
162 /** Indicates that any of the modifier keys is active. */
164 };
165 Q_DECLARE_FLAGS(States,State)
166
167 /**
168 * This enum describes commands which are associated with particular key sequences.
169 */
171 {
172 /** Indicates that no command is associated with this command sequence */
174 /** TODO Document me */
176 /** Scroll the terminal display up one page */
178 /** Scroll the terminal display down one page */
180 /** Scroll the terminal display up one line */
182 /** Scroll the terminal display down one line */
184 /** Toggles scroll lock mode */
186 /** Echos the operating system specific erase character. */
187 EraseCommand = 64
188 };
189 Q_DECLARE_FLAGS(Commands,Command)
190
191 /**
192 * Represents an association between a key sequence pressed by the user
193 * and the character sequence and commands associated with it for a particular
194 * KeyboardTranslator.
195 */
196 class Entry
197 {
198 public:
199 /**
200 * Constructs a new entry for a keyboard translator.
201 */
202 Entry();
203
204 /**
205 * Returns true if this entry is null.
206 * This is true for newly constructed entries which have no properties set.
207 */
208 bool isNull() const;
209
210 /** Returns the commands associated with this entry */
211 Command command() const;
212 /** Sets the command associated with this entry. */
213 void setCommand(Command command);
214
215 /**
216 * Returns the character sequence associated with this entry, optionally replacing
217 * wildcard '*' characters with numbers to indicate the keyboard modifiers being pressed.
218 *
219 * TODO: The numbers used to replace '*' characters are taken from the Konsole/KDE 3 code.
220 * Document them.
221 *
222 * @param expandWildCards Specifies whether wild cards (occurrences of the '*' character) in
223 * the entry should be replaced with a number to indicate the modifier keys being pressed.
224 *
225 * @param modifiers The keyboard modifiers being pressed.
226 */
227 QByteArray text(bool expandWildCards = false,
228 Qt::KeyboardModifiers modifiers = Qt::NoModifier) const;
229
230 /** Sets the character sequence associated with this entry */
231 void setText(const QByteArray& text);
232
233 /**
234 * Returns the character sequence associated with this entry,
235 * with any non-printable characters replaced with escape sequences.
236 *
237 * eg. \\E for Escape, \\t for tab, \\n for new line.
238 *
239 * @param expandWildCards See text()
240 * @param modifiers See text()
241 */
242 QByteArray escapedText(bool expandWildCards = false,
243 Qt::KeyboardModifiers modifiers = Qt::NoModifier) const;
244
245 /** Returns the character code ( from the Qt::Key enum ) associated with this entry */
246 int keyCode() const;
247 /** Sets the character code associated with this entry */
248 void setKeyCode(int keyCode);
249
250 /**
251 * Returns a bitwise-OR of the enabled keyboard modifiers associated with this entry.
252 * If a modifier is set in modifierMask() but not in modifiers(), this means that the entry
253 * only matches when that modifier is NOT pressed.
254 *
255 * If a modifier is not set in modifierMask() then the entry matches whether the modifier
256 * is pressed or not.
257 */
258 Qt::KeyboardModifiers modifiers() const;
259
260 /** Returns the keyboard modifiers which are valid in this entry. See modifiers() */
261 Qt::KeyboardModifiers modifierMask() const;
262
263 /** See modifiers() */
264 void setModifiers( Qt::KeyboardModifiers modifiers );
265 /** See modifierMask() and modifiers() */
266 void setModifierMask( Qt::KeyboardModifiers modifiers );
267
268 /**
269 * Returns a bitwise-OR of the enabled state flags associated with this entry.
270 * If flag is set in stateMask() but not in state(), this means that the entry only
271 * matches when the terminal is NOT in that state.
272 *
273 * If a state is not set in stateMask() then the entry matches whether the terminal
274 * is in that state or not.
275 */
276 States state() const;
277
278 /** Returns the state flags which are valid in this entry. See state() */
279 States stateMask() const;
280
281 /** See state() */
282 void setState( States state );
283 /** See stateMask() */
284 void setStateMask( States mask );
285
286 /**
287 * Returns the key code and modifiers associated with this entry
288 * as a QKeySequence
289 */
290 //QKeySequence keySequence() const;
291
292 /**
293 * Returns this entry's conditions ( ie. its key code, modifier and state criteria )
294 * as a string.
295 */
296 QString conditionToString() const;
297
298 /**
299 * Returns this entry's result ( ie. its command or character sequence )
300 * as a string.
301 *
302 * @param expandWildCards See text()
303 * @param modifiers See text()
304 */
305 QString resultToString(bool expandWildCards = false,
306 Qt::KeyboardModifiers modifiers = Qt::NoModifier) const;
307
308 /**
309 * Returns true if this entry matches the given key sequence, specified
310 * as a combination of @p keyCode , @p modifiers and @p state.
311 */
312 bool matches( int keyCode ,
313 Qt::KeyboardModifiers modifiers ,
314 States flags ) const;
315
316 bool operator==(const Entry& rhs) const;
317
318 private:
319 void insertModifier( QString& item , int modifier ) const;
320 void insertState( QString& item , int state ) const;
321 QByteArray unescape(const QByteArray& text) const;
322
324 Qt::KeyboardModifiers _modifiers;
325 Qt::KeyboardModifiers _modifierMask;
326 States _state;
328
330 QByteArray _text;
331 };
332
333 /** Constructs a new keyboard translator with the given @p name */
334 KeyboardTranslator(const QString& name);
335
336 //KeyboardTranslator(const KeyboardTranslator& other);
337
338 /** Returns the name of this keyboard translator */
339 QString name() const;
340
341 /** Sets the name of this keyboard translator */
342 void setName(const QString& name);
343
344 /** Returns the descriptive name of this keyboard translator */
345 QString description() const;
346
347 /** Sets the descriptive name of this keyboard translator */
348 void setDescription(const QString& description);
349
350 /**
351 * Looks for an entry in this keyboard translator which matches the given
352 * key code, keyboard modifiers and state flags.
353 *
354 * Returns the matching entry if found or a null Entry otherwise ( ie.
355 * entry.isNull() will return true )
356 *
357 * @param keyCode A key code from the Qt::Key enum
358 * @param modifiers A combination of modifiers
359 * @param state Optional flags which specify the current state of the terminal
360 */
361 Entry findEntry(int keyCode ,
362 Qt::KeyboardModifiers modifiers ,
363 States state = NoState) const;
364
365 /**
366 * Adds an entry to this keyboard translator's table. Entries can be looked up according
367 * to their key sequence using findEntry()
368 */
369 void addEntry(const Entry& entry);
370
371 /**
372 * Replaces an entry in the translator. If the @p existing entry is null,
373 * then this is equivalent to calling addEntry(@p replacement)
374 */
375 void replaceEntry(const Entry& existing , const Entry& replacement);
376
377 /**
378 * Removes an entry from the table.
379 */
380 void removeEntry(const Entry& entry);
381
382 /** Returns a list of all entries in the translator. */
383 QList<Entry> entries() const;
384
385private:
386
387 QMultiHash<int,Entry> _entries; // entries in this keyboard translation,
388 // entries are indexed according to
389 // their keycode
390 QString _name;
392};
393Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardTranslator::States)
394Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardTranslator::Commands)
395
396/**
397 * Parses the contents of a Keyboard Translator (.keytab) file and
398 * returns the entries found in it.
399 *
400 * Usage example:
401 *
402 * @code
403 * QFile source( "/path/to/keytab" );
404 * source.open( QIODevice::ReadOnly );
405 *
406 * KeyboardTranslator* translator = new KeyboardTranslator( "name-of-translator" );
407 *
408 * KeyboardTranslatorReader reader(source);
409 * while ( reader.hasNextEntry() )
410 * translator->addEntry(reader.nextEntry());
411 *
412 * source.close();
413 *
414 * if ( !reader.parseError() )
415 * {
416 * // parsing succeeded, do something with the translator
417 * }
418 * else
419 * {
420 * // parsing failed
421 * }
422 * @endcode
423 */
425{
426public:
427 /** Constructs a new reader which parses the given @p source */
428 KeyboardTranslatorReader( QIODevice* source );
429
430 /**
431 * Returns the description text.
432 * TODO: More documentation
433 */
434 QString description() const;
435
436 /** Returns true if there is another entry in the source stream */
437 bool hasNextEntry();
438 /** Returns the next entry found in the source stream */
439 KeyboardTranslator::Entry nextEntry();
440
441 /**
442 * Returns true if an error occurred whilst parsing the input or
443 * false if no error occurred.
444 */
445 bool parseError();
446
447 /**
448 * Parses a condition and result string for a translator entry
449 * and produces a keyboard translator entry.
450 *
451 * The condition and result strings are in the same format as in
452 */
453 static KeyboardTranslator::Entry createEntry( const QString& condition ,
454 const QString& result );
455private:
456 struct Token
457 {
458 enum Type
459 {
465 OutputText
466 };
468 QString text;
469 };
470 QList<Token> tokenize(const QString&);
471 void readNext();
472 bool decodeSequence(const QString& ,
473 int& keyCode,
474 Qt::KeyboardModifiers& modifiers,
475 Qt::KeyboardModifiers& modifierMask,
476 KeyboardTranslator::States& state,
477 KeyboardTranslator::States& stateFlags);
478
479 static bool parseAsModifier(const QString& item , Qt::KeyboardModifier& modifier);
480 static bool parseAsStateFlag(const QString& item , KeyboardTranslator::State& state);
481 static bool parseAsKeyCode(const QString& item , int& keyCode);
482 static bool parseAsCommand(const QString& text , KeyboardTranslator::Command& command);
483
484 QIODevice* _source;
488};
489
490/** Writes a keyboard translation to disk. */
492{
493public:
494 /**
495 * Constructs a new writer which saves data into @p destination.
496 * The caller is responsible for closing the device when writing is complete.
497 */
498 KeyboardTranslatorWriter(QIODevice* destination);
500
501 /**
502 * Writes the header for the keyboard translator.
503 * @param description Description of the keyboard translator.
504 */
505 void writeHeader( const QString& description );
506 /** Writes a translator entry. */
507 void writeEntry( const KeyboardTranslator::Entry& entry );
508
509private:
510 QIODevice* _destination;
511 QTextStream* _writer;
512};
513
514/**
515 * Manages the keyboard translations available for use by terminal sessions,
516 * see KeyboardTranslator.
517 */
519{
520public:
521 /**
522 * Constructs a new KeyboardTranslatorManager and loads the list of
523 * available keyboard translations.
524 *
525 * The keyboard translations themselves are not loaded until they are
526 * first requested via a call to findTranslator()
527 */
530
531 /**
532 * Adds a new translator. If a translator with the same name
533 * already exists, it will be replaced by the new translator.
534 *
535 * TODO: More documentation.
536 */
537 void addTranslator(KeyboardTranslator* translator);
538
539 /**
540 * Deletes a translator. Returns true on successful deletion or false otherwise.
541 *
542 * TODO: More documentation
543 */
544 bool deleteTranslator(const QString& name);
545
546 /** Returns the default translator for Konsole. */
548
549 /**
550 * Returns the keyboard translator with the given name or 0 if no translator
551 * with that name exists.
552 *
553 * The first time that a translator with a particular name is requested,
554 * the on-disk .keyboard file is loaded and parsed.
555 */
556 const KeyboardTranslator* findTranslator(const QString& name);
557 /**
558 * Returns a list of the names of available keyboard translators.
559 *
560 * The first time this is called, a search for available
561 * translators is started.
562 */
564
565 /** Returns the global KeyboardTranslatorManager instance. */
567
568private:
569 static const char* defaultTranslatorText;
570
571 void findTranslators(); // locate the available translators
572 KeyboardTranslator* loadTranslator(const QString& name); // loads the translator
573 // with the given name
574 KeyboardTranslator* loadTranslator(QIODevice* device,const QString& name);
575
576 bool saveTranslator(const KeyboardTranslator* translator);
577 QString findTranslatorPath(const QString& name);
578
579 QHash<QString,KeyboardTranslator*> _translators; // maps translator-name -> KeyboardTranslator
580 // instance
582};
583
584inline int KeyboardTranslator::Entry::keyCode() const { return _keyCode; }
585inline void KeyboardTranslator::Entry::setKeyCode(int keyCode) { _keyCode = keyCode; }
586
587inline void KeyboardTranslator::Entry::setModifiers( Qt::KeyboardModifiers modifier )
588{
589 _modifiers = modifier;
590}
591inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifiers() const { return _modifiers; }
592
593inline void KeyboardTranslator::Entry::setModifierMask( Qt::KeyboardModifiers mask )
594{
595 _modifierMask = mask;
596}
597inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifierMask() const { return _modifierMask; }
598
600{
601 return ( *this == Entry() );
602}
603
605{
606 _command = command;
607}
609
610inline void KeyboardTranslator::Entry::setText( const QByteArray& text )
611{
612 _text = unescape(text);
613}
614inline int oneOrZero(int value)
615{
616 return value ? 1 : 0;
617}
618inline QByteArray KeyboardTranslator::Entry::text(bool expandWildCards,Qt::KeyboardModifiers modifiers) const
619{
620 QByteArray expandedText = _text;
621
622 if (expandWildCards)
623 {
624 int modifierValue = 1;
625 modifierValue += oneOrZero(modifiers & Qt::ShiftModifier);
626 modifierValue += oneOrZero(modifiers & Qt::AltModifier) << 1;
627 modifierValue += oneOrZero(modifiers & Qt::ControlModifier) << 2;
628
629 for (int i=0;i<_text.length();i++)
630 {
631 if (expandedText[i] == '*')
632 expandedText[i] = '0' + modifierValue;
633 }
634 }
635
636 return expandedText;
637}
638
640{
641 _state = state;
642}
643inline KeyboardTranslator::States KeyboardTranslator::Entry::state() const { return _state; }
644
645inline void KeyboardTranslator::Entry::setStateMask( States stateMask )
646{
647 _stateMask = stateMask;
648}
649inline KeyboardTranslator::States KeyboardTranslator::Entry::stateMask() const { return _stateMask; }
650
651
652#endif // KEYBOARDTRANSLATOR_H
int oneOrZero(int value)
void(* CleanUpFunction)()
CleanUpFunction func
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.
static KeyboardTranslatorManager * instance()
Returns the global KeyboardTranslatorManager instance.
Parses the contents of a Keyboard Translator (.keytab) file and returns the entries found in it.
KeyboardTranslator::Entry _nextEntry
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 text(bool expandWildCards=false, Qt::KeyboardModifiers modifiers=Qt::NoModifier) const
Returns the character sequence associated with this entry, optionally replacing wildcard '*' characte...
void setText(const QByteArray &text)
Sets the character sequence associated with this entry.
States state() const
Returns a bitwise-OR of the enabled state flags associated with this entry.
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
Qt::KeyboardModifiers modifiers() const
Returns a bitwise-OR of the enabled keyboard modifiers associated with this entry.
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.
void setStateMask(States mask)
See stateMask()
void setCommand(Command command)
Sets the command associated with this entry.
States stateMask() const
Returns the state flags which are valid in this entry.
Qt::KeyboardModifiers modifierMask() const
Returns the keyboard modifiers which are valid in this entry.
void setState(States state)
See state()
void setModifierMask(Qt::KeyboardModifiers modifiers)
See modifierMask() and modifiers()
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.
@ SendCommand
TODO Document me.
@ 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.
bool operator==(const dim_vector &a, const dim_vector &b)
Definition: dim-vector.h:520
QString name
static uint32_t state[624]
Definition: randmtzig.cc:192