32 #include <QtCore/QBuffer>
33 #include <QtCore/QFile>
34 #include <QtCore/QFileInfo>
44 : _haveLoadedAll(false)
53 return QString(
"kb-layouts/" + name +
".keytab");
57 QDir dir(
"kb-layouts/");
59 filters <<
"*.keytab";
60 dir.setNameFilters(filters);
61 QStringList list = dir.entryList(filters);
64 list = dir.entryList(filters);
68 QStringListIterator listIter(list);
69 while (listIter.hasNext())
71 QString translatorPath = listIter.next();
73 QString name = QFileInfo(translatorPath).baseName();
96 if ( translator != 0 )
98 else if ( !name.isEmpty() )
99 qWarning() <<
"Unable to load translator" << name;
106 const QString path =
".keytab";
109 qDebug() <<
"Saving translator to" << path;
111 QFile destination(path);
113 if (!destination.open(QIODevice::WriteOnly | QIODevice::Text))
115 qWarning() <<
"Unable to save keyboard translation:"
116 << destination.errorString();
125 QListIterator<KeyboardTranslator::Entry> iter(translator->
entries());
126 while ( iter.hasNext() )
141 if (name.isEmpty() || !source.open(QIODevice::ReadOnly | QIODevice::Text))
152 if (!textBuffer.open(QIODevice::ReadOnly))
182 : _destination(destination)
184 Q_ASSERT( destination && destination->isWritable() );
194 *
_writer <<
"keyboard \"" << description <<
'\"' <<
'\n';
255 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
256 Qt::KeyboardModifiers modifierMask = Qt::NoModifier;
258 int keyCode = Qt::Key_unknown;
273 text = tokens[2].text.toLocal8Bit();
279 qWarning() <<
"Command" << tokens[2].text <<
"not understood.";
304 if ( text.compare(
"erase",Qt::CaseInsensitive) == 0 )
306 else if ( text.compare(
"scrollpageup",Qt::CaseInsensitive) == 0 )
308 else if ( text.compare(
"scrollpagedown",Qt::CaseInsensitive) == 0 )
310 else if ( text.compare(
"scrolllineup",Qt::CaseInsensitive) == 0 )
312 else if ( text.compare(
"scrolllinedown",Qt::CaseInsensitive) == 0 )
314 else if ( text.compare(
"scrolllock",Qt::CaseInsensitive) == 0 )
324 Qt::KeyboardModifiers& modifiers,
325 Qt::KeyboardModifiers& modifierMask,
326 KeyboardTranslator::States& flags,
327 KeyboardTranslator::States& flagMask)
329 bool isWanted =
true;
330 bool endOfItem =
false;
333 Qt::KeyboardModifiers tempModifiers = modifiers;
334 Qt::KeyboardModifiers tempModifierMask = modifierMask;
335 KeyboardTranslator::States tempFlags = flags;
336 KeyboardTranslator::States tempFlagMask = flagMask;
338 for (
int i = 0 ; i < text.count() ; i++ )
340 const QChar& ch = text[i];
341 bool isLastLetter = ( i == text.count()-1 );
344 if ( ch.isLetterOrNumber() )
350 if ( (endOfItem || isLastLetter) && !buffer.isEmpty() )
352 Qt::KeyboardModifier itemModifier = Qt::NoModifier;
358 tempModifierMask |= itemModifier;
361 tempModifiers |= itemModifier;
365 tempFlagMask |= itemFlag;
368 tempFlags |= itemFlag;
371 keyCode = itemKeyCode;
373 qDebug() <<
"Unable to parse key binding item:" << buffer;
382 else if ( ch ==
'-' )
386 modifiers = tempModifiers;
387 modifierMask = tempModifierMask;
389 flagMask = tempFlagMask;
396 if ( item ==
"shift" )
397 modifier = Qt::ShiftModifier;
398 else if ( item ==
"ctrl" || item ==
"control" )
399 modifier = Qt::ControlModifier;
400 else if ( item ==
"alt" )
401 modifier = Qt::AltModifier;
402 else if ( item ==
"meta" )
403 modifier = Qt::MetaModifier;
404 else if ( item ==
"keypad" )
405 modifier = Qt::KeypadModifier;
413 if ( item ==
"appcukeys" )
415 else if ( item ==
"ansi" )
417 else if ( item ==
"newline" )
419 else if ( item ==
"appscreen" )
421 else if ( item ==
"anymod" )
430 QKeySequence sequence = QKeySequence::fromString(item);
431 if ( !sequence.isEmpty() )
433 keyCode = sequence[0];
435 if ( sequence.count() > 1 )
437 qDebug() <<
"Unhandled key codes in sequence: " << item;
441 else if ( item ==
"prior" )
442 keyCode = Qt::Key_PageUp;
443 else if ( item ==
"next" )
444 keyCode = Qt::Key_PageDown;
460 const QString& result )
462 QString entryString(
"keyboard \"temporary\"\nkey ");
463 entryString.append(condition);
464 entryString.append(
" : ");
471 entryString.append(result);
473 entryString.append(
'\"' + result +
'\"');
475 QByteArray array = entryString.toUtf8();
479 QBuffer buffer(&array);
480 buffer.open(QIODevice::ReadOnly);
506 QString
text = line.simplified();
509 static QRegExp comment(
"\\#.*");
511 static QRegExp title(
"keyboard\\s+\"(.*)\"");
514 static QRegExp key(
"key\\s+([\\w\\+\\s\\-]+)\\s*:\\s*(\"(.*)\"|\\w+)");
518 if ( text.isEmpty() || comment.exactMatch(text) )
523 if ( title.exactMatch(text) )
528 list << titleToken << textToken;
530 else if ( key.exactMatch(text) )
535 list << keyToken << sequenceToken;
537 if ( key.capturedTexts()[3].isEmpty() )
541 list << commandToken;
552 qWarning() <<
"Line in keyboard translator file could not be understood:" << text;
570 , _modifiers(Qt::NoModifier)
571 , _modifierMask(Qt::NoModifier)
573 , _stateMask(NoState)
574 , _command(NoCommand)
590 Qt::KeyboardModifiers modifiers,
593 if ( _keyCode != keyCode )
596 if ( (modifiers & _modifierMask) != (_modifiers & _modifierMask) )
600 if ( modifiers != 0 )
603 if ( (state & _stateMask) != (_state & _stateMask) )
608 bool anyModifiersSet = modifiers != 0 && modifiers != Qt::KeypadModifier;
612 if ( (_state & KeyboardTranslator::AnyModifierState) && !anyModifiersSet )
616 if ( !(_state & KeyboardTranslator::AnyModifierState) && anyModifiersSet )
624 QByteArray result(
text(expandWildCards,modifiers));
626 for (
int i = 0 ; i < result.count() ; i++ )
629 char replacement = 0;
633 case 27 : replacement =
'E';
break;
634 case 8 : replacement =
'b';
break;
635 case 12 : replacement =
'f';
break;
636 case 9 : replacement =
't';
break;
637 case 13 : replacement =
'r';
break;
638 case 10 : replacement =
'n';
break;
642 if ( !QChar(ch).isPrint() )
646 if ( replacement ==
'x' )
648 result.replace(i,1,
"\\x"+QByteArray(1,ch).toInt(0, 16));
649 }
else if ( replacement != 0 )
652 result.insert(i,
'\\');
653 result.insert(i+1,replacement);
661 QByteArray result(input);
663 for (
int i = 0 ; i < result.count()-1 ; i++ )
666 QByteRef ch = result[i];
669 char replacement[2] = {0,0};
670 int charsToRemove = 2;
671 bool escapedChar =
true;
673 switch ( result[i+1] )
675 case 'E' : replacement[0] = 27;
break;
676 case 'b' : replacement[0] = 8 ;
break;
677 case 'f' : replacement[0] = 12;
break;
678 case 't' : replacement[0] = 9 ;
break;
679 case 'r' : replacement[0] = 13;
break;
680 case 'n' : replacement[0] = 10;
break;
686 char hexDigits[3] = {0};
688 if ( (i < result.count()-2) && isxdigit(result[i+2]) )
689 hexDigits[0] = result[i+2];
690 if ( (i < result.count()-3) && isxdigit(result[i+3]) )
691 hexDigits[1] = result[i+3];
694 sscanf(hexDigits,
"%x",&charValue);
696 replacement[0] = (
char)charValue;
698 charsToRemove = 2 + strlen(hexDigits);
706 result.replace(i,charsToRemove,replacement);
715 if ( !(modifier & _modifierMask) )
718 if ( modifier & _modifiers )
723 if ( modifier == Qt::ShiftModifier )
725 else if ( modifier == Qt::ControlModifier )
727 else if ( modifier == Qt::AltModifier )
729 else if ( modifier == Qt::MetaModifier )
731 else if ( modifier == Qt::KeypadModifier )
736 if ( !(state & _stateMask) )
739 if ( state & _state )
757 if ( !_text.isEmpty() )
758 return escapedText(expandWildCards,modifiers);
762 return "ScrollPageUp";
764 return "ScrollPageDown";
766 return "ScrollLineUp";
768 return "ScrollLineDown";
776 QString result = QKeySequence(_keyCode).toString();
779 insertModifier( result , Qt::ShiftModifier );
780 insertModifier( result , Qt::ControlModifier );
781 insertModifier( result , Qt::AltModifier );
782 insertModifier( result , Qt::MetaModifier );
823 const int keyCode = entry.
keyCode();
824 _entries.insertMulti(keyCode,entry);
842 QListIterator<Entry> iter(entriesForKey);
844 while (iter.hasNext())
847 if ( next.
matches(keyCode,modifiers,state) )
864 qWarning() <<
"Unable to save translator" << translator->
name()
873 if ( QFile::remove(path) )
880 qWarning() <<
"Failed to remove translator - " << path;
887 return theKeyboardTranslatorManager;