1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include <QtTest/QtTest>
44 #include <qapplication.h>
45 #include <qtextedit.h>
46 #include <qpushbutton.h>
47 #include <qmainwindow.h>
48 #include <qstatusbar.h>
49 #include <qboxlayout.h>
52 #include <qshortcut.h>
60 class tst_QShortcut : public QObject
65 virtual ~tst_QShortcut();
98 void slotTrig1() { currentResult = Slot1Triggered; }
99 void slotTrig2() { currentResult = Slot2Triggered; }
100 void slotTrig3() { currentResult = Slot3Triggered; }
101 void slotTrig4() { currentResult = Slot4Triggered; }
102 void slotTrig5() { currentResult = Slot5Triggered; }
103 void slotTrig6() { currentResult = Slot6Triggered; }
104 void slotTrig7() { currentResult = Slot7Triggered; }
105 void ambigSlot1() { currentResult = Ambiguous; ambigResult = Slot1Triggered; }
106 void ambigSlot2() { currentResult = Ambiguous; ambigResult = Slot2Triggered; }
107 void ambigSlot3() { currentResult = Ambiguous; ambigResult = Slot3Triggered; }
108 void ambigSlot4() { currentResult = Ambiguous; ambigResult = Slot4Triggered; }
109 void ambigSlot5() { currentResult = Ambiguous; ambigResult = Slot5Triggered; }
110 void ambigSlot6() { currentResult = Ambiguous; ambigResult = Slot6Triggered; }
111 void ambigSlot7() { currentResult = Ambiguous; ambigResult = Slot7Triggered; }
112 void statusMessage( const QString& message ) { sbText = message; }
113 void shortcutDestroyed(QObject* obj);
117 void cleanupTestCase();
124 void disabledItems();
125 void ambiguousItems();
126 void ambiguousRotation();
127 void keypressConsumption();
128 void unicodeCompare();
132 static Qt::KeyboardModifiers toButtons( int key );
135 void clearAllShortcuts();
136 QShortcut *setupShortcut(int testWidget, const QKeySequence &ks);
137 QShortcut *setupShortcut(int testWidget, const QString &txt, int k1 = 0, int k2 = 0, int k3 = 0, int k4 = 0);
139 QShortcut *setupShortcut(QWidget *parent, const char *name, int testWidget, const QString &txt, int k1 = 0, int k2 = 0, int k3 = 0, int k4 = 0);
140 QShortcut *setupShortcut(QWidget *parent, const char *name, int testWidget, const QKeySequence &ks, Qt::ShortcutContext context = Qt::WindowShortcut);
142 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);
143 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);
148 QList<QShortcut*> shortcuts;
155 template<> struct QMetaTypeId<tst_QShortcut::Widget> : public QMetaTypeId<int>
156 { static inline int qt_metatype_id() { return QMetaType::Int; } };
157 template<> struct QMetaTypeId<tst_QShortcut::Result> : public QMetaTypeId<int>
158 { static inline int qt_metatype_id() { return QMetaType::Int; } };
159 template<> struct QMetaTypeId<tst_QShortcut::Action> : public QMetaTypeId<int>
160 { static inline int qt_metatype_id() { return QMetaType::Int; } };
163 class TestEdit : public QTextEdit
167 TestEdit(QWidget *parent, const char *name)
174 bool event(QEvent *e) {
175 // Make testedit allow any Ctrl+Key as shortcut
176 if (e->type() == QEvent::ShortcutOverride) {
177 QKeyEvent *ke = static_cast<QKeyEvent*>(e);
178 if (ke->modifiers() == Qt::ControlModifier
179 && ke->key() > Qt::Key_Any
180 && ke->key() < Qt::Key_ydiaeresis) {
186 // If keypress not processed as normal, check for
187 // Ctrl+Key event, and input custom string for
188 // result comparison.
189 if (e->type() == QEvent::KeyPress) {
190 QKeyEvent *ke = static_cast<QKeyEvent*>(e);
191 if (ke->modifiers() && ke->key() > Qt::Key_Any
192 && ke->key() < Qt::Key_ydiaeresis) {
193 if (ke->modifiers() == Qt::ControlModifier)
194 insertPlainText(QString("<Ctrl+%1>").arg(char(ke->key())));
195 else if (ke->modifiers() == Qt::AltModifier)
196 insertPlainText(QString("<Alt+%1>").arg(char(ke->key())));
197 else if (ke->modifiers() == Qt::ShiftModifier)
198 insertPlainText(QString("<Shift+%1>").arg(char(ke->key())));
202 return QTextEdit::event(e);
206 tst_QShortcut::tst_QShortcut(): mainW( 0 )
210 tst_QShortcut::~tst_QShortcut()
215 void tst_QShortcut::initTestCase()
217 currentResult = NoResult;
218 mainW = new QMainWindow(0);
219 mainW->setWindowFlags(Qt::X11BypassWindowManagerHint);
220 edit = new TestEdit(mainW, "test_edit");
221 mainW->setFixedSize( 100, 100 );
222 mainW->setCentralWidget( edit );
225 qt_x11_wait_for_window_manager(mainW);
227 mainW->activateWindow();
229 connect( mainW->statusBar(), SIGNAL(messageChanged(const QString&)),
230 this, SLOT(statusMessage(const QString&)) );
233 void tst_QShortcut::cleanupTestCase()
238 Qt::KeyboardModifiers tst_QShortcut::toButtons( int key )
240 Qt::KeyboardModifiers result = Qt::NoModifier;
241 if ( key & Qt::SHIFT )
242 result |= Qt::ShiftModifier;
243 if ( key & Qt::CTRL )
244 result |= Qt::ControlModifier;
245 if ( key & Qt::META )
246 result |= Qt::MetaModifier;
248 result |= Qt::AltModifier;
252 void tst_QShortcut::defElements()
254 QTest::addColumn<int>("action");
255 QTest::addColumn<int>("testWidget");
256 QTest::addColumn<QString>("txt");
257 QTest::addColumn<int>("k1");
258 QTest::addColumn<int>("c1");
259 QTest::addColumn<int>("k2");
260 QTest::addColumn<int>("c2");
261 QTest::addColumn<int>("k3");
262 QTest::addColumn<int>("c3");
263 QTest::addColumn<int>("k4");
264 QTest::addColumn<int>("c4");
265 QTest::addColumn<int>("result");
268 void tst_QShortcut::number()
270 // We expect a failure on these tests, until QtTestKeyboard is
271 // fixed to do real platform dependent keyboard simulations
272 if (QTest::currentDataTag() == QString("N006a:Shift+Tab - [BackTab]")
273 || QTest::currentDataTag() == QString("N006b:Shift+Tab - [Shift+BackTab]"))
274 QEXPECT_FAIL("", "FLAW IN QTESTKEYBOARD: Keyboard events not passed through "
275 "platform dependent key handling code", Continue);
278 void tst_QShortcut::text()
282 // ------------------------------------------------------------------
283 // Number Elements --------------------------------------------------
284 // ------------------------------------------------------------------
285 void tst_QShortcut::number_data()
290 QTest::newRow("N00 - clear") << ClearAll <<0<<QString("")<<0<<0<<0<<0<<0<<0<<0<<0<<0;
292 //===========================================
293 // [Shift + key] on non-shift shortcuts testing
294 //===========================================
296 /* Testing Single Sequences
297 Shift + Qt::Key_M on Qt::Key_M
298 Qt::Key_M on Qt::Key_M
299 Shift + Qt::Key_Plus on Qt::Key_Pluss
300 Qt::Key_Plus on Qt::Key_Pluss
302 QTest::newRow("N001 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
303 //commented out because the behaviour changed, those tests should be updated
304 //QTest::newRow("N001:Shift + M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
305 QTest::newRow("N001:M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
306 QTest::newRow("N001 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
307 //commented out because the behaviour changed, those tests should be updated
308 //QTest::newRow("N001:Shift++ [+]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
309 QTest::newRow("N001:+ [+]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
310 QTest::newRow("N001 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
312 /* Testing Single Sequences
313 Shift + Qt::Key_M on Shift + Qt::Key_M
314 Qt::Key_M on Shift + Qt::Key_M
315 Shift + Qt::Key_Plus on Shift + Qt::Key_Pluss
316 Qt::Key_Plus on Shift + Qt::Key_Pluss
318 QTest::newRow("N002 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
319 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;
320 QTest::newRow("N002:M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
321 QTest::newRow("N002 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
322 QTest::newRow("N002:Shift++ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
323 QTest::newRow("N002:+ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
324 QTest::newRow("N002 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
326 /* Testing Single Sequences
327 Shift + Qt::Key_F1 on Qt::Key_F1
328 Qt::Key_F1 on Qt::Key_F1
330 QTest::newRow("N003 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
331 //commented out because the behaviour changed, those tests should be updated
332 //QTest::newRow("N003:Shift+F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
333 QTest::newRow("N003:F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
334 QTest::newRow("N003 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
335 /* Testing Single Sequences
336 Shift + Qt::Key_F1 on Shift + Qt::Key_F1
337 Qt::Key_F1 on Shift + Qt::Key_F1
340 QTest::newRow("N004 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
341 QTest::newRow("N004:Shift+F1 - [Shift+F1]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
342 QTest::newRow("N004:F1 - [Shift+F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
343 QTest::newRow("N004 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
345 /* Testing Single Sequences
346 Qt::Key_Tab on Qt::Key_Tab
347 Shift + Qt::Key_Tab on Qt::Key_Tab
348 Qt::Key_Backtab on Qt::Key_Tab
349 Shift + Qt::Key_Backtab on Qt::Key_Tab
351 QTest::newRow("N005a - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
352 QTest::newRow("N005a:Tab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
353 //commented out because the behaviour changed, those tests should be updated
354 //QTest::newRow("N005a:Shift+Tab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
355 // (Shift+)BackTab != Tab, but Shift+BackTab == Shift+Tab
356 QTest::newRow("N005a:Backtab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
357 QTest::newRow("N005a:Shift+Backtab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
358 QTest::newRow("N005a - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
360 /* Testing Single Sequences
361 Qt::Key_Tab on Shift + Qt::Key_Tab
362 Shift + Qt::Key_Tab on Shift + Qt::Key_Tab
363 Qt::Key_Backtab on Shift + Qt::Key_Tab
364 Shift + Qt::Key_Backtab on Shift + Qt::Key_Tab
366 QTest::newRow("N005b - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
367 QTest::newRow("N005b:Tab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
368 QTest::newRow("N005b:Shift+Tab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
369 QTest::newRow("N005b:BackTab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
370 QTest::newRow("N005b:Shift+BackTab - [Shift+Tab]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
371 QTest::newRow("N005b - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
373 /* Testing Single Sequences
374 Qt::Key_Tab on Qt::Key_Backtab
375 Shift + Qt::Key_Tab on Qt::Key_Backtab
376 Qt::Key_Backtab on Qt::Key_Backtab
377 Shift + Qt::Key_Backtab on Qt::Key_Backtab
379 QTest::newRow("N006a - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
380 QTest::newRow("N006a:Tab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
381 // This should work, since platform dependent code will transform the
382 // Shift+Tab into a Shift+BackTab, which should trigger the shortcut
383 QTest::newRow("N006a:Shift+Tab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; //XFAIL
384 QTest::newRow("N006a:BackTab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
385 //commented out because the behaviour changed, those tests should be updated
386 //QTest::newRow("N006a:Shift+BackTab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
387 QTest::newRow("N006a - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
389 /* Testing Single Sequences
390 Qt::Key_Tab on Shift + Qt::Key_Backtab
391 Shift + Qt::Key_Tab on Shift + Qt::Key_Backtab
392 Qt::Key_Backtab on Shift + Qt::Key_Backtab
393 Shift + Qt::Key_Backtab on Shift + Qt::Key_Backtab
395 QTest::newRow("N006b - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
396 QTest::newRow("N006b:Tab - [Shift+BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
397 QTest::newRow("N006b:Shift+Tab - [Shift+BackTab]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
398 QTest::newRow("N006b:BackTab - [Shift+BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
399 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
400 QTest::newRow("N006b - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
402 //===========================================
403 // [Shift + key] and [key] on shortcuts with
404 // and without modifiers
405 //===========================================
407 /* Testing Single Sequences
411 QTest::newRow("N007 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
412 QTest::newRow("N007 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
413 QTest::newRow("N007:F1") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
414 QTest::newRow("N007:Shift + F1") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
415 QTest::newRow("N007 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
417 /* Testing Single Sequences
423 QTest::newRow("N01 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
424 QTest::newRow("N02 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
425 QTest::newRow("N03 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
426 QTest::newRow("N04 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
427 QTest::newRow("N:Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
428 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;
429 QTest::newRow("N:Ctrl+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
430 QTest::newRow("N:Alt+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
432 /* Testing Single Sequence Ambiguity
433 Qt::Key_M on shortcut2
435 QTest::newRow("N05 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
436 QTest::newRow("N:Qt::Key_M on slot") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Ambiguous;
437 QTest::newRow("N05 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
439 /* Testing Single Specialkeys
442 Qt::UNICODE_ACCEL + Qt::Key_K
444 QTest::newRow("N06 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
445 QTest::newRow("N07 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
446 QTest::newRow("N08 - slot2") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::UNICODE_ACCEL + Qt::Key_K) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
448 QTest::newRow("N:Qt::Key_aring") << TestAccel << NoWidget << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
449 QTest::newRow("N:Qt::Key_Aring") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
450 QTest::newRow("N:Qt::Key_aring - Text Form") << TestAccel << NoWidget << QString("") << 0 << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
451 QTest::newRow("N:Qt::Key_Aring - Text Form") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+0) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
452 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;
453 QTest::newRow("N09 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
455 /* Testing Multiple Sequences
458 Shift+Qt::Key_I, Qt::Key_M
460 QTest::newRow("N10 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
461 QTest::newRow("N11 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_I) << 0 << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << NoResult;
462 QTest::newRow("N12 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_I) << 0 << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << NoResult;
464 QTest::newRow("N:Qt::Key_M (2)") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
465 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;
466 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;
467 QTest::newRow("N13 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
470 // ------------------------------------------------------------------
471 // Text Elements ----------------------------------------------------
472 // ------------------------------------------------------------------
473 void tst_QShortcut::text_data()
477 QTest::newRow("T00 - clear") << ClearAll <<0<<QString("")<<0<<0<<0<<0<<0<<0<<0<<0<<0;
479 //===========================================
480 // [Shift + key] on non-shift shortcuts testing
481 //===========================================
483 /* Testing Single Sequences
484 Shift + Qt::Key_M on Qt::Key_M
485 Qt::Key_M on Qt::Key_M
486 Shift + Qt::Key_Plus on Qt::Key_Pluss
487 Qt::Key_Plus on Qt::Key_Pluss
489 QTest::newRow("T001 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
490 //commented out because the behaviour changed, those tests should be updated
491 //QTest::newRow("T001:Shift+M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
492 QTest::newRow("T001:M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
493 QTest::newRow("T001 - slot2") << SetupAccel << TriggerSlot2 << QString("+") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
494 //commented out because the behaviour changed, those tests should be updated
495 //QTest::newRow("T001:Shift++ [+]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
496 QTest::newRow("T001:+ [+]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
497 QTest::newRow("T001 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
499 /* Testing Single Sequences
500 Shift + Qt::Key_M on Shift + Qt::Key_M
501 Qt::Key_M on Shift + Qt::Key_M
502 Shift + Qt::Key_Plus on Shift + Qt::Key_Pluss
503 Qt::Key_Plus on Shift + Qt::Key_Pluss
504 Shift + Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Pluss
505 Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Pluss
507 QTest::newRow("T002 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
508 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;
509 QTest::newRow("T002:M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
510 QTest::newRow("T002 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift++") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
511 QTest::newRow("T002:Shift++ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
512 QTest::newRow("T002:+ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
513 QTest::newRow("T002 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
515 /* Testing Single Sequences
516 Shift + Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Plus
517 Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Plus
518 Qt::Key_Plus on Ctrl + Qt::Key_Plus
520 QTest::newRow("T002b - slot1") << SetupAccel << TriggerSlot1 << QString("Ctrl++") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
521 //commented out because the behaviour changed, those tests should be updated
522 //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;
523 QTest::newRow("T002b:Ctrl++ [Ctrl++]") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
524 QTest::newRow("T002b:+ [Ctrl++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
525 QTest::newRow("T002b - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
527 /* Testing Single Sequences
528 Shift + Qt::Key_F1 on Qt::Key_F1
529 Qt::Key_F1 on Qt::Key_F1
531 QTest::newRow("T003 - slot1") << SetupAccel << TriggerSlot1 << QString("F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
532 //commented out because the behaviour changed, those tests should be updated
533 //QTest::newRow("T003:Shift+F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
534 QTest::newRow("T003:F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
535 QTest::newRow("T003 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
537 /* Testing Single Sequences
538 Shift + Qt::Key_F1 on Shift + Qt::Key_F1
539 Qt::Key_F1 on Shift + Qt::Key_F1
541 QTest::newRow("T004 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
542 QTest::newRow("T004:Shift+F1 - [Shift+F1]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
543 QTest::newRow("T004:F1 - [Shift+F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
544 QTest::newRow("T004 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
546 //===========================================
547 // [Shift + key] and [key] on shortcuts with
548 // and without modifiers
549 //===========================================
551 /* Testing Single Sequences
555 QTest::newRow("T007 - slot1") << SetupAccel << TriggerSlot1 << QString("F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
556 QTest::newRow("T007 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
557 QTest::newRow("T007:F1") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
558 QTest::newRow("T007:Shift + F1") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
559 QTest::newRow("T007 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
561 /* Testing Single Sequences
567 QTest::newRow("T01 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
568 QTest::newRow("T02 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
569 QTest::newRow("T03 - slot1") << SetupAccel << TriggerSlot1 << QString("Ctrl+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
570 QTest::newRow("T04 - slot2") << SetupAccel << TriggerSlot2 << QString("Alt+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
572 QTest::newRow("T:Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
573 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;
574 QTest::newRow("T:Ctrl + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
575 QTest::newRow("T:Alt + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
577 /* Testing Single Sequence Ambiguity
578 Qt::Key_M on shortcut2
580 QTest::newRow("T05 - slot2") << SetupAccel << TriggerSlot2 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
581 QTest::newRow("T:Qt::Key_M on TriggerSlot2") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Ambiguous;
582 QTest::newRow("T06 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
584 /* Testing Single Specialkeys
587 Qt::UNICODE_ACCEL + Qt::Key_K
589 /* see comments above on the #ifdef'ery */
590 QTest::newRow("T06 - slot1") << SetupAccel << TriggerSlot1 << QString("\x0C5")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
591 QTest::newRow("T07 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+\x0C5")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
592 QTest::newRow("T08 - slot2") << SetupAccel << TriggerSlot1 << QString("K") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
593 QTest::newRow("T:Qt::Key_aring") << TestAccel << NoWidget << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
594 QTest::newRow("T:Qt::Key_Aring") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
595 QTest::newRow("T:Qt::Key_aring - Text Form") << TestAccel << NoWidget << QString("") << 0 << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
596 QTest::newRow("T:Qt::Key_Aring - Text Form") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+0) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
597 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;
598 QTest::newRow("T09 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
600 /* Testing Multiple Sequences
603 Shift+Qt::Key_I, Qt::Key_M
605 QTest::newRow("T10 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
606 QTest::newRow("T11 - slot2") << SetupAccel << TriggerSlot2 << QString("I, M")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
607 QTest::newRow("T12 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+I, M")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
608 QTest::newRow("T:Qt::Key_M (2)") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
609 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;
610 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;
611 QTest::newRow("T13 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
614 // ------------------------------------------------------------------
615 // Disabled Elements ------------------------------------------------
616 // ------------------------------------------------------------------
617 void tst_QShortcut::disabledItems()
620 mainW->activateWindow();
624 /* Testing Disabled Shortcuts
626 Shift + Qt::Key_M on slot1
627 Qt::Key_M on slot2 (disabled)
628 Shift + Qt::Key_M on slot2 (disabled)
631 // Setup two identical shortcuts on different pushbuttons
632 QPushButton pb1(mainW);
633 QPushButton pb2(mainW);
634 pb1.setObjectName("pushbutton-1");
635 pb2.setObjectName("pushbutton-2");
636 pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger
639 QShortcut *cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "M");
640 QShortcut *cut2 = setupShortcut(&pb1, "shortcut2-pb1", TriggerSlot1, "Shift+M");
641 QShortcut *cut3 = setupShortcut(&pb2, "shortcut3-pb2", TriggerSlot2, "M");
642 QShortcut *cut4 = setupShortcut(&pb2, "shortcut4-pb2", TriggerSlot2, "Shift+M");
644 cut3->setEnabled(false);
645 cut4->setEnabled(false);
647 currentResult = NoResult;
648 sendKeyEvents(Qt::Key_M, 'm');
649 QCOMPARE(currentResult, Slot1Triggered);
651 currentResult = NoResult;
652 sendKeyEvents(Qt::SHIFT+Qt::Key_M, 'M');
653 QCOMPARE(currentResult, Slot1Triggered);
655 cut2->setEnabled(false);
656 cut4->setEnabled(true);
658 /* Testing Disabled Shortcuts
660 Shift + Qt::Key_M on slot1 (disabled)
661 Qt::Key_M on slot2 (disabled)
662 Shift + Qt::Key_M on slot2
664 currentResult = NoResult;
665 sendKeyEvents( Qt::Key_M, 'm' );
666 QCOMPARE( currentResult, Slot1Triggered );
668 currentResult = NoResult;
669 sendKeyEvents( Qt::SHIFT+Qt::Key_M, 'M' );
670 QCOMPARE( currentResult, Slot2Triggered );
673 /* Testing Disabled Accel
675 Shift + Qt::Key_F5 on slot2 (disabled)
678 cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "F5");
679 cut4 = setupShortcut(&pb2, "shortcut4-pb2", TriggerSlot2, "Shift+F5");
681 cut1->setKey(QKeySequence("F5"));
682 cut4->setKey(QKeySequence("Shift+F5"));
684 cut1->setEnabled(true);
685 cut4->setEnabled(false);
687 currentResult = NoResult;
688 sendKeyEvents( Qt::Key_F5, 0 );
689 QCOMPARE( currentResult, Slot1Triggered );
691 currentResult = NoResult;
692 sendKeyEvents( Qt::SHIFT+Qt::Key_F5, 0 );
693 QCOMPARE( currentResult, NoResult );
696 qFatal("Not testing statusbar text feedback yet, since not implemented");
697 /* Testing Disabled Accel, and the corresponding statusbar feedback
698 Ctrl + Qt::Key_K, Ctrl + Qt::Key_L on slot1
699 Ctrl + Qt::Key_K, Ctrl + Qt::Key_M on slot2 (disabled)
701 cut1->setKey(QKeySequence("Ctrl+K, Ctrl+L"));
702 cut4->setKey(QKeySequence("Ctrl+K, Ctrl+M"));
704 cut1->setEnabled(true);
705 cut4->setEnabled(false);
707 currentResult = NoResult;
708 sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 );
709 sendKeyEvents( Qt::CTRL+Qt::Key_Q, 0 );
710 QCOMPARE( currentResult, NoResult );
712 QCOMPARE( sbText, QString("Ctrl+K, Ctrl+Q not defined") );
714 currentResult = NoResult;
715 sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 );
716 sendKeyEvents( Qt::CTRL+Qt::Key_M, 0 );
717 QCOMPARE( currentResult, NoResult );
719 QCOMPARE( sbText, QString::null );
721 currentResult = NoResult;
722 sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 );
723 sendKeyEvents( Qt::CTRL+Qt::Key_L, 0 );
724 QCOMPARE( currentResult, Slot1Triggered );
726 QCOMPARE( sbText, QString::null );
732 // ------------------------------------------------------------------
733 // Ambiguous Elements -----------------------------------------------
734 // ------------------------------------------------------------------
735 void tst_QShortcut::ambiguousRotation()
738 /* Testing Shortcut rotation scheme
739 Ctrl + Qt::Key_A on slot1 (disabled)
740 Ctrl + Qt::Key_A on slot2 (disabled)
741 Ctrl + Qt::Key_A on slot3
742 Ctrl + Qt::Key_A on slot4
743 Ctrl + Qt::Key_A on slot5 (disabled)
744 Ctrl + Qt::Key_A on slot6
745 Ctrl + Qt::Key_A on slot7 (disabled)
747 QShortcut *cut1 = setupShortcut(TriggerSlot1, "Ctrl+A");
748 QShortcut *cut2 = setupShortcut(TriggerSlot2, "Ctrl+A");
749 QShortcut *cut3 = setupShortcut(TriggerSlot3, "Ctrl+A");
750 QShortcut *cut4 = setupShortcut(TriggerSlot4, "Ctrl+A");
751 QShortcut *cut5 = setupShortcut(TriggerSlot5, "Ctrl+A");
752 QShortcut *cut6 = setupShortcut(TriggerSlot6, "Ctrl+A");
753 QShortcut *cut7 = setupShortcut(TriggerSlot7, "Ctrl+A");
755 cut1->setEnabled(false);
756 cut2->setEnabled(false);
757 cut5->setEnabled(false);
758 cut7->setEnabled(false);
760 // Test proper rotation
765 currentResult = NoResult;
766 ambigResult = NoResult;
767 sendKeyEvents(Qt::CTRL+Qt::Key_A);
768 QCOMPARE(currentResult, Ambiguous);
769 QCOMPARE(ambigResult, Slot3Triggered);
771 currentResult = NoResult;
772 ambigResult = NoResult;
773 sendKeyEvents(Qt::CTRL+Qt::Key_A);
774 QCOMPARE(currentResult, Ambiguous);
775 QCOMPARE(ambigResult, Slot4Triggered);
777 currentResult = NoResult;
778 ambigResult = NoResult;
779 sendKeyEvents(Qt::CTRL+Qt::Key_A);
780 QCOMPARE(currentResult, Ambiguous);
781 QCOMPARE(ambigResult, Slot6Triggered);
783 currentResult = NoResult;
784 ambigResult = NoResult;
785 sendKeyEvents(Qt::CTRL+Qt::Key_A);
786 QCOMPARE(currentResult, Ambiguous);
787 QCOMPARE(ambigResult, Slot3Triggered);
789 currentResult = NoResult;
790 ambigResult = NoResult;
791 sendKeyEvents(Qt::CTRL+Qt::Key_A);
792 QCOMPARE(currentResult, Ambiguous);
793 QCOMPARE(ambigResult, Slot4Triggered);
795 currentResult = NoResult;
796 ambigResult = NoResult;
797 sendKeyEvents(Qt::CTRL+Qt::Key_A);
798 QCOMPARE(currentResult, Ambiguous);
799 QCOMPARE(ambigResult, Slot6Triggered);
801 /* Testing Shortcut rotation scheme
802 Ctrl + Qt::Key_A on slot1
803 Ctrl + Qt::Key_A on slot2
804 Ctrl + Qt::Key_A on slot3 (disabled)
805 Ctrl + Qt::Key_A on slot4 (disabled)
806 Ctrl + Qt::Key_A on slot5
807 Ctrl + Qt::Key_A on slot6 (disabled)
808 Ctrl + Qt::Key_A on slot7
811 cut1->setEnabled(true);
812 cut2->setEnabled(true);
813 cut5->setEnabled(true);
814 cut7->setEnabled(true);
816 cut3->setEnabled(false);
817 cut4->setEnabled(false);
818 cut6->setEnabled(false);
820 currentResult = NoResult;
821 ambigResult = NoResult;
822 sendKeyEvents(Qt::CTRL+Qt::Key_A);
823 QCOMPARE(currentResult, Ambiguous);
824 QCOMPARE(ambigResult, Slot1Triggered);
826 currentResult = NoResult;
827 ambigResult = NoResult;
828 sendKeyEvents(Qt::CTRL+Qt::Key_A);
829 QCOMPARE(currentResult, Ambiguous);
830 QCOMPARE(ambigResult, Slot2Triggered);
832 currentResult = NoResult;
833 ambigResult = NoResult;
834 sendKeyEvents(Qt::CTRL+Qt::Key_A);
835 QCOMPARE(currentResult, Ambiguous);
836 QCOMPARE(ambigResult, Slot5Triggered);
838 currentResult = NoResult;
839 ambigResult = NoResult;
840 sendKeyEvents(Qt::CTRL+Qt::Key_A);
841 QCOMPARE(currentResult, Ambiguous);
842 QCOMPARE(ambigResult, Slot7Triggered);
844 currentResult = NoResult;
845 ambigResult = NoResult;
846 sendKeyEvents(Qt::CTRL+Qt::Key_A);
847 QCOMPARE(currentResult, Ambiguous);
848 QCOMPARE(ambigResult, Slot1Triggered);
850 currentResult = NoResult;
851 ambigResult = NoResult;
852 sendKeyEvents(Qt::CTRL+Qt::Key_A);
853 QCOMPARE(currentResult, Ambiguous);
854 QCOMPARE(ambigResult, Slot2Triggered);
856 currentResult = NoResult;
857 ambigResult = NoResult;
858 sendKeyEvents(Qt::CTRL+Qt::Key_A);
859 QCOMPARE(currentResult, Ambiguous);
860 QCOMPARE(ambigResult, Slot5Triggered);
862 currentResult = NoResult;
863 ambigResult = NoResult;
864 sendKeyEvents(Qt::CTRL+Qt::Key_A);
865 QCOMPARE(currentResult, Ambiguous);
866 QCOMPARE(ambigResult, Slot7Triggered);
875 void tst_QShortcut::ambiguousItems()
878 /* Testing Ambiguous Shortcuts
879 Qt::Key_M on Pushbutton 1
880 Qt::Key_M on Pushbutton 2
883 // Setup two identical shortcuts on different pushbuttons
884 QPushButton pb1(mainW);
885 QPushButton pb2(mainW);
886 pb1.setObjectName("pushbutton-1");
887 pb2.setObjectName("pushbutton-2");
888 pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger
891 setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "M");
892 setupShortcut(&pb1, "shortcut2-pb2", TriggerSlot2, "M");
894 currentResult = NoResult;
895 sendKeyEvents( Qt::Key_M, 'm' );
896 QCOMPARE( currentResult, Ambiguous );
897 QCOMPARE( ambigResult, Slot1Triggered );
899 currentResult = NoResult;
900 sendKeyEvents( Qt::Key_M, 'm' );
901 QCOMPARE( currentResult, Ambiguous );
902 QCOMPARE( ambigResult, Slot2Triggered );
904 currentResult = NoResult;
905 sendKeyEvents( Qt::Key_M, 'm' );
906 QCOMPARE( currentResult, Ambiguous );
907 QCOMPARE( ambigResult, Slot1Triggered );
913 // ------------------------------------------------------------------
914 // Unicode and non-unicode Elements ---------------------------------
915 // ------------------------------------------------------------------
916 void tst_QShortcut::unicodeCompare()
919 /* Testing Unicode/non-Unicode Shortcuts
920 Qt::Key_M on Pushbutton 1
921 Qt::Key_M on Pushbutton 2
923 QPushButton pb1(mainW);
924 QPushButton pb2(mainW);
925 pb1.setObjectName("pushbutton-1");
926 pb2.setObjectName("pushbutton-2");
927 pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger
930 QKeySequence ks1("Ctrl+M"); // Unicode
931 QKeySequence ks2(Qt::CTRL+Qt::Key_M); // non-Unicode
932 setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, ks1);
933 setupShortcut(&pb1, "shortcut2-pb2", TriggerSlot2, ks2);
935 currentResult = NoResult;
936 sendKeyEvents( Qt::CTRL+Qt::Key_M, 0 );
937 QCOMPARE( currentResult, Ambiguous );
938 // They _are_ ambiguous, so the QKeySequence operator==
939 // should indicate the same
940 QVERIFY( ks1 == ks2 );
941 QVERIFY( !(ks1 != ks2) );
946 // ------------------------------------------------------------------
947 // Keypress consumption verification --------------------------------
948 // ------------------------------------------------------------------
949 void tst_QShortcut::keypressConsumption()
953 QCOMPARE(edit->toPlainText().size(), 0);
955 QShortcut *cut1 = setupShortcut(edit, "shortcut1-line", TriggerSlot1, "Ctrl+I, A");
956 QShortcut *cut2 = setupShortcut(edit, "shortcut1-line", TriggerSlot2, "Ctrl+I, B");
958 currentResult = NoResult;
959 ambigResult = NoResult;
960 sendKeyEvents(edit, Qt::CTRL + Qt::Key_I, 0); // Send key to edit
961 QCOMPARE( currentResult, NoResult );
962 QCOMPARE( ambigResult, NoResult );
963 QCOMPARE(edit->toPlainText(), QString(""));
965 // Make sure next keypress is eaten (failing multiple keysequence)
966 sendKeyEvents(edit, Qt::Key_C, 'c'); // Send key to edit
967 QCOMPARE( currentResult, NoResult );
968 QCOMPARE( ambigResult, NoResult );
969 QCOMPARE(edit->toPlainText(), QString(""));
971 // Next keypress should be normal
972 sendKeyEvents(edit, Qt::Key_C, 'c'); // Send key to edit
973 QCOMPARE( currentResult, NoResult );
974 QCOMPARE( ambigResult, NoResult );
975 QCOMPARE(edit->toPlainText(), QString("c"));
977 currentResult = NoResult;
978 ambigResult = NoResult;
980 QCOMPARE(edit->toPlainText().size(), 0);
982 cut1->setEnabled(false);
983 cut2->setEnabled(false);
985 // Make sure keypresses is passed on, since all multiple keysequences
986 // with Ctrl+I are disabled
987 sendKeyEvents(edit, Qt::CTRL + Qt::Key_I, 0); // Send key to edit
988 QCOMPARE( currentResult, NoResult );
989 QCOMPARE( ambigResult, NoResult );
990 QVERIFY(edit->toPlainText().endsWith("<Ctrl+I>"));
992 sendKeyEvents(edit, Qt::Key_A, 'a'); // Send key to edit
993 QCOMPARE( currentResult, NoResult );
994 QCOMPARE( ambigResult, NoResult );
995 QVERIFY(edit->toPlainText().endsWith("<Ctrl+I>a"));
1000 // ------------------------------------------------------------------
1001 // Context Validation -----------------------------------------------
1002 // ------------------------------------------------------------------
1003 void tst_QShortcut::context()
1005 clearAllShortcuts();
1008 TestEdit *other1 = new TestEdit(&myBox, "test_edit_other1");
1009 TestEdit *other2 = new TestEdit(&myBox, "test_edit_other2");
1010 QHBoxLayout *layout = new QHBoxLayout(&myBox);
1011 layout->addWidget(other1);
1012 layout->addWidget(other2);
1015 qt_x11_wait_for_window_manager(&myBox);
1018 setupShortcut(other1, "ActiveWindow", TriggerSlot1, QKeySequence("Alt+1"), Qt::WindowShortcut);
1019 setupShortcut(other2, "Focus", TriggerSlot2, QKeySequence("Alt+2"), Qt::WidgetShortcut);
1020 setupShortcut(edit, "Application", TriggerSlot3, QKeySequence("Alt+3"), Qt::ApplicationShortcut);
1022 currentResult = NoResult;
1023 ambigResult = NoResult;
1028 // edit doesn't have focus, so ActiveWindow context should work
1029 // ..but Focus context shouldn't..
1030 // Changing focus to edit should make focus context work
1031 // Application context should always work
1034 // Focus on 'other1' edit, so Active Window context should trigger
1035 other1->activateWindow(); // <---
1036 QApplication::setActiveWindow(other1);
1037 QCOMPARE(qApp->activeWindow(), other1->window());
1038 QCOMPARE(qApp->focusWidget(), (QWidget *)other1);
1040 currentResult = NoResult;
1041 ambigResult = NoResult;
1046 QCOMPARE(qApp->focusWidget(), (QWidget *)other1);
1047 sendKeyEvents(other1, Qt::ALT+Qt::Key_1);
1048 QCOMPARE(currentResult, Slot1Triggered);
1049 QCOMPARE(ambigResult, NoResult);
1050 QCOMPARE(edit->toPlainText(), QString(""));
1051 QCOMPARE(other1->toPlainText(), QString(""));
1052 QCOMPARE(other2->toPlainText(), QString(""));
1054 // ..but not Focus context on 'other2'..
1055 currentResult = NoResult;
1056 ambigResult = NoResult;
1061 sendKeyEvents(other1, Qt::ALT+Qt::Key_2);
1062 QCOMPARE(currentResult, NoResult);
1063 QCOMPARE(ambigResult, NoResult);
1064 QCOMPARE(edit->toPlainText(), QString(""));
1065 QCOMPARE(other1->toPlainText(), QString("<Alt+2>"));
1066 QCOMPARE(other2->toPlainText(), QString(""));
1068 // ..however, application global context on 'edit' should..
1069 currentResult = NoResult;
1070 ambigResult = NoResult;
1075 sendKeyEvents(other1, Qt::ALT+Qt::Key_3);
1076 QCOMPARE(currentResult, Slot3Triggered);
1077 QCOMPARE(ambigResult, NoResult);
1078 QCOMPARE(edit->toPlainText(), QString(""));
1079 QCOMPARE(other1->toPlainText(), QString(""));
1080 QCOMPARE(other2->toPlainText(), QString(""));
1082 // Changing focus to 'other2' should make the Focus context there work
1083 other2->activateWindow();
1084 other2->setFocus(); // ###
1087 qt_x11_wait_for_window_manager(other2);
1090 QCOMPARE(qApp->activeWindow(), other2->window());
1091 QCOMPARE(qApp->focusWidget(), (QWidget *)other2);
1093 currentResult = NoResult;
1094 ambigResult = NoResult;
1099 sendKeyEvents(other2, Qt::ALT+Qt::Key_2);
1100 QCOMPARE(currentResult, Slot2Triggered);
1101 QCOMPARE(ambigResult, NoResult);
1102 QCOMPARE(edit->toPlainText(), QString(""));
1103 QCOMPARE(other1->toPlainText(), QString(""));
1104 QCOMPARE(other2->toPlainText(), QString(""));
1106 clearAllShortcuts();
1109 edit->activateWindow();
1112 qt_x11_wait_for_window_manager(edit);
1117 // ------------------------------------------------------------------
1118 // Element Testing helper functions ---------------------------------
1119 // ------------------------------------------------------------------
1120 void tst_QShortcut::clearAllShortcuts()
1122 QList<QShortcut *> shortcutsCpy = shortcuts;
1123 qDeleteAll(shortcutsCpy);
1127 QShortcut *tst_QShortcut::setupShortcut(int testWidget, const QKeySequence &ks)
1129 return setupShortcut(mainW, QTest::currentDataTag() ? QTest::currentDataTag() : "", testWidget, ks);
1132 QShortcut *tst_QShortcut::setupShortcut(int testWidget, const QString &txt, int k1, int k2, int k3, int k4)
1134 return setupShortcut(mainW, QTest::currentDataTag() ? QTest::currentDataTag() : "", testWidget,
1135 (txt.isEmpty() ? QKeySequence(k1, k2, k3, k4) : QKeySequence(txt)));
1138 QShortcut *tst_QShortcut::setupShortcut(QWidget *parent, const char *name, int testWidget, const QString &txt, int k1, int k2, int k3, int k4)
1140 return setupShortcut(parent, name, testWidget,
1141 (txt.isEmpty() ? QKeySequence(k1, k2, k3, k4) : QKeySequence(txt)));
1144 QShortcut *tst_QShortcut::setupShortcut(QWidget *parent, const char *name, int testWidget,
1145 const QKeySequence &ks, Qt::ShortcutContext context)
1147 // Set up shortcut for next test
1148 QShortcut *cut = new QShortcut(QKeySequence(), parent, 0, 0, context);
1149 cut->setObjectName(name);
1152 const char *normal = 0;
1153 const char *ambig = 0;
1157 normal = SLOT(slotTrig1());
1158 ambig = SLOT(ambigSlot1());
1161 normal = SLOT(slotTrig2());
1162 ambig = SLOT(ambigSlot2());
1165 normal = SLOT(slotTrig3());
1166 ambig = SLOT(ambigSlot3());
1169 normal = SLOT(slotTrig4());
1170 ambig = SLOT(ambigSlot4());
1173 normal = SLOT(slotTrig5());
1174 ambig = SLOT(ambigSlot5());
1177 normal = SLOT(slotTrig6());
1178 ambig = SLOT(ambigSlot6());
1181 normal = SLOT(slotTrig7());
1182 ambig = SLOT(ambigSlot7());
1185 connect(cut, SIGNAL(activated()), this, normal);
1186 connect(cut, SIGNAL(activatedAmbiguously()), this, ambig);
1187 connect(cut, SIGNAL(destroyed(QObject*)), this, SLOT(shortcutDestroyed(QObject*)));
1188 shortcuts.append(cut);
1192 void tst_QShortcut::shortcutDestroyed(QObject* obj)
1194 shortcuts.removeAll(static_cast<QShortcut *>(obj));
1197 void tst_QShortcut::sendKeyEvents(int k1, QChar c1, int k2, QChar c2, int k3, QChar c3, int k4, QChar c4)
1199 sendKeyEvents(mainW, k1, c1, k2, c2, k3, c3, k4, c4);
1202 void tst_QShortcut::sendKeyEvents(QWidget *w, int k1, QChar c1, int k2, QChar c2, int k3, QChar c3, int k4, QChar c4)
1204 Qt::KeyboardModifiers b1 = toButtons( k1 );
1205 Qt::KeyboardModifiers b2 = toButtons( k2 );
1206 Qt::KeyboardModifiers b3 = toButtons( k3 );
1207 Qt::KeyboardModifiers b4 = toButtons( k4 );
1208 k1 &= ~Qt::MODIFIER_MASK;
1209 k2 &= ~Qt::MODIFIER_MASK;
1210 k3 &= ~Qt::MODIFIER_MASK;
1211 k4 &= ~Qt::MODIFIER_MASK;
1214 if (k1 || c1.toAscii()) {
1215 QString c(c1.unicode() == QChar::Null ? QString() : QString(c1));
1216 QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k1), c, b1);
1217 QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k1), c, b1);
1220 if (k2 || c2.toAscii()) {
1221 QString c(c2.unicode() == QChar::Null ? QString() : QString(c2));
1222 QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k2), c, b2);
1223 QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k2), c, b2);
1226 if (k3 || c3.toAscii()) {
1227 QString c(c3.unicode() == QChar::Null ? QString() : QString(c3));
1228 QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k3), c, b3);
1229 QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k3), c, b3);
1232 if (k4 || c4.toAscii()) {
1233 QString c(c4.unicode() == QChar::Null ? QString() : QString(c4));
1234 QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k4), c, b4);
1235 QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k4), c, b4);
1239 void tst_QShortcut::testElement()
1241 currentResult = NoResult;
1242 QFETCH(int, action);
1243 QFETCH(int, testWidget);
1244 QFETCH(QString, txt);
1253 QFETCH(int, result);
1255 if (action == ClearAll) {
1256 clearAllShortcuts();
1257 } else if (action == SetupAccel) {
1258 setupShortcut(testWidget, txt, k1, k2, k3, k4);
1260 sendKeyEvents(k1, c1, k2, c2, k3, c3, k4, c4);
1261 QCOMPARE(int(currentResult), result);
1265 QTEST_MAIN(tst_QShortcut)
1266 #include "tst_qshortcut.moc"