|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the test suite of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 |
|
43 #include <QtTest/QtTest> |
|
44 |
|
45 #include <qapplication.h> |
|
46 #include <qevent.h> |
|
47 #include <qaction.h> |
|
48 #include <qmenu.h> |
|
49 |
|
50 //TESTED_CLASS= |
|
51 //TESTED_FILES= |
|
52 |
|
53 class tst_QAction : public QObject |
|
54 { |
|
55 Q_OBJECT |
|
56 |
|
57 public: |
|
58 tst_QAction(); |
|
59 virtual ~tst_QAction(); |
|
60 |
|
61 |
|
62 void updateState(QActionEvent *e); |
|
63 |
|
64 public slots: |
|
65 void initTestCase(); |
|
66 void cleanupTestCase(); |
|
67 private slots: |
|
68 void getSetCheck(); |
|
69 void setText_data(); |
|
70 void setText(); |
|
71 void setIconText_data() { setText_data(); } |
|
72 void setIconText(); |
|
73 void actionEvent(); |
|
74 void setStandardKeys(); |
|
75 void alternateShortcuts(); |
|
76 void enabledVisibleInteraction(); |
|
77 void task200823_tooltip(); |
|
78 void task229128TriggeredSignalWithoutActiongroup(); |
|
79 void task229128TriggeredSignalWhenInActiongroup(); |
|
80 |
|
81 private: |
|
82 int m_lastEventType; |
|
83 QAction *m_lastAction; |
|
84 QWidget *m_tstWidget; |
|
85 }; |
|
86 |
|
87 // Testing get/set functions |
|
88 void tst_QAction::getSetCheck() |
|
89 { |
|
90 QAction obj1(0); |
|
91 // QActionGroup * QAction::actionGroup() |
|
92 // void QAction::setActionGroup(QActionGroup *) |
|
93 QActionGroup *var1 = new QActionGroup(0); |
|
94 obj1.setActionGroup(var1); |
|
95 QCOMPARE(var1, obj1.actionGroup()); |
|
96 obj1.setActionGroup((QActionGroup *)0); |
|
97 QCOMPARE((QActionGroup *)0, obj1.actionGroup()); |
|
98 delete var1; |
|
99 |
|
100 // QMenu * QAction::menu() |
|
101 // void QAction::setMenu(QMenu *) |
|
102 QMenu *var2 = new QMenu(0); |
|
103 obj1.setMenu(var2); |
|
104 QCOMPARE(var2, obj1.menu()); |
|
105 obj1.setMenu((QMenu *)0); |
|
106 QCOMPARE((QMenu *)0, obj1.menu()); |
|
107 delete var2; |
|
108 |
|
109 QCOMPARE(obj1.priority(), QAction::NormalPriority); |
|
110 obj1.setPriority(QAction::LowPriority); |
|
111 QCOMPARE(obj1.priority(), QAction::LowPriority); |
|
112 } |
|
113 |
|
114 class MyWidget : public QWidget |
|
115 { |
|
116 Q_OBJECT |
|
117 public: |
|
118 MyWidget(tst_QAction *tst, QWidget *parent = 0) : QWidget(parent) { this->tst = tst; } |
|
119 |
|
120 protected: |
|
121 virtual void actionEvent(QActionEvent *e) { tst->updateState(e); } |
|
122 |
|
123 private: |
|
124 tst_QAction *tst; |
|
125 }; |
|
126 |
|
127 tst_QAction::tst_QAction() |
|
128 { |
|
129 } |
|
130 |
|
131 tst_QAction::~tst_QAction() |
|
132 { |
|
133 |
|
134 } |
|
135 |
|
136 void tst_QAction::initTestCase() |
|
137 { |
|
138 m_lastEventType = 0; |
|
139 m_lastAction = 0; |
|
140 |
|
141 MyWidget *mw = new MyWidget(this); |
|
142 m_tstWidget = mw; |
|
143 mw->show(); |
|
144 qApp->setActiveWindow(mw); |
|
145 } |
|
146 |
|
147 void tst_QAction::cleanupTestCase() |
|
148 { |
|
149 QWidget *testWidget = m_tstWidget; |
|
150 if (testWidget) { |
|
151 testWidget->hide(); |
|
152 delete testWidget; |
|
153 } |
|
154 } |
|
155 |
|
156 void tst_QAction::setText_data() |
|
157 { |
|
158 QTest::addColumn<QString>("text"); |
|
159 QTest::addColumn<QString>("iconText"); |
|
160 QTest::addColumn<QString>("textFromIconText"); |
|
161 |
|
162 //next we fill it with data |
|
163 QTest::newRow("Normal") << "Action" << "Action" << "Action"; |
|
164 QTest::newRow("Ampersand") << "Search && Destroy" << "Search & Destroy" << "Search && Destroy"; |
|
165 QTest::newRow("Mnemonic and ellipsis") << "O&pen File ..." << "Open File" << "Open File"; |
|
166 } |
|
167 |
|
168 void tst_QAction::setText() |
|
169 { |
|
170 QFETCH(QString, text); |
|
171 |
|
172 QAction action(0); |
|
173 action.setText(text); |
|
174 |
|
175 QCOMPARE(action.text(), text); |
|
176 |
|
177 QFETCH(QString, iconText); |
|
178 QCOMPARE(action.iconText(), iconText); |
|
179 } |
|
180 |
|
181 void tst_QAction::setIconText() |
|
182 { |
|
183 QFETCH(QString, iconText); |
|
184 |
|
185 QAction action(0); |
|
186 action.setIconText(iconText); |
|
187 QCOMPARE(action.iconText(), iconText); |
|
188 |
|
189 QFETCH(QString, textFromIconText); |
|
190 QCOMPARE(action.text(), textFromIconText); |
|
191 } |
|
192 |
|
193 |
|
194 void tst_QAction::updateState(QActionEvent *e) |
|
195 { |
|
196 if (!e) { |
|
197 m_lastEventType = 0; |
|
198 m_lastAction = 0; |
|
199 } else { |
|
200 m_lastEventType = (int)e->type(); |
|
201 m_lastAction = e->action(); |
|
202 } |
|
203 } |
|
204 |
|
205 void tst_QAction::actionEvent() |
|
206 { |
|
207 QAction a(0); |
|
208 a.setText("action text"); |
|
209 |
|
210 // add action |
|
211 m_tstWidget->addAction(&a); |
|
212 qApp->processEvents(); |
|
213 |
|
214 QCOMPARE(m_lastEventType, (int)QEvent::ActionAdded); |
|
215 QCOMPARE(m_lastAction, &a); |
|
216 |
|
217 // change action |
|
218 a.setText("new action text"); |
|
219 qApp->processEvents(); |
|
220 |
|
221 QCOMPARE(m_lastEventType, (int)QEvent::ActionChanged); |
|
222 QCOMPARE(m_lastAction, &a); |
|
223 |
|
224 // remove action |
|
225 m_tstWidget->removeAction(&a); |
|
226 qApp->processEvents(); |
|
227 |
|
228 QCOMPARE(m_lastEventType, (int)QEvent::ActionRemoved); |
|
229 QCOMPARE(m_lastAction, &a); |
|
230 } |
|
231 |
|
232 //basic testing of standard keys |
|
233 void tst_QAction::setStandardKeys() |
|
234 { |
|
235 QAction act(0); |
|
236 act.setShortcut(QKeySequence("CTRL+L")); |
|
237 QList<QKeySequence> list; |
|
238 act.setShortcuts(list); |
|
239 act.setShortcuts(QKeySequence::Copy); |
|
240 QVERIFY(act.shortcut() == act.shortcuts().first()); |
|
241 |
|
242 QList<QKeySequence> expected; |
|
243 #if defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN) |
|
244 expected << QKeySequence("CTRL+C"); |
|
245 #elif defined(Q_WS_WIN) || defined(Q_WS_QWS) |
|
246 expected << QKeySequence("CTRL+C") << QKeySequence("CTRL+INSERT"); |
|
247 #else |
|
248 expected << QKeySequence("CTRL+C") << QKeySequence("F16") << QKeySequence("CTRL+INSERT"); |
|
249 #endif |
|
250 QVERIFY(act.shortcuts() == expected); |
|
251 } |
|
252 |
|
253 |
|
254 void tst_QAction::alternateShortcuts() |
|
255 { |
|
256 //test the alternate shortcuts (by adding more than 1 shortcut) |
|
257 |
|
258 QWidget *wid = m_tstWidget; |
|
259 |
|
260 { |
|
261 QAction act(wid); |
|
262 wid->addAction(&act); |
|
263 QList<QKeySequence> shlist = QList<QKeySequence>() << QKeySequence("CTRL+P") << QKeySequence("CTRL+A"); |
|
264 act.setShortcuts(shlist); |
|
265 |
|
266 QSignalSpy spy(&act, SIGNAL(triggered())); |
|
267 |
|
268 act.setAutoRepeat(true); |
|
269 QTest::keyClick(wid, Qt::Key_A, Qt::ControlModifier); |
|
270 QCOMPARE(spy.count(), 1); //act should have been triggered |
|
271 |
|
272 act.setAutoRepeat(false); |
|
273 QTest::keyClick(wid, Qt::Key_A, Qt::ControlModifier); |
|
274 QCOMPARE(spy.count(), 2); //act should have been triggered a 2nd time |
|
275 |
|
276 //end of the scope of the action, it will be destroyed and removed from wid |
|
277 //This action should also unregister its shortcuts |
|
278 } |
|
279 |
|
280 |
|
281 //this tests a crash (if the action did not unregister its alternate shortcuts) |
|
282 QTest::keyClick(wid, Qt::Key_A, Qt::ControlModifier); |
|
283 } |
|
284 |
|
285 void tst_QAction::enabledVisibleInteraction() |
|
286 { |
|
287 QAction act(0); |
|
288 // check defaults |
|
289 QVERIFY(act.isEnabled()); |
|
290 QVERIFY(act.isVisible()); |
|
291 |
|
292 // !visible => !enabled |
|
293 act.setVisible(false); |
|
294 QVERIFY(!act.isEnabled()); |
|
295 act.setVisible(true); |
|
296 QVERIFY(act.isEnabled()); |
|
297 act.setEnabled(false); |
|
298 QVERIFY(act.isVisible()); |
|
299 |
|
300 // check if shortcut is disabled if not visible |
|
301 m_tstWidget->addAction(&act); |
|
302 act.setShortcut(QKeySequence("Ctrl+T")); |
|
303 QSignalSpy spy(&act, SIGNAL(triggered())); |
|
304 act.setEnabled(true); |
|
305 act.setVisible(false); |
|
306 QTest::keyClick(m_tstWidget, Qt::Key_T, Qt::ControlModifier); |
|
307 QCOMPARE(spy.count(), 0); //act is not visible, so don't trigger |
|
308 act.setVisible(false); |
|
309 act.setEnabled(true); |
|
310 QTest::keyClick(m_tstWidget, Qt::Key_T, Qt::ControlModifier); |
|
311 QCOMPARE(spy.count(), 0); //act is not visible, so don't trigger |
|
312 act.setVisible(true); |
|
313 act.setEnabled(true); |
|
314 QTest::keyClick(m_tstWidget, Qt::Key_T, Qt::ControlModifier); |
|
315 QCOMPARE(spy.count(), 1); //act is visible and enabled, so trigger |
|
316 } |
|
317 |
|
318 void tst_QAction::task200823_tooltip() |
|
319 { |
|
320 QAction *action = new QAction("foo", 0); |
|
321 QString shortcut("ctrl+o"); |
|
322 action->setShortcut(shortcut); |
|
323 |
|
324 // we want a non-standard tooltip that shows the shortcut |
|
325 action->setToolTip(QString("%1 (%2)").arg(action->text()).arg(action->shortcut().toString())); |
|
326 |
|
327 QString ref = QString("foo (%1)").arg(QKeySequence(shortcut).toString()); |
|
328 QCOMPARE(action->toolTip(), ref); |
|
329 } |
|
330 |
|
331 void tst_QAction::task229128TriggeredSignalWithoutActiongroup() |
|
332 { |
|
333 // test without a group |
|
334 QAction *actionWithoutGroup = new QAction("Test", qApp); |
|
335 QSignalSpy spyWithoutGroup(actionWithoutGroup, SIGNAL(triggered(bool))); |
|
336 QCOMPARE(spyWithoutGroup.count(), 0); |
|
337 actionWithoutGroup->trigger(); |
|
338 // signal should be emitted |
|
339 QCOMPARE(spyWithoutGroup.count(), 1); |
|
340 |
|
341 // it is now a checkable checked action |
|
342 actionWithoutGroup->setCheckable(true); |
|
343 actionWithoutGroup->setChecked(true); |
|
344 spyWithoutGroup.clear(); |
|
345 QCOMPARE(spyWithoutGroup.count(), 0); |
|
346 actionWithoutGroup->trigger(); |
|
347 // signal should be emitted |
|
348 QCOMPARE(spyWithoutGroup.count(), 1); |
|
349 } |
|
350 |
|
351 void tst_QAction::task229128TriggeredSignalWhenInActiongroup() |
|
352 { |
|
353 QActionGroup ag(0); |
|
354 QAction *action = new QAction("Test", &ag); |
|
355 QAction *checkedAction = new QAction("Test 2", &ag); |
|
356 ag.addAction(action); |
|
357 action->setCheckable(true); |
|
358 ag.addAction(checkedAction); |
|
359 checkedAction->setCheckable(true); |
|
360 checkedAction->setChecked(true); |
|
361 |
|
362 QSignalSpy actionSpy(checkedAction, SIGNAL(triggered(bool))); |
|
363 QSignalSpy actionGroupSpy(&ag, SIGNAL(triggered(QAction *))); |
|
364 QCOMPARE(actionGroupSpy.count(), 0); |
|
365 QCOMPARE(actionSpy.count(), 0); |
|
366 checkedAction->trigger(); |
|
367 // check that both the group and the action have emitted the signal |
|
368 QCOMPARE(actionGroupSpy.count(), 1); |
|
369 QCOMPARE(actionSpy.count(), 1); |
|
370 } |
|
371 |
|
372 QTEST_MAIN(tst_QAction) |
|
373 #include "tst_qaction.moc" |