Fix handling of invalid modifiers in QKeySequence.
authorDavid Faure <faure@kde.org>
Wed, 21 Dec 2011 19:15:25 +0000 (20:15 +0100)
committerQt by Nokia <qt-info@nokia.com>
Thu, 22 Dec 2011 12:20:40 +0000 (13:20 +0100)
When decoding a string don't assume valid modifier strings. If a
modifier string is unknown return Qt::Key_unknown instead of skipping
the modifier.
Currently 'Win+a' is decoded to 'A' but should be Qt::Key_unknown.

Change-Id: I1c82031159a8b3c19924a7c9e991bc6b1f90d617
Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
src/gui/kernel/qkeysequence.cpp
tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp

index 6ea502b..9c0b07c 100644 (file)
@@ -1259,13 +1259,20 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
         // Rational: A modifier will contain the name AND +, so longer than 1, a length of 1 is just
         // the remaining part of the shortcut (ei. The 'C' in "Ctrl+C"), so no need to check that.
         if (sub.length() > 1) {
+            bool validModifier = false;
             for (int j = 0; j < modifs.size(); ++j) {
                 const QModifKeyName &mkf = modifs.at(j);
                 if (sub == mkf.name) {
                     ret |= mkf.qt_key;
+                    validModifier = true;
                     break; // Shortcut, since if we find an other it would/should just be a dup
                 }
             }
+            // We couldn't match the string with a modifier. This is only
+            // possible if this part is the key. The key is never followed by a
+            // '+'. And if the key is '+' the if() above would have skipped it.
+            if (!validModifier)
+                return Qt::Key_unknown;
         }
         lastI = i + 1;
     }
index 6fbd77c..9845b38 100644 (file)
@@ -124,6 +124,8 @@ private slots:
     void toString();
     void streamOperators_data();
     void streamOperators();
+    void parseString_data();
+    void parseString();
     void fromString_data();
     void fromString();
     void ensureSorted();
@@ -501,6 +503,31 @@ void tst_QKeySequence::streamOperators()
        QVERIFY( orgK != copyOrgK );
 }
 
+
+void tst_QKeySequence::parseString_data()
+{
+    QTest::addColumn<QString>("strSequence");
+    QTest::addColumn<QKeySequence>("keycode");
+
+    QTest::newRow("A") << "A" << QKeySequence(Qt::Key_A);
+    QTest::newRow("a") << "a" << QKeySequence(Qt::Key_A);
+    QTest::newRow("Ctrl+Left") << "Ctrl+Left" << QKeySequence(Qt::CTRL + Qt::Key_Left);
+    QTest::newRow("Ctrl++") << "Ctrl++" << QKeySequence(Qt::CTRL + Qt::Key_Plus);
+    QTest::newRow("Meta+A") << "Meta+a" <<  QKeySequence(Qt::META + Qt::Key_A);
+    QTest::newRow("Win+A") << "Win+a" <<  QKeySequence(Qt::Key_unknown);
+    QTest::newRow("4+3=2") << "4+3=2" <<  QKeySequence(Qt::Key_unknown);
+    QTest::newRow("Super+Meta+A") << "Super+Meta+A" << QKeySequence(Qt::Key_unknown);
+}
+
+void tst_QKeySequence::parseString()
+{
+    QFETCH( QString, strSequence );
+    QFETCH( QKeySequence, keycode );
+
+    QCOMPARE( QKeySequence(strSequence).toString(), keycode.toString() );
+    QVERIFY( QKeySequence(strSequence) == keycode );
+}
+
 void tst_QKeySequence::fromString_data()
 {
     toString_data();