/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include <QtTest/QtTest> #include <qapplication.h> #include <qtextedit.h> #include <qpushbutton.h> #include <qmainwindow.h> #include <qstatusbar.h> #include <qboxlayout.h> #include <qdebug.h> #include <qstring.h> #include <qshortcut.h> class AccelForm; QT_BEGIN_NAMESPACE class QMainWindow; class QTextEdit; QT_END_NAMESPACE //TESTED_CLASS= //TESTED_FILES= class tst_QShortcut : public QObject { Q_OBJECT public: tst_QShortcut(); virtual ~tst_QShortcut(); enum Action { SetupAccel, TestAccel, ClearAll } currentAction; enum Widget { NoWidget, TriggerSlot1, TriggerSlot2, TriggerSlot3, TriggerSlot4, TriggerSlot5, TriggerSlot6, TriggerSlot7 }; enum Result { NoResult, Slot1Triggered, Slot2Triggered, Slot3Triggered, Slot4Triggered, Slot5Triggered, Slot6Triggered, Slot7Triggered, Ambiguous } currentResult; public slots: void slotTrig1() { currentResult = Slot1Triggered; } void slotTrig2() { currentResult = Slot2Triggered; } void slotTrig3() { currentResult = Slot3Triggered; } void slotTrig4() { currentResult = Slot4Triggered; } void slotTrig5() { currentResult = Slot5Triggered; } void slotTrig6() { currentResult = Slot6Triggered; } void slotTrig7() { currentResult = Slot7Triggered; } void ambigSlot1() { currentResult = Ambiguous; ambigResult = Slot1Triggered; } void ambigSlot2() { currentResult = Ambiguous; ambigResult = Slot2Triggered; } void ambigSlot3() { currentResult = Ambiguous; ambigResult = Slot3Triggered; } void ambigSlot4() { currentResult = Ambiguous; ambigResult = Slot4Triggered; } void ambigSlot5() { currentResult = Ambiguous; ambigResult = Slot5Triggered; } void ambigSlot6() { currentResult = Ambiguous; ambigResult = Slot6Triggered; } void ambigSlot7() { currentResult = Ambiguous; ambigResult = Slot7Triggered; } void statusMessage( const QString& message ) { sbText = message; } void shortcutDestroyed(QObject* obj); public slots: void initTestCase(); void cleanupTestCase(); private slots: void number_data(); void number(); void text_data(); void text(); void disabledItems(); void ambiguousItems(); void ambiguousRotation(); void keypressConsumption(); void unicodeCompare(); void context(); protected: static Qt::KeyboardModifiers toButtons( int key ); void defElements(); void clearAllShortcuts(); QShortcut *setupShortcut(int testWidget, const QKeySequence &ks); QShortcut *setupShortcut(int testWidget, const QString &txt, int k1 = 0, int k2 = 0, int k3 = 0, int k4 = 0); QShortcut *setupShortcut(QWidget *parent, const char *name, int testWidget, const QString &txt, int k1 = 0, int k2 = 0, int k3 = 0, int k4 = 0); QShortcut *setupShortcut(QWidget *parent, const char *name, int testWidget, const QKeySequence &ks, Qt::ShortcutContext context = Qt::WindowShortcut); void sendKeyEvents(QWidget *w, int k1, QChar c1 = 0, int k2 = 0, QChar c2 = 0, int k3 = 0, QChar c3 = 0, int k4 = 0, QChar c4 = 0); void sendKeyEvents(int k1, QChar c1 = 0, int k2 = 0, QChar c2 = 0, int k3 = 0, QChar c3 = 0, int k4 = 0, QChar c4 = 0); void testElement(); QMainWindow *mainW; QList<QShortcut*> shortcuts; QTextEdit *edit; QString sbText; Result ambigResult; }; QT_BEGIN_NAMESPACE template<> struct QMetaTypeId<tst_QShortcut::Widget> { enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } }; template<> struct QMetaTypeId<tst_QShortcut::Result> { enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } }; template<> struct QMetaTypeId<tst_QShortcut::Action> { enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } }; QT_END_NAMESPACE class TestEdit : public QTextEdit { Q_OBJECT public: TestEdit(QWidget *parent, const char *name) : QTextEdit(parent) { setObjectName(name); } protected: bool event(QEvent *e) { // Make testedit allow any Ctrl+Key as shortcut if (e->type() == QEvent::ShortcutOverride) { QKeyEvent *ke = static_cast<QKeyEvent*>(e); if (ke->modifiers() == Qt::ControlModifier && ke->key() > Qt::Key_Any && ke->key() < Qt::Key_ydiaeresis) { ke->ignore(); return true; } } // If keypress not processed as normal, check for // Ctrl+Key event, and input custom string for // result comparison. if (e->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast<QKeyEvent*>(e); if (ke->modifiers() && ke->key() > Qt::Key_Any && ke->key() < Qt::Key_ydiaeresis) { if (ke->modifiers() == Qt::ControlModifier) insertPlainText(QString("<Ctrl+%1>").arg(char(ke->key()))); else if (ke->modifiers() == Qt::AltModifier) insertPlainText(QString("<Alt+%1>").arg(char(ke->key()))); else if (ke->modifiers() == Qt::ShiftModifier) insertPlainText(QString("<Shift+%1>").arg(char(ke->key()))); return true; } } return QTextEdit::event(e); } }; tst_QShortcut::tst_QShortcut(): mainW( 0 ) { } tst_QShortcut::~tst_QShortcut() { clearAllShortcuts(); } void tst_QShortcut::initTestCase() { currentResult = NoResult; mainW = new QMainWindow(0); mainW->setWindowFlags(Qt::X11BypassWindowManagerHint); edit = new TestEdit(mainW, "test_edit"); mainW->setFixedSize( 100, 100 ); mainW->setCentralWidget( edit ); mainW->show(); #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(mainW); #endif mainW->activateWindow(); QTest::qWait(100); connect( mainW->statusBar(), SIGNAL(messageChanged(const QString&)), this, SLOT(statusMessage(const QString&)) ); } void tst_QShortcut::cleanupTestCase() { delete mainW; } Qt::KeyboardModifiers tst_QShortcut::toButtons( int key ) { Qt::KeyboardModifiers result = Qt::NoModifier; if ( key & Qt::SHIFT ) result |= Qt::ShiftModifier; if ( key & Qt::CTRL ) result |= Qt::ControlModifier; if ( key & Qt::META ) result |= Qt::MetaModifier; if ( key & Qt::ALT ) result |= Qt::AltModifier; return result; } void tst_QShortcut::defElements() { QTest::addColumn<int>("action"); QTest::addColumn<int>("testWidget"); QTest::addColumn<QString>("txt"); QTest::addColumn<int>("k1"); QTest::addColumn<int>("c1"); QTest::addColumn<int>("k2"); QTest::addColumn<int>("c2"); QTest::addColumn<int>("k3"); QTest::addColumn<int>("c3"); QTest::addColumn<int>("k4"); QTest::addColumn<int>("c4"); QTest::addColumn<int>("result"); } void tst_QShortcut::number() { // We expect a failure on these tests, until QtTestKeyboard is // fixed to do real platform dependent keyboard simulations if (QTest::currentDataTag() == QString("N006a:Shift+Tab - [BackTab]") || QTest::currentDataTag() == QString("N006b:Shift+Tab - [Shift+BackTab]")) QEXPECT_FAIL("", "FLAW IN QTESTKEYBOARD: Keyboard events not passed through " "platform dependent key handling code", Continue); testElement(); } void tst_QShortcut::text() { testElement(); } // ------------------------------------------------------------------ // Number Elements -------------------------------------------------- // ------------------------------------------------------------------ void tst_QShortcut::number_data() { defElements(); // Clear all QTest::newRow("N00 - clear") << ClearAll <<0<<QString("")<<0<<0<<0<<0<<0<<0<<0<<0<<0; //=========================================== // [Shift + key] on non-shift shortcuts testing //=========================================== /* Testing Single Sequences Shift + Qt::Key_M on Qt::Key_M Qt::Key_M on Qt::Key_M Shift + Qt::Key_Plus on Qt::Key_Pluss Qt::Key_Plus on Qt::Key_Pluss */ QTest::newRow("N001 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; //commented out because the behaviour changed, those tests should be updated //QTest::newRow("N001:Shift + M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N001:M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N001 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; //commented out because the behaviour changed, those tests should be updated //QTest::newRow("N001:Shift++ [+]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("N001:+ [+]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("N001 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Shift + Qt::Key_M on Shift + Qt::Key_M Qt::Key_M on Shift + Qt::Key_M Shift + Qt::Key_Plus on Shift + Qt::Key_Pluss Qt::Key_Plus on Shift + Qt::Key_Pluss */ QTest::newRow("N002 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N002:Shift+M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N002:M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N002 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N002:Shift++ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("N002:+ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N002 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Shift + Qt::Key_F1 on Qt::Key_F1 Qt::Key_F1 on Qt::Key_F1 */ QTest::newRow("N003 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; //commented out because the behaviour changed, those tests should be updated //QTest::newRow("N003:Shift+F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N003:F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N003 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Shift + Qt::Key_F1 on Shift + Qt::Key_F1 Qt::Key_F1 on Shift + Qt::Key_F1 */ QTest::newRow("N004 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N004:Shift+F1 - [Shift+F1]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N004:F1 - [Shift+F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N004 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Qt::Key_Tab on Qt::Key_Tab Shift + Qt::Key_Tab on Qt::Key_Tab Qt::Key_Backtab on Qt::Key_Tab Shift + Qt::Key_Backtab on Qt::Key_Tab */ QTest::newRow("N005a - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N005a:Tab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; //commented out because the behaviour changed, those tests should be updated //QTest::newRow("N005a:Shift+Tab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; // (Shift+)BackTab != Tab, but Shift+BackTab == Shift+Tab QTest::newRow("N005a:Backtab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N005a:Shift+Backtab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N005a - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Qt::Key_Tab on Shift + Qt::Key_Tab Shift + Qt::Key_Tab on Shift + Qt::Key_Tab Qt::Key_Backtab on Shift + Qt::Key_Tab Shift + Qt::Key_Backtab on Shift + Qt::Key_Tab */ QTest::newRow("N005b - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N005b:Tab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N005b:Shift+Tab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N005b:BackTab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N005b:Shift+BackTab - [Shift+Tab]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N005b - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Qt::Key_Tab on Qt::Key_Backtab Shift + Qt::Key_Tab on Qt::Key_Backtab Qt::Key_Backtab on Qt::Key_Backtab Shift + Qt::Key_Backtab on Qt::Key_Backtab */ QTest::newRow("N006a - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N006a:Tab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // This should work, since platform dependent code will transform the // Shift+Tab into a Shift+BackTab, which should trigger the shortcut QTest::newRow("N006a:Shift+Tab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; //XFAIL QTest::newRow("N006a:BackTab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; //commented out because the behaviour changed, those tests should be updated //QTest::newRow("N006a:Shift+BackTab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N006a - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Qt::Key_Tab on Shift + Qt::Key_Backtab Shift + Qt::Key_Tab on Shift + Qt::Key_Backtab Qt::Key_Backtab on Shift + Qt::Key_Backtab Shift + Qt::Key_Backtab on Shift + Qt::Key_Backtab */ QTest::newRow("N006b - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N006b:Tab - [Shift+BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N006b:Shift+Tab - [Shift+BackTab]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N006b:BackTab - [Shift+BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N006b:Shift+BackTab - [Shift+BackTab]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; //XFAIL QTest::newRow("N006b - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all //=========================================== // [Shift + key] and [key] on shortcuts with // and without modifiers //=========================================== /* Testing Single Sequences Qt::Key_F1 Shift + Qt::Key_F1 */ QTest::newRow("N007 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N007 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N007:F1") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N007:Shift + F1") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("N007 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Qt::Key_M Shift + Qt::Key_M Ctrl + Qt::Key_M Alt + Qt::Key_M */ QTest::newRow("N01 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N02 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N03 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N04 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N:Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N:Shift+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("N:Ctrl+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N:Alt+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; /* Testing Single Sequence Ambiguity Qt::Key_M on shortcut2 */ QTest::newRow("N05 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N:Qt::Key_M on slot") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Ambiguous; QTest::newRow("N05 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Specialkeys Qt::Key_aring Qt::Key_Aring Qt::UNICODE_ACCEL + Qt::Key_K */ QTest::newRow("N06 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N07 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N08 - slot2") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::UNICODE_ACCEL + Qt::Key_K) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N:Qt::Key_aring") << TestAccel << NoWidget << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N:Qt::Key_Aring") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("N:Qt::Key_aring - Text Form") << TestAccel << NoWidget << QString("") << 0 << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N:Qt::Key_Aring - Text Form") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+0) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("N:Qt::UNICODE_ACCEL + Qt::Key_K") << TestAccel << NoWidget << QString("") << int(Qt::UNICODE_ACCEL + Qt::Key_K) << int('k') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N09 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Multiple Sequences Qt::Key_M Qt::Key_I, Qt::Key_M Shift+Qt::Key_I, Qt::Key_M */ QTest::newRow("N10 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N11 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_I) << 0 << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N12 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_I) << 0 << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("N:Qt::Key_M (2)") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N:Qt::Key_I, Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_I) << int('i') << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("N:Shift+Qt::Key_I, Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_I) << int('I') << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("N13 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all } // ------------------------------------------------------------------ // Text Elements ---------------------------------------------------- // ------------------------------------------------------------------ void tst_QShortcut::text_data() { defElements(); // Clear all QTest::newRow("T00 - clear") << ClearAll <<0<<QString("")<<0<<0<<0<<0<<0<<0<<0<<0<<0; //=========================================== // [Shift + key] on non-shift shortcuts testing //=========================================== /* Testing Single Sequences Shift + Qt::Key_M on Qt::Key_M Qt::Key_M on Qt::Key_M Shift + Qt::Key_Plus on Qt::Key_Pluss Qt::Key_Plus on Qt::Key_Pluss */ QTest::newRow("T001 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; //commented out because the behaviour changed, those tests should be updated //QTest::newRow("T001:Shift+M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T001:M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T001 - slot2") << SetupAccel << TriggerSlot2 << QString("+") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; //commented out because the behaviour changed, those tests should be updated //QTest::newRow("T001:Shift++ [+]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("T001:+ [+]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("T001 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Shift + Qt::Key_M on Shift + Qt::Key_M Qt::Key_M on Shift + Qt::Key_M Shift + Qt::Key_Plus on Shift + Qt::Key_Pluss Qt::Key_Plus on Shift + Qt::Key_Pluss Shift + Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Pluss Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Pluss */ QTest::newRow("T002 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T002:Shift+M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T002:M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T002 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift++") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T002:Shift++ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("T002:+ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T002 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Shift + Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Plus Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Plus Qt::Key_Plus on Ctrl + Qt::Key_Plus */ QTest::newRow("T002b - slot1") << SetupAccel << TriggerSlot1 << QString("Ctrl++") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; //commented out because the behaviour changed, those tests should be updated //QTest::newRow("T002b:Shift+Ctrl++ [Ctrl++]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::CTRL + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T002b:Ctrl++ [Ctrl++]") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T002b:+ [Ctrl++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T002b - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Shift + Qt::Key_F1 on Qt::Key_F1 Qt::Key_F1 on Qt::Key_F1 */ QTest::newRow("T003 - slot1") << SetupAccel << TriggerSlot1 << QString("F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; //commented out because the behaviour changed, those tests should be updated //QTest::newRow("T003:Shift+F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T003:F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T003 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Shift + Qt::Key_F1 on Shift + Qt::Key_F1 Qt::Key_F1 on Shift + Qt::Key_F1 */ QTest::newRow("T004 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T004:Shift+F1 - [Shift+F1]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T004:F1 - [Shift+F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T004 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all //=========================================== // [Shift + key] and [key] on shortcuts with // and without modifiers //=========================================== /* Testing Single Sequences Qt::Key_F1 Shift + Qt::Key_F1 */ QTest::newRow("T007 - slot1") << SetupAccel << TriggerSlot1 << QString("F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T007 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T007:F1") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T007:Shift + F1") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("T007 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Sequences Qt::Key_M Shift + Qt::Key_M Ctrl + Qt::Key_M Alt + Qt::Key_M */ QTest::newRow("T01 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T02 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T03 - slot1") << SetupAccel << TriggerSlot1 << QString("Ctrl+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T04 - slot2") << SetupAccel << TriggerSlot2 << QString("Alt+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T:Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T:Shift + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("T:Ctrl + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T:Alt + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; /* Testing Single Sequence Ambiguity Qt::Key_M on shortcut2 */ QTest::newRow("T05 - slot2") << SetupAccel << TriggerSlot2 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T:Qt::Key_M on TriggerSlot2") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Ambiguous; QTest::newRow("T06 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Single Specialkeys Qt::Key_aring Qt::Key_Aring Qt::UNICODE_ACCEL + Qt::Key_K */ /* see comments above on the #ifdef'ery */ QTest::newRow("T06 - slot1") << SetupAccel << TriggerSlot1 << QString("\x0C5")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T07 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+\x0C5")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T08 - slot2") << SetupAccel << TriggerSlot1 << QString("K") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T:Qt::Key_aring") << TestAccel << NoWidget << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T:Qt::Key_Aring") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("T:Qt::Key_aring - Text Form") << TestAccel << NoWidget << QString("") << 0 << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T:Qt::Key_Aring - Text Form") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+0) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("T:Qt::UNICODE_ACCEL + Qt::Key_K") << TestAccel << NoWidget << QString("") << int(Qt::UNICODE_ACCEL + Qt::Key_K) << int('k') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T09 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all /* Testing Multiple Sequences Qt::Key_M Qt::Key_I, Qt::Key_M Shift+Qt::Key_I, Qt::Key_M */ QTest::newRow("T10 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T11 - slot2") << SetupAccel << TriggerSlot2 << QString("I, M")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T12 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+I, M")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; QTest::newRow("T:Qt::Key_M (2)") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T:Qt::Key_I, Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_I) << int('i') << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << Slot2Triggered; QTest::newRow("T:Shift+Qt::Key_I, Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_I) << int('I') << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << Slot1Triggered; QTest::newRow("T13 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all } // ------------------------------------------------------------------ // Disabled Elements ------------------------------------------------ // ------------------------------------------------------------------ void tst_QShortcut::disabledItems() { clearAllShortcuts(); mainW->activateWindow(); qApp->syncX(); QTest::qWait(100); /* Testing Disabled Shortcuts Qt::Key_M on slot1 Shift + Qt::Key_M on slot1 Qt::Key_M on slot2 (disabled) Shift + Qt::Key_M on slot2 (disabled) */ // Setup two identical shortcuts on different pushbuttons QPushButton pb1(mainW); QPushButton pb2(mainW); pb1.setObjectName("pushbutton-1"); pb2.setObjectName("pushbutton-2"); pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger pb2.show(); QShortcut *cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "M"); QShortcut *cut2 = setupShortcut(&pb1, "shortcut2-pb1", TriggerSlot1, "Shift+M"); QShortcut *cut3 = setupShortcut(&pb2, "shortcut3-pb2", TriggerSlot2, "M"); QShortcut *cut4 = setupShortcut(&pb2, "shortcut4-pb2", TriggerSlot2, "Shift+M"); cut3->setEnabled(false); cut4->setEnabled(false); currentResult = NoResult; sendKeyEvents(Qt::Key_M, 'm'); QCOMPARE(currentResult, Slot1Triggered); currentResult = NoResult; sendKeyEvents(Qt::SHIFT+Qt::Key_M, 'M'); QCOMPARE(currentResult, Slot1Triggered); cut2->setEnabled(false); cut4->setEnabled(true); /* Testing Disabled Shortcuts Qt::Key_M on slot1 Shift + Qt::Key_M on slot1 (disabled) Qt::Key_M on slot2 (disabled) Shift + Qt::Key_M on slot2 */ currentResult = NoResult; sendKeyEvents( Qt::Key_M, 'm' ); QCOMPARE( currentResult, Slot1Triggered ); currentResult = NoResult; sendKeyEvents( Qt::SHIFT+Qt::Key_M, 'M' ); QCOMPARE( currentResult, Slot2Triggered ); /* Testing Disabled Accel Qt::Key_F5 on slot1 Shift + Qt::Key_F5 on slot2 (disabled) */ clearAllShortcuts(); cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "F5"); cut4 = setupShortcut(&pb2, "shortcut4-pb2", TriggerSlot2, "Shift+F5"); cut1->setKey(QKeySequence("F5")); cut4->setKey(QKeySequence("Shift+F5")); cut1->setEnabled(true); cut4->setEnabled(false); currentResult = NoResult; sendKeyEvents( Qt::Key_F5, 0 ); QCOMPARE( currentResult, Slot1Triggered ); currentResult = NoResult; sendKeyEvents( Qt::SHIFT+Qt::Key_F5, 0 ); QCOMPARE( currentResult, NoResult ); #if 0 qFatal("Not testing statusbar text feedback yet, since not implemented"); /* Testing Disabled Accel, and the corresponding statusbar feedback Ctrl + Qt::Key_K, Ctrl + Qt::Key_L on slot1 Ctrl + Qt::Key_K, Ctrl + Qt::Key_M on slot2 (disabled) */ cut1->setKey(QKeySequence("Ctrl+K, Ctrl+L")); cut4->setKey(QKeySequence("Ctrl+K, Ctrl+M")); cut1->setEnabled(true); cut4->setEnabled(false); currentResult = NoResult; sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 ); sendKeyEvents( Qt::CTRL+Qt::Key_Q, 0 ); QCOMPARE( currentResult, NoResult ); if (over_330) QCOMPARE( sbText, QString("Ctrl+K, Ctrl+Q not defined") ); currentResult = NoResult; sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 ); sendKeyEvents( Qt::CTRL+Qt::Key_M, 0 ); QCOMPARE( currentResult, NoResult ); if (over_330) QCOMPARE( sbText, QString::null ); currentResult = NoResult; sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 ); sendKeyEvents( Qt::CTRL+Qt::Key_L, 0 ); QCOMPARE( currentResult, Slot1Triggered ); if (over_330) QCOMPARE( sbText, QString::null ); #endif clearAllShortcuts(); cut1 = 0; cut4 = 0; } // ------------------------------------------------------------------ // Ambiguous Elements ----------------------------------------------- // ------------------------------------------------------------------ void tst_QShortcut::ambiguousRotation() { clearAllShortcuts(); /* Testing Shortcut rotation scheme Ctrl + Qt::Key_A on slot1 (disabled) Ctrl + Qt::Key_A on slot2 (disabled) Ctrl + Qt::Key_A on slot3 Ctrl + Qt::Key_A on slot4 Ctrl + Qt::Key_A on slot5 (disabled) Ctrl + Qt::Key_A on slot6 Ctrl + Qt::Key_A on slot7 (disabled) */ QShortcut *cut1 = setupShortcut(TriggerSlot1, "Ctrl+A"); QShortcut *cut2 = setupShortcut(TriggerSlot2, "Ctrl+A"); QShortcut *cut3 = setupShortcut(TriggerSlot3, "Ctrl+A"); QShortcut *cut4 = setupShortcut(TriggerSlot4, "Ctrl+A"); QShortcut *cut5 = setupShortcut(TriggerSlot5, "Ctrl+A"); QShortcut *cut6 = setupShortcut(TriggerSlot6, "Ctrl+A"); QShortcut *cut7 = setupShortcut(TriggerSlot7, "Ctrl+A"); cut1->setEnabled(false); cut2->setEnabled(false); cut5->setEnabled(false); cut7->setEnabled(false); // Test proper rotation // Start on first // Go to last // Go back to first // Continue... currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot3Triggered); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot4Triggered); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot6Triggered); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot3Triggered); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot4Triggered); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot6Triggered); /* Testing Shortcut rotation scheme Ctrl + Qt::Key_A on slot1 Ctrl + Qt::Key_A on slot2 Ctrl + Qt::Key_A on slot3 (disabled) Ctrl + Qt::Key_A on slot4 (disabled) Ctrl + Qt::Key_A on slot5 Ctrl + Qt::Key_A on slot6 (disabled) Ctrl + Qt::Key_A on slot7 */ cut1->setEnabled(true); cut2->setEnabled(true); cut5->setEnabled(true); cut7->setEnabled(true); cut3->setEnabled(false); cut4->setEnabled(false); cut6->setEnabled(false); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot1Triggered); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot2Triggered); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot5Triggered); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot7Triggered); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot1Triggered); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot2Triggered); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot5Triggered); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(Qt::CTRL+Qt::Key_A); QCOMPARE(currentResult, Ambiguous); QCOMPARE(ambigResult, Slot7Triggered); clearAllShortcuts(); cut1 = 0; cut2 = 0; cut3 = 0; cut4 = 0; cut5 = 0; cut6 = 0; cut7 = 0; } void tst_QShortcut::ambiguousItems() { clearAllShortcuts(); /* Testing Ambiguous Shortcuts Qt::Key_M on Pushbutton 1 Qt::Key_M on Pushbutton 2 */ // Setup two identical shortcuts on different pushbuttons QPushButton pb1(mainW); QPushButton pb2(mainW); pb1.setObjectName("pushbutton-1"); pb2.setObjectName("pushbutton-2"); pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger pb2.show(); QShortcut *cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "M"); QShortcut *cut2 = setupShortcut(&pb1, "shortcut2-pb2", TriggerSlot2, "M"); currentResult = NoResult; sendKeyEvents( Qt::Key_M, 'm' ); QCOMPARE( currentResult, Ambiguous ); QCOMPARE( ambigResult, Slot1Triggered ); currentResult = NoResult; sendKeyEvents( Qt::Key_M, 'm' ); QCOMPARE( currentResult, Ambiguous ); QCOMPARE( ambigResult, Slot2Triggered ); currentResult = NoResult; sendKeyEvents( Qt::Key_M, 'm' ); QCOMPARE( currentResult, Ambiguous ); QCOMPARE( ambigResult, Slot1Triggered ); clearAllShortcuts(); cut1 = 0; cut2 = 0; } // ------------------------------------------------------------------ // Unicode and non-unicode Elements --------------------------------- // ------------------------------------------------------------------ void tst_QShortcut::unicodeCompare() { clearAllShortcuts(); /* Testing Unicode/non-Unicode Shortcuts Qt::Key_M on Pushbutton 1 Qt::Key_M on Pushbutton 2 */ QPushButton pb1(mainW); QPushButton pb2(mainW); pb1.setObjectName("pushbutton-1"); pb2.setObjectName("pushbutton-2"); pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger pb2.show(); QKeySequence ks1("Ctrl+M"); // Unicode QKeySequence ks2(Qt::CTRL+Qt::Key_M); // non-Unicode QShortcut *cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, ks1); QShortcut *cut2 = setupShortcut(&pb1, "shortcut2-pb2", TriggerSlot2, ks2); currentResult = NoResult; sendKeyEvents( Qt::CTRL+Qt::Key_M, 0 ); QCOMPARE( currentResult, Ambiguous ); // They _are_ ambiguous, so the QKeySequence operator== // should indicate the same QVERIFY( ks1 == ks2 ); QVERIFY( !(ks1 != ks2) ); clearAllShortcuts(); cut1 = 0; cut2 = 0; } // ------------------------------------------------------------------ // Keypress consumption verification -------------------------------- // ------------------------------------------------------------------ void tst_QShortcut::keypressConsumption() { clearAllShortcuts(); edit->clear(); QCOMPARE(edit->toPlainText().size(), 0); QShortcut *cut1 = setupShortcut(edit, "shortcut1-line", TriggerSlot1, "Ctrl+I, A"); QShortcut *cut2 = setupShortcut(edit, "shortcut1-line", TriggerSlot2, "Ctrl+I, B"); currentResult = NoResult; ambigResult = NoResult; sendKeyEvents(edit, Qt::CTRL + Qt::Key_I, 0); // Send key to edit QCOMPARE( currentResult, NoResult ); QCOMPARE( ambigResult, NoResult ); QCOMPARE(edit->toPlainText(), QString("")); // Make sure next keypress is eaten (failing multiple keysequence) sendKeyEvents(edit, Qt::Key_C, 'c'); // Send key to edit QCOMPARE( currentResult, NoResult ); QCOMPARE( ambigResult, NoResult ); QCOMPARE(edit->toPlainText(), QString("")); // Next keypress should be normal sendKeyEvents(edit, Qt::Key_C, 'c'); // Send key to edit QCOMPARE( currentResult, NoResult ); QCOMPARE( ambigResult, NoResult ); QCOMPARE(edit->toPlainText(), QString("c")); currentResult = NoResult; ambigResult = NoResult; edit->clear(); QCOMPARE(edit->toPlainText().size(), 0); cut1->setEnabled(false); cut2->setEnabled(false); // Make sure keypresses is passed on, since all multiple keysequences // with Ctrl+I are disabled sendKeyEvents(edit, Qt::CTRL + Qt::Key_I, 0); // Send key to edit QCOMPARE( currentResult, NoResult ); QCOMPARE( ambigResult, NoResult ); QVERIFY(edit->toPlainText().endsWith("<Ctrl+I>")); sendKeyEvents(edit, Qt::Key_A, 'a'); // Send key to edit QCOMPARE( currentResult, NoResult ); QCOMPARE( ambigResult, NoResult ); QVERIFY(edit->toPlainText().endsWith("<Ctrl+I>a")); clearAllShortcuts(); } // ------------------------------------------------------------------ // Context Validation ----------------------------------------------- // ------------------------------------------------------------------ void tst_QShortcut::context() { clearAllShortcuts(); QWidget myBox; TestEdit *other1 = new TestEdit(&myBox, "test_edit_other1"); TestEdit *other2 = new TestEdit(&myBox, "test_edit_other2"); QHBoxLayout *layout = new QHBoxLayout(&myBox); layout->addWidget(other1); layout->addWidget(other2); myBox.show(); #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(&myBox); #endif setupShortcut(other1, "ActiveWindow", TriggerSlot1, QKeySequence("Alt+1"), Qt::WindowShortcut); setupShortcut(other2, "Focus", TriggerSlot2, QKeySequence("Alt+2"), Qt::WidgetShortcut); setupShortcut(edit, "Application", TriggerSlot3, QKeySequence("Alt+3"), Qt::ApplicationShortcut); currentResult = NoResult; ambigResult = NoResult; edit->clear(); other1->clear(); other2->clear(); // edit doens't have focus, so ActiveWindow context should work // ..but Focus context shouldn't.. // Changing focus to edit should make focus context work // Application context should always work // Focus on 'other1' edit, so Active Window context should trigger other1->activateWindow(); // <--- QApplication::setActiveWindow(other1); QCOMPARE(qApp->activeWindow(), other1->window()); QCOMPARE(qApp->focusWidget(), (QWidget *)other1); currentResult = NoResult; ambigResult = NoResult; edit->clear(); other1->clear(); other2->clear(); QCOMPARE(qApp->focusWidget(), (QWidget *)other1); sendKeyEvents(other1, Qt::ALT+Qt::Key_1); QCOMPARE(currentResult, Slot1Triggered); QCOMPARE(ambigResult, NoResult); QCOMPARE(edit->toPlainText(), QString("")); QCOMPARE(other1->toPlainText(), QString("")); QCOMPARE(other2->toPlainText(), QString("")); // ..but not Focus context on 'other2'.. currentResult = NoResult; ambigResult = NoResult; edit->clear(); other1->clear(); other2->clear(); sendKeyEvents(other1, Qt::ALT+Qt::Key_2); QCOMPARE(currentResult, NoResult); QCOMPARE(ambigResult, NoResult); QCOMPARE(edit->toPlainText(), QString("")); QCOMPARE(other1->toPlainText(), QString("<Alt+2>")); QCOMPARE(other2->toPlainText(), QString("")); // ..however, application global context on 'edit' should.. currentResult = NoResult; ambigResult = NoResult; edit->clear(); other1->clear(); other2->clear(); sendKeyEvents(other1, Qt::ALT+Qt::Key_3); QCOMPARE(currentResult, Slot3Triggered); QCOMPARE(ambigResult, NoResult); QCOMPARE(edit->toPlainText(), QString("")); QCOMPARE(other1->toPlainText(), QString("")); QCOMPARE(other2->toPlainText(), QString("")); // Changing focus to 'other2' should make the Focus context there work other2->activateWindow(); other2->setFocus(); // ### qApp->syncX(); #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(other2); #endif QTest::qWait(100); QCOMPARE(qApp->activeWindow(), other2->window()); QCOMPARE(qApp->focusWidget(), (QWidget *)other2); currentResult = NoResult; ambigResult = NoResult; edit->clear(); other1->clear(); other2->clear(); sendKeyEvents(other2, Qt::ALT+Qt::Key_2); QCOMPARE(currentResult, Slot2Triggered); QCOMPARE(ambigResult, NoResult); QCOMPARE(edit->toPlainText(), QString("")); QCOMPARE(other1->toPlainText(), QString("")); QCOMPARE(other2->toPlainText(), QString("")); clearAllShortcuts(); delete other1; delete other2; edit->activateWindow(); qApp->syncX(); #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(edit); #endif QTest::qWait(100); } // ------------------------------------------------------------------ // Element Testing helper functions --------------------------------- // ------------------------------------------------------------------ void tst_QShortcut::clearAllShortcuts() { qDeleteAll(shortcuts); shortcuts.clear(); } QShortcut *tst_QShortcut::setupShortcut(int testWidget, const QKeySequence &ks) { return setupShortcut(mainW, QTest::currentDataTag() ? QTest::currentDataTag() : "", testWidget, ks); } QShortcut *tst_QShortcut::setupShortcut(int testWidget, const QString &txt, int k1, int k2, int k3, int k4) { return setupShortcut(mainW, QTest::currentDataTag() ? QTest::currentDataTag() : "", testWidget, (txt.isEmpty() ? QKeySequence(k1, k2, k3, k4) : QKeySequence(txt))); } QShortcut *tst_QShortcut::setupShortcut(QWidget *parent, const char *name, int testWidget, const QString &txt, int k1, int k2, int k3, int k4) { return setupShortcut(parent, name, testWidget, (txt.isEmpty() ? QKeySequence(k1, k2, k3, k4) : QKeySequence(txt))); } QShortcut *tst_QShortcut::setupShortcut(QWidget *parent, const char *name, int testWidget, const QKeySequence &ks, Qt::ShortcutContext context) { // Set up shortcut for next test QShortcut *cut = new QShortcut(QKeySequence(), parent, 0, 0, context); cut->setObjectName(name); cut->setKey(ks); const char *normal = 0; const char *ambig = 0; switch(testWidget) { case TriggerSlot1: normal = SLOT(slotTrig1()); ambig = SLOT(ambigSlot1()); break; case TriggerSlot2: normal = SLOT(slotTrig2()); ambig = SLOT(ambigSlot2()); break; case TriggerSlot3: normal = SLOT(slotTrig3()); ambig = SLOT(ambigSlot3()); break; case TriggerSlot4: normal = SLOT(slotTrig4()); ambig = SLOT(ambigSlot4()); break; case TriggerSlot5: normal = SLOT(slotTrig5()); ambig = SLOT(ambigSlot5()); break; case TriggerSlot6: normal = SLOT(slotTrig6()); ambig = SLOT(ambigSlot6()); break; case TriggerSlot7: normal = SLOT(slotTrig7()); ambig = SLOT(ambigSlot7()); break; } connect(cut, SIGNAL(activated()), this, normal); connect(cut, SIGNAL(activatedAmbiguously()), this, ambig); connect(cut, SIGNAL(destroyed(QObject*)), this, SLOT(shortcutDestroyed(QObject*))); shortcuts.append(cut); return cut; } void tst_QShortcut::shortcutDestroyed(QObject* obj) { shortcuts.removeAll(static_cast<QShortcut *>(obj)); } void tst_QShortcut::sendKeyEvents(int k1, QChar c1, int k2, QChar c2, int k3, QChar c3, int k4, QChar c4) { sendKeyEvents(mainW, k1, c1, k2, c2, k3, c3, k4, c4); } void tst_QShortcut::sendKeyEvents(QWidget *w, int k1, QChar c1, int k2, QChar c2, int k3, QChar c3, int k4, QChar c4) { Qt::KeyboardModifiers b1 = toButtons( k1 ); Qt::KeyboardModifiers b2 = toButtons( k2 ); Qt::KeyboardModifiers b3 = toButtons( k3 ); Qt::KeyboardModifiers b4 = toButtons( k4 ); k1 &= ~Qt::MODIFIER_MASK; k2 &= ~Qt::MODIFIER_MASK; k3 &= ~Qt::MODIFIER_MASK; k4 &= ~Qt::MODIFIER_MASK; if (k1 || c1.toAscii()) { QString c(c1.unicode() == QChar::Null ? QString() : QString(c1)); QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k1), c, b1); QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k1), c, b1); } if (k2 || c2.toAscii()) { QString c(c2.unicode() == QChar::Null ? QString() : QString(c2)); QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k2), c, b2); QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k2), c, b2); } if (k3 || c3.toAscii()) { QString c(c3.unicode() == QChar::Null ? QString() : QString(c3)); QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k3), c, b3); QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k3), c, b3); } if (k4 || c4.toAscii()) { QString c(c4.unicode() == QChar::Null ? QString() : QString(c4)); QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k4), c, b4); QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k4), c, b4); } } void tst_QShortcut::testElement() { currentResult = NoResult; QFETCH(int, action); QFETCH(int, testWidget); QFETCH(QString, txt); QFETCH(int, k1); QFETCH(int, c1); QFETCH(int, k2); QFETCH(int, c2); QFETCH(int, k3); QFETCH(int, c3); QFETCH(int, k4); QFETCH(int, c4); QFETCH(int, result); if (action == ClearAll) { clearAllShortcuts(); QCOMPARE(TRUE, TRUE); } else if (action == SetupAccel) { setupShortcut(testWidget, txt, k1, k2, k3, k4); QCOMPARE(TRUE, TRUE); } else { sendKeyEvents(k1, c1, k2, c2, k3, c3, k4, c4); QCOMPARE(int(currentResult), result); } } QTEST_MAIN(tst_QShortcut) #include "tst_qshortcut.moc"