tst_QShortcut: Remove test widget and other member variables

Remove the mainW, edit widget member variables from the test and use
widgets instantiated on the stack in the tests.

For the data-driven tests, use a static QScopedPointer, which is
reset by a newly introduced TestEnd action.

The book-keeping logic maintaining a list of shortcuts can then be
removed.

The setupShortcut() helpers are simplified and the special case
TestWidget::SendKeyEvent is replaced by a lambda in
keypressConsumption().

Task-number: QTBUG-76493
Change-Id: I15dfa86dfa0666ed8288b7190e37cdb862c261c8
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
Friedemann Kleint 2019-07-02 14:15:04 +02:00
parent 9ea53c4a98
commit e5ab131c18

View File

@ -50,14 +50,12 @@ class tst_QShortcut : public QObject
{
Q_OBJECT
public:
tst_QShortcut();
virtual ~tst_QShortcut();
enum Action {
SetupAccel,
TestAccel,
ClearAll
ClearAll,
TestEnd
};
Q_ENUM(Action)
@ -70,7 +68,6 @@ public:
TriggerSlot5,
TriggerSlot6,
TriggerSlot7,
SendKeyEvent
};
Q_ENUM(Widget)
@ -85,7 +82,7 @@ public:
Slot7Triggered,
SentKeyEvent,
Ambiguous
} currentResult;
} currentResult = NoResult;
Q_ENUM(Result)
public slots:
@ -103,15 +100,9 @@ public slots:
void ambigSlot5() { currentResult = Ambiguous; ambigResult = Slot5Triggered; }
void ambigSlot6() { currentResult = Ambiguous; ambigResult = Slot6Triggered; }
void ambigSlot7() { currentResult = Ambiguous; ambigResult = Slot7Triggered; }
void shortcutDestroyed(QObject* obj);
void sendKeyEvent() { sendKeyEvents(edit, Qt::CTRL + Qt::Key_B, 0); currentResult = SentKeyEvent; }
public slots:
void initTestCase();
void cleanupTestCase();
void cleanup() { QCOMPARE(QApplication::topLevelWidgets().size(), 1); }
private slots:
void cleanup();
void number_data();
void number();
void text_data();
@ -129,21 +120,16 @@ protected:
static Qt::KeyboardModifiers toButtons( int key );
void defElements();
void clearAllShortcuts();
QShortcut *setupShortcut(Widget testWidget, const QKeySequence &ks);
QShortcut *setupShortcut(Widget testWidget, const QString &txt, int k1 = 0, int k2 = 0, int k3 = 0, int k4 = 0);
QShortcut *setupShortcut(QWidget *parent, const QString &name, const QKeySequence &ks,
Qt::ShortcutContext context = Qt::WindowShortcut);
QShortcut *setupShortcut(QWidget *parent, const QString &name, Widget testWidget,
const QKeySequence &ks, Qt::ShortcutContext context = Qt::WindowShortcut);
QShortcut *setupShortcut(QWidget *parent, const char *name, Widget testWidget, const QString &txt, int k1 = 0, int k2 = 0, int k3 = 0, int k4 = 0);
QShortcut *setupShortcut(QWidget *parent, const char *name, Widget 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);
static 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 testElement();
QMainWindow *mainW;
QList<QShortcut*> shortcuts;
QTextEdit *edit;
Result ambigResult;
};
@ -192,31 +178,28 @@ protected:
}
};
tst_QShortcut::tst_QShortcut(): mainW( nullptr )
class MainWindow : public QMainWindow
{
public:
MainWindow();
TestEdit *testEdit() const { return m_testEdit; }
private:
TestEdit *m_testEdit;
};
MainWindow::MainWindow()
{
setWindowFlags(Qt::X11BypassWindowManagerHint);
m_testEdit = new TestEdit(this, "test_edit");
setCentralWidget(m_testEdit);
setFixedSize(200, 200);
}
tst_QShortcut::~tst_QShortcut()
void tst_QShortcut::cleanup()
{
clearAllShortcuts();
}
void tst_QShortcut::initTestCase()
{
currentResult = NoResult;
mainW = new QMainWindow(nullptr);
mainW->setWindowFlags(Qt::X11BypassWindowManagerHint);
edit = new TestEdit(mainW, "test_edit");
mainW->setFixedSize( 200, 200 );
mainW->setCentralWidget( edit );
mainW->show();
mainW->activateWindow();
QVERIFY(QTest::qWaitForWindowActive(mainW));
}
void tst_QShortcut::cleanupTestCase()
{
delete mainW;
QVERIFY(QApplication::topLevelWidgets().size() <= 1); // The data driven tests keep a widget around
}
Qt::KeyboardModifiers tst_QShortcut::toButtons( int key )
@ -448,7 +431,7 @@ void tst_QShortcut::number_data()
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 << NoWidget << QString() << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
QTest::newRow("N:end") << TestEnd << NoWidget << QString() << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
}
// ------------------------------------------------------------------
@ -592,7 +575,35 @@ void tst_QShortcut::text_data()
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 << NoWidget << QString() << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
QTest::newRow("T:end") << TestEnd << NoWidget << QString() << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
}
class ButtonWidget : public QWidget
{
public:
ButtonWidget();
QPushButton *pushButton1() const { return m_pb1; }
QPushButton *pushButton2() const { return m_pb2; }
private:
QPushButton *m_pb1;
QPushButton *m_pb2;
};
ButtonWidget::ButtonWidget()
{
// Setup two identical shortcuts on different pushbuttons
QString name = QLatin1String("pushbutton-1");
m_pb1 = new QPushButton(name, this);
m_pb1->setObjectName(name);
name = QLatin1String("pushbutton-2");
m_pb2 = new QPushButton(name, this);
m_pb2->setObjectName(name);
auto hLayout = new QHBoxLayout(this);
hLayout->addWidget(m_pb1);
hLayout->addWidget(m_pb2);
hLayout->addStretch();
}
// ------------------------------------------------------------------
@ -600,9 +611,11 @@ void tst_QShortcut::text_data()
// ------------------------------------------------------------------
void tst_QShortcut::disabledItems()
{
clearAllShortcuts();
mainW->activateWindow();
QVERIFY(QTest::qWaitForWindowActive(mainW));
ButtonWidget mainW;
mainW.setWindowTitle(QTest::currentTestFunction());
mainW.show();
mainW.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&mainW));
/* Testing Disabled Shortcuts
Qt::Key_M on slot1
@ -612,27 +625,27 @@ void tst_QShortcut::disabledItems()
*/
// 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");
auto pb1 = mainW.pushButton1();
auto pb2 = mainW.pushButton2();
const int shiftM = Qt::SHIFT + Qt::Key_M;
QShortcut *cut1 = setupShortcut(pb1, "shortcut1-pb1", TriggerSlot1,
QKeySequence(Qt::Key_M));
QShortcut *cut2 = setupShortcut(pb1, "shortcut2-pb1", TriggerSlot1,
QKeySequence(shiftM));
QShortcut *cut3 = setupShortcut(pb2, "shortcut3-pb2", TriggerSlot2,
QKeySequence(Qt::Key_M));
QShortcut *cut4 = setupShortcut(pb2, "shortcut4-pb2", TriggerSlot2,
QKeySequence(shiftM));
cut3->setEnabled(false);
cut4->setEnabled(false);
currentResult = NoResult;
sendKeyEvents(Qt::Key_M, 'm');
sendKeyEvents(&mainW, Qt::Key_M, 'm');
QCOMPARE(currentResult, Slot1Triggered);
currentResult = NoResult;
sendKeyEvents(Qt::SHIFT+Qt::Key_M, 'M');
sendKeyEvents(&mainW, shiftM, 'M');
QCOMPARE(currentResult, Slot1Triggered);
cut2->setEnabled(false);
@ -645,11 +658,11 @@ void tst_QShortcut::disabledItems()
Shift + Qt::Key_M on slot2
*/
currentResult = NoResult;
sendKeyEvents( Qt::Key_M, 'm' );
sendKeyEvents(&mainW, Qt::Key_M, 'm' );
QCOMPARE( currentResult, Slot1Triggered );
currentResult = NoResult;
sendKeyEvents( Qt::SHIFT+Qt::Key_M, 'M' );
sendKeyEvents(&mainW, shiftM, 'M' );
QCOMPARE( currentResult, Slot2Triggered );
@ -657,32 +670,34 @@ void tst_QShortcut::disabledItems()
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"));
qDeleteAll(mainW.findChildren<QShortcut *>());
const int shiftF5 = Qt::SHIFT + Qt::Key_F5;
cut1 = setupShortcut(pb1, "shortcut1-pb1", TriggerSlot1, QKeySequence(Qt::Key_F5));
cut4 = setupShortcut(pb2, "shortcut4-pb2", TriggerSlot2, QKeySequence(shiftF5));
cut1->setEnabled(true);
cut4->setEnabled(false);
currentResult = NoResult;
sendKeyEvents( Qt::Key_F5, 0 );
sendKeyEvents(&mainW, Qt::Key_F5, 0 );
QCOMPARE( currentResult, Slot1Triggered );
currentResult = NoResult;
sendKeyEvents( Qt::SHIFT+Qt::Key_F5, 0 );
sendKeyEvents(&mainW, shiftF5, 0 );
QCOMPARE( currentResult, NoResult );
clearAllShortcuts();
}
// ------------------------------------------------------------------
// Ambiguous Elements -----------------------------------------------
// ------------------------------------------------------------------
void tst_QShortcut::ambiguousRotation()
{
clearAllShortcuts();
MainWindow mainW;
const QString name = QLatin1String(QTest::currentTestFunction());
mainW.setWindowTitle(name);
mainW.show();
mainW.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&mainW));
/* Testing Shortcut rotation scheme
Ctrl + Qt::Key_A on slot1 (disabled)
Ctrl + Qt::Key_A on slot2 (disabled)
@ -692,13 +707,15 @@ void tst_QShortcut::ambiguousRotation()
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");
const int ctrlA = Qt::CTRL + Qt::Key_A;
QKeySequence ctrlA_Sequence(ctrlA);
QShortcut *cut1 = setupShortcut(&mainW, name, TriggerSlot1, ctrlA_Sequence);
QShortcut *cut2 = setupShortcut(&mainW, name, TriggerSlot2, ctrlA_Sequence);
QShortcut *cut3 = setupShortcut(&mainW, name, TriggerSlot3, ctrlA_Sequence);
QShortcut *cut4 = setupShortcut(&mainW, name, TriggerSlot4, ctrlA_Sequence);
QShortcut *cut5 = setupShortcut(&mainW, name, TriggerSlot5, ctrlA_Sequence);
QShortcut *cut6 = setupShortcut(&mainW, name, TriggerSlot6, ctrlA_Sequence);
QShortcut *cut7 = setupShortcut(&mainW, name, TriggerSlot7, ctrlA_Sequence);
cut1->setEnabled(false);
cut2->setEnabled(false);
@ -712,37 +729,37 @@ void tst_QShortcut::ambiguousRotation()
// Continue...
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot3Triggered);
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot4Triggered);
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot6Triggered);
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot3Triggered);
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot4Triggered);
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot6Triggered);
@ -767,90 +784,87 @@ void tst_QShortcut::ambiguousRotation()
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot1Triggered);
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot2Triggered);
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot5Triggered);
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot7Triggered);
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot1Triggered);
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot2Triggered);
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot5Triggered);
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(Qt::CTRL+Qt::Key_A);
sendKeyEvents(&mainW, ctrlA);
QCOMPARE(currentResult, Ambiguous);
QCOMPARE(ambigResult, Slot7Triggered);
clearAllShortcuts();
}
void tst_QShortcut::ambiguousItems()
{
clearAllShortcuts();
ButtonWidget mainW;
mainW.setWindowTitle(QTest::currentTestFunction());
mainW.show();
mainW.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&mainW));
/* 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();
auto pb1 = mainW.pushButton1();
auto pb2 = mainW.pushButton2();
setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "M");
setupShortcut(&pb2, "shortcut2-pb2", TriggerSlot2, "M");
setupShortcut(pb1, "shortcut1-pb1", TriggerSlot1, QKeySequence(Qt::Key_M));
setupShortcut(pb2, "shortcut2-pb2", TriggerSlot2, QKeySequence(Qt::Key_M));
currentResult = NoResult;
sendKeyEvents( Qt::Key_M, 'm' );
sendKeyEvents(&mainW, Qt::Key_M, 'm' );
QCOMPARE( currentResult, Ambiguous );
QCOMPARE( ambigResult, Slot1Triggered );
currentResult = NoResult;
sendKeyEvents( Qt::Key_M, 'm' );
sendKeyEvents(&mainW, Qt::Key_M, 'm' );
QCOMPARE( currentResult, Ambiguous );
QCOMPARE( ambigResult, Slot2Triggered );
currentResult = NoResult;
sendKeyEvents( Qt::Key_M, 'm' );
sendKeyEvents(&mainW, Qt::Key_M, 'm' );
QCOMPARE( currentResult, Ambiguous );
QCOMPARE( ambigResult, Slot1Triggered );
clearAllShortcuts();
}
@ -859,32 +873,31 @@ void tst_QShortcut::ambiguousItems()
// ------------------------------------------------------------------
void tst_QShortcut::unicodeCompare()
{
clearAllShortcuts();
ButtonWidget mainW;
mainW.setWindowTitle(QTest::currentTestFunction());
mainW.show();
mainW.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&mainW));
/* 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();
auto pb1 = mainW.pushButton1();
auto pb2 = mainW.pushButton2();
QKeySequence ks1("Ctrl+M"); // Unicode
QKeySequence ks2(Qt::CTRL+Qt::Key_M); // non-Unicode
setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, ks1);
setupShortcut(&pb2, "shortcut2-pb2", TriggerSlot2, ks2);
setupShortcut(pb1, "shortcut1-pb1", TriggerSlot1, ks1);
setupShortcut(pb2, "shortcut2-pb2", TriggerSlot2, ks2);
currentResult = NoResult;
sendKeyEvents( Qt::CTRL+Qt::Key_M, 0 );
sendKeyEvents(&mainW, 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();
}
// ------------------------------------------------------------------
@ -892,16 +905,20 @@ void tst_QShortcut::unicodeCompare()
// ------------------------------------------------------------------
void tst_QShortcut::keypressConsumption()
{
clearAllShortcuts();
edit->clear();
QCOMPARE(edit->toPlainText().size(), 0);
MainWindow mainW;
mainW.setWindowTitle(QTest::currentTestFunction());
mainW.show();
mainW.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&mainW));
auto edit = mainW.testEdit();
QShortcut *cut1 = setupShortcut(edit, "shortcut1-line", TriggerSlot1, "Ctrl+I, A");
QShortcut *cut2 = setupShortcut(edit, "shortcut1-line", TriggerSlot2, "Ctrl+I, B");
const int ctrlI = Qt::CTRL + Qt::Key_I;
QShortcut *cut1 = setupShortcut(edit, "shortcut1-line", TriggerSlot1, QKeySequence(ctrlI, Qt::Key_A));
QShortcut *cut2 = setupShortcut(edit, "shortcut1-line", TriggerSlot2, QKeySequence(ctrlI, Qt::Key_B));
currentResult = NoResult;
ambigResult = NoResult;
sendKeyEvents(edit, Qt::CTRL + Qt::Key_I, 0); // Send key to edit
sendKeyEvents(edit, ctrlI, 0); // Send key to edit
QCOMPARE( currentResult, NoResult );
QCOMPARE( ambigResult, NoResult );
QCOMPARE(edit->toPlainText(), QString());
@ -938,11 +955,15 @@ void tst_QShortcut::keypressConsumption()
QCOMPARE( ambigResult, NoResult );
QVERIFY(edit->toPlainText().endsWith("<Ctrl+I>a"));
clearAllShortcuts();
qDeleteAll(mainW.findChildren<QShortcut *>());
edit->clear();
QCOMPARE(edit->toPlainText().size(), 0);
setupShortcut(edit, "first", SendKeyEvent, "Ctrl+A");
auto cut = setupShortcut(edit, QLatin1String("first"), QKeySequence(Qt::CTRL + Qt::Key_A));
connect(cut, &QShortcut::activated, edit, [this, edit] () {
this->sendKeyEvents(edit, Qt::CTRL + Qt::Key_B, 0);
this->currentResult = tst_QShortcut::SentKeyEvent;
});
// Verify reentrancy when a non-shortcut is triggered as part
// of shortcut processing.
@ -959,9 +980,14 @@ void tst_QShortcut::keypressConsumption()
// ------------------------------------------------------------------
void tst_QShortcut::context()
{
clearAllShortcuts();
const QString name = QLatin1String(QTest::currentTestFunction());
MainWindow mainW;
mainW.setWindowTitle(name + QLatin1String("_Helper"));
mainW.show();
auto edit = mainW.testEdit();
QWidget myBox;
myBox.setWindowTitle(name);
auto other1 = new TestEdit(&myBox, "test_edit_other1");
auto other2 = new TestEdit(&myBox, "test_edit_other2");
auto layout = new QHBoxLayout(&myBox);
@ -1052,8 +1078,6 @@ void tst_QShortcut::context()
QCOMPARE(edit->toPlainText(), QString());
QCOMPARE(other1->toPlainText(), QString());
QCOMPARE(other2->toPlainText(), QString());
clearAllShortcuts();
}
// QTBUG-38986, do not generate duplicated QEvent::ShortcutOverride in event processing.
@ -1086,42 +1110,21 @@ void tst_QShortcut::duplicatedShortcutOverride()
QCOMPARE(w.overrideCount, 1);
}
// ------------------------------------------------------------------
// Element Testing helper functions ---------------------------------
// ------------------------------------------------------------------
void tst_QShortcut::clearAllShortcuts()
{
QList<QShortcut *> shortcutsCpy = shortcuts;
qDeleteAll(shortcutsCpy);
shortcuts.clear();
}
QShortcut *tst_QShortcut::setupShortcut(Widget testWidget, const QKeySequence &ks)
{
return setupShortcut(mainW, QTest::currentDataTag() ? QTest::currentDataTag() : "", testWidget, ks);
}
QShortcut *tst_QShortcut::setupShortcut(Widget 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, Widget 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, Widget testWidget,
const QKeySequence &ks, Qt::ShortcutContext context)
QShortcut *tst_QShortcut::setupShortcut(QWidget *parent, const QString &name, const QKeySequence &ks, Qt::ShortcutContext context)
{
// Set up shortcut for next test
auto cut = new QShortcut(ks, parent, nullptr, nullptr, context);
cut->setObjectName(name);
return cut;
}
switch(testWidget)
{
QShortcut *tst_QShortcut::setupShortcut(QWidget *parent, const QString &name, Widget testWidget,
const QKeySequence &ks, Qt::ShortcutContext context)
{
// Set up shortcut for next test
auto cut = setupShortcut(parent, name, ks, context);
switch (testWidget) {
case TriggerSlot1:
connect(cut, &QShortcut::activated, this, &tst_QShortcut::slotTrig1);
connect(cut, &QShortcut::activatedAmbiguously, this, &tst_QShortcut::ambigSlot1);
@ -1150,28 +1153,12 @@ QShortcut *tst_QShortcut::setupShortcut(QWidget *parent, const char *name, Widge
connect(cut, &QShortcut::activated, this, &tst_QShortcut::slotTrig7);
connect(cut, &QShortcut::activatedAmbiguously, this, &tst_QShortcut::ambigSlot7);
break;
case SendKeyEvent:
connect(cut, &QShortcut::activated, this, &tst_QShortcut::sendKeyEvent);
break;
case NoWidget:
break;
}
connect(cut, &QObject::destroyed, this, &tst_QShortcut::shortcutDestroyed);
shortcuts.append(cut);
return cut;
}
void tst_QShortcut::shortcutDestroyed(QObject* obj)
{
shortcuts.erase(std::remove(shortcuts.begin(), shortcuts.end(), obj),
shortcuts.end());
}
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 );
@ -1211,6 +1198,8 @@ void tst_QShortcut::sendKeyEvents(QWidget *w, int k1, QChar c1, int k2, QChar c2
void tst_QShortcut::testElement()
{
static QScopedPointer<MainWindow> mainW;
currentResult = NoResult;
QFETCH(tst_QShortcut::Action, action);
QFETCH(tst_QShortcut::Widget, testWidget);
@ -1225,13 +1214,29 @@ void tst_QShortcut::testElement()
QFETCH(int, c4);
QFETCH(tst_QShortcut::Result, result);
if (action == ClearAll) {
clearAllShortcuts();
} else if (action == SetupAccel) {
setupShortcut(testWidget, txt, k1, k2, k3, k4);
} else {
sendKeyEvents(k1, c1, k2, c2, k3, c3, k4, c4);
if (mainW.isNull()) {
mainW.reset(new MainWindow);
mainW->setWindowTitle(QTest::currentTestFunction());
mainW->show();
mainW->activateWindow();
QVERIFY(QTest::qWaitForWindowActive(mainW.data()));
}
switch (action) {
case ClearAll:
qDeleteAll(mainW->findChildren<QShortcut *>());
break;
case SetupAccel:
setupShortcut(mainW.data(), txt, testWidget, txt.isEmpty()
? QKeySequence(k1, k2, k3, k4) : QKeySequence::fromString(txt));
break;
case TestAccel:
sendKeyEvents(mainW.data(), k1, c1, k2, c2, k3, c3, k4, c4);
QCOMPARE(currentResult, result);
break;
case TestEnd:
mainW.reset();
break;
}
}