source: ogBrowser-Git/qtermwidget/src/KeyboardTranslator.cpp

qndtest
Last change on this file was 050d67a, checked in by adelcastillo <adelcastillo@…>, 15 years ago

Ahora el browser tiene consola en vez del output.
Pasado todo el sistema de compilacion a cmake.

git-svn-id: https://opengnsys.es/svn/trunk@408 a21b9725-9963-47de-94b9-378ad31fedc9

  • Property mode set to 100644
File size: 26.5 KB
Line 
1/*
2    This source file was part of Konsole, a terminal emulator.
3
4    Copyright (C) 2007 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
25#include "KeyboardTranslator.h"
26
27// System
28#include <ctype.h>
29#include <stdio.h>
30
31// Qt
32#include <QtCore/QBuffer>
33//#include <KDebug>
34#include <QtCore/QFile>
35#include <QtCore/QFileInfo>
36#include <QtCore>
37#include <QtGui>
38
39// KDE
40//#include <KDebug>
41//#include <KLocale>
42//#include <KStandardDirs>
43
44using namespace Konsole;
45
46//this is for default REALLY fallback translator.
47
48//const char* KeyboardTranslatorManager::defaultTranslatorText =
49//#include "DefaultTranslatorText.h"
50//;
51
52//and this is default now translator - default.keytab from original Konsole
53const char* KeyboardTranslatorManager::defaultTranslatorText = 
54#include "ExtendedDefaultTranslator.h"
55;
56
57KeyboardTranslatorManager::KeyboardTranslatorManager()
58    : _haveLoadedAll(false)
59{
60}
61KeyboardTranslatorManager::~KeyboardTranslatorManager()
62{
63    qDeleteAll(_translators.values());
64}
65QString KeyboardTranslatorManager::findTranslatorPath(const QString& name)
66{
67    return QString("kb-layouts/" + name + ".keytab");
68}
69void KeyboardTranslatorManager::findTranslators()
70{
71    QDir dir("kb-layouts/");
72    QStringList filters;
73    filters << "*.keytab";
74    dir.setNameFilters(filters);
75    QStringList list = dir.entryList(filters); //(".keytab"); // = KGlobal::dirs()->findAllResources("data",
76                        //                                 "konsole/*.keytab",
77                        //                                 KStandardDirs::NoDuplicates);
78    list = dir.entryList(filters);
79    // add the name of each translator to the list and associated
80    // the name with a null pointer to indicate that the translator
81    // has not yet been loaded from disk
82    QStringListIterator listIter(list);
83    while (listIter.hasNext())
84    {
85        QString translatorPath = listIter.next();
86
87        QString name = QFileInfo(translatorPath).baseName();
88       
89        if ( !_translators.contains(name) ) {
90            _translators.insert(name,0);
91        }
92    }
93    _haveLoadedAll = true;
94}
95
96const KeyboardTranslator* KeyboardTranslatorManager::findTranslator(const QString& name)
97{
98    if ( name.isEmpty() )
99        return defaultTranslator();
100
101//here was smth wrong in original Konsole source
102    findTranslators();
103
104    if ( _translators.contains(name) && _translators[name] != 0 ) {
105        return _translators[name];
106    }
107
108    KeyboardTranslator* translator = loadTranslator(name);
109
110    if ( translator != 0 )
111        _translators[name] = translator;
112    else if ( !name.isEmpty() )
113        qWarning() << "Unable to load translator" << name;
114
115    return translator;
116}
117
118bool KeyboardTranslatorManager::saveTranslator(const KeyboardTranslator* translator)
119{
120    const QString path = ".keytab";// = KGlobal::dirs()->saveLocation("data","konsole/")+translator->name()
121//           +".keytab";
122
123    qDebug() << "Saving translator to" << path;
124
125    QFile destination(path);
126   
127    if (!destination.open(QIODevice::WriteOnly | QIODevice::Text))
128    {
129        qWarning() << "Unable to save keyboard translation:" 
130                   << destination.errorString();
131
132        return false;
133    }
134
135    {
136        KeyboardTranslatorWriter writer(&destination);
137        writer.writeHeader(translator->description());
138   
139        QListIterator<KeyboardTranslator::Entry> iter(translator->entries());
140        while ( iter.hasNext() )
141            writer.writeEntry(iter.next());
142    }
143
144    destination.close();
145
146    return true;
147}
148
149KeyboardTranslator* KeyboardTranslatorManager::loadTranslator(const QString& name)
150{
151    const QString& path = findTranslatorPath(name);
152
153    QFile source(path); 
154   
155    if (name.isEmpty() || !source.open(QIODevice::ReadOnly | QIODevice::Text))
156        return 0;
157
158    return loadTranslator(&source,name);
159}
160
161const KeyboardTranslator* KeyboardTranslatorManager::defaultTranslator()
162{
163    qDebug() << "Loading default translator from text";
164    QBuffer textBuffer;
165    textBuffer.setData(defaultTranslatorText,strlen(defaultTranslatorText));
166
167    if (!textBuffer.open(QIODevice::ReadOnly))
168        return 0;
169
170    return loadTranslator(&textBuffer,"fallback");
171}
172
173KeyboardTranslator* KeyboardTranslatorManager::loadTranslator(QIODevice* source,const QString& name)
174{
175    KeyboardTranslator* translator = new KeyboardTranslator(name);
176    KeyboardTranslatorReader reader(source);
177    translator->setDescription( reader.description() );
178   
179    while ( reader.hasNextEntry() ) {
180        translator->addEntry(reader.nextEntry());
181    }   
182
183    source->close();
184
185    if ( !reader.parseError() )
186    {
187        return translator;
188    }
189    else
190    {
191        delete translator;
192        return 0;
193    }
194}
195
196KeyboardTranslatorWriter::KeyboardTranslatorWriter(QIODevice* destination)
197: _destination(destination)
198{
199    Q_ASSERT( destination && destination->isWritable() );
200
201    _writer = new QTextStream(_destination);
202}
203KeyboardTranslatorWriter::~KeyboardTranslatorWriter()
204{
205    delete _writer;
206}
207void KeyboardTranslatorWriter::writeHeader( const QString& description )
208{
209    *_writer << "keyboard \"" << description << '\"' << '\n';
210}
211void KeyboardTranslatorWriter::writeEntry( const KeyboardTranslator::Entry& entry )
212{
213    QString result;
214
215    if ( entry.command() != KeyboardTranslator::NoCommand )
216        result = entry.resultToString();
217    else
218        result = '\"' + entry.resultToString() + '\"';
219
220    *_writer << "key " << entry.conditionToString() << " : " << result << '\n';
221}
222
223
224// each line of the keyboard translation file is one of:
225//
226// - keyboard "name"
227// - key KeySequence : "characters"
228// - key KeySequence : CommandName
229//
230// KeySequence begins with the name of the key ( taken from the Qt::Key enum )
231// and is followed by the keyboard modifiers and state flags ( with + or - in front
232// of each modifier or flag to indicate whether it is required ).  All keyboard modifiers
233// and flags are optional, if a particular modifier or state is not specified it is
234// assumed not to be a part of the sequence.  The key sequence may contain whitespace
235//
236// eg:  "key Up+Shift : scrollLineUp"
237//      "key Next-Shift : "\E[6~"
238//
239// (lines containing only whitespace are ignored, parseLine assumes that comments have
240// already been removed)
241//
242
243KeyboardTranslatorReader::KeyboardTranslatorReader( QIODevice* source )
244    : _source(source)
245    , _hasNext(false)
246{
247   // read input until we find the description
248   while ( _description.isEmpty() && !source->atEnd() )
249   {
250        const QList<Token>& tokens = tokenize( QString(source->readLine()) );
251   
252        if ( !tokens.isEmpty() && tokens.first().type == Token::TitleKeyword )
253        {
254            _description = (tokens[1].text.toUtf8());
255        }
256   }
257
258   readNext();
259}
260void KeyboardTranslatorReader::readNext() 
261{
262    // find next entry
263    while ( !_source->atEnd() )
264    {
265        const QList<Token>& tokens = tokenize( QString(_source->readLine()) );
266        if ( !tokens.isEmpty() && tokens.first().type == Token::KeyKeyword )
267        {
268            KeyboardTranslator::States flags = KeyboardTranslator::NoState;
269            KeyboardTranslator::States flagMask = KeyboardTranslator::NoState;
270            Qt::KeyboardModifiers modifiers = Qt::NoModifier;
271            Qt::KeyboardModifiers modifierMask = Qt::NoModifier;
272
273            int keyCode = Qt::Key_unknown;
274
275            decodeSequence(tokens[1].text.toLower(),
276                           keyCode,
277                           modifiers,
278                           modifierMask,
279                           flags,
280                           flagMask); 
281
282            KeyboardTranslator::Command command = KeyboardTranslator::NoCommand;
283            QByteArray text;
284
285            // get text or command
286            if ( tokens[2].type == Token::OutputText )
287            {
288                text = tokens[2].text.toLocal8Bit();
289            }
290            else if ( tokens[2].type == Token::Command )
291            {
292                // identify command
293                                if (!parseAsCommand(tokens[2].text,command))
294                                        qWarning() << "Command" << tokens[2].text << "not understood.";
295            }
296
297            KeyboardTranslator::Entry newEntry;
298            newEntry.setKeyCode( keyCode );
299            newEntry.setState( flags );
300            newEntry.setStateMask( flagMask );
301            newEntry.setModifiers( modifiers );
302            newEntry.setModifierMask( modifierMask );
303            newEntry.setText( text );
304            newEntry.setCommand( command );
305
306            _nextEntry = newEntry;
307
308            _hasNext = true;
309
310            return;
311        }
312    } 
313
314    _hasNext = false;
315}
316
317bool KeyboardTranslatorReader::parseAsCommand(const QString& text,KeyboardTranslator::Command& command) 
318{
319        if ( text.compare("erase",Qt::CaseInsensitive) == 0 )
320                command = KeyboardTranslator::EraseCommand;
321    else if ( text.compare("scrollpageup",Qt::CaseInsensitive) == 0 )
322        command = KeyboardTranslator::ScrollPageUpCommand;
323    else if ( text.compare("scrollpagedown",Qt::CaseInsensitive) == 0 )
324        command = KeyboardTranslator::ScrollPageDownCommand;
325    else if ( text.compare("scrolllineup",Qt::CaseInsensitive) == 0 )
326        command = KeyboardTranslator::ScrollLineUpCommand;
327    else if ( text.compare("scrolllinedown",Qt::CaseInsensitive) == 0 )
328        command = KeyboardTranslator::ScrollLineDownCommand;
329    else if ( text.compare("scrolllock",Qt::CaseInsensitive) == 0 )
330        command = KeyboardTranslator::ScrollLockCommand;
331    else
332        return false;
333
334        return true;
335}
336
337bool KeyboardTranslatorReader::decodeSequence(const QString& text,
338                                              int& keyCode,
339                                              Qt::KeyboardModifiers& modifiers,
340                                              Qt::KeyboardModifiers& modifierMask,
341                                              KeyboardTranslator::States& flags,
342                                              KeyboardTranslator::States& flagMask)
343{
344    bool isWanted = true; 
345    bool endOfItem = false;
346    QString buffer;
347
348    Qt::KeyboardModifiers tempModifiers = modifiers;
349    Qt::KeyboardModifiers tempModifierMask = modifierMask;
350    KeyboardTranslator::States tempFlags = flags;
351    KeyboardTranslator::States tempFlagMask = flagMask;
352
353    for ( int i = 0 ; i < text.count() ; i++ )
354    {
355        const QChar& ch = text[i];
356        bool isLastLetter = ( i == text.count()-1 );
357
358        endOfItem = true;
359        if ( ch.isLetterOrNumber() )
360        {
361            endOfItem = false;
362            buffer.append(ch);
363        }
364
365        if ( (endOfItem || isLastLetter) && !buffer.isEmpty() )
366        {
367            Qt::KeyboardModifier itemModifier = Qt::NoModifier;
368            int itemKeyCode = 0;
369            KeyboardTranslator::State itemFlag = KeyboardTranslator::NoState;
370
371            if ( parseAsModifier(buffer,itemModifier) )
372            {
373                tempModifierMask |= itemModifier;
374
375                if ( isWanted )
376                    tempModifiers |= itemModifier;
377            }
378            else if ( parseAsStateFlag(buffer,itemFlag) )
379            {
380                tempFlagMask |= itemFlag;
381
382                if ( isWanted )
383                    tempFlags |= itemFlag;
384            }
385            else if ( parseAsKeyCode(buffer,itemKeyCode) )
386                keyCode = itemKeyCode;
387            else
388                qDebug() << "Unable to parse key binding item:" << buffer;
389
390            buffer.clear();
391        }
392
393        // check if this is a wanted / not-wanted flag and update the
394        // state ready for the next item
395        if ( ch == '+' )
396           isWanted = true;
397        else if ( ch == '-' )
398           isWanted = false; 
399    } 
400
401    modifiers = tempModifiers;
402    modifierMask = tempModifierMask;
403    flags = tempFlags;
404    flagMask = tempFlagMask;
405
406    return true;
407}
408
409bool KeyboardTranslatorReader::parseAsModifier(const QString& item , Qt::KeyboardModifier& modifier)
410{
411    if ( item == "shift" )
412        modifier = Qt::ShiftModifier;
413    else if ( item == "ctrl" || item == "control" )
414        modifier = Qt::ControlModifier;
415    else if ( item == "alt" )
416        modifier = Qt::AltModifier;
417    else if ( item == "meta" )
418        modifier = Qt::MetaModifier;
419        else if ( item == "keypad" )
420                modifier = Qt::KeypadModifier;
421    else
422        return false;
423
424    return true;
425}
426bool KeyboardTranslatorReader::parseAsStateFlag(const QString& item , KeyboardTranslator::State& flag)
427{
428    if ( item == "appcukeys" )
429        flag = KeyboardTranslator::CursorKeysState;
430    else if ( item == "ansi" )
431        flag = KeyboardTranslator::AnsiState;
432    else if ( item == "newline" )
433        flag = KeyboardTranslator::NewLineState;
434    else if ( item == "appscreen" )
435        flag = KeyboardTranslator::AlternateScreenState;
436    else if ( item == "anymod" )
437        flag = KeyboardTranslator::AnyModifierState;
438    else
439        return false;
440
441    return true;
442}
443bool KeyboardTranslatorReader::parseAsKeyCode(const QString& item , int& keyCode)
444{
445    QKeySequence sequence = QKeySequence::fromString(item);
446    if ( !sequence.isEmpty() )
447    {
448        keyCode = sequence[0];
449
450        if ( sequence.count() > 1 )
451        {
452            qDebug() << "Unhandled key codes in sequence: " << item;
453        }
454    }
455    // additional cases implemented for backwards compatibility with KDE 3
456    else if ( item == "prior" )
457        keyCode = Qt::Key_PageUp;
458    else if ( item == "next" )
459        keyCode = Qt::Key_PageDown;
460    else
461        return false;
462
463    return true;
464}
465
466QString KeyboardTranslatorReader::description() const
467{
468    return _description;
469}
470bool KeyboardTranslatorReader::hasNextEntry()
471{
472    return _hasNext;
473}
474KeyboardTranslator::Entry KeyboardTranslatorReader::createEntry( const QString& condition , 
475                                                                 const QString& result )
476{
477    QString entryString("keyboard \"temporary\"\nkey ");
478    entryString.append(condition);
479    entryString.append(" : ");
480
481        // if 'result' is the name of a command then the entry result will be that command,
482        // otherwise the result will be treated as a string to echo when the key sequence
483        // specified by 'condition' is pressed
484        KeyboardTranslator::Command command;
485        if (parseAsCommand(result,command))
486        entryString.append(result);
487        else
488                entryString.append('\"' + result + '\"');
489
490    QByteArray array = entryString.toUtf8();
491
492    KeyboardTranslator::Entry entry;
493
494    QBuffer buffer(&array);
495    buffer.open(QIODevice::ReadOnly);
496    KeyboardTranslatorReader reader(&buffer);
497
498    if ( reader.hasNextEntry() )
499        entry = reader.nextEntry();
500
501    return entry;
502}
503
504KeyboardTranslator::Entry KeyboardTranslatorReader::nextEntry() 
505{
506    Q_ASSERT( _hasNext );
507
508
509    KeyboardTranslator::Entry entry = _nextEntry;
510
511    readNext();
512
513    return entry;
514}
515bool KeyboardTranslatorReader::parseError()
516{
517    return false;
518}
519QList<KeyboardTranslatorReader::Token> KeyboardTranslatorReader::tokenize(const QString& line)
520{
521    QString text = line.simplified();
522
523    // comment line: # comment
524    static QRegExp comment("\\#.*");
525    // title line: keyboard "title"
526    static QRegExp title("keyboard\\s+\"(.*)\"");
527    // key line: key KeySequence : "output"
528    // key line: key KeySequence : command
529    static QRegExp key("key\\s+([\\w\\+\\s\\-]+)\\s*:\\s*(\"(.*)\"|\\w+)");
530
531    QList<Token> list;
532
533    if ( text.isEmpty() || comment.exactMatch(text) )
534    {
535        return list;
536    }
537
538    if ( title.exactMatch(text) )
539    {
540        Token titleToken = { Token::TitleKeyword , QString() };
541        Token textToken = { Token::TitleText , title.capturedTexts()[1] };
542   
543        list << titleToken << textToken;
544    }
545    else if  ( key.exactMatch(text) )
546    {
547        Token keyToken = { Token::KeyKeyword , QString() };
548        Token sequenceToken = { Token::KeySequence , key.capturedTexts()[1].remove(' ') };
549
550        list << keyToken << sequenceToken;
551
552        if ( key.capturedTexts()[3].isEmpty() )
553        {
554            // capturedTexts()[2] is a command
555            Token commandToken = { Token::Command , key.capturedTexts()[2] };
556            list << commandToken;   
557        }   
558        else
559        {
560            // capturedTexts()[3] is the output string
561           Token outputToken = { Token::OutputText , key.capturedTexts()[3] };
562           list << outputToken;
563        }     
564    }
565    else
566    {
567        qWarning() << "Line in keyboard translator file could not be understood:" << text;
568    }
569
570    return list;
571}
572
573QList<QString> KeyboardTranslatorManager::allTranslators() 
574{
575    if ( !_haveLoadedAll )
576    {
577        findTranslators();
578    }
579
580    return _translators.keys();
581}
582
583KeyboardTranslator::Entry::Entry()
584: _keyCode(0)
585, _modifiers(Qt::NoModifier)
586, _modifierMask(Qt::NoModifier)
587, _state(NoState)
588, _stateMask(NoState)
589, _command(NoCommand)
590{
591}
592
593bool KeyboardTranslator::Entry::operator==(const Entry& rhs) const
594{
595    return _keyCode == rhs._keyCode &&
596           _modifiers == rhs._modifiers &&
597           _modifierMask == rhs._modifierMask &&
598           _state == rhs._state &&
599           _stateMask == rhs._stateMask &&
600           _command == rhs._command &&
601           _text == rhs._text;
602}
603
604bool KeyboardTranslator::Entry::matches(int keyCode , 
605                                        Qt::KeyboardModifiers modifiers,
606                                        States state) const
607{
608    if ( _keyCode != keyCode )
609        return false;
610
611    if ( (modifiers & _modifierMask) != (_modifiers & _modifierMask) ) 
612        return false;
613
614    // if modifiers is non-zero, the 'any modifier' state is implicit
615    if ( modifiers != 0 )
616        state |= AnyModifierState;
617
618    if ( (state & _stateMask) != (_state & _stateMask) )
619        return false;
620
621    // special handling for the 'Any Modifier' state, which checks for the presence of
622    // any or no modifiers.  In this context, the 'keypad' modifier does not count.
623    bool anyModifiersSet = modifiers != 0 && modifiers != Qt::KeypadModifier;
624    if ( _stateMask & KeyboardTranslator::AnyModifierState )
625    {
626        // test fails if any modifier is required but none are set
627        if ( (_state & KeyboardTranslator::AnyModifierState) && !anyModifiersSet )
628           return false;
629
630        // test fails if no modifier is allowed but one or more are set
631        if ( !(_state & KeyboardTranslator::AnyModifierState) && anyModifiersSet )
632            return false;
633    }
634
635    return true;
636}
637QByteArray KeyboardTranslator::Entry::escapedText(bool expandWildCards,Qt::KeyboardModifiers modifiers) const
638{
639    QByteArray result(text(expandWildCards,modifiers));
640
641    for ( int i = 0 ; i < result.count() ; i++ )
642    {
643        char ch = result[i];
644        char replacement = 0;
645
646        switch ( ch )
647        {
648            case 27 : replacement = 'E'; break;
649            case 8  : replacement = 'b'; break;
650            case 12 : replacement = 'f'; break;
651            case 9  : replacement = 't'; break;
652            case 13 : replacement = 'r'; break;
653            case 10 : replacement = 'n'; break;
654            default:
655                // any character which is not printable is replaced by an equivalent
656                // \xhh escape sequence (where 'hh' are the corresponding hex digits)
657                if ( !QChar(ch).isPrint() )
658                    replacement = 'x';
659        }
660
661        if ( replacement == 'x' )
662        {
663            result.replace(i,1,"\\x"+QByteArray(1,ch).toInt(0, 16)); 
664        } else if ( replacement != 0 )
665        {
666            result.remove(i,1);
667            result.insert(i,'\\');
668            result.insert(i+1,replacement);
669        }
670    }
671
672    return result;
673}
674QByteArray KeyboardTranslator::Entry::unescape(const QByteArray& input) const
675{
676    QByteArray result(input);
677
678    for ( int i = 0 ; i < result.count()-1 ; i++ )
679    {
680
681        QByteRef ch = result[i];
682        if ( ch == '\\' )
683        {
684           char replacement[2] = {0,0};
685           int charsToRemove = 2;
686                   bool escapedChar = true;
687
688           switch ( result[i+1] )
689           {
690              case 'E' : replacement[0] = 27; break;
691              case 'b' : replacement[0] = 8 ; break;
692              case 'f' : replacement[0] = 12; break;
693              case 't' : replacement[0] = 9 ; break;
694              case 'r' : replacement[0] = 13; break;
695              case 'n' : replacement[0] = 10; break;
696              case 'x' :
697                          {
698                    // format is \xh or \xhh where 'h' is a hexadecimal
699                    // digit from 0-9 or A-F which should be replaced
700                    // with the corresponding character value
701                    char hexDigits[3] = {0};
702
703                    if ( (i < result.count()-2) && isxdigit(result[i+2]) )
704                            hexDigits[0] = result[i+2];
705                    if ( (i < result.count()-3) && isxdigit(result[i+3]) )
706                            hexDigits[1] = result[i+3];
707
708                    int charValue = 0;
709                    sscanf(hexDigits,"%x",&charValue);
710                   
711                    replacement[0] = (char)charValue; 
712
713                    charsToRemove = 2 + strlen(hexDigits);
714                          }
715              break;
716                          default:
717                                        escapedChar = false;
718           }
719
720           if ( escapedChar )
721               result.replace(i,charsToRemove,replacement);
722        }
723    }
724   
725    return result;
726}
727
728void KeyboardTranslator::Entry::insertModifier( QString& item , int modifier ) const
729{
730    if ( !(modifier & _modifierMask) )
731        return;
732
733    if ( modifier & _modifiers )
734        item += '+';
735    else
736        item += '-';
737
738    if ( modifier == Qt::ShiftModifier )
739        item += "Shift";
740    else if ( modifier == Qt::ControlModifier )
741        item += "Ctrl";
742    else if ( modifier == Qt::AltModifier )
743        item += "Alt";
744    else if ( modifier == Qt::MetaModifier )
745        item += "Meta";
746        else if ( modifier == Qt::KeypadModifier )
747                item += "KeyPad";
748}
749void KeyboardTranslator::Entry::insertState( QString& item , int state ) const
750{
751    if ( !(state & _stateMask) )
752        return;
753
754    if ( state & _state )
755        item += '+' ;
756    else
757        item += '-' ;
758
759    if ( state == KeyboardTranslator::AlternateScreenState )
760        item += "AppScreen";
761    else if ( state == KeyboardTranslator::NewLineState )
762        item += "NewLine";
763    else if ( state == KeyboardTranslator::AnsiState )
764        item += "Ansi";
765    else if ( state == KeyboardTranslator::CursorKeysState )
766        item += "AppCuKeys";
767    else if ( state == KeyboardTranslator::AnyModifierState )
768        item += "AnyMod";
769}
770QString KeyboardTranslator::Entry::resultToString(bool expandWildCards,Qt::KeyboardModifiers modifiers) const
771{
772    if ( !_text.isEmpty() )
773        return escapedText(expandWildCards,modifiers);
774        else if ( _command == EraseCommand )
775                return "Erase";
776    else if ( _command == ScrollPageUpCommand )
777        return "ScrollPageUp";
778    else if ( _command == ScrollPageDownCommand )
779        return "ScrollPageDown";
780    else if ( _command == ScrollLineUpCommand )
781        return "ScrollLineUp";
782    else if ( _command == ScrollLineDownCommand )
783        return "ScrollLineDown";
784    else if ( _command == ScrollLockCommand )
785        return "ScrollLock";
786
787    return QString();
788}
789QString KeyboardTranslator::Entry::conditionToString() const
790{
791    QString result = QKeySequence(_keyCode).toString();
792
793    // add modifiers
794    insertModifier( result , Qt::ShiftModifier );
795    insertModifier( result , Qt::ControlModifier );
796    insertModifier( result , Qt::AltModifier );
797    insertModifier( result , Qt::MetaModifier ); 
798
799    // add states
800    insertState( result , KeyboardTranslator::AlternateScreenState );
801    insertState( result , KeyboardTranslator::NewLineState );
802    insertState( result , KeyboardTranslator::AnsiState );
803    insertState( result , KeyboardTranslator::CursorKeysState );
804    insertState( result , KeyboardTranslator::AnyModifierState );
805
806    return result;
807}
808
809KeyboardTranslator::KeyboardTranslator(const QString& name)
810: _name(name)
811{
812}
813
814void KeyboardTranslator::setDescription(const QString& description) 
815{
816    _description = description;
817}
818QString KeyboardTranslator::description() const
819{
820    return _description;
821}
822void KeyboardTranslator::setName(const QString& name)
823{
824    _name = name;
825}
826QString KeyboardTranslator::name() const
827{
828    return _name;
829}
830
831QList<KeyboardTranslator::Entry> KeyboardTranslator::entries() const
832{
833    return _entries.values();
834}
835
836void KeyboardTranslator::addEntry(const Entry& entry)
837{
838    const int keyCode = entry.keyCode();
839    _entries.insertMulti(keyCode,entry);
840}
841void KeyboardTranslator::replaceEntry(const Entry& existing , const Entry& replacement)
842{
843    if ( !existing.isNull() )
844        _entries.remove(existing.keyCode());
845    _entries.insertMulti(replacement.keyCode(),replacement);
846}
847void KeyboardTranslator::removeEntry(const Entry& entry)
848{
849    _entries.remove(entry.keyCode());
850}
851KeyboardTranslator::Entry KeyboardTranslator::findEntry(int keyCode, Qt::KeyboardModifiers modifiers, States state) const
852{
853    if ( _entries.contains(keyCode) )
854    {
855        QList<Entry> entriesForKey = _entries.values(keyCode);
856       
857        QListIterator<Entry> iter(entriesForKey);
858
859        while (iter.hasNext())
860        {
861            const Entry& next = iter.next();
862            if ( next.matches(keyCode,modifiers,state) )
863                return next;
864        }
865
866        return Entry(); // entry not found
867    }
868    else
869    {
870        return Entry();
871    }
872   
873}
874void KeyboardTranslatorManager::addTranslator(KeyboardTranslator* translator)
875{
876    _translators.insert(translator->name(),translator);
877
878    if ( !saveTranslator(translator) )
879        qWarning() << "Unable to save translator" << translator->name()
880                   << "to disk.";
881}
882bool KeyboardTranslatorManager::deleteTranslator(const QString& name)
883{
884    Q_ASSERT( _translators.contains(name) );
885
886    // locate and delete
887    QString path = findTranslatorPath(name);
888    if ( QFile::remove(path) )
889    {
890        _translators.remove(name);
891        return true; 
892    }
893    else
894    {
895        qWarning() << "Failed to remove translator - " << path;
896        return false;
897    }
898}
899K_GLOBAL_STATIC( KeyboardTranslatorManager , theKeyboardTranslatorManager )
900KeyboardTranslatorManager* KeyboardTranslatorManager::instance()
901{
902    return theKeyboardTranslatorManager;
903}
Note: See TracBrowser for help on using the repository browser.