1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 
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>
50 #include <qdebug.h>
51 #include <qstring.h>
52 #include <qshortcut.h>
53 
54 class AccelForm;
55 QT_BEGIN_NAMESPACE
56 class QMainWindow;
57 class QTextEdit;
58 QT_END_NAMESPACE
59 
60 //TESTED_CLASS=
61 //TESTED_FILES=
62 
63 class tst_QShortcut : public QObject
64 {
65     Q_OBJECT
66 public:
67     tst_QShortcut();
68     virtual ~tst_QShortcut();
69 
70 
71     enum Action {
72         SetupAccel,
73         TestAccel,
74         ClearAll
75     } currentAction;
76 
77     enum Widget {
78         NoWidget,
79         TriggerSlot1,
80         TriggerSlot2,
81         TriggerSlot3,
82         TriggerSlot4,
83         TriggerSlot5,
84         TriggerSlot6,
85         TriggerSlot7
86     };
87 
88     enum Result {
89         NoResult,
90         Slot1Triggered,
91         Slot2Triggered,
92         Slot3Triggered,
93         Slot4Triggered,
94         Slot5Triggered,
95         Slot6Triggered,
96         Slot7Triggered,
97         Ambiguous
98     } currentResult;
99 
100 public slots:
slotTrig1()101     void slotTrig1() { currentResult = Slot1Triggered; }
slotTrig2()102     void slotTrig2() { currentResult = Slot2Triggered; }
slotTrig3()103     void slotTrig3() { currentResult = Slot3Triggered; }
slotTrig4()104     void slotTrig4() { currentResult = Slot4Triggered; }
slotTrig5()105     void slotTrig5() { currentResult = Slot5Triggered; }
slotTrig6()106     void slotTrig6() { currentResult = Slot6Triggered; }
slotTrig7()107     void slotTrig7() { currentResult = Slot7Triggered; }
ambigSlot1()108     void ambigSlot1() { currentResult = Ambiguous; ambigResult = Slot1Triggered; }
ambigSlot2()109     void ambigSlot2() { currentResult = Ambiguous; ambigResult = Slot2Triggered; }
ambigSlot3()110     void ambigSlot3() { currentResult = Ambiguous; ambigResult = Slot3Triggered; }
ambigSlot4()111     void ambigSlot4() { currentResult = Ambiguous; ambigResult = Slot4Triggered; }
ambigSlot5()112     void ambigSlot5() { currentResult = Ambiguous; ambigResult = Slot5Triggered; }
ambigSlot6()113     void ambigSlot6() { currentResult = Ambiguous; ambigResult = Slot6Triggered; }
ambigSlot7()114     void ambigSlot7() { currentResult = Ambiguous; ambigResult = Slot7Triggered; }
statusMessage(const QString & message)115     void statusMessage( const QString& message ) { sbText = message; }
116     void shortcutDestroyed(QObject* obj);
117 
118 public slots:
119     void initTestCase();
120     void cleanupTestCase();
121 
122 private slots:
123     void number_data();
124     void number();
125     void text_data();
126     void text();
127     void disabledItems();
128     void ambiguousItems();
129     void ambiguousRotation();
130     void keypressConsumption();
131     void unicodeCompare();
132     void context();
133 
134 protected:
135     static Qt::KeyboardModifiers toButtons( int key );
136     void defElements();
137 
138     void clearAllShortcuts();
139     QShortcut *setupShortcut(int testWidget, const QKeySequence &ks);
140     QShortcut *setupShortcut(int testWidget, const QString &txt, int k1 = 0, int k2 = 0, int k3 = 0, int k4 = 0);
141 
142     QShortcut *setupShortcut(QWidget *parent, const char *name, int testWidget, const QString &txt, int k1 = 0, int k2 = 0, int k3 = 0, int k4 = 0);
143     QShortcut *setupShortcut(QWidget *parent, const char *name, int testWidget, const QKeySequence &ks, Qt::ShortcutContext context = Qt::WindowShortcut);
144 
145     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);
146     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);
147 
148     void testElement();
149 
150     QMainWindow *mainW;
151     QList<QShortcut*> shortcuts;
152     QTextEdit *edit;
153     QString sbText;
154     Result ambigResult;
155 };
156 
157 QT_BEGIN_NAMESPACE
158 template<> struct QMetaTypeId<tst_QShortcut::Widget>
qt_metatype_idQMetaTypeId159 { enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } };
160 template<> struct QMetaTypeId<tst_QShortcut::Result>
qt_metatype_idQMetaTypeId161 { enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } };
162 template<> struct QMetaTypeId<tst_QShortcut::Action>
qt_metatype_idQMetaTypeId163 { enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } };
164 QT_END_NAMESPACE
165 
166 class TestEdit : public QTextEdit
167 {
168     Q_OBJECT
169 public:
TestEdit(QWidget * parent,const char * name)170     TestEdit(QWidget *parent, const char *name)
171 	: QTextEdit(parent)
172     {
173         setObjectName(name);
174     }
175 
176 protected:
event(QEvent * e)177     bool event(QEvent *e) {
178         // Make testedit allow any Ctrl+Key as shortcut
179         if (e->type() == QEvent::ShortcutOverride) {
180             QKeyEvent *ke = static_cast<QKeyEvent*>(e);
181             if (ke->modifiers() == Qt::ControlModifier
182                 && ke->key() > Qt::Key_Any
183                 && ke->key() < Qt::Key_ydiaeresis) {
184                 ke->ignore();
185                 return true;
186             }
187         }
188 
189         // If keypress not processed as normal, check for
190         // Ctrl+Key event, and input custom string for
191         // result comparison.
192         if (e->type() == QEvent::KeyPress) {
193             QKeyEvent *ke = static_cast<QKeyEvent*>(e);
194             if (ke->modifiers() && ke->key() > Qt::Key_Any
195                 && ke->key() < Qt::Key_ydiaeresis) {
196                 if (ke->modifiers() == Qt::ControlModifier)
197                     insertPlainText(QString("<Ctrl+%1>").arg(char(ke->key())));
198                 else if (ke->modifiers() == Qt::AltModifier)
199                     insertPlainText(QString("<Alt+%1>").arg(char(ke->key())));
200                 else if (ke->modifiers() == Qt::ShiftModifier)
201                     insertPlainText(QString("<Shift+%1>").arg(char(ke->key())));
202                 return true;
203             }
204         }
205         return QTextEdit::event(e);
206     }
207 };
208 
tst_QShortcut()209 tst_QShortcut::tst_QShortcut(): mainW( 0 )
210 {
211 }
212 
~tst_QShortcut()213 tst_QShortcut::~tst_QShortcut()
214 {
215     clearAllShortcuts();
216 }
217 
initTestCase()218 void tst_QShortcut::initTestCase()
219 {
220     currentResult = NoResult;
221     mainW = new QMainWindow(0);
222     mainW->setWindowFlags(Qt::X11BypassWindowManagerHint);
223     edit  = new TestEdit(mainW, "test_edit");
224     mainW->setFixedSize( 100, 100 );
225     mainW->setCentralWidget( edit );
226     mainW->show();
227 #ifdef Q_WS_X11
228     qt_x11_wait_for_window_manager(mainW);
229 #endif
230     mainW->activateWindow();
231     QTest::qWait(100);
232     connect( mainW->statusBar(), SIGNAL(messageChanged(const QString&)),
233 	     this, SLOT(statusMessage(const QString&)) );
234 }
235 
cleanupTestCase()236 void tst_QShortcut::cleanupTestCase()
237 {
238     delete mainW;
239 }
240 
toButtons(int key)241 Qt::KeyboardModifiers tst_QShortcut::toButtons( int key )
242 {
243     Qt::KeyboardModifiers result = Qt::NoModifier;
244     if ( key & Qt::SHIFT )
245 	result |= Qt::ShiftModifier;
246     if ( key & Qt::CTRL )
247 	result |= Qt::ControlModifier;
248    if ( key & Qt::META )
249 	result |= Qt::MetaModifier;
250    if ( key & Qt::ALT )
251 	result |= Qt::AltModifier;
252     return result;
253 }
254 
defElements()255 void tst_QShortcut::defElements()
256 {
257     QTest::addColumn<int>("action");
258     QTest::addColumn<int>("testWidget");
259     QTest::addColumn<QString>("txt");
260     QTest::addColumn<int>("k1");
261     QTest::addColumn<int>("c1");
262     QTest::addColumn<int>("k2");
263     QTest::addColumn<int>("c2");
264     QTest::addColumn<int>("k3");
265     QTest::addColumn<int>("c3");
266     QTest::addColumn<int>("k4");
267     QTest::addColumn<int>("c4");
268     QTest::addColumn<int>("result");
269 }
270 
number()271 void tst_QShortcut::number()
272 {
273     // We expect a failure on these tests, until QtTestKeyboard is
274     // fixed to do real platform dependent keyboard simulations
275     if (QTest::currentDataTag() == QString("N006a:Shift+Tab - [BackTab]")
276         || QTest::currentDataTag() == QString("N006b:Shift+Tab - [Shift+BackTab]"))
277         QEXPECT_FAIL("", "FLAW IN QTESTKEYBOARD: Keyboard events not passed through "
278                         "platform dependent key handling code", Continue);
279     testElement();
280 }
text()281 void tst_QShortcut::text()
282 {
283     testElement();
284 }
285 // ------------------------------------------------------------------
286 // Number Elements --------------------------------------------------
287 // ------------------------------------------------------------------
number_data()288 void tst_QShortcut::number_data()
289 {
290     defElements();
291 
292     // Clear all
293     QTest::newRow("N00 - clear") << ClearAll <<0<<QString("")<<0<<0<<0<<0<<0<<0<<0<<0<<0;
294 
295     //===========================================
296     // [Shift + key] on non-shift shortcuts testing
297     //===========================================
298 
299     /* Testing Single Sequences
300        Shift + Qt::Key_M    on  Qt::Key_M
301                Qt::Key_M    on  Qt::Key_M
302        Shift + Qt::Key_Plus on  Qt::Key_Pluss
303                Qt::Key_Plus on  Qt::Key_Pluss
304     */
305     QTest::newRow("N001 - slot1")		    << SetupAccel << TriggerSlot1 << QString("")    << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
306     //commented out because the behaviour changed, those tests should be updated
307     //QTest::newRow("N001:Shift + M - [M]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
308     QTest::newRow("N001:M - [M]")		    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
309     QTest::newRow("N001 - slot2")		    << SetupAccel << TriggerSlot2 << QString("")    << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
310     //commented out because the behaviour changed, those tests should be updated
311     //QTest::newRow("N001:Shift++ [+]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
312     QTest::newRow("N001:+ [+]")		    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
313     QTest::newRow("N001 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
314 
315     /* Testing Single Sequences
316        Shift + Qt::Key_M    on  Shift + Qt::Key_M
317                Qt::Key_M    on  Shift + Qt::Key_M
318        Shift + Qt::Key_Plus on  Shift + Qt::Key_Pluss
319                Qt::Key_Plus on  Shift + Qt::Key_Pluss
320     */
321     QTest::newRow("N002 - slot1")		    << SetupAccel << TriggerSlot1 << QString("")    << int(Qt::SHIFT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
322     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;
323     QTest::newRow("N002:M - [Shift+M]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
324     QTest::newRow("N002 - slot2")		    << SetupAccel << TriggerSlot2 << QString("")    << int(Qt::SHIFT + Qt::Key_Plus) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
325     QTest::newRow("N002:Shift++ [Shift++]")    << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
326     QTest::newRow("N002:+ [Shift++]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
327     QTest::newRow("N002 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
328 
329     /* Testing Single Sequences
330        Shift + Qt::Key_F1   on  Qt::Key_F1
331                Qt::Key_F1   on  Qt::Key_F1
332     */
333     QTest::newRow("N003 - slot1")		    << SetupAccel << TriggerSlot1 << QString("")    << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
334     //commented out because the behaviour changed, those tests should be updated
335     //QTest::newRow("N003:Shift+F1 - [F1]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
336     QTest::newRow("N003:F1 - [F1]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
337     QTest::newRow("N003 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
338     /* Testing Single Sequences
339        Shift + Qt::Key_F1   on  Shift + Qt::Key_F1
340                Qt::Key_F1   on  Shift + Qt::Key_F1
341     */
342 
343     QTest::newRow("N004 - slot1")		    << SetupAccel << TriggerSlot1 << QString("")    << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
344     QTest::newRow("N004:Shift+F1 - [Shift+F1]")<< TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
345     QTest::newRow("N004:F1 - [Shift+F1]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
346     QTest::newRow("N004 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
347 
348     /* Testing Single Sequences
349                Qt::Key_Tab      on  Qt::Key_Tab
350        Shift + Qt::Key_Tab      on  Qt::Key_Tab
351                Qt::Key_Backtab  on  Qt::Key_Tab
352        Shift + Qt::Key_Backtab  on  Qt::Key_Tab
353     */
354     QTest::newRow("N005a - slot1")		           << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
355     QTest::newRow("N005a:Tab - [Tab]")	           << TestAccel << NoWidget << QString("")     << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
356     //commented out because the behaviour changed, those tests should be updated
357     //QTest::newRow("N005a:Shift+Tab - [Tab]")          << TestAccel << NoWidget << QString("")     << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
358     // (Shift+)BackTab != Tab, but Shift+BackTab == Shift+Tab
359     QTest::newRow("N005a:Backtab - [Tab]")	           << TestAccel << NoWidget << QString("")     << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
360     QTest::newRow("N005a:Shift+Backtab - [Tab]")      << TestAccel << NoWidget << QString("")     << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
361     QTest::newRow("N005a - clear")		           << ClearAll << 0 << QString("")	       << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
362 
363     /* Testing Single Sequences
364                Qt::Key_Tab      on  Shift + Qt::Key_Tab
365        Shift + Qt::Key_Tab      on  Shift + Qt::Key_Tab
366                Qt::Key_Backtab  on  Shift + Qt::Key_Tab
367        Shift + Qt::Key_Backtab  on  Shift + Qt::Key_Tab
368     */
369     QTest::newRow("N005b - slot1")		           << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
370     QTest::newRow("N005b:Tab - [Shift+Tab]")          << TestAccel << NoWidget << QString("")     << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
371     QTest::newRow("N005b:Shift+Tab - [Shift+Tab]")    << TestAccel << NoWidget << QString("")     << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
372     QTest::newRow("N005b:BackTab - [Shift+Tab]")      << TestAccel << NoWidget << QString("")     << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
373     QTest::newRow("N005b:Shift+BackTab - [Shift+Tab]")<< TestAccel << NoWidget << QString("")     << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
374     QTest::newRow("N005b - clear")		           << ClearAll << 0 << QString("")	       << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
375 
376     /* Testing Single Sequences
377                Qt::Key_Tab      on  Qt::Key_Backtab
378        Shift + Qt::Key_Tab      on  Qt::Key_Backtab
379                Qt::Key_Backtab  on  Qt::Key_Backtab
380        Shift + Qt::Key_Backtab  on  Qt::Key_Backtab
381     */
382     QTest::newRow("N006a - slot1")		           << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
383     QTest::newRow("N006a:Tab - [BackTab]")	           << TestAccel << NoWidget << QString("")     << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
384     // This should work, since platform dependent code will transform the
385     // Shift+Tab into a Shift+BackTab, which should trigger the shortcut
386     QTest::newRow("N006a:Shift+Tab - [BackTab]")      << TestAccel << NoWidget << QString("")     << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; //XFAIL
387     QTest::newRow("N006a:BackTab - [BackTab]")        << TestAccel << NoWidget << QString("")     << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
388     //commented out because the behaviour changed, those tests should be updated
389     //QTest::newRow("N006a:Shift+BackTab - [BackTab]")  << TestAccel << NoWidget << QString("")     << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
390     QTest::newRow("N006a - clear")		           << ClearAll << 0 << QString("")	       << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
391 
392     /* Testing Single Sequences
393                Qt::Key_Tab      on  Shift + Qt::Key_Backtab
394        Shift + Qt::Key_Tab      on  Shift + Qt::Key_Backtab
395                Qt::Key_Backtab  on  Shift + Qt::Key_Backtab
396        Shift + Qt::Key_Backtab  on  Shift + Qt::Key_Backtab
397     */
398     QTest::newRow("N006b - slot1")		           << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
399     QTest::newRow("N006b:Tab - [Shift+BackTab]")      << TestAccel << NoWidget << QString("")     << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
400     QTest::newRow("N006b:Shift+Tab - [Shift+BackTab]")<< TestAccel << NoWidget << QString("")     << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
401     QTest::newRow("N006b:BackTab - [Shift+BackTab]")  << TestAccel << NoWidget << QString("")     << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
402     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
403     QTest::newRow("N006b - clear")		           << ClearAll << 0 << QString("")	       << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
404 
405     //===========================================
406     // [Shift + key] and [key] on shortcuts with
407     // and without modifiers
408     //===========================================
409 
410     /* Testing Single Sequences
411        Qt::Key_F1
412        Shift + Qt::Key_F1
413     */
414     QTest::newRow("N007 - slot1")		    << SetupAccel << TriggerSlot1 << QString("")    << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
415     QTest::newRow("N007 - slot2")		    << SetupAccel << TriggerSlot2 << QString("")    << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
416     QTest::newRow("N007:F1")		    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
417     QTest::newRow("N007:Shift + F1")	    << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
418     QTest::newRow("N007 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
419 
420     /* Testing Single Sequences
421        Qt::Key_M
422        Shift + Qt::Key_M
423        Ctrl  + Qt::Key_M
424        Alt   + Qt::Key_M
425     */
426     QTest::newRow("N01 - slot1")		    << SetupAccel << TriggerSlot1 << QString("")    << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
427     QTest::newRow("N02 - slot2")		    << SetupAccel << TriggerSlot2 << QString("")    << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
428     QTest::newRow("N03 - slot1")		    << SetupAccel << TriggerSlot1 << QString("")    << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
429     QTest::newRow("N04 - slot2")		    << SetupAccel << TriggerSlot2 << QString("")    << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
430     QTest::newRow("N:Qt::Key_M")		    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
431     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;
432     QTest::newRow("N:Ctrl+Qt::Key_M")		    << TestAccel << NoWidget << QString("")	    << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
433     QTest::newRow("N:Alt+Qt::Key_M")		    << TestAccel << NoWidget << QString("")	    << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
434 
435     /* Testing Single Sequence Ambiguity
436        Qt::Key_M on shortcut2
437     */
438     QTest::newRow("N05 - slot2")		    << SetupAccel << TriggerSlot2 << QString("")    << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
439     QTest::newRow("N:Qt::Key_M on slot")	    << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Ambiguous;
440     QTest::newRow("N05 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
441 
442     /* Testing Single Specialkeys
443        Qt::Key_aring
444        Qt::Key_Aring
445        Qt::UNICODE_ACCEL + Qt::Key_K
446     */
447     QTest::newRow("N06 - slot1")		    << SetupAccel << TriggerSlot1 << QString("")    << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
448     QTest::newRow("N07 - slot2")		    << SetupAccel << TriggerSlot2 << QString("")    << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
449     QTest::newRow("N08 - slot2")		    << SetupAccel << TriggerSlot1 << QString("")    << int(Qt::UNICODE_ACCEL + Qt::Key_K) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
450 
451     QTest::newRow("N:Qt::Key_aring")		    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
452     QTest::newRow("N:Qt::Key_Aring")		    << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
453     QTest::newRow("N:Qt::Key_aring - Text Form")   << TestAccel << NoWidget << QString("")	    << 0 << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
454     QTest::newRow("N:Qt::Key_Aring - Text Form")   << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT+0) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
455     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;
456     QTest::newRow("N09 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
457 
458     /* Testing Multiple Sequences
459        Qt::Key_M
460        Qt::Key_I, Qt::Key_M
461        Shift+Qt::Key_I, Qt::Key_M
462     */
463     QTest::newRow("N10 - slot1")		    << SetupAccel << TriggerSlot1 << QString("")    << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
464     QTest::newRow("N11 - slot2")		    << SetupAccel << TriggerSlot2 << QString("")    << int(Qt::Key_I) << 0 << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << NoResult;
465     QTest::newRow("N12 - slot1")		    << SetupAccel << TriggerSlot1 << QString("")    << int(Qt::SHIFT + Qt::Key_I) << 0 << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << NoResult;
466 
467     QTest::newRow("N:Qt::Key_M (2)")		    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
468     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;
469     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;
470     QTest::newRow("N13 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
471 }
472 
473 // ------------------------------------------------------------------
474 // Text Elements ----------------------------------------------------
475 // ------------------------------------------------------------------
text_data()476 void tst_QShortcut::text_data()
477 {
478     defElements();
479     // Clear all
480     QTest::newRow("T00 - clear") << ClearAll <<0<<QString("")<<0<<0<<0<<0<<0<<0<<0<<0<<0;
481 
482     //===========================================
483     // [Shift + key] on non-shift shortcuts testing
484     //===========================================
485 
486     /* Testing Single Sequences
487        Shift + Qt::Key_M    on  Qt::Key_M
488                Qt::Key_M    on  Qt::Key_M
489        Shift + Qt::Key_Plus on  Qt::Key_Pluss
490                Qt::Key_Plus on  Qt::Key_Pluss
491     */
492     QTest::newRow("T001 - slot1")		    << SetupAccel << TriggerSlot1 << QString("M")   << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
493     //commented out because the behaviour changed, those tests should be updated
494     //QTest::newRow("T001:Shift+M - [M]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
495     QTest::newRow("T001:M - [M]")		    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
496     QTest::newRow("T001 - slot2")		    << SetupAccel << TriggerSlot2 << QString("+")   << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
497     //commented out because the behaviour changed, those tests should be updated
498     //QTest::newRow("T001:Shift++ [+]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
499     QTest::newRow("T001:+ [+]")		    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
500     QTest::newRow("T001 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
501 
502     /* Testing Single Sequences
503        Shift + Qt::Key_M    on  Shift + Qt::Key_M
504                Qt::Key_M    on  Shift + Qt::Key_M
505        Shift + Qt::Key_Plus on  Shift + Qt::Key_Pluss
506                Qt::Key_Plus on  Shift + Qt::Key_Pluss
507        Shift + Ctrl + Qt::Key_Plus on  Ctrl + Qt::Key_Pluss
508                Ctrl + Qt::Key_Plus on  Ctrl + Qt::Key_Pluss
509     */
510     QTest::newRow("T002 - slot1")		    << SetupAccel << TriggerSlot1 << QString("Shift+M")   << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
511     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;
512     QTest::newRow("T002:M - [Shift+M]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
513     QTest::newRow("T002 - slot2")		    << SetupAccel << TriggerSlot2 << QString("Shift++")   << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
514     QTest::newRow("T002:Shift++ [Shift++]")    << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
515     QTest::newRow("T002:+ [Shift++]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
516     QTest::newRow("T002 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
517 
518     /* Testing Single Sequences
519        Shift + Ctrl + Qt::Key_Plus on  Ctrl + Qt::Key_Plus
520                Ctrl + Qt::Key_Plus on  Ctrl + Qt::Key_Plus
521 	              Qt::Key_Plus on  Ctrl + Qt::Key_Plus
522     */
523     QTest::newRow("T002b - slot1")		    << SetupAccel << TriggerSlot1 << QString("Ctrl++")    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
524     //commented out because the behaviour changed, those tests should be updated
525     //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;
526     QTest::newRow("T002b:Ctrl++ [Ctrl++]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::CTRL + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
527     QTest::newRow("T002b:+ [Ctrl++]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
528     QTest::newRow("T002b - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
529 
530     /* Testing Single Sequences
531        Shift + Qt::Key_F1   on  Qt::Key_F1
532                Qt::Key_F1   on  Qt::Key_F1
533     */
534     QTest::newRow("T003 - slot1")		    << SetupAccel << TriggerSlot1 << QString("F1")  << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
535     //commented out because the behaviour changed, those tests should be updated
536     //QTest::newRow("T003:Shift+F1 - [F1]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
537     QTest::newRow("T003:F1 - [F1]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
538     QTest::newRow("T003 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
539 
540     /* Testing Single Sequences
541        Shift + Qt::Key_F1   on  Shift + Qt::Key_F1
542                Qt::Key_F1   on  Shift + Qt::Key_F1
543     */
544     QTest::newRow("T004 - slot1")		    << SetupAccel << TriggerSlot1 << QString("Shift+F1")  << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
545     QTest::newRow("T004:Shift+F1 - [Shift+F1]")<< TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
546     QTest::newRow("T004:F1 - [Shift+F1]")	    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
547     QTest::newRow("T004 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
548 
549     //===========================================
550     // [Shift + key] and [key] on shortcuts with
551     // and without modifiers
552     //===========================================
553 
554     /* Testing Single Sequences
555        Qt::Key_F1
556        Shift + Qt::Key_F1
557     */
558     QTest::newRow("T007 - slot1")		    << SetupAccel << TriggerSlot1 << QString("F1")  << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
559     QTest::newRow("T007 - slot2")		    << SetupAccel << TriggerSlot2 << QString("Shift+F1")  << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
560     QTest::newRow("T007:F1")		    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
561     QTest::newRow("T007:Shift + F1")	    << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
562     QTest::newRow("T007 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
563 
564     /* Testing Single Sequences
565        Qt::Key_M
566        Shift + Qt::Key_M
567        Ctrl  + Qt::Key_M
568        Alt   + Qt::Key_M
569     */
570     QTest::newRow("T01 - slot1")		    << SetupAccel << TriggerSlot1 << QString("M")	  << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
571     QTest::newRow("T02 - slot2")		    << SetupAccel << TriggerSlot2 << QString("Shift+M")   << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
572     QTest::newRow("T03 - slot1")		    << SetupAccel << TriggerSlot1 << QString("Ctrl+M")    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
573     QTest::newRow("T04 - slot2")		    << SetupAccel << TriggerSlot2 << QString("Alt+M")	  << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
574 
575     QTest::newRow("T:Qt::Key_M")		    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
576     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;
577     QTest::newRow("T:Ctrl + Qt::Key_M")	    << TestAccel << NoWidget << QString("")	    << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
578     QTest::newRow("T:Alt + Qt::Key_M")		    << TestAccel << NoWidget << QString("")	    << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
579 
580     /* Testing Single Sequence Ambiguity
581        Qt::Key_M on shortcut2
582     */
583     QTest::newRow("T05 - slot2")		    << SetupAccel << TriggerSlot2 << QString("M")   << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
584     QTest::newRow("T:Qt::Key_M on TriggerSlot2")	    << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Ambiguous;
585     QTest::newRow("T06 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
586 
587     /* Testing Single Specialkeys
588        Qt::Key_aring
589        Qt::Key_Aring
590        Qt::UNICODE_ACCEL + Qt::Key_K
591     */
592     /* see comments above on the #ifdef'ery */
593     QTest::newRow("T06 - slot1")		    << SetupAccel << TriggerSlot1 << QString("\x0C5")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
594     QTest::newRow("T07 - slot2")		    << SetupAccel << TriggerSlot2 << QString("Shift+\x0C5")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
595     QTest::newRow("T08 - slot2")		    << SetupAccel << TriggerSlot1 << QString("K")   << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
596     QTest::newRow("T:Qt::Key_aring")		    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
597     QTest::newRow("T:Qt::Key_Aring")		    << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
598     QTest::newRow("T:Qt::Key_aring - Text Form")   << TestAccel << NoWidget << QString("")	    << 0 << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
599     QTest::newRow("T:Qt::Key_Aring - Text Form")   << TestAccel << NoWidget << QString("")	    << int(Qt::SHIFT+0) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
600     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;
601     QTest::newRow("T09 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
602 
603     /* Testing Multiple Sequences
604        Qt::Key_M
605        Qt::Key_I, Qt::Key_M
606        Shift+Qt::Key_I, Qt::Key_M
607     */
608     QTest::newRow("T10 - slot1")		    << SetupAccel << TriggerSlot1 << QString("M")   << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
609     QTest::newRow("T11 - slot2")		    << SetupAccel << TriggerSlot2 << QString("I, M")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
610     QTest::newRow("T12 - slot1")		    << SetupAccel << TriggerSlot1 << QString("Shift+I, M")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
611     QTest::newRow("T:Qt::Key_M (2)")		    << TestAccel << NoWidget << QString("")	    << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
612     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;
613     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;
614     QTest::newRow("T13 - clear")		    << ClearAll << 0 << QString("")		    << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // Clear all
615 }
616 
617 // ------------------------------------------------------------------
618 // Disabled Elements ------------------------------------------------
619 // ------------------------------------------------------------------
disabledItems()620 void tst_QShortcut::disabledItems()
621 {
622     clearAllShortcuts();
623     mainW->activateWindow();
624     qApp->syncX();
625     QTest::qWait(100);
626 
627     /* Testing Disabled Shortcuts
628        Qt::Key_M          on slot1
629        Shift + Qt::Key_M  on slot1
630        Qt::Key_M          on slot2 (disabled)
631        Shift + Qt::Key_M  on slot2 (disabled)
632     */
633 
634     // Setup two identical shortcuts on different pushbuttons
635     QPushButton pb1(mainW);
636     QPushButton pb2(mainW);
637     pb1.setObjectName("pushbutton-1");
638     pb2.setObjectName("pushbutton-2");
639     pb1.show();	// Must be show for QShortcutMap::correctSubWindow to trigger
640     pb2.show();
641 
642     QShortcut *cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "M");
643     QShortcut *cut2 = setupShortcut(&pb1, "shortcut2-pb1", TriggerSlot1, "Shift+M");
644     QShortcut *cut3 = setupShortcut(&pb2, "shortcut3-pb2", TriggerSlot2, "M");
645     QShortcut *cut4 = setupShortcut(&pb2, "shortcut4-pb2", TriggerSlot2, "Shift+M");
646 
647     cut3->setEnabled(false);
648     cut4->setEnabled(false);
649 
650     currentResult = NoResult;
651     sendKeyEvents(Qt::Key_M, 'm');
652     QCOMPARE(currentResult, Slot1Triggered);
653 
654     currentResult = NoResult;
655     sendKeyEvents(Qt::SHIFT+Qt::Key_M, 'M');
656     QCOMPARE(currentResult, Slot1Triggered);
657 
658     cut2->setEnabled(false);
659     cut4->setEnabled(true);
660 
661     /* Testing Disabled Shortcuts
662        Qt::Key_M          on slot1
663        Shift + Qt::Key_M  on slot1 (disabled)
664        Qt::Key_M          on slot2 (disabled)
665        Shift + Qt::Key_M  on slot2
666     */
667     currentResult = NoResult;
668     sendKeyEvents( Qt::Key_M, 'm' );
669     QCOMPARE( currentResult, Slot1Triggered );
670 
671     currentResult = NoResult;
672     sendKeyEvents( Qt::SHIFT+Qt::Key_M, 'M' );
673     QCOMPARE( currentResult, Slot2Triggered );
674 
675 
676     /* Testing Disabled Accel
677        Qt::Key_F5          on slot1
678        Shift + Qt::Key_F5  on slot2 (disabled)
679     */
680     clearAllShortcuts();
681     cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "F5");
682     cut4 = setupShortcut(&pb2, "shortcut4-pb2", TriggerSlot2, "Shift+F5");
683 
684     cut1->setKey(QKeySequence("F5"));
685     cut4->setKey(QKeySequence("Shift+F5"));
686 
687     cut1->setEnabled(true);
688     cut4->setEnabled(false);
689 
690     currentResult = NoResult;
691     sendKeyEvents( Qt::Key_F5, 0 );
692     QCOMPARE( currentResult, Slot1Triggered );
693 
694     currentResult = NoResult;
695     sendKeyEvents( Qt::SHIFT+Qt::Key_F5, 0 );
696     QCOMPARE( currentResult, NoResult );
697 
698 #if 0
699     qFatal("Not testing statusbar text feedback yet, since not implemented");
700     /* Testing Disabled Accel, and the corresponding statusbar feedback
701        Ctrl + Qt::Key_K, Ctrl + Qt::Key_L on slot1
702        Ctrl + Qt::Key_K, Ctrl + Qt::Key_M on slot2 (disabled)
703     */
704     cut1->setKey(QKeySequence("Ctrl+K, Ctrl+L"));
705     cut4->setKey(QKeySequence("Ctrl+K, Ctrl+M"));
706 
707     cut1->setEnabled(true);
708     cut4->setEnabled(false);
709 
710     currentResult = NoResult;
711     sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 );
712     sendKeyEvents( Qt::CTRL+Qt::Key_Q, 0 );
713     QCOMPARE( currentResult, NoResult );
714     if (over_330)
715     	QCOMPARE( sbText, QString("Ctrl+K, Ctrl+Q not defined") );
716 
717     currentResult = NoResult;
718     sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 );
719     sendKeyEvents( Qt::CTRL+Qt::Key_M, 0 );
720     QCOMPARE( currentResult, NoResult );
721     if (over_330)
722     	QCOMPARE( sbText, QString::null );
723 
724     currentResult = NoResult;
725     sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 );
726     sendKeyEvents( Qt::CTRL+Qt::Key_L, 0 );
727     QCOMPARE( currentResult, Slot1Triggered );
728     if (over_330)
729     	QCOMPARE( sbText, QString::null );
730 #endif
731     clearAllShortcuts();
732     cut1 = 0;
733     cut4 = 0;
734 }
735 // ------------------------------------------------------------------
736 // Ambiguous Elements -----------------------------------------------
737 // ------------------------------------------------------------------
ambiguousRotation()738 void tst_QShortcut::ambiguousRotation()
739 {
740     clearAllShortcuts();
741     /* Testing Shortcut rotation scheme
742        Ctrl + Qt::Key_A   on slot1 (disabled)
743        Ctrl + Qt::Key_A   on slot2 (disabled)
744        Ctrl + Qt::Key_A   on slot3
745        Ctrl + Qt::Key_A   on slot4
746        Ctrl + Qt::Key_A   on slot5 (disabled)
747        Ctrl + Qt::Key_A   on slot6
748        Ctrl + Qt::Key_A   on slot7 (disabled)
749     */
750     QShortcut *cut1 = setupShortcut(TriggerSlot1, "Ctrl+A");
751     QShortcut *cut2 = setupShortcut(TriggerSlot2, "Ctrl+A");
752     QShortcut *cut3 = setupShortcut(TriggerSlot3, "Ctrl+A");
753     QShortcut *cut4 = setupShortcut(TriggerSlot4, "Ctrl+A");
754     QShortcut *cut5 = setupShortcut(TriggerSlot5, "Ctrl+A");
755     QShortcut *cut6 = setupShortcut(TriggerSlot6, "Ctrl+A");
756     QShortcut *cut7 = setupShortcut(TriggerSlot7, "Ctrl+A");
757 
758     cut1->setEnabled(false);
759     cut2->setEnabled(false);
760     cut5->setEnabled(false);
761     cut7->setEnabled(false);
762 
763     // Test proper rotation
764     //   Start on first
765     //   Go to last
766     //   Go back to first
767     //   Continue...
768     currentResult = NoResult;
769     ambigResult = NoResult;
770     sendKeyEvents(Qt::CTRL+Qt::Key_A);
771     QCOMPARE(currentResult, Ambiguous);
772     QCOMPARE(ambigResult, Slot3Triggered);
773 
774     currentResult = NoResult;
775     ambigResult = NoResult;
776     sendKeyEvents(Qt::CTRL+Qt::Key_A);
777     QCOMPARE(currentResult, Ambiguous);
778     QCOMPARE(ambigResult, Slot4Triggered);
779 
780     currentResult = NoResult;
781     ambigResult = NoResult;
782     sendKeyEvents(Qt::CTRL+Qt::Key_A);
783     QCOMPARE(currentResult, Ambiguous);
784     QCOMPARE(ambigResult, Slot6Triggered);
785 
786     currentResult = NoResult;
787     ambigResult = NoResult;
788     sendKeyEvents(Qt::CTRL+Qt::Key_A);
789     QCOMPARE(currentResult, Ambiguous);
790     QCOMPARE(ambigResult, Slot3Triggered);
791 
792     currentResult = NoResult;
793     ambigResult = NoResult;
794     sendKeyEvents(Qt::CTRL+Qt::Key_A);
795     QCOMPARE(currentResult, Ambiguous);
796     QCOMPARE(ambigResult, Slot4Triggered);
797 
798     currentResult = NoResult;
799     ambigResult = NoResult;
800     sendKeyEvents(Qt::CTRL+Qt::Key_A);
801     QCOMPARE(currentResult, Ambiguous);
802     QCOMPARE(ambigResult, Slot6Triggered);
803 
804     /* Testing Shortcut rotation scheme
805        Ctrl + Qt::Key_A   on slot1
806        Ctrl + Qt::Key_A   on slot2
807        Ctrl + Qt::Key_A   on slot3 (disabled)
808        Ctrl + Qt::Key_A   on slot4 (disabled)
809        Ctrl + Qt::Key_A   on slot5
810        Ctrl + Qt::Key_A   on slot6 (disabled)
811        Ctrl + Qt::Key_A   on slot7
812     */
813 
814     cut1->setEnabled(true);
815     cut2->setEnabled(true);
816     cut5->setEnabled(true);
817     cut7->setEnabled(true);
818 
819     cut3->setEnabled(false);
820     cut4->setEnabled(false);
821     cut6->setEnabled(false);
822 
823     currentResult = NoResult;
824     ambigResult = NoResult;
825     sendKeyEvents(Qt::CTRL+Qt::Key_A);
826     QCOMPARE(currentResult, Ambiguous);
827     QCOMPARE(ambigResult, Slot1Triggered);
828 
829     currentResult = NoResult;
830     ambigResult = NoResult;
831     sendKeyEvents(Qt::CTRL+Qt::Key_A);
832     QCOMPARE(currentResult, Ambiguous);
833     QCOMPARE(ambigResult, Slot2Triggered);
834 
835     currentResult = NoResult;
836     ambigResult = NoResult;
837     sendKeyEvents(Qt::CTRL+Qt::Key_A);
838     QCOMPARE(currentResult, Ambiguous);
839     QCOMPARE(ambigResult, Slot5Triggered);
840 
841     currentResult = NoResult;
842     ambigResult = NoResult;
843     sendKeyEvents(Qt::CTRL+Qt::Key_A);
844     QCOMPARE(currentResult, Ambiguous);
845     QCOMPARE(ambigResult, Slot7Triggered);
846 
847     currentResult = NoResult;
848     ambigResult = NoResult;
849     sendKeyEvents(Qt::CTRL+Qt::Key_A);
850     QCOMPARE(currentResult, Ambiguous);
851     QCOMPARE(ambigResult, Slot1Triggered);
852 
853     currentResult = NoResult;
854     ambigResult = NoResult;
855     sendKeyEvents(Qt::CTRL+Qt::Key_A);
856     QCOMPARE(currentResult, Ambiguous);
857     QCOMPARE(ambigResult, Slot2Triggered);
858 
859     currentResult = NoResult;
860     ambigResult = NoResult;
861     sendKeyEvents(Qt::CTRL+Qt::Key_A);
862     QCOMPARE(currentResult, Ambiguous);
863     QCOMPARE(ambigResult, Slot5Triggered);
864 
865     currentResult = NoResult;
866     ambigResult = NoResult;
867     sendKeyEvents(Qt::CTRL+Qt::Key_A);
868     QCOMPARE(currentResult, Ambiguous);
869     QCOMPARE(ambigResult, Slot7Triggered);
870 
871     clearAllShortcuts();
872     cut1 = 0; cut2 = 0;
873     cut3 = 0; cut4 = 0;
874     cut5 = 0; cut6 = 0;
875     cut7 = 0;
876 }
877 
ambiguousItems()878 void tst_QShortcut::ambiguousItems()
879 {
880     clearAllShortcuts();
881     /* Testing Ambiguous Shortcuts
882        Qt::Key_M  on Pushbutton 1
883        Qt::Key_M  on Pushbutton 2
884     */
885 
886     // Setup two identical shortcuts on different pushbuttons
887     QPushButton pb1(mainW);
888     QPushButton pb2(mainW);
889     pb1.setObjectName("pushbutton-1");
890     pb2.setObjectName("pushbutton-2");
891     pb1.show();	// Must be show for QShortcutMap::correctSubWindow to trigger
892     pb2.show();
893 
894     QShortcut *cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "M");
895     QShortcut *cut2 = setupShortcut(&pb1, "shortcut2-pb2", TriggerSlot2, "M");
896 
897     currentResult = NoResult;
898     sendKeyEvents( Qt::Key_M, 'm' );
899     QCOMPARE( currentResult, Ambiguous );
900     QCOMPARE( ambigResult, Slot1Triggered );
901 
902     currentResult = NoResult;
903     sendKeyEvents( Qt::Key_M, 'm' );
904     QCOMPARE( currentResult, Ambiguous );
905     QCOMPARE( ambigResult, Slot2Triggered );
906 
907     currentResult = NoResult;
908     sendKeyEvents( Qt::Key_M, 'm' );
909     QCOMPARE( currentResult, Ambiguous );
910     QCOMPARE( ambigResult, Slot1Triggered );
911 
912     clearAllShortcuts();
913     cut1 = 0; cut2 = 0;
914 }
915 
916 
917 // ------------------------------------------------------------------
918 // Unicode and non-unicode Elements ---------------------------------
919 // ------------------------------------------------------------------
unicodeCompare()920 void tst_QShortcut::unicodeCompare()
921 {
922     clearAllShortcuts();
923     /* Testing Unicode/non-Unicode Shortcuts
924        Qt::Key_M  on Pushbutton 1
925        Qt::Key_M  on Pushbutton 2
926     */
927     QPushButton pb1(mainW);
928     QPushButton pb2(mainW);
929     pb1.setObjectName("pushbutton-1");
930     pb2.setObjectName("pushbutton-2");
931     pb1.show();	// Must be show for QShortcutMap::correctSubWindow to trigger
932     pb2.show();
933 
934     QKeySequence ks1("Ctrl+M");     // Unicode
935     QKeySequence ks2(Qt::CTRL+Qt::Key_M);   // non-Unicode
936     QShortcut *cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, ks1);
937     QShortcut *cut2 = setupShortcut(&pb1, "shortcut2-pb2", TriggerSlot2, ks2);
938 
939     currentResult = NoResult;
940     sendKeyEvents( Qt::CTRL+Qt::Key_M, 0 );
941     QCOMPARE( currentResult, Ambiguous );
942     // They _are_ ambiguous, so the QKeySequence operator==
943     // should indicate the same
944     QVERIFY( ks1 == ks2 );
945     QVERIFY( !(ks1 != ks2) );
946 
947     clearAllShortcuts();
948     cut1 = 0; cut2 = 0;
949 }
950 
951 // ------------------------------------------------------------------
952 // Keypress consumption verification --------------------------------
953 // ------------------------------------------------------------------
keypressConsumption()954 void tst_QShortcut::keypressConsumption()
955 {
956     clearAllShortcuts();
957     edit->clear();
958     QCOMPARE(edit->toPlainText().size(), 0);
959 
960     QShortcut *cut1 = setupShortcut(edit, "shortcut1-line", TriggerSlot1, "Ctrl+I, A");
961     QShortcut *cut2 = setupShortcut(edit, "shortcut1-line", TriggerSlot2, "Ctrl+I, B");
962 
963     currentResult = NoResult;
964     ambigResult = NoResult;
965     sendKeyEvents(edit, Qt::CTRL + Qt::Key_I, 0);   // Send key to edit
966     QCOMPARE( currentResult, NoResult );
967     QCOMPARE( ambigResult, NoResult );
968     QCOMPARE(edit->toPlainText(), QString(""));
969 
970     // Make sure next keypress is eaten (failing multiple keysequence)
971     sendKeyEvents(edit, Qt::Key_C, 'c');         // Send key to edit
972     QCOMPARE( currentResult, NoResult );
973     QCOMPARE( ambigResult, NoResult );
974     QCOMPARE(edit->toPlainText(), QString(""));
975 
976     // Next keypress should be normal
977     sendKeyEvents(edit, Qt::Key_C, 'c');         // Send key to edit
978     QCOMPARE( currentResult, NoResult );
979     QCOMPARE( ambigResult, NoResult );
980     QCOMPARE(edit->toPlainText(), QString("c"));
981 
982     currentResult = NoResult;
983     ambigResult = NoResult;
984     edit->clear();
985     QCOMPARE(edit->toPlainText().size(), 0);
986 
987     cut1->setEnabled(false);
988     cut2->setEnabled(false);
989 
990     // Make sure keypresses is passed on, since all multiple keysequences
991     // with Ctrl+I are disabled
992     sendKeyEvents(edit, Qt::CTRL + Qt::Key_I, 0);   // Send key to edit
993     QCOMPARE( currentResult, NoResult );
994     QCOMPARE( ambigResult, NoResult );
995     QVERIFY(edit->toPlainText().endsWith("<Ctrl+I>"));
996 
997     sendKeyEvents(edit, Qt::Key_A, 'a');         // Send key to edit
998     QCOMPARE( currentResult, NoResult );
999     QCOMPARE( ambigResult, NoResult );
1000     QVERIFY(edit->toPlainText().endsWith("<Ctrl+I>a"));
1001 
1002     clearAllShortcuts();
1003 }
1004 
1005 // ------------------------------------------------------------------
1006 // Context Validation -----------------------------------------------
1007 // ------------------------------------------------------------------
context()1008 void tst_QShortcut::context()
1009 {
1010     clearAllShortcuts();
1011 
1012     QWidget myBox;
1013     TestEdit *other1 = new TestEdit(&myBox, "test_edit_other1");
1014     TestEdit *other2 = new TestEdit(&myBox, "test_edit_other2");
1015     QHBoxLayout *layout = new QHBoxLayout(&myBox);
1016     layout->addWidget(other1);
1017     layout->addWidget(other2);
1018     myBox.show();
1019 #ifdef Q_WS_X11
1020     qt_x11_wait_for_window_manager(&myBox);
1021 #endif
1022 
1023     setupShortcut(other1, "ActiveWindow", TriggerSlot1, QKeySequence("Alt+1"), Qt::WindowShortcut);
1024     setupShortcut(other2, "Focus",        TriggerSlot2, QKeySequence("Alt+2"), Qt::WidgetShortcut);
1025     setupShortcut(edit,   "Application",  TriggerSlot3, QKeySequence("Alt+3"), Qt::ApplicationShortcut);
1026 
1027     currentResult = NoResult;
1028     ambigResult = NoResult;
1029     edit->clear();
1030     other1->clear();
1031     other2->clear();
1032 
1033     // edit doesn't have focus, so ActiveWindow context should work
1034     // ..but Focus context shouldn't..
1035     // Changing focus to edit should make focus context work
1036     // Application context should always work
1037 
1038 
1039     // Focus on 'other1' edit, so Active Window context should trigger
1040     other1->activateWindow(); // <---
1041     QApplication::setActiveWindow(other1);
1042     QCOMPARE(qApp->activeWindow(), other1->window());
1043     QCOMPARE(qApp->focusWidget(), (QWidget *)other1);
1044 
1045     currentResult = NoResult;
1046     ambigResult = NoResult;
1047     edit->clear();
1048     other1->clear();
1049     other2->clear();
1050 
1051     QCOMPARE(qApp->focusWidget(), (QWidget *)other1);
1052     sendKeyEvents(other1, Qt::ALT+Qt::Key_1);
1053     QCOMPARE(currentResult, Slot1Triggered);
1054     QCOMPARE(ambigResult, NoResult);
1055     QCOMPARE(edit->toPlainText(), QString(""));
1056     QCOMPARE(other1->toPlainText(), QString(""));
1057     QCOMPARE(other2->toPlainText(), QString(""));
1058 
1059     // ..but not Focus context on 'other2'..
1060     currentResult = NoResult;
1061     ambigResult = NoResult;
1062     edit->clear();
1063     other1->clear();
1064     other2->clear();
1065 
1066     sendKeyEvents(other1, Qt::ALT+Qt::Key_2);
1067     QCOMPARE(currentResult, NoResult);
1068     QCOMPARE(ambigResult, NoResult);
1069     QCOMPARE(edit->toPlainText(), QString(""));
1070     QCOMPARE(other1->toPlainText(), QString("<Alt+2>"));
1071     QCOMPARE(other2->toPlainText(), QString(""));
1072 
1073     // ..however, application global context on 'edit' should..
1074     currentResult = NoResult;
1075     ambigResult = NoResult;
1076     edit->clear();
1077     other1->clear();
1078     other2->clear();
1079 
1080     sendKeyEvents(other1, Qt::ALT+Qt::Key_3);
1081     QCOMPARE(currentResult, Slot3Triggered);
1082     QCOMPARE(ambigResult, NoResult);
1083     QCOMPARE(edit->toPlainText(), QString(""));
1084     QCOMPARE(other1->toPlainText(), QString(""));
1085     QCOMPARE(other2->toPlainText(), QString(""));
1086 
1087     // Changing focus to 'other2' should make the Focus context there work
1088     other2->activateWindow();
1089     other2->setFocus(); // ###
1090     qApp->syncX();
1091 #ifdef Q_WS_X11
1092     qt_x11_wait_for_window_manager(other2);
1093 #endif
1094     QTest::qWait(100);
1095     QCOMPARE(qApp->activeWindow(), other2->window());
1096     QCOMPARE(qApp->focusWidget(), (QWidget *)other2);
1097 
1098     currentResult = NoResult;
1099     ambigResult = NoResult;
1100     edit->clear();
1101     other1->clear();
1102     other2->clear();
1103 
1104     sendKeyEvents(other2, Qt::ALT+Qt::Key_2);
1105     QCOMPARE(currentResult, Slot2Triggered);
1106     QCOMPARE(ambigResult, NoResult);
1107     QCOMPARE(edit->toPlainText(), QString(""));
1108     QCOMPARE(other1->toPlainText(), QString(""));
1109     QCOMPARE(other2->toPlainText(), QString(""));
1110 
1111     clearAllShortcuts();
1112     delete other1;
1113     delete other2;
1114     edit->activateWindow();
1115     qApp->syncX();
1116 #ifdef Q_WS_X11
1117     qt_x11_wait_for_window_manager(edit);
1118 #endif
1119     QTest::qWait(100);
1120 }
1121 
1122 // ------------------------------------------------------------------
1123 // Element Testing helper functions ---------------------------------
1124 // ------------------------------------------------------------------
clearAllShortcuts()1125 void tst_QShortcut::clearAllShortcuts()
1126 {
1127     QList<QShortcut *> shortcutsCpy = shortcuts;
1128     qDeleteAll(shortcutsCpy);
1129     shortcuts.clear();
1130 }
1131 
setupShortcut(int testWidget,const QKeySequence & ks)1132 QShortcut *tst_QShortcut::setupShortcut(int testWidget, const QKeySequence &ks)
1133 {
1134     return setupShortcut(mainW, QTest::currentDataTag() ? QTest::currentDataTag() : "", testWidget, ks);
1135 }
1136 
setupShortcut(int testWidget,const QString & txt,int k1,int k2,int k3,int k4)1137 QShortcut *tst_QShortcut::setupShortcut(int testWidget, const QString &txt, int k1, int k2, int k3, int k4)
1138 {
1139     return setupShortcut(mainW, QTest::currentDataTag() ? QTest::currentDataTag() : "", testWidget,
1140                          (txt.isEmpty() ? QKeySequence(k1, k2, k3, k4) : QKeySequence(txt)));
1141 }
1142 
setupShortcut(QWidget * parent,const char * name,int testWidget,const QString & txt,int k1,int k2,int k3,int k4)1143 QShortcut *tst_QShortcut::setupShortcut(QWidget *parent, const char *name, int testWidget, const QString &txt, int k1, int k2, int k3, int k4)
1144 {
1145     return setupShortcut(parent, name, testWidget,
1146                          (txt.isEmpty() ? QKeySequence(k1, k2, k3, k4) : QKeySequence(txt)));
1147 }
1148 
setupShortcut(QWidget * parent,const char * name,int testWidget,const QKeySequence & ks,Qt::ShortcutContext context)1149 QShortcut *tst_QShortcut::setupShortcut(QWidget *parent, const char *name, int testWidget,
1150                                         const QKeySequence &ks, Qt::ShortcutContext context)
1151 {
1152     // Set up shortcut for next test
1153     QShortcut *cut = new QShortcut(QKeySequence(), parent, 0, 0, context);
1154     cut->setObjectName(name);
1155     cut->setKey(ks);
1156 
1157     const char *normal = 0;
1158     const char *ambig  = 0;
1159     switch(testWidget)
1160     {
1161     case TriggerSlot1:
1162         normal = SLOT(slotTrig1());
1163         ambig  = SLOT(ambigSlot1());
1164         break;
1165     case TriggerSlot2:
1166         normal = SLOT(slotTrig2());
1167         ambig  = SLOT(ambigSlot2());
1168         break;
1169     case TriggerSlot3:
1170         normal = SLOT(slotTrig3());
1171         ambig  = SLOT(ambigSlot3());
1172         break;
1173     case TriggerSlot4:
1174         normal = SLOT(slotTrig4());
1175         ambig  = SLOT(ambigSlot4());
1176         break;
1177     case TriggerSlot5:
1178         normal = SLOT(slotTrig5());
1179         ambig  = SLOT(ambigSlot5());
1180         break;
1181     case TriggerSlot6:
1182         normal = SLOT(slotTrig6());
1183         ambig  = SLOT(ambigSlot6());
1184         break;
1185     case TriggerSlot7:
1186         normal = SLOT(slotTrig7());
1187         ambig  = SLOT(ambigSlot7());
1188         break;
1189     }
1190     connect(cut, SIGNAL(activated()), this, normal);
1191     connect(cut, SIGNAL(activatedAmbiguously()), this, ambig);
1192     connect(cut, SIGNAL(destroyed(QObject*)), this, SLOT(shortcutDestroyed(QObject*)));
1193     shortcuts.append(cut);
1194     return cut;
1195 }
1196 
shortcutDestroyed(QObject * obj)1197 void tst_QShortcut::shortcutDestroyed(QObject* obj)
1198 {
1199     shortcuts.removeAll(static_cast<QShortcut *>(obj));
1200 }
1201 
sendKeyEvents(int k1,QChar c1,int k2,QChar c2,int k3,QChar c3,int k4,QChar c4)1202 void tst_QShortcut::sendKeyEvents(int k1, QChar c1, int k2, QChar c2, int k3, QChar c3, int k4, QChar c4)
1203 {
1204     sendKeyEvents(mainW, k1, c1, k2, c2, k3, c3, k4, c4);
1205 }
1206 
sendKeyEvents(QWidget * w,int k1,QChar c1,int k2,QChar c2,int k3,QChar c3,int k4,QChar c4)1207 void tst_QShortcut::sendKeyEvents(QWidget *w, int k1, QChar c1, int k2, QChar c2, int k3, QChar c3, int k4, QChar c4)
1208 {
1209     Qt::KeyboardModifiers b1 = toButtons( k1 );
1210     Qt::KeyboardModifiers b2 = toButtons( k2 );
1211     Qt::KeyboardModifiers b3 = toButtons( k3 );
1212     Qt::KeyboardModifiers b4 = toButtons( k4 );
1213     k1 &= ~Qt::MODIFIER_MASK;
1214     k2 &= ~Qt::MODIFIER_MASK;
1215     k3 &= ~Qt::MODIFIER_MASK;
1216     k4 &= ~Qt::MODIFIER_MASK;
1217 
1218 
1219     if (k1 || c1.toAscii()) {
1220         QString c(c1.unicode() == QChar::Null ? QString() : QString(c1));
1221         QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k1), c, b1);
1222 	QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k1), c, b1);
1223     }
1224 
1225     if (k2 || c2.toAscii()) {
1226         QString c(c2.unicode() == QChar::Null ? QString() : QString(c2));
1227 	QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k2), c, b2);
1228 	QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k2), c, b2);
1229     }
1230 
1231     if (k3 || c3.toAscii()) {
1232         QString c(c3.unicode() == QChar::Null ? QString() : QString(c3));
1233 	QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k3), c, b3);
1234 	QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k3), c, b3);
1235     }
1236 
1237     if (k4 || c4.toAscii()) {
1238         QString c(c4.unicode() == QChar::Null ? QString() : QString(c4));
1239 	QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k4), c, b4);
1240 	QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k4), c, b4);
1241     }
1242 }
1243 
testElement()1244 void tst_QShortcut::testElement()
1245 {
1246     currentResult = NoResult;
1247     QFETCH(int, action);
1248     QFETCH(int, testWidget);
1249     QFETCH(QString, txt);
1250     QFETCH(int, k1);
1251     QFETCH(int, c1);
1252     QFETCH(int, k2);
1253     QFETCH(int, c2);
1254     QFETCH(int, k3);
1255     QFETCH(int, c3);
1256     QFETCH(int, k4);
1257     QFETCH(int, c4);
1258     QFETCH(int, result);
1259 
1260     if (action == ClearAll) {
1261 	clearAllShortcuts();
1262 	QCOMPARE(TRUE, TRUE);
1263     } else if (action == SetupAccel) {
1264 	setupShortcut(testWidget, txt, k1, k2, k3, k4);
1265 	QCOMPARE(TRUE, TRUE);
1266     } else {
1267 	sendKeyEvents(k1, c1, k2, c2, k3, c3, k4, c4);
1268 	QCOMPARE(int(currentResult), result);
1269     }
1270 }
1271 
1272 QTEST_MAIN(tst_QShortcut)
1273 #include "tst_qshortcut.moc"
1274