File indexing completed on 2024-04-21 11:28:49

0001 /* This file is part of the KDE libraries
0002     Copyright 2006 Simon Hausmann <hausmann@kde.org>
0003     Copyright 2008 David Faure <faure@kde.org>
0004 
0005     This library is free software; you can redistribute it and/or
0006     modify it under the terms of the GNU Library General Public
0007     License as published by the Free Software Foundation; either
0008     version 2 of the License, or (at your option) any later version.
0009 
0010     This library is distributed in the hope that it will be useful,
0011     but WITHOUT ANY WARRANTY; without even the implied warranty of
0012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013     Library General Public License for more details.
0014 
0015     You should have received a copy of the GNU Library General Public License
0016     along with this library; see the file COPYING.LIB.  If not, write to
0017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018     Boston, MA 02110-1301, USA.
0019 */
0020 
0021 #include <QTest>
0022 #include "kshortcut.h"
0023 
0024 class tst_KShortcut : public QObject
0025 {
0026     Q_OBJECT
0027 private Q_SLOTS:
0028     void testRemoveShortcut()
0029     {
0030         KShortcut cutShortCut(Qt::CTRL | Qt::Key_X, Qt::SHIFT | Qt::Key_Delete);
0031         cutShortCut.remove(Qt::SHIFT | Qt::Key_Delete, KShortcut::KeepEmpty);
0032         cutShortCut.remove(Qt::CTRL | Qt::Key_X, KShortcut::KeepEmpty);
0033         //qDebug( "%s", qPrintable( cutShortCut.toString() ) );
0034         QVERIFY(cutShortCut.isEmpty());
0035 
0036         cutShortCut = KShortcut(Qt::CTRL | Qt::Key_X, Qt::SHIFT | Qt::Key_Delete);
0037         //remove primary shortcut. We expect the alternate to become primary.
0038         cutShortCut.remove(Qt::CTRL | Qt::Key_X, KShortcut::RemoveEmpty);
0039         QVERIFY(cutShortCut.primary() == QKeySequence(Qt::SHIFT | Qt::Key_Delete));
0040         QVERIFY(cutShortCut.alternate().isEmpty());
0041     }
0042 
0043     void testKShortcut()
0044     {
0045         KShortcut null;
0046         QVERIFY(null.isEmpty());
0047 
0048         KShortcut zero(0);
0049         QVERIFY(zero.isEmpty());
0050         QVERIFY(zero.primary().isEmpty());
0051         QVERIFY(zero.alternate().isEmpty());
0052 
0053         KShortcut quit("Ctrl+X, Ctrl+C; Z, Z");   // quit in emacs vs. quit in vi :)
0054         QCOMPARE(quit.primary().toString(), QString::fromLatin1("Ctrl+X, Ctrl+C"));
0055         QCOMPARE(quit.alternate().toString(), QString::fromLatin1("Z, Z"));
0056         QCOMPARE(quit.primary(), QKeySequence(Qt::CTRL | Qt::Key_X, Qt::CTRL | Qt::Key_C));
0057         QVERIFY(quit != null);
0058         QVERIFY(!(quit == null));
0059 
0060         QVERIFY(!quit.contains(Qt::CTRL | Qt::Key_X));
0061         QVERIFY(!quit.contains(Qt::CTRL | Qt::Key_Z));
0062         QVERIFY(!quit.contains(Qt::CTRL | Qt::Key_C));
0063         QKeySequence seq(Qt::CTRL | Qt::Key_X, Qt::CTRL | Qt::Key_C);
0064         QVERIFY(quit.contains(seq));
0065         QVERIFY(!null.contains(seq));
0066 
0067         quit.setAlternate(seq);
0068         QCOMPARE(quit.primary().toString(), quit.alternate().toString());
0069     }
0070 
0071     void isEmpty()
0072     {
0073         KShortcut cut;
0074         QVERIFY(cut.isEmpty());
0075 
0076         cut = KShortcut(0, 0);
0077         QVERIFY(cut.isEmpty());
0078 
0079         cut = KShortcut(QKeySequence());
0080         QVERIFY(cut.isEmpty());
0081 
0082         cut = KShortcut(QKeySequence(), QKeySequence());
0083         QVERIFY(cut.isEmpty());
0084 
0085         cut = KShortcut(QList<QKeySequence>());
0086         QVERIFY(cut.isEmpty());
0087 
0088         cut = KShortcut(Qt::Key_A);
0089         QVERIFY(!cut.isEmpty());
0090     }
0091 
0092     void checkQKeySequence()
0093     {
0094         // Check that the valid keycode Qt::Key_unknown is handled gracefully
0095         //
0096         // Qt::Key_unknown is a valid Qt Key. But toString makes unicode gibberish
0097         // from it. '???'.
0098         // Reported with patch - mjansen
0099         QKeySequence unknown_key(Qt::Key_unknown);
0100         // The keycode falls into the unicode handling
0101         QString p = QChar(QChar::highSurrogate(Qt::Key_unknown)) + QChar(QChar::lowSurrogate(Qt::Key_unknown));
0102 
0103 #if QT_VERSION < 0x050000
0104         QCOMPARE(unknown_key.toString(), p); // What happens in Qt4
0105 #else
0106         QCOMPARE(unknown_key.toString(), QString());     // What i would expect, and which happens in Qt5
0107 #endif
0108 
0109         // Check that the keycode -1 is handled gracefully.
0110         //
0111         // -1 happens for some keys when listening to keyPressEvent in QWidget::event()
0112         // It means the key is not supported by Qt. It probably should be
0113         // Qt::Key_unknown instead. Unsupported keys: (Alt+Print for example).
0114         // Reported with patch - mjansen
0115         QKeySequence invalid_key(-1);
0116         // The keycode falls into the unicode handling too
0117         int k = int(-1) & ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier);
0118         QString p1 = QChar(QChar::highSurrogate(k)) + QChar(QChar::lowSurrogate(k));
0119 
0120 #if QT_VERSION < 0x050000
0121         QCOMPARE(invalid_key.toString(), QString("Meta+Ctrl+Alt+Shift+" + p1)); // What happens
0122 #else
0123         QCOMPARE(invalid_key.toString(), QString());     // What i would expect
0124 #endif
0125 
0126         // The famous "KDE4 eats my E key" bug: Win+E isn't parsed anymore.
0127         QKeySequence seq("Win+E");
0128         QEXPECT_FAIL("", "Qt Bug 205255/134941 - QKeySequence silently discards unknown key modifiers", Continue);
0129         QVERIFY(seq.isEmpty());
0130         // And what really happens
0131 #if QT_VERSION < 0x050000
0132         QCOMPARE(seq.toString(), QLatin1String("E"));
0133 #else
0134         QCOMPARE(seq.toString(), QString());
0135 #endif
0136 
0137         // KDE3 -> KDE4 migration. KDE3 used xKeycodeToKeysym or something and
0138         // stored the result
0139         QKeySequence seq2("Meta+Alt+Period");
0140         QEXPECT_FAIL("", "Qt Bug 205255/134941 - QKeySequence silently discards unknown key modifiers", Continue);
0141         QVERIFY(seq2.isEmpty());
0142         // And what really happens
0143 #if QT_VERSION < 0x050000
0144         QCOMPARE(seq2.toString(), QLatin1String("Meta+Alt+"));
0145 #else
0146         QCOMPARE(seq2.toString(), QString());
0147 #endif
0148     }
0149 
0150     void parsing()
0151     {
0152         KShortcut cut;
0153         cut = KShortcut(";, Alt+;; ;, Alt+A, ;");
0154         QVERIFY(cut.primary() == QKeySequence::fromString(";, Alt+;"));
0155         QVERIFY(cut.alternate() == QKeySequence::fromString(";, Alt+A, ;"));
0156 
0157         cut = KShortcut("Win+E");
0158         //QTest::ignoreMessage(QtWarningMsg, "QKeySequence::fromString: Unknown modifier 'win+'");
0159         QEXPECT_FAIL("", "Qt Bug 205255 - QKeySequence silently discards unknown key modifiers", Continue);
0160         QVERIFY(cut.isEmpty());
0161 
0162         cut = KShortcut("Meta+E");
0163         QVERIFY(cut.primary()[0] == (Qt::META | Qt::Key_E));
0164 
0165         //qDebug() << QKeySequence(Qt::ALT | Qt::Key_Plus).toString();
0166         //qDebug() << QKeySequence(Qt::ALT | Qt::Key_Minus).toString();
0167         cut = KShortcut("Alt+Plus"); // KDE3 said "Alt+Plus", while Qt4 says "Alt++", so KShortcut has to handle this
0168         QVERIFY(cut.primary()[0] == (Qt::ALT | Qt::Key_Plus));
0169         cut = KShortcut("Alt+Minus"); // KDE3 said "Alt+Minus", while Qt4 says "Alt+-", so KShortcut has to handle this
0170         QVERIFY(cut.primary()[0] == (Qt::ALT | Qt::Key_Minus));
0171     }
0172 };
0173 
0174 QTEST_MAIN(tst_KShortcut)
0175 
0176 #include "kshortcuttest.moc"