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 );
224 QTest::qWaitForWindowShown(mainW);
225 mainW->activateWindow();
227 connect( mainW->statusBar(), SIGNAL(messageChanged(const QString&)),
228 this, SLOT(statusMessage(const QString&)) );
231 void tst_QShortcut::cleanupTestCase()
236 Qt::KeyboardModifiers tst_QShortcut::toButtons( int key )
238 Qt::KeyboardModifiers result = Qt::NoModifier;
239 if ( key & Qt::SHIFT )
240 result |= Qt::ShiftModifier;
241 if ( key & Qt::CTRL )
242 result |= Qt::ControlModifier;
243 if ( key & Qt::META )
244 result |= Qt::MetaModifier;
246 result |= Qt::AltModifier;
250 void tst_QShortcut::defElements()
252 QTest::addColumn<int>("action");
253 QTest::addColumn<int>("testWidget");
254 QTest::addColumn<QString>("txt");
255 QTest::addColumn<int>("k1");
256 QTest::addColumn<int>("c1");
257 QTest::addColumn<int>("k2");
258 QTest::addColumn<int>("c2");
259 QTest::addColumn<int>("k3");
260 QTest::addColumn<int>("c3");
261 QTest::addColumn<int>("k4");
262 QTest::addColumn<int>("c4");
263 QTest::addColumn<int>("result");
266 void tst_QShortcut::number()
268 // We expect a failure on these tests, until QtTestKeyboard is
269 // fixed to do real platform dependent keyboard simulations
270 if (QTest::currentDataTag() == QString("N006a:Shift+Tab - [BackTab]")
271 || QTest::currentDataTag() == QString("N006b:Shift+Tab - [Shift+BackTab]"))
272 QEXPECT_FAIL("", "FLAW IN QTESTKEYBOARD: Keyboard events not passed through "
273 "platform dependent key handling code", Continue);
276 void tst_QShortcut::text()
280 // ------------------------------------------------------------------
281 // Number Elements --------------------------------------------------
282 // ------------------------------------------------------------------
283 void tst_QShortcut::number_data()
288 QTest::newRow("N00 - clear") << ClearAll <<0<<QString("")<<0<<0<<0<<0<<0<<0<<0<<0<<0;
290 //===========================================
291 // [Shift + key] on non-shift shortcuts testing
292 //===========================================
294 /* Testing Single Sequences
295 Shift + Qt::Key_M on Qt::Key_M
296 Qt::Key_M on Qt::Key_M
297 Shift + Qt::Key_Plus on Qt::Key_Pluss
298 Qt::Key_Plus on Qt::Key_Pluss
300 QTest::newRow("N001 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
301 //commented out because the behaviour changed, those tests should be updated
302 //QTest::newRow("N001:Shift + M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
303 QTest::newRow("N001:M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
304 QTest::newRow("N001 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
305 //commented out because the behaviour changed, those tests should be updated
306 //QTest::newRow("N001:Shift++ [+]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
307 QTest::newRow("N001:+ [+]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
308 QTest::newRow("N001 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
310 /* Testing Single Sequences
311 Shift + Qt::Key_M on Shift + Qt::Key_M
312 Qt::Key_M on Shift + Qt::Key_M
313 Shift + Qt::Key_Plus on Shift + Qt::Key_Pluss
314 Qt::Key_Plus on Shift + Qt::Key_Pluss
316 QTest::newRow("N002 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
317 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;
318 QTest::newRow("N002:M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
319 QTest::newRow("N002 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
320 QTest::newRow("N002:Shift++ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
321 QTest::newRow("N002:+ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
322 QTest::newRow("N002 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
324 /* Testing Single Sequences
325 Shift + Qt::Key_F1 on Qt::Key_F1
326 Qt::Key_F1 on Qt::Key_F1
328 QTest::newRow("N003 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
329 //commented out because the behaviour changed, those tests should be updated
330 //QTest::newRow("N003:Shift+F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
331 QTest::newRow("N003:F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
332 QTest::newRow("N003 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
333 /* Testing Single Sequences
334 Shift + Qt::Key_F1 on Shift + Qt::Key_F1
335 Qt::Key_F1 on Shift + Qt::Key_F1
338 QTest::newRow("N004 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
339 QTest::newRow("N004:Shift+F1 - [Shift+F1]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
340 QTest::newRow("N004:F1 - [Shift+F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
341 QTest::newRow("N004 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
343 /* Testing Single Sequences
344 Qt::Key_Tab on Qt::Key_Tab
345 Shift + Qt::Key_Tab on Qt::Key_Tab
346 Qt::Key_Backtab on Qt::Key_Tab
347 Shift + Qt::Key_Backtab on Qt::Key_Tab
349 QTest::newRow("N005a - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
350 QTest::newRow("N005a:Tab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
351 //commented out because the behaviour changed, those tests should be updated
352 //QTest::newRow("N005a:Shift+Tab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
353 // (Shift+)BackTab != Tab, but Shift+BackTab == Shift+Tab
354 QTest::newRow("N005a:Backtab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
355 QTest::newRow("N005a:Shift+Backtab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
356 QTest::newRow("N005a - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
358 /* Testing Single Sequences
359 Qt::Key_Tab on Shift + Qt::Key_Tab
360 Shift + Qt::Key_Tab on Shift + Qt::Key_Tab
361 Qt::Key_Backtab on Shift + Qt::Key_Tab
362 Shift + Qt::Key_Backtab on Shift + Qt::Key_Tab
364 QTest::newRow("N005b - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
365 QTest::newRow("N005b:Tab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
366 QTest::newRow("N005b:Shift+Tab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
367 QTest::newRow("N005b:BackTab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
368 QTest::newRow("N005b:Shift+BackTab - [Shift+Tab]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
369 QTest::newRow("N005b - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
371 /* Testing Single Sequences
372 Qt::Key_Tab on Qt::Key_Backtab
373 Shift + Qt::Key_Tab on Qt::Key_Backtab
374 Qt::Key_Backtab on Qt::Key_Backtab
375 Shift + Qt::Key_Backtab on Qt::Key_Backtab
377 QTest::newRow("N006a - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
378 QTest::newRow("N006a:Tab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
379 // This should work, since platform dependent code will transform the
380 // Shift+Tab into a Shift+BackTab, which should trigger the shortcut
381 QTest::newRow("N006a:Shift+Tab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; //XFAIL
382 QTest::newRow("N006a:BackTab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
383 //commented out because the behaviour changed, those tests should be updated
384 //QTest::newRow("N006a:Shift+BackTab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
385 QTest::newRow("N006a - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
387 /* Testing Single Sequences
388 Qt::Key_Tab on Shift + Qt::Key_Backtab
389 Shift + Qt::Key_Tab on Shift + Qt::Key_Backtab
390 Qt::Key_Backtab on Shift + Qt::Key_Backtab
391 Shift + Qt::Key_Backtab on Shift + Qt::Key_Backtab
393 QTest::newRow("N006b - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
394 QTest::newRow("N006b:Tab - [Shift+BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
395 QTest::newRow("N006b:Shift+Tab - [Shift+BackTab]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
396 QTest::newRow("N006b:BackTab - [Shift+BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
397 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
398 QTest::newRow("N006b - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
400 //===========================================
401 // [Shift + key] and [key] on shortcuts with
402 // and without modifiers
403 //===========================================
405 /* Testing Single Sequences
409 QTest::newRow("N007 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
410 QTest::newRow("N007 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
411 QTest::newRow("N007:F1") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
412 QTest::newRow("N007:Shift + F1") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
413 QTest::newRow("N007 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
415 /* Testing Single Sequences
421 QTest::newRow("N01 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
422 QTest::newRow("N02 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
423 QTest::newRow("N03 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
424 QTest::newRow("N04 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
425 QTest::newRow("N:Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
426 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;
427 QTest::newRow("N:Ctrl+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
428 QTest::newRow("N:Alt+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
430 /* Testing Single Sequence Ambiguity
431 Qt::Key_M on shortcut2
433 QTest::newRow("N05 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
434 QTest::newRow("N:Qt::Key_M on slot") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Ambiguous;
435 QTest::newRow("N05 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
437 /* Testing Single Specialkeys
440 Qt::UNICODE_ACCEL + Qt::Key_K
442 QTest::newRow("N06 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
443 QTest::newRow("N07 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
444 QTest::newRow("N08 - slot2") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::UNICODE_ACCEL + Qt::Key_K) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
446 QTest::newRow("N:Qt::Key_aring") << TestAccel << NoWidget << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
447 QTest::newRow("N:Qt::Key_Aring") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
448 QTest::newRow("N:Qt::Key_aring - Text Form") << TestAccel << NoWidget << QString("") << 0 << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
449 QTest::newRow("N:Qt::Key_Aring - Text Form") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+0) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
450 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;
451 QTest::newRow("N09 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
453 /* Testing Multiple Sequences
456 Shift+Qt::Key_I, Qt::Key_M
458 QTest::newRow("N10 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
459 QTest::newRow("N11 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_I) << 0 << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << NoResult;
460 QTest::newRow("N12 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_I) << 0 << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << NoResult;
462 QTest::newRow("N:Qt::Key_M (2)") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
463 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;
464 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;
465 QTest::newRow("N13 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
468 // ------------------------------------------------------------------
469 // Text Elements ----------------------------------------------------
470 // ------------------------------------------------------------------
471 void tst_QShortcut::text_data()
475 QTest::newRow("T00 - clear") << ClearAll <<0<<QString("")<<0<<0<<0<<0<<0<<0<<0<<0<<0;
477 //===========================================
478 // [Shift + key] on non-shift shortcuts testing
479 //===========================================
481 /* Testing Single Sequences
482 Shift + Qt::Key_M on Qt::Key_M
483 Qt::Key_M on Qt::Key_M
484 Shift + Qt::Key_Plus on Qt::Key_Pluss
485 Qt::Key_Plus on Qt::Key_Pluss
487 QTest::newRow("T001 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
488 //commented out because the behaviour changed, those tests should be updated
489 //QTest::newRow("T001:Shift+M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
490 QTest::newRow("T001:M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
491 QTest::newRow("T001 - slot2") << SetupAccel << TriggerSlot2 << QString("+") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
492 //commented out because the behaviour changed, those tests should be updated
493 //QTest::newRow("T001:Shift++ [+]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
494 QTest::newRow("T001:+ [+]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
495 QTest::newRow("T001 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
497 /* Testing Single Sequences
498 Shift + Qt::Key_M on Shift + Qt::Key_M
499 Qt::Key_M on Shift + Qt::Key_M
500 Shift + Qt::Key_Plus on Shift + Qt::Key_Pluss
501 Qt::Key_Plus on Shift + Qt::Key_Pluss
502 Shift + Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Pluss
503 Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Pluss
505 QTest::newRow("T002 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
506 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;
507 QTest::newRow("T002:M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
508 QTest::newRow("T002 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift++") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
509 QTest::newRow("T002:Shift++ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
510 QTest::newRow("T002:+ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
511 QTest::newRow("T002 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
513 /* Testing Single Sequences
514 Shift + Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Plus
515 Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Plus
516 Qt::Key_Plus on Ctrl + Qt::Key_Plus
518 QTest::newRow("T002b - slot1") << SetupAccel << TriggerSlot1 << QString("Ctrl++") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
519 //commented out because the behaviour changed, those tests should be updated
520 //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;
521 QTest::newRow("T002b:Ctrl++ [Ctrl++]") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
522 QTest::newRow("T002b:+ [Ctrl++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
523 QTest::newRow("T002b - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
525 /* Testing Single Sequences
526 Shift + Qt::Key_F1 on Qt::Key_F1
527 Qt::Key_F1 on Qt::Key_F1
529 QTest::newRow("T003 - slot1") << SetupAccel << TriggerSlot1 << QString("F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
530 //commented out because the behaviour changed, those tests should be updated
531 //QTest::newRow("T003:Shift+F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
532 QTest::newRow("T003:F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
533 QTest::newRow("T003 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
535 /* Testing Single Sequences
536 Shift + Qt::Key_F1 on Shift + Qt::Key_F1
537 Qt::Key_F1 on Shift + Qt::Key_F1
539 QTest::newRow("T004 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
540 QTest::newRow("T004:Shift+F1 - [Shift+F1]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
541 QTest::newRow("T004:F1 - [Shift+F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
542 QTest::newRow("T004 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
544 //===========================================
545 // [Shift + key] and [key] on shortcuts with
546 // and without modifiers
547 //===========================================
549 /* Testing Single Sequences
553 QTest::newRow("T007 - slot1") << SetupAccel << TriggerSlot1 << QString("F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
554 QTest::newRow("T007 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
555 QTest::newRow("T007:F1") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
556 QTest::newRow("T007:Shift + F1") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
557 QTest::newRow("T007 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
559 /* Testing Single Sequences
565 QTest::newRow("T01 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
566 QTest::newRow("T02 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
567 QTest::newRow("T03 - slot1") << SetupAccel << TriggerSlot1 << QString("Ctrl+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
568 QTest::newRow("T04 - slot2") << SetupAccel << TriggerSlot2 << QString("Alt+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
570 QTest::newRow("T:Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
571 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;
572 QTest::newRow("T:Ctrl + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
573 QTest::newRow("T:Alt + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
575 /* Testing Single Sequence Ambiguity
576 Qt::Key_M on shortcut2
578 QTest::newRow("T05 - slot2") << SetupAccel << TriggerSlot2 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
579 QTest::newRow("T:Qt::Key_M on TriggerSlot2") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Ambiguous;
580 QTest::newRow("T06 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
582 /* Testing Single Specialkeys
585 Qt::UNICODE_ACCEL + Qt::Key_K
587 /* see comments above on the #ifdef'ery */
588 QTest::newRow("T06 - slot1") << SetupAccel << TriggerSlot1 << QString("\x0C5")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
589 QTest::newRow("T07 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+\x0C5")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
590 QTest::newRow("T08 - slot2") << SetupAccel << TriggerSlot1 << QString("K") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
591 QTest::newRow("T:Qt::Key_aring") << TestAccel << NoWidget << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
592 QTest::newRow("T:Qt::Key_Aring") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
593 QTest::newRow("T:Qt::Key_aring - Text Form") << TestAccel << NoWidget << QString("") << 0 << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
594 QTest::newRow("T:Qt::Key_Aring - Text Form") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+0) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
595 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;
596 QTest::newRow("T09 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
598 /* Testing Multiple Sequences
601 Shift+Qt::Key_I, Qt::Key_M
603 QTest::newRow("T10 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
604 QTest::newRow("T11 - slot2") << SetupAccel << TriggerSlot2 << QString("I, M")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
605 QTest::newRow("T12 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+I, M")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
606 QTest::newRow("T:Qt::Key_M (2)") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
607 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;
608 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;
609 QTest::newRow("T13 - clear") << ClearAll << 0 << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
612 // ------------------------------------------------------------------
613 // Disabled Elements ------------------------------------------------
614 // ------------------------------------------------------------------
615 void tst_QShortcut::disabledItems()
618 mainW->activateWindow();
622 /* Testing Disabled Shortcuts
624 Shift + Qt::Key_M on slot1
625 Qt::Key_M on slot2 (disabled)
626 Shift + Qt::Key_M on slot2 (disabled)
629 // Setup two identical shortcuts on different pushbuttons
630 QPushButton pb1(mainW);
631 QPushButton pb2(mainW);
632 pb1.setObjectName("pushbutton-1");
633 pb2.setObjectName("pushbutton-2");
634 pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger
637 QShortcut *cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "M");
638 QShortcut *cut2 = setupShortcut(&pb1, "shortcut2-pb1", TriggerSlot1, "Shift+M");
639 QShortcut *cut3 = setupShortcut(&pb2, "shortcut3-pb2", TriggerSlot2, "M");
640 QShortcut *cut4 = setupShortcut(&pb2, "shortcut4-pb2", TriggerSlot2, "Shift+M");
642 cut3->setEnabled(false);
643 cut4->setEnabled(false);
645 currentResult = NoResult;
646 sendKeyEvents(Qt::Key_M, 'm');
647 QCOMPARE(currentResult, Slot1Triggered);
649 currentResult = NoResult;
650 sendKeyEvents(Qt::SHIFT+Qt::Key_M, 'M');
651 QCOMPARE(currentResult, Slot1Triggered);
653 cut2->setEnabled(false);
654 cut4->setEnabled(true);
656 /* Testing Disabled Shortcuts
658 Shift + Qt::Key_M on slot1 (disabled)
659 Qt::Key_M on slot2 (disabled)
660 Shift + Qt::Key_M on slot2
662 currentResult = NoResult;
663 sendKeyEvents( Qt::Key_M, 'm' );
664 QCOMPARE( currentResult, Slot1Triggered );
666 currentResult = NoResult;
667 sendKeyEvents( Qt::SHIFT+Qt::Key_M, 'M' );
668 QCOMPARE( currentResult, Slot2Triggered );
671 /* Testing Disabled Accel
673 Shift + Qt::Key_F5 on slot2 (disabled)
676 cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "F5");
677 cut4 = setupShortcut(&pb2, "shortcut4-pb2", TriggerSlot2, "Shift+F5");
679 cut1->setKey(QKeySequence("F5"));
680 cut4->setKey(QKeySequence("Shift+F5"));
682 cut1->setEnabled(true);
683 cut4->setEnabled(false);
685 currentResult = NoResult;
686 sendKeyEvents( Qt::Key_F5, 0 );
687 QCOMPARE( currentResult, Slot1Triggered );
689 currentResult = NoResult;
690 sendKeyEvents( Qt::SHIFT+Qt::Key_F5, 0 );
691 QCOMPARE( currentResult, NoResult );
694 qFatal("Not testing statusbar text feedback yet, since not implemented");
695 /* Testing Disabled Accel, and the corresponding statusbar feedback
696 Ctrl + Qt::Key_K, Ctrl + Qt::Key_L on slot1
697 Ctrl + Qt::Key_K, Ctrl + Qt::Key_M on slot2 (disabled)
699 cut1->setKey(QKeySequence("Ctrl+K, Ctrl+L"));
700 cut4->setKey(QKeySequence("Ctrl+K, Ctrl+M"));
702 cut1->setEnabled(true);
703 cut4->setEnabled(false);
705 currentResult = NoResult;
706 sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 );
707 sendKeyEvents( Qt::CTRL+Qt::Key_Q, 0 );
708 QCOMPARE( currentResult, NoResult );
710 QCOMPARE( sbText, QString("Ctrl+K, Ctrl+Q not defined") );
712 currentResult = NoResult;
713 sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 );
714 sendKeyEvents( Qt::CTRL+Qt::Key_M, 0 );
715 QCOMPARE( currentResult, NoResult );
717 QCOMPARE( sbText, QString::null );
719 currentResult = NoResult;
720 sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 );
721 sendKeyEvents( Qt::CTRL+Qt::Key_L, 0 );
722 QCOMPARE( currentResult, Slot1Triggered );
724 QCOMPARE( sbText, QString::null );
730 // ------------------------------------------------------------------
731 // Ambiguous Elements -----------------------------------------------
732 // ------------------------------------------------------------------
733 void tst_QShortcut::ambiguousRotation()
736 /* Testing Shortcut rotation scheme
737 Ctrl + Qt::Key_A on slot1 (disabled)
738 Ctrl + Qt::Key_A on slot2 (disabled)
739 Ctrl + Qt::Key_A on slot3
740 Ctrl + Qt::Key_A on slot4
741 Ctrl + Qt::Key_A on slot5 (disabled)
742 Ctrl + Qt::Key_A on slot6
743 Ctrl + Qt::Key_A on slot7 (disabled)
745 QShortcut *cut1 = setupShortcut(TriggerSlot1, "Ctrl+A");
746 QShortcut *cut2 = setupShortcut(TriggerSlot2, "Ctrl+A");
747 QShortcut *cut3 = setupShortcut(TriggerSlot3, "Ctrl+A");
748 QShortcut *cut4 = setupShortcut(TriggerSlot4, "Ctrl+A");
749 QShortcut *cut5 = setupShortcut(TriggerSlot5, "Ctrl+A");
750 QShortcut *cut6 = setupShortcut(TriggerSlot6, "Ctrl+A");
751 QShortcut *cut7 = setupShortcut(TriggerSlot7, "Ctrl+A");
753 cut1->setEnabled(false);
754 cut2->setEnabled(false);
755 cut5->setEnabled(false);
756 cut7->setEnabled(false);
758 // Test proper rotation
763 currentResult = NoResult;
764 ambigResult = NoResult;
765 sendKeyEvents(Qt::CTRL+Qt::Key_A);
766 QCOMPARE(currentResult, Ambiguous);
767 QCOMPARE(ambigResult, Slot3Triggered);
769 currentResult = NoResult;
770 ambigResult = NoResult;
771 sendKeyEvents(Qt::CTRL+Qt::Key_A);
772 QCOMPARE(currentResult, Ambiguous);
773 QCOMPARE(ambigResult, Slot4Triggered);
775 currentResult = NoResult;
776 ambigResult = NoResult;
777 sendKeyEvents(Qt::CTRL+Qt::Key_A);
778 QCOMPARE(currentResult, Ambiguous);
779 QCOMPARE(ambigResult, Slot6Triggered);
781 currentResult = NoResult;
782 ambigResult = NoResult;
783 sendKeyEvents(Qt::CTRL+Qt::Key_A);
784 QCOMPARE(currentResult, Ambiguous);
785 QCOMPARE(ambigResult, Slot3Triggered);
787 currentResult = NoResult;
788 ambigResult = NoResult;
789 sendKeyEvents(Qt::CTRL+Qt::Key_A);
790 QCOMPARE(currentResult, Ambiguous);
791 QCOMPARE(ambigResult, Slot4Triggered);
793 currentResult = NoResult;
794 ambigResult = NoResult;
795 sendKeyEvents(Qt::CTRL+Qt::Key_A);
796 QCOMPARE(currentResult, Ambiguous);
797 QCOMPARE(ambigResult, Slot6Triggered);
799 /* Testing Shortcut rotation scheme
800 Ctrl + Qt::Key_A on slot1
801 Ctrl + Qt::Key_A on slot2
802 Ctrl + Qt::Key_A on slot3 (disabled)
803 Ctrl + Qt::Key_A on slot4 (disabled)
804 Ctrl + Qt::Key_A on slot5
805 Ctrl + Qt::Key_A on slot6 (disabled)
806 Ctrl + Qt::Key_A on slot7
809 cut1->setEnabled(true);
810 cut2->setEnabled(true);
811 cut5->setEnabled(true);
812 cut7->setEnabled(true);
814 cut3->setEnabled(false);
815 cut4->setEnabled(false);
816 cut6->setEnabled(false);
818 currentResult = NoResult;
819 ambigResult = NoResult;
820 sendKeyEvents(Qt::CTRL+Qt::Key_A);
821 QCOMPARE(currentResult, Ambiguous);
822 QCOMPARE(ambigResult, Slot1Triggered);
824 currentResult = NoResult;
825 ambigResult = NoResult;
826 sendKeyEvents(Qt::CTRL+Qt::Key_A);
827 QCOMPARE(currentResult, Ambiguous);
828 QCOMPARE(ambigResult, Slot2Triggered);
830 currentResult = NoResult;
831 ambigResult = NoResult;
832 sendKeyEvents(Qt::CTRL+Qt::Key_A);
833 QCOMPARE(currentResult, Ambiguous);
834 QCOMPARE(ambigResult, Slot5Triggered);
836 currentResult = NoResult;
837 ambigResult = NoResult;
838 sendKeyEvents(Qt::CTRL+Qt::Key_A);
839 QCOMPARE(currentResult, Ambiguous);
840 QCOMPARE(ambigResult, Slot7Triggered);
842 currentResult = NoResult;
843 ambigResult = NoResult;
844 sendKeyEvents(Qt::CTRL+Qt::Key_A);
845 QCOMPARE(currentResult, Ambiguous);
846 QCOMPARE(ambigResult, Slot1Triggered);
848 currentResult = NoResult;
849 ambigResult = NoResult;
850 sendKeyEvents(Qt::CTRL+Qt::Key_A);
851 QCOMPARE(currentResult, Ambiguous);
852 QCOMPARE(ambigResult, Slot2Triggered);
854 currentResult = NoResult;
855 ambigResult = NoResult;
856 sendKeyEvents(Qt::CTRL+Qt::Key_A);
857 QCOMPARE(currentResult, Ambiguous);
858 QCOMPARE(ambigResult, Slot5Triggered);
860 currentResult = NoResult;
861 ambigResult = NoResult;
862 sendKeyEvents(Qt::CTRL+Qt::Key_A);
863 QCOMPARE(currentResult, Ambiguous);
864 QCOMPARE(ambigResult, Slot7Triggered);
873 void tst_QShortcut::ambiguousItems()
876 /* Testing Ambiguous Shortcuts
877 Qt::Key_M on Pushbutton 1
878 Qt::Key_M on Pushbutton 2
881 // Setup two identical shortcuts on different pushbuttons
882 QPushButton pb1(mainW);
883 QPushButton pb2(mainW);
884 pb1.setObjectName("pushbutton-1");
885 pb2.setObjectName("pushbutton-2");
886 pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger
889 setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "M");
890 setupShortcut(&pb1, "shortcut2-pb2", TriggerSlot2, "M");
892 currentResult = NoResult;
893 sendKeyEvents( Qt::Key_M, 'm' );
894 QCOMPARE( currentResult, Ambiguous );
895 QCOMPARE( ambigResult, Slot1Triggered );
897 currentResult = NoResult;
898 sendKeyEvents( Qt::Key_M, 'm' );
899 QCOMPARE( currentResult, Ambiguous );
900 QCOMPARE( ambigResult, Slot2Triggered );
902 currentResult = NoResult;
903 sendKeyEvents( Qt::Key_M, 'm' );
904 QCOMPARE( currentResult, Ambiguous );
905 QCOMPARE( ambigResult, Slot1Triggered );
911 // ------------------------------------------------------------------
912 // Unicode and non-unicode Elements ---------------------------------
913 // ------------------------------------------------------------------
914 void tst_QShortcut::unicodeCompare()
917 /* Testing Unicode/non-Unicode Shortcuts
918 Qt::Key_M on Pushbutton 1
919 Qt::Key_M on Pushbutton 2
921 QPushButton pb1(mainW);
922 QPushButton pb2(mainW);
923 pb1.setObjectName("pushbutton-1");
924 pb2.setObjectName("pushbutton-2");
925 pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger
928 QKeySequence ks1("Ctrl+M"); // Unicode
929 QKeySequence ks2(Qt::CTRL+Qt::Key_M); // non-Unicode
930 setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, ks1);
931 setupShortcut(&pb1, "shortcut2-pb2", TriggerSlot2, ks2);
933 currentResult = NoResult;
934 sendKeyEvents( Qt::CTRL+Qt::Key_M, 0 );
935 QCOMPARE( currentResult, Ambiguous );
936 // They _are_ ambiguous, so the QKeySequence operator==
937 // should indicate the same
938 QVERIFY( ks1 == ks2 );
939 QVERIFY( !(ks1 != ks2) );
944 // ------------------------------------------------------------------
945 // Keypress consumption verification --------------------------------
946 // ------------------------------------------------------------------
947 void tst_QShortcut::keypressConsumption()
951 QCOMPARE(edit->toPlainText().size(), 0);
953 QShortcut *cut1 = setupShortcut(edit, "shortcut1-line", TriggerSlot1, "Ctrl+I, A");
954 QShortcut *cut2 = setupShortcut(edit, "shortcut1-line", TriggerSlot2, "Ctrl+I, B");
956 currentResult = NoResult;
957 ambigResult = NoResult;
958 sendKeyEvents(edit, Qt::CTRL + Qt::Key_I, 0); // Send key to edit
959 QCOMPARE( currentResult, NoResult );
960 QCOMPARE( ambigResult, NoResult );
961 QCOMPARE(edit->toPlainText(), QString(""));
963 // Make sure next keypress is eaten (failing multiple keysequence)
964 sendKeyEvents(edit, Qt::Key_C, 'c'); // Send key to edit
965 QCOMPARE( currentResult, NoResult );
966 QCOMPARE( ambigResult, NoResult );
967 QCOMPARE(edit->toPlainText(), QString(""));
969 // Next keypress should be normal
970 sendKeyEvents(edit, Qt::Key_C, 'c'); // Send key to edit
971 QCOMPARE( currentResult, NoResult );
972 QCOMPARE( ambigResult, NoResult );
973 QCOMPARE(edit->toPlainText(), QString("c"));
975 currentResult = NoResult;
976 ambigResult = NoResult;
978 QCOMPARE(edit->toPlainText().size(), 0);
980 cut1->setEnabled(false);
981 cut2->setEnabled(false);
983 // Make sure keypresses is passed on, since all multiple keysequences
984 // with Ctrl+I are disabled
985 sendKeyEvents(edit, Qt::CTRL + Qt::Key_I, 0); // Send key to edit
986 QCOMPARE( currentResult, NoResult );
987 QCOMPARE( ambigResult, NoResult );
988 QVERIFY(edit->toPlainText().endsWith("<Ctrl+I>"));
990 sendKeyEvents(edit, Qt::Key_A, 'a'); // Send key to edit
991 QCOMPARE( currentResult, NoResult );
992 QCOMPARE( ambigResult, NoResult );
993 QVERIFY(edit->toPlainText().endsWith("<Ctrl+I>a"));
998 // ------------------------------------------------------------------
999 // Context Validation -----------------------------------------------
1000 // ------------------------------------------------------------------
1001 void tst_QShortcut::context()
1003 clearAllShortcuts();
1006 TestEdit *other1 = new TestEdit(&myBox, "test_edit_other1");
1007 TestEdit *other2 = new TestEdit(&myBox, "test_edit_other2");
1008 QHBoxLayout *layout = new QHBoxLayout(&myBox);
1009 layout->addWidget(other1);
1010 layout->addWidget(other2);
1013 qt_x11_wait_for_window_manager(&myBox);
1016 setupShortcut(other1, "ActiveWindow", TriggerSlot1, QKeySequence("Alt+1"), Qt::WindowShortcut);
1017 setupShortcut(other2, "Focus", TriggerSlot2, QKeySequence("Alt+2"), Qt::WidgetShortcut);
1018 setupShortcut(edit, "Application", TriggerSlot3, QKeySequence("Alt+3"), Qt::ApplicationShortcut);
1020 currentResult = NoResult;
1021 ambigResult = NoResult;
1026 // edit doesn't have focus, so ActiveWindow context should work
1027 // ..but Focus context shouldn't..
1028 // Changing focus to edit should make focus context work
1029 // Application context should always work
1032 // Focus on 'other1' edit, so Active Window context should trigger
1033 other1->activateWindow(); // <---
1034 QApplication::setActiveWindow(other1);
1035 QCOMPARE(qApp->activeWindow(), other1->window());
1036 QCOMPARE(qApp->focusWidget(), (QWidget *)other1);
1038 currentResult = NoResult;
1039 ambigResult = NoResult;
1044 QCOMPARE(qApp->focusWidget(), (QWidget *)other1);
1045 sendKeyEvents(other1, Qt::ALT+Qt::Key_1);
1046 QCOMPARE(currentResult, Slot1Triggered);
1047 QCOMPARE(ambigResult, NoResult);
1048 QCOMPARE(edit->toPlainText(), QString(""));
1049 QCOMPARE(other1->toPlainText(), QString(""));
1050 QCOMPARE(other2->toPlainText(), QString(""));
1052 // ..but not Focus context on 'other2'..
1053 currentResult = NoResult;
1054 ambigResult = NoResult;
1059 sendKeyEvents(other1, Qt::ALT+Qt::Key_2);
1060 QCOMPARE(currentResult, NoResult);
1061 QCOMPARE(ambigResult, NoResult);
1062 QCOMPARE(edit->toPlainText(), QString(""));
1063 QCOMPARE(other1->toPlainText(), QString("<Alt+2>"));
1064 QCOMPARE(other2->toPlainText(), QString(""));
1066 // ..however, application global context on 'edit' should..
1067 currentResult = NoResult;
1068 ambigResult = NoResult;
1073 sendKeyEvents(other1, Qt::ALT+Qt::Key_3);
1074 QCOMPARE(currentResult, Slot3Triggered);
1075 QCOMPARE(ambigResult, NoResult);
1076 QCOMPARE(edit->toPlainText(), QString(""));
1077 QCOMPARE(other1->toPlainText(), QString(""));
1078 QCOMPARE(other2->toPlainText(), QString(""));
1080 // Changing focus to 'other2' should make the Focus context there work
1081 other2->activateWindow();
1082 other2->setFocus(); // ###
1085 qt_x11_wait_for_window_manager(other2);
1088 QCOMPARE(qApp->activeWindow(), other2->window());
1089 QCOMPARE(qApp->focusWidget(), (QWidget *)other2);
1091 currentResult = NoResult;
1092 ambigResult = NoResult;
1097 sendKeyEvents(other2, Qt::ALT+Qt::Key_2);
1098 QCOMPARE(currentResult, Slot2Triggered);
1099 QCOMPARE(ambigResult, NoResult);
1100 QCOMPARE(edit->toPlainText(), QString(""));
1101 QCOMPARE(other1->toPlainText(), QString(""));
1102 QCOMPARE(other2->toPlainText(), QString(""));
1104 clearAllShortcuts();
1107 edit->activateWindow();
1110 qt_x11_wait_for_window_manager(edit);
1115 // ------------------------------------------------------------------
1116 // Element Testing helper functions ---------------------------------
1117 // ------------------------------------------------------------------
1118 void tst_QShortcut::clearAllShortcuts()
1120 QList<QShortcut *> shortcutsCpy = shortcuts;
1121 qDeleteAll(shortcutsCpy);
1125 QShortcut *tst_QShortcut::setupShortcut(int testWidget, const QKeySequence &ks)
1127 return setupShortcut(mainW, QTest::currentDataTag() ? QTest::currentDataTag() : "", testWidget, ks);
1130 QShortcut *tst_QShortcut::setupShortcut(int testWidget, const QString &txt, int k1, int k2, int k3, int k4)
1132 return setupShortcut(mainW, QTest::currentDataTag() ? QTest::currentDataTag() : "", testWidget,
1133 (txt.isEmpty() ? QKeySequence(k1, k2, k3, k4) : QKeySequence(txt)));
1136 QShortcut *tst_QShortcut::setupShortcut(QWidget *parent, const char *name, int testWidget, const QString &txt, int k1, int k2, int k3, int k4)
1138 return setupShortcut(parent, name, testWidget,
1139 (txt.isEmpty() ? QKeySequence(k1, k2, k3, k4) : QKeySequence(txt)));
1142 QShortcut *tst_QShortcut::setupShortcut(QWidget *parent, const char *name, int testWidget,
1143 const QKeySequence &ks, Qt::ShortcutContext context)
1145 // Set up shortcut for next test
1146 QShortcut *cut = new QShortcut(QKeySequence(), parent, 0, 0, context);
1147 cut->setObjectName(name);
1150 const char *normal = 0;
1151 const char *ambig = 0;
1155 normal = SLOT(slotTrig1());
1156 ambig = SLOT(ambigSlot1());
1159 normal = SLOT(slotTrig2());
1160 ambig = SLOT(ambigSlot2());
1163 normal = SLOT(slotTrig3());
1164 ambig = SLOT(ambigSlot3());
1167 normal = SLOT(slotTrig4());
1168 ambig = SLOT(ambigSlot4());
1171 normal = SLOT(slotTrig5());
1172 ambig = SLOT(ambigSlot5());
1175 normal = SLOT(slotTrig6());
1176 ambig = SLOT(ambigSlot6());
1179 normal = SLOT(slotTrig7());
1180 ambig = SLOT(ambigSlot7());
1183 connect(cut, SIGNAL(activated()), this, normal);
1184 connect(cut, SIGNAL(activatedAmbiguously()), this, ambig);
1185 connect(cut, SIGNAL(destroyed(QObject*)), this, SLOT(shortcutDestroyed(QObject*)));
1186 shortcuts.append(cut);
1190 void tst_QShortcut::shortcutDestroyed(QObject* obj)
1192 shortcuts.removeAll(static_cast<QShortcut *>(obj));
1195 void tst_QShortcut::sendKeyEvents(int k1, QChar c1, int k2, QChar c2, int k3, QChar c3, int k4, QChar c4)
1197 sendKeyEvents(mainW, k1, c1, k2, c2, k3, c3, k4, c4);
1200 void tst_QShortcut::sendKeyEvents(QWidget *w, int k1, QChar c1, int k2, QChar c2, int k3, QChar c3, int k4, QChar c4)
1202 Qt::KeyboardModifiers b1 = toButtons( k1 );
1203 Qt::KeyboardModifiers b2 = toButtons( k2 );
1204 Qt::KeyboardModifiers b3 = toButtons( k3 );
1205 Qt::KeyboardModifiers b4 = toButtons( k4 );
1206 k1 &= ~Qt::MODIFIER_MASK;
1207 k2 &= ~Qt::MODIFIER_MASK;
1208 k3 &= ~Qt::MODIFIER_MASK;
1209 k4 &= ~Qt::MODIFIER_MASK;
1212 if (k1 || c1.toAscii()) {
1213 QString c(c1.unicode() == QChar::Null ? QString() : QString(c1));
1214 QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k1), c, b1);
1215 QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k1), c, b1);
1218 if (k2 || c2.toAscii()) {
1219 QString c(c2.unicode() == QChar::Null ? QString() : QString(c2));
1220 QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k2), c, b2);
1221 QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k2), c, b2);
1224 if (k3 || c3.toAscii()) {
1225 QString c(c3.unicode() == QChar::Null ? QString() : QString(c3));
1226 QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k3), c, b3);
1227 QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k3), c, b3);
1230 if (k4 || c4.toAscii()) {
1231 QString c(c4.unicode() == QChar::Null ? QString() : QString(c4));
1232 QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k4), c, b4);
1233 QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k4), c, b4);
1237 void tst_QShortcut::testElement()
1239 currentResult = NoResult;
1240 QFETCH(int, action);
1241 QFETCH(int, testWidget);
1242 QFETCH(QString, txt);
1251 QFETCH(int, result);
1253 if (action == ClearAll) {
1254 clearAllShortcuts();
1255 } else if (action == SetupAccel) {
1256 setupShortcut(testWidget, txt, k1, k2, k3, k4);
1258 sendKeyEvents(k1, c1, k2, c2, k3, c3, k4, c4);
1259 QCOMPARE(int(currentResult), result);
1263 QTEST_MAIN(tst_QShortcut)
1264 #include "tst_qshortcut.moc"