1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
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 https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | #include <QtTest/QtTest> |
29 | #include <QtWidgets/QPushButton> |
30 | #include <QtWidgets/QStyle> |
31 | #include <QtWidgets/QLayout> |
32 | #include <QtWidgets/QDialog> |
33 | #include <QtWidgets/QAction> |
34 | #include <qdialogbuttonbox.h> |
35 | #include <limits.h> |
36 | |
37 | Q_DECLARE_METATYPE(QDialogButtonBox::ButtonRole) |
38 | Q_DECLARE_METATYPE(QDialogButtonBox::StandardButton) |
39 | Q_DECLARE_METATYPE(QDialogButtonBox::StandardButtons) |
40 | |
41 | class tst_QDialogButtonBox : public QObject |
42 | { |
43 | Q_OBJECT |
44 | public: |
45 | tst_QDialogButtonBox(); |
46 | ~tst_QDialogButtonBox(); |
47 | |
48 | |
49 | public slots: |
50 | void buttonClicked1(QAbstractButton *); |
51 | void acceptClicked(); |
52 | void rejectClicked(); |
53 | void helpRequestedClicked(); |
54 | |
55 | private slots: |
56 | void standardButtons(); |
57 | void testConstructor1(); |
58 | void testConstructor2(); |
59 | void testConstructor2_data(); |
60 | void testConstructor3(); |
61 | void testConstructor3_data(); |
62 | void testConstructor4(); |
63 | void testConstructor4_data(); |
64 | void setOrientation_data(); |
65 | void setOrientation(); |
66 | void addButton1_data(); |
67 | void addButton1(); |
68 | void addButton2_data(); |
69 | void addButton2(); |
70 | void addButton3_data(); |
71 | void addButton3(); |
72 | void clear_data(); |
73 | void clear(); |
74 | void removeButton_data(); |
75 | void removeButton(); |
76 | void buttonRole_data(); |
77 | void buttonRole(); |
78 | void setStandardButtons_data(); |
79 | void setStandardButtons(); |
80 | void layoutReuse(); |
81 | |
82 | |
83 | // Skip these tests, buttons is used in every test thus far. |
84 | // void buttons_data(); |
85 | // void buttons(); |
86 | |
87 | void testDelete(); |
88 | void testSignalEmissionAfterDelete_QTBUG_45835(); |
89 | void testRemove(); |
90 | void testMultipleAdd(); |
91 | void testStandardButtonMapping_data(); |
92 | void testStandardButtonMapping(); |
93 | void testSignals_data(); |
94 | void testSignals(); |
95 | void testSignalOrder(); |
96 | void testDefaultButton_data(); |
97 | void testDefaultButton(); |
98 | |
99 | void task191642_default(); |
100 | void testDeletedStandardButton(); |
101 | |
102 | private: |
103 | qint64 timeStamp; |
104 | qint64 buttonClicked1TimeStamp; |
105 | qint64 acceptTimeStamp; |
106 | qint64 rejectTimeStamp; |
107 | qint64 helpRequestedTimeStamp; |
108 | }; |
109 | |
110 | tst_QDialogButtonBox::tst_QDialogButtonBox() |
111 | { |
112 | qRegisterMetaType<QAbstractButton *>(); |
113 | } |
114 | |
115 | tst_QDialogButtonBox::~tst_QDialogButtonBox() |
116 | { |
117 | } |
118 | |
119 | void tst_QDialogButtonBox::testConstructor1() |
120 | { |
121 | QDialogButtonBox buttonbox; |
122 | QCOMPARE(buttonbox.orientation(), Qt::Horizontal); |
123 | |
124 | QCOMPARE(buttonbox.buttons().count(), 0); |
125 | } |
126 | |
127 | void tst_QDialogButtonBox::layoutReuse() |
128 | { |
129 | QDialogButtonBox *box = new QDialogButtonBox(QDialogButtonBox::Ok); |
130 | QPointer<QLayout> layout = box->layout(); |
131 | box->setCenterButtons(!box->centerButtons()); |
132 | QCOMPARE(layout.data(), box->layout()); |
133 | QEvent event(QEvent::StyleChange); |
134 | QApplication::sendEvent(receiver: box, event: &event); |
135 | QCOMPARE(layout.data(), box->layout()); |
136 | box->setOrientation(box->orientation() == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal); |
137 | QVERIFY(layout.isNull()); |
138 | QVERIFY(layout != box->layout()); |
139 | delete box; |
140 | } |
141 | |
142 | void tst_QDialogButtonBox::testConstructor2_data() |
143 | { |
144 | QTest::addColumn<int>(name: "orientation" ); |
145 | |
146 | QTest::newRow(dataTag: "horizontal" ) << int(Qt::Horizontal); |
147 | QTest::newRow(dataTag: "vertical" ) << int(Qt::Vertical); |
148 | } |
149 | |
150 | void tst_QDialogButtonBox::testConstructor2() |
151 | { |
152 | QFETCH(int, orientation); |
153 | Qt::Orientation orient = Qt::Orientation(orientation); |
154 | QDialogButtonBox buttonBox(orient); |
155 | |
156 | QCOMPARE(buttonBox.orientation(), orient); |
157 | QCOMPARE(buttonBox.buttons().count(), 0); |
158 | } |
159 | |
160 | void tst_QDialogButtonBox::testConstructor3_data() |
161 | { |
162 | QTest::addColumn<int>(name: "orientation" ); |
163 | QTest::addColumn<QDialogButtonBox::StandardButtons>(name: "buttons" ); |
164 | QTest::addColumn<int>(name: "buttonCount" ); |
165 | |
166 | QTest::newRow(dataTag: "nothing" ) << int(Qt::Horizontal) << QDialogButtonBox::StandardButtons{} << 0; |
167 | QTest::newRow(dataTag: "only 1" ) << int(Qt::Horizontal) << QDialogButtonBox::StandardButtons(QDialogButtonBox::Ok) << 1; |
168 | QTest::newRow(dataTag: "only 1.. twice" ) << int(Qt::Horizontal) |
169 | << (QDialogButtonBox::Ok | QDialogButtonBox::Ok) |
170 | << 1; |
171 | QTest::newRow(dataTag: "only 2" ) << int(Qt::Horizontal) |
172 | << (QDialogButtonBox::Ok | QDialogButtonBox::Cancel) |
173 | << 2; |
174 | QTest::newRow(dataTag: "two different things" ) << int(Qt::Horizontal) |
175 | << (QDialogButtonBox::Save | QDialogButtonBox::Close) |
176 | << 2; |
177 | QTest::newRow(dataTag: "three" ) << int(Qt::Horizontal) |
178 | << (QDialogButtonBox::Ok |
179 | | QDialogButtonBox::Cancel |
180 | | QDialogButtonBox::Help) |
181 | << 3; |
182 | QTest::newRow(dataTag: "everything" ) << int(Qt::Vertical) |
183 | << (QDialogButtonBox::StandardButtons)UINT_MAX |
184 | << 18; |
185 | } |
186 | |
187 | void tst_QDialogButtonBox::testConstructor3() |
188 | { |
189 | QFETCH(int, orientation); |
190 | QFETCH(QDialogButtonBox::StandardButtons, buttons); |
191 | |
192 | QDialogButtonBox buttonBox(buttons, (Qt::Orientation)orientation); |
193 | QCOMPARE(int(buttonBox.orientation()), orientation); |
194 | QTEST(buttonBox.buttons().count(), "buttonCount" ); |
195 | } |
196 | |
197 | void tst_QDialogButtonBox::testConstructor4_data() |
198 | { |
199 | QTest::addColumn<QDialogButtonBox::StandardButtons>(name: "buttons" ); |
200 | QTest::addColumn<int>(name: "buttonCount" ); |
201 | |
202 | QTest::newRow(dataTag: "nothing" ) << QDialogButtonBox::StandardButtons{} << 0; |
203 | QTest::newRow(dataTag: "only 1" ) << QDialogButtonBox::StandardButtons(QDialogButtonBox::Ok) << 1; |
204 | QTest::newRow(dataTag: "only 1.. twice" ) |
205 | << (QDialogButtonBox::Ok | QDialogButtonBox::Ok) |
206 | << 1; |
207 | QTest::newRow(dataTag: "only 2" ) |
208 | << (QDialogButtonBox::Ok | QDialogButtonBox::Cancel) |
209 | << 2; |
210 | QTest::newRow(dataTag: "two different things" ) |
211 | << (QDialogButtonBox::Save | QDialogButtonBox::Close) |
212 | << 2; |
213 | QTest::newRow(dataTag: "three" ) |
214 | << (QDialogButtonBox::Ok |
215 | | QDialogButtonBox::Cancel |
216 | | QDialogButtonBox::Help) |
217 | << 3; |
218 | QTest::newRow(dataTag: "everything" ) |
219 | << (QDialogButtonBox::StandardButtons)UINT_MAX |
220 | << 18; |
221 | } |
222 | |
223 | void tst_QDialogButtonBox::testConstructor4() |
224 | { |
225 | QFETCH(QDialogButtonBox::StandardButtons, buttons); |
226 | |
227 | QDialogButtonBox buttonBox(buttons); |
228 | QCOMPARE(buttonBox.orientation(), Qt::Horizontal); |
229 | QTEST(buttonBox.buttons().count(), "buttonCount" ); |
230 | } |
231 | |
232 | void tst_QDialogButtonBox::setOrientation_data() |
233 | { |
234 | QTest::addColumn<int>(name: "orientation" ); |
235 | |
236 | QTest::newRow(dataTag: "Horizontal" ) << int(Qt::Horizontal); |
237 | QTest::newRow(dataTag: "Vertical" ) << int(Qt::Vertical); |
238 | } |
239 | |
240 | void tst_QDialogButtonBox::setOrientation() |
241 | { |
242 | QFETCH(int, orientation); |
243 | QDialogButtonBox buttonBox; |
244 | QCOMPARE(int(buttonBox.orientation()), int(Qt::Horizontal)); |
245 | |
246 | buttonBox.setOrientation(Qt::Orientation(orientation)); |
247 | QCOMPARE(int(buttonBox.orientation()), orientation); |
248 | } |
249 | |
250 | /* |
251 | void tst_QDialogButtonBox::setLayoutPolicy_data() |
252 | { |
253 | QTest::addColumn<int>("layoutPolicy"); |
254 | |
255 | QTest::newRow("win") << int(QDialogButtonBox::WinLayout); |
256 | QTest::newRow("mac") << int(QDialogButtonBox::MacLayout); |
257 | QTest::newRow("kde") << int(QDialogButtonBox::KdeLayout); |
258 | QTest::newRow("gnome") << int(QDialogButtonBox::GnomeLayout); |
259 | |
260 | } |
261 | |
262 | void tst_QDialogButtonBox::setLayoutPolicy() |
263 | { |
264 | QFETCH(int, layoutPolicy); |
265 | |
266 | QDialogButtonBox buttonBox; |
267 | QCOMPARE(int(buttonBox.layoutPolicy()), |
268 | int(buttonBox.style()->styleHint(QStyle::SH_DialogButtonLayout))); |
269 | buttonBox.setLayoutPolicy(QDialogButtonBox::ButtonLayout(layoutPolicy)); |
270 | QCOMPARE(int(buttonBox.layoutPolicy()), layoutPolicy); |
271 | } |
272 | */ |
273 | |
274 | void tst_QDialogButtonBox::addButton1_data() |
275 | { |
276 | QTest::addColumn<QDialogButtonBox::ButtonRole>(name: "role" ); |
277 | QTest::addColumn<int>(name: "totalCount" ); |
278 | |
279 | QTest::newRow(dataTag: "InvalidRole" ) << QDialogButtonBox::InvalidRole << 0; |
280 | QTest::newRow(dataTag: "AcceptRole" ) << QDialogButtonBox::AcceptRole << 1; |
281 | QTest::newRow(dataTag: "RejectRole" ) << QDialogButtonBox::RejectRole << 1; |
282 | QTest::newRow(dataTag: "DestructiveRole" ) << QDialogButtonBox::DestructiveRole << 1; |
283 | QTest::newRow(dataTag: "ActionRole" ) << QDialogButtonBox::ActionRole << 1; |
284 | QTest::newRow(dataTag: "HelpRole" ) << QDialogButtonBox::HelpRole << 1; |
285 | QTest::newRow(dataTag: "WackyValue" ) << (QDialogButtonBox::ButtonRole)-1 << 0; |
286 | } |
287 | |
288 | void tst_QDialogButtonBox::addButton1() |
289 | { |
290 | QFETCH(QDialogButtonBox::ButtonRole, role); |
291 | QDialogButtonBox buttonBox; |
292 | QCOMPARE(buttonBox.buttons().count(), 0); |
293 | QPushButton *button = new QPushButton(); |
294 | buttonBox.addButton(button, role); |
295 | QTEST(buttonBox.buttons().count(), "totalCount" ); |
296 | QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>(); |
297 | QTEST(children.count(), "totalCount" ); |
298 | delete button; |
299 | } |
300 | |
301 | void tst_QDialogButtonBox::addButton2_data() |
302 | { |
303 | QTest::addColumn<QString>(name: "text" ); |
304 | QTest::addColumn<QDialogButtonBox::ButtonRole>(name: "role" ); |
305 | QTest::addColumn<int>(name: "totalCount" ); |
306 | QTest::newRow(dataTag: "InvalidRole" ) << QString("foo" ) << QDialogButtonBox::InvalidRole << 0; |
307 | QTest::newRow(dataTag: "AcceptRole" ) << QString("foo" ) << QDialogButtonBox::AcceptRole << 1; |
308 | QTest::newRow(dataTag: "RejectRole" ) << QString("foo" ) << QDialogButtonBox::RejectRole << 1; |
309 | QTest::newRow(dataTag: "DestructiveRole" ) << QString("foo" ) << QDialogButtonBox::DestructiveRole << 1; |
310 | QTest::newRow(dataTag: "ActionRole" ) << QString("foo" ) << QDialogButtonBox::ActionRole << 1; |
311 | QTest::newRow(dataTag: "HelpRole" ) << QString("foo" ) << QDialogButtonBox::HelpRole << 1; |
312 | QTest::newRow(dataTag: "WackyValue" ) << QString("foo" ) << (QDialogButtonBox::ButtonRole)-1 << 0; |
313 | } |
314 | |
315 | void tst_QDialogButtonBox::addButton2() |
316 | { |
317 | QFETCH(QString, text); |
318 | QFETCH(QDialogButtonBox::ButtonRole, role); |
319 | QDialogButtonBox buttonBox; |
320 | QCOMPARE(buttonBox.buttons().count(), 0); |
321 | buttonBox.addButton(text, role); |
322 | QTEST(buttonBox.buttons().count(), "totalCount" ); |
323 | QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>(); |
324 | QTEST(children.count(), "totalCount" ); |
325 | } |
326 | |
327 | void tst_QDialogButtonBox::addButton3_data() |
328 | { |
329 | QTest::addColumn<QDialogButtonBox::StandardButton>(name: "button" ); |
330 | QTest::addColumn<int>(name: "totalCount" ); |
331 | QTest::newRow(dataTag: "Ok" ) << QDialogButtonBox::Ok << 1; |
332 | QTest::newRow(dataTag: "Open" ) << QDialogButtonBox::Open << 1; |
333 | QTest::newRow(dataTag: "Save" ) << QDialogButtonBox::Save << 1; |
334 | QTest::newRow(dataTag: "Cancel" ) << QDialogButtonBox::Cancel << 1; |
335 | QTest::newRow(dataTag: "Close" ) << QDialogButtonBox::Close << 1; |
336 | QTest::newRow(dataTag: "Discard" ) << QDialogButtonBox::Discard << 1; |
337 | QTest::newRow(dataTag: "Apply" ) << QDialogButtonBox::Apply << 1; |
338 | QTest::newRow(dataTag: "Reset" ) << QDialogButtonBox::Reset << 1; |
339 | QTest::newRow(dataTag: "Help" ) << QDialogButtonBox::Help << 1; |
340 | QTest::newRow(dataTag: "noButton" ) << (QDialogButtonBox::StandardButton)0 << 0; |
341 | } |
342 | |
343 | void tst_QDialogButtonBox::addButton3() |
344 | { |
345 | QFETCH(QDialogButtonBox::StandardButton, button); |
346 | QDialogButtonBox buttonBox; |
347 | QCOMPARE(buttonBox.buttons().count(), 0); |
348 | buttonBox.addButton(button); |
349 | QTEST(buttonBox.buttons().count(), "totalCount" ); |
350 | QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>(); |
351 | QTEST(children.count(), "totalCount" ); |
352 | } |
353 | |
354 | void tst_QDialogButtonBox::clear_data() |
355 | { |
356 | QTest::addColumn<int>(name: "rolesToAdd" ); |
357 | |
358 | QTest::newRow(dataTag: "nothing" ) << 0; |
359 | QTest::newRow(dataTag: "one" ) << 1; |
360 | QTest::newRow(dataTag: "all" ) << int(QDialogButtonBox::NRoles); |
361 | } |
362 | |
363 | void tst_QDialogButtonBox::clear() |
364 | { |
365 | QFETCH(int, rolesToAdd); |
366 | |
367 | QDialogButtonBox buttonBox; |
368 | for (int i = 1; i < rolesToAdd; ++i) |
369 | buttonBox.addButton(text: "Happy" , role: QDialogButtonBox::ButtonRole(i)); |
370 | buttonBox.clear(); |
371 | QCOMPARE(buttonBox.buttons().count(), 0); |
372 | QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>(); |
373 | QCOMPARE(children.count(), 0); |
374 | } |
375 | |
376 | void tst_QDialogButtonBox::removeButton_data() |
377 | { |
378 | QTest::addColumn<QDialogButtonBox::ButtonRole>(name: "roleToAdd" ); |
379 | QTest::addColumn<int>(name: "expectedCount" ); |
380 | QTest::newRow(dataTag: "no button added" ) << QDialogButtonBox::InvalidRole << 0; |
381 | QTest::newRow(dataTag: "a button" ) << QDialogButtonBox::AcceptRole << 1; |
382 | } |
383 | |
384 | void tst_QDialogButtonBox::removeButton() |
385 | { |
386 | QFETCH(QDialogButtonBox::ButtonRole, roleToAdd); |
387 | |
388 | QDialogButtonBox buttonBox; |
389 | QCOMPARE(buttonBox.buttons().count(), 0); |
390 | QPushButton *button = new QPushButton("RemoveButton test" ); |
391 | buttonBox.addButton(button, role: roleToAdd); |
392 | QTEST(buttonBox.buttons().count(), "expectedCount" ); |
393 | |
394 | buttonBox.removeButton(button); |
395 | QCOMPARE(buttonBox.buttons().count(), 0); |
396 | delete button; |
397 | } |
398 | |
399 | void tst_QDialogButtonBox::testDelete() |
400 | { |
401 | QDialogButtonBox buttonBox; |
402 | QCOMPARE(buttonBox.buttons().count(), 0); |
403 | |
404 | QPushButton *deleteMe = new QPushButton("Happy" ); |
405 | buttonBox.addButton(button: deleteMe, role: QDialogButtonBox::HelpRole); |
406 | QCOMPARE(buttonBox.buttons().count(), 1); |
407 | QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>(); |
408 | QCOMPARE(children.count(), 1); |
409 | |
410 | delete deleteMe; |
411 | children = buttonBox.findChildren<QAbstractButton *>(); |
412 | QCOMPARE(children.count(), 0); |
413 | QCOMPARE(buttonBox.buttons().count(), 0); |
414 | } |
415 | |
416 | class ObjectDeleter : public QObject |
417 | { |
418 | Q_OBJECT |
419 | public slots: |
420 | void deleteButton(QAbstractButton *button) |
421 | { |
422 | delete button; |
423 | } |
424 | |
425 | void deleteSender() |
426 | { |
427 | delete sender(); |
428 | } |
429 | }; |
430 | |
431 | void tst_QDialogButtonBox::testSignalEmissionAfterDelete_QTBUG_45835() |
432 | { |
433 | { |
434 | QDialogButtonBox buttonBox; |
435 | QCOMPARE(buttonBox.buttons().count(), 0); |
436 | |
437 | QSignalSpy buttonClickedSpy(&buttonBox, &QDialogButtonBox::clicked); |
438 | QVERIFY(buttonClickedSpy.isValid()); |
439 | |
440 | QSignalSpy buttonBoxAcceptedSpy(&buttonBox, &QDialogButtonBox::accepted); |
441 | QVERIFY(buttonBoxAcceptedSpy.isValid()); |
442 | |
443 | QPushButton *button = buttonBox.addButton(text: "Test" , role: QDialogButtonBox::AcceptRole); |
444 | QCOMPARE(buttonBox.buttons().count(), 1); |
445 | |
446 | ObjectDeleter objectDeleter; |
447 | connect(sender: &buttonBox, signal: &QDialogButtonBox::clicked, receiver: &objectDeleter, slot: &ObjectDeleter::deleteButton); |
448 | |
449 | button->click(); |
450 | |
451 | QCOMPARE(buttonBox.buttons().count(), 0); |
452 | QCOMPARE(buttonClickedSpy.count(), 1); |
453 | QCOMPARE(buttonBoxAcceptedSpy.count(), 1); |
454 | } |
455 | |
456 | { |
457 | QPointer<QDialogButtonBox> buttonBox(new QDialogButtonBox); |
458 | QCOMPARE(buttonBox->buttons().count(), 0); |
459 | |
460 | QSignalSpy buttonClickedSpy(buttonBox.data(), &QDialogButtonBox::clicked); |
461 | QVERIFY(buttonClickedSpy.isValid()); |
462 | |
463 | QSignalSpy buttonBoxAcceptedSpy(buttonBox.data(), &QDialogButtonBox::accepted); |
464 | QVERIFY(buttonBoxAcceptedSpy.isValid()); |
465 | |
466 | QPushButton *button = buttonBox->addButton(text: "Test" , role: QDialogButtonBox::AcceptRole); |
467 | QCOMPARE(buttonBox->buttons().count(), 1); |
468 | |
469 | ObjectDeleter objectDeleter; |
470 | connect(sender: buttonBox.data(), signal: &QDialogButtonBox::clicked, receiver: &objectDeleter, slot: &ObjectDeleter::deleteSender); |
471 | |
472 | button->click(); |
473 | |
474 | QVERIFY(buttonBox.isNull()); |
475 | QCOMPARE(buttonClickedSpy.count(), 1); |
476 | QCOMPARE(buttonBoxAcceptedSpy.count(), 0); |
477 | } |
478 | } |
479 | |
480 | void tst_QDialogButtonBox::testMultipleAdd() |
481 | { |
482 | // Add a button into the thing multiple times. |
483 | QDialogButtonBox buttonBox; |
484 | QCOMPARE(buttonBox.buttons().count(), 0); |
485 | |
486 | QPushButton *button = new QPushButton("Foo away" ); |
487 | buttonBox.addButton(button, role: QDialogButtonBox::AcceptRole); |
488 | QCOMPARE(buttonBox.buttons().count(), 1); |
489 | QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::AcceptRole); |
490 | buttonBox.addButton(button, role: QDialogButtonBox::AcceptRole); |
491 | QCOMPARE(buttonBox.buttons().count(), 1); |
492 | QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::AcceptRole); |
493 | |
494 | // Add it again with a different role |
495 | buttonBox.addButton(button, role: QDialogButtonBox::RejectRole); |
496 | QCOMPARE(buttonBox.buttons().count(), 1); |
497 | QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::RejectRole); |
498 | |
499 | // Add it as an "invalid" role |
500 | buttonBox.addButton(button, role: QDialogButtonBox::InvalidRole); |
501 | QCOMPARE(buttonBox.buttons().count(), 1); |
502 | QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::RejectRole); |
503 | } |
504 | |
505 | void tst_QDialogButtonBox::buttonRole_data() |
506 | { |
507 | QTest::addColumn<QDialogButtonBox::ButtonRole>(name: "roleToAdd" ); |
508 | QTest::addColumn<QDialogButtonBox::ButtonRole>(name: "expectedRole" ); |
509 | |
510 | QTest::newRow(dataTag: "AcceptRole stuff" ) << QDialogButtonBox::AcceptRole |
511 | << QDialogButtonBox::AcceptRole; |
512 | QTest::newRow(dataTag: "Nothing" ) << QDialogButtonBox::InvalidRole << QDialogButtonBox::InvalidRole; |
513 | QTest::newRow(dataTag: "bad stuff" ) << (QDialogButtonBox::ButtonRole)-1 << QDialogButtonBox::InvalidRole; |
514 | } |
515 | |
516 | void tst_QDialogButtonBox::buttonRole() |
517 | { |
518 | QFETCH(QDialogButtonBox::ButtonRole, roleToAdd); |
519 | QDialogButtonBox buttonBox; |
520 | QAbstractButton *button = buttonBox.addButton(text: "Here's a button" , role: roleToAdd); |
521 | QTEST(buttonBox.buttonRole(button), "expectedRole" ); |
522 | } |
523 | |
524 | void tst_QDialogButtonBox::testStandardButtonMapping_data() |
525 | { |
526 | QTest::addColumn<QDialogButtonBox::StandardButton>(name: "button" ); |
527 | QTest::addColumn<QDialogButtonBox::ButtonRole>(name: "expectedRole" ); |
528 | QTest::addColumn<QString>(name: "expectedText" ); |
529 | |
530 | int layoutPolicy = qApp->style()->styleHint(stylehint: QStyle::SH_DialogButtonLayout); |
531 | |
532 | QTest::newRow(dataTag: "QDialogButtonBox::Ok" ) << QDialogButtonBox::Ok |
533 | << QDialogButtonBox::AcceptRole |
534 | << QDialogButtonBox::tr(s: "OK" ); |
535 | QTest::newRow(dataTag: "QDialogButtonBox::Open" ) << QDialogButtonBox::Open |
536 | << QDialogButtonBox::AcceptRole |
537 | << QDialogButtonBox::tr(s: "Open" ); |
538 | QTest::newRow(dataTag: "QDialogButtonBox::Save" ) << QDialogButtonBox::Save |
539 | << QDialogButtonBox::AcceptRole |
540 | << QDialogButtonBox::tr(s: "Save" ); |
541 | QTest::newRow(dataTag: "QDialogButtonBox::Cancel" ) << QDialogButtonBox::Cancel |
542 | << QDialogButtonBox::RejectRole |
543 | << QDialogButtonBox::tr(s: "Cancel" ); |
544 | QTest::newRow(dataTag: "QDialogButtonBox::Close" ) << QDialogButtonBox::Close |
545 | << QDialogButtonBox::RejectRole |
546 | << QDialogButtonBox::tr(s: "Close" ); |
547 | if (layoutPolicy == QDialogButtonBox::MacLayout) { |
548 | QTest::newRow(dataTag: "QDialogButtonBox::Discard" ) << QDialogButtonBox::Discard |
549 | << QDialogButtonBox::DestructiveRole |
550 | << QDialogButtonBox::tr(s: "Don't Save" ); |
551 | } else if (layoutPolicy == QDialogButtonBox::GnomeLayout) { |
552 | QTest::newRow(dataTag: "QDialogButtonBox::Discard" ) |
553 | << QDialogButtonBox::Discard |
554 | << QDialogButtonBox::DestructiveRole |
555 | << QDialogButtonBox::tr(s: "Close without Saving" ); |
556 | } else { |
557 | QTest::newRow(dataTag: "QDialogButtonBox::Discard" ) << QDialogButtonBox::Discard |
558 | << QDialogButtonBox::DestructiveRole |
559 | << QDialogButtonBox::tr(s: "Discard" ); |
560 | } |
561 | QTest::newRow(dataTag: "QDialogButtonBox::Apply" ) << QDialogButtonBox::Apply |
562 | << QDialogButtonBox::ApplyRole |
563 | << QDialogButtonBox::tr(s: "Apply" ); |
564 | QTest::newRow(dataTag: "QDialogButtonBox::Reset" ) << QDialogButtonBox::Reset |
565 | << QDialogButtonBox::ResetRole |
566 | << QDialogButtonBox::tr(s: "Reset" ); |
567 | QTest::newRow(dataTag: "QDialogButtonBox::Help" ) << QDialogButtonBox::Help |
568 | << QDialogButtonBox::HelpRole |
569 | << QDialogButtonBox::tr(s: "Help" ); |
570 | } |
571 | |
572 | void tst_QDialogButtonBox::testStandardButtonMapping() |
573 | { |
574 | QFETCH(QDialogButtonBox::StandardButton, button); |
575 | QDialogButtonBox buttonBox; |
576 | |
577 | QAbstractButton *theButton = buttonBox.addButton(button); |
578 | QTEST(buttonBox.buttonRole(theButton), "expectedRole" ); |
579 | QString textWithoutMnemonic = theButton->text().remove(s: "&" ); |
580 | QTEST(textWithoutMnemonic, "expectedText" ); |
581 | } |
582 | |
583 | void tst_QDialogButtonBox::testSignals_data() |
584 | { |
585 | QTest::addColumn<QDialogButtonBox::ButtonRole>(name: "buttonToClick" ); |
586 | QTest::addColumn<int>(name: "clicked2Count" ); |
587 | QTest::addColumn<int>(name: "acceptCount" ); |
588 | QTest::addColumn<int>(name: "rejectCount" ); |
589 | QTest::addColumn<int>(name: "helpRequestedCount" ); |
590 | |
591 | QTest::newRow(dataTag: "nothing" ) << QDialogButtonBox::InvalidRole << 0 << 0 << 0 << 0; |
592 | QTest::newRow(dataTag: "accept" ) << QDialogButtonBox::AcceptRole << 1 << 1 << 0 << 0; |
593 | QTest::newRow(dataTag: "reject" ) << QDialogButtonBox::RejectRole << 1 << 0 << 1 << 0; |
594 | QTest::newRow(dataTag: "destructive" ) << QDialogButtonBox::DestructiveRole << 1 << 0 << 0 << 0; |
595 | QTest::newRow(dataTag: "Action" ) << QDialogButtonBox::ActionRole << 1 << 0 << 0 << 0; |
596 | QTest::newRow(dataTag: "Help" ) << QDialogButtonBox::HelpRole << 1 << 0 << 0 << 1; |
597 | } |
598 | |
599 | void tst_QDialogButtonBox::testSignals() |
600 | { |
601 | QFETCH(QDialogButtonBox::ButtonRole, buttonToClick); |
602 | QFETCH(int, clicked2Count); |
603 | QDialogButtonBox buttonBox; |
604 | qRegisterMetaType<QAbstractButton *>(typeName: "QAbstractButton*" ); |
605 | QSignalSpy clicked2(&buttonBox, &QDialogButtonBox::clicked); |
606 | QSignalSpy accept(&buttonBox, &QDialogButtonBox::accepted); |
607 | QSignalSpy reject(&buttonBox, &QDialogButtonBox::rejected); |
608 | QSignalSpy helpRequested(&buttonBox, &QDialogButtonBox::helpRequested); |
609 | |
610 | QAbstractButton *clickMe = nullptr; |
611 | for (int i = QDialogButtonBox::AcceptRole; i < QDialogButtonBox::NRoles; ++i) { |
612 | auto button = buttonBox.addButton(text: QString::number(i), |
613 | role: QDialogButtonBox::ButtonRole(i)); |
614 | |
615 | if (i == buttonToClick) |
616 | clickMe = button; |
617 | } |
618 | if (clickMe) |
619 | clickMe->click(); |
620 | |
621 | QTRY_COMPARE(clicked2.count(), clicked2Count); |
622 | if (clicked2.count() > 0) |
623 | QCOMPARE(qvariant_cast<QAbstractButton *>(clicked2.at(0).at(0)), clickMe); |
624 | |
625 | QTEST(accept.count(), "acceptCount" ); |
626 | QTEST(reject.count(), "rejectCount" ); |
627 | QTEST(helpRequested.count(), "helpRequestedCount" ); |
628 | } |
629 | |
630 | void tst_QDialogButtonBox::testSignalOrder() |
631 | { |
632 | buttonClicked1TimeStamp = acceptTimeStamp |
633 | = rejectTimeStamp = helpRequestedTimeStamp = timeStamp = 0LL; |
634 | QDialogButtonBox buttonBox; |
635 | connect(sender: &buttonBox, signal: &QDialogButtonBox::clicked, |
636 | receiver: this, slot: &tst_QDialogButtonBox::buttonClicked1); |
637 | connect(sender: &buttonBox, signal: &QDialogButtonBox::accepted, receiver: this, slot: &tst_QDialogButtonBox::acceptClicked); |
638 | connect(sender: &buttonBox, signal: &QDialogButtonBox::rejected, receiver: this, slot: &tst_QDialogButtonBox::rejectClicked); |
639 | connect(sender: &buttonBox, signal: &QDialogButtonBox::helpRequested, receiver: this, slot: &tst_QDialogButtonBox::helpRequestedClicked); |
640 | |
641 | QPushButton *acceptButton = buttonBox.addButton(text: "OK" , role: QDialogButtonBox::AcceptRole); |
642 | QPushButton *rejectButton = buttonBox.addButton(text: "Cancel" , role: QDialogButtonBox::RejectRole); |
643 | QPushButton *actionButton = buttonBox.addButton(text: "Action This" , role: QDialogButtonBox::ActionRole); |
644 | QPushButton *helpButton = buttonBox.addButton(text: "Help Me!" , role: QDialogButtonBox::HelpRole); |
645 | |
646 | // Try accept |
647 | acceptButton->click(); |
648 | QTRY_VERIFY(acceptTimeStamp > 0LL); |
649 | QCOMPARE(rejectTimeStamp, 0LL); |
650 | QCOMPARE(helpRequestedTimeStamp, 0LL); |
651 | |
652 | QVERIFY(buttonClicked1TimeStamp < acceptTimeStamp); |
653 | acceptTimeStamp = 0; |
654 | |
655 | rejectButton->click(); |
656 | QTRY_VERIFY(rejectTimeStamp > 0LL); |
657 | QCOMPARE(acceptTimeStamp, 0LL); |
658 | QCOMPARE(helpRequestedTimeStamp, 0LL); |
659 | QVERIFY(buttonClicked1TimeStamp < rejectTimeStamp); |
660 | |
661 | rejectTimeStamp = 0; |
662 | actionButton->click(); |
663 | QTest::qWait(ms: 100); |
664 | QCOMPARE(acceptTimeStamp, 0LL); |
665 | QCOMPARE(rejectTimeStamp, 0LL); |
666 | QCOMPARE(helpRequestedTimeStamp, 0LL); |
667 | |
668 | helpButton->click(); |
669 | QTRY_VERIFY(helpRequestedTimeStamp > 0LL); |
670 | QCOMPARE(acceptTimeStamp, 0LL); |
671 | QCOMPARE(rejectTimeStamp, 0LL); |
672 | QVERIFY(buttonClicked1TimeStamp < helpRequestedTimeStamp); |
673 | } |
674 | |
675 | void tst_QDialogButtonBox::buttonClicked1(QAbstractButton *) |
676 | { |
677 | buttonClicked1TimeStamp = ++timeStamp; |
678 | } |
679 | |
680 | void tst_QDialogButtonBox::acceptClicked() |
681 | { |
682 | acceptTimeStamp = ++timeStamp; |
683 | } |
684 | |
685 | void tst_QDialogButtonBox::rejectClicked() |
686 | { |
687 | rejectTimeStamp = ++timeStamp; |
688 | } |
689 | |
690 | void tst_QDialogButtonBox::helpRequestedClicked() |
691 | { |
692 | helpRequestedTimeStamp = ++timeStamp; |
693 | } |
694 | |
695 | void tst_QDialogButtonBox::setStandardButtons_data() |
696 | { |
697 | QTest::addColumn<QDialogButtonBox::StandardButtons>(name: "buttonsToAdd" ); |
698 | QTest::addColumn<QDialogButtonBox::StandardButtons>(name: "expectedResult" ); |
699 | |
700 | QTest::newRow(dataTag: "Nothing" ) << QDialogButtonBox::StandardButtons(QDialogButtonBox::NoButton) |
701 | << QDialogButtonBox::StandardButtons(QDialogButtonBox::NoButton); |
702 | QTest::newRow(dataTag: "Everything" ) << (QDialogButtonBox::StandardButtons)0xffffffff |
703 | << (QDialogButtonBox::Ok |
704 | | QDialogButtonBox::Open |
705 | | QDialogButtonBox::Save |
706 | | QDialogButtonBox::Cancel |
707 | | QDialogButtonBox::Close |
708 | | QDialogButtonBox::Discard |
709 | | QDialogButtonBox::Apply |
710 | | QDialogButtonBox::Reset |
711 | | QDialogButtonBox::Help |
712 | | QDialogButtonBox::Yes |
713 | | QDialogButtonBox::YesToAll |
714 | | QDialogButtonBox::No |
715 | | QDialogButtonBox::NoToAll |
716 | | QDialogButtonBox::SaveAll |
717 | | QDialogButtonBox::Abort |
718 | | QDialogButtonBox::Retry |
719 | | QDialogButtonBox::Ignore |
720 | | QDialogButtonBox::RestoreDefaults |
721 | ); |
722 | QTest::newRow(dataTag: "Simple thing" ) << QDialogButtonBox::StandardButtons(QDialogButtonBox::Help) |
723 | << QDialogButtonBox::StandardButtons(QDialogButtonBox::Help); |
724 | QTest::newRow(dataTag: "Standard thing" ) << (QDialogButtonBox::Ok | QDialogButtonBox::Cancel) |
725 | << (QDialogButtonBox::Ok | QDialogButtonBox::Cancel); |
726 | } |
727 | |
728 | void tst_QDialogButtonBox::setStandardButtons() |
729 | { |
730 | QFETCH(QDialogButtonBox::StandardButtons, buttonsToAdd); |
731 | QDialogButtonBox buttonBox; |
732 | buttonBox.setStandardButtons(buttonsToAdd); |
733 | QTEST(buttonBox.standardButtons(), "expectedResult" ); |
734 | } |
735 | |
736 | void tst_QDialogButtonBox::standardButtons() |
737 | { |
738 | // Test various cases of setting StandardButtons |
739 | QDialogButtonBox buttonBox; |
740 | |
741 | QCOMPARE(buttonBox.standardButtons(), |
742 | QDialogButtonBox::StandardButtons(QDialogButtonBox::NoButton)); |
743 | |
744 | // Set some buttons |
745 | buttonBox.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); |
746 | QCOMPARE(buttonBox.standardButtons(), QDialogButtonBox::Ok | QDialogButtonBox::Cancel); |
747 | |
748 | // Now add a button |
749 | buttonBox.addButton(button: QDialogButtonBox::Apply); |
750 | QCOMPARE(buttonBox.standardButtons(), |
751 | QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply); |
752 | |
753 | // Set the standard buttons to other things |
754 | buttonBox.setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Cancel |
755 | | QDialogButtonBox::Discard); |
756 | QCOMPARE(buttonBox.standardButtons(), QDialogButtonBox::Save | QDialogButtonBox::Cancel |
757 | | QDialogButtonBox::Discard); |
758 | QCOMPARE(buttonBox.buttons().size(), 3); |
759 | |
760 | // Add another button (not a standard one) |
761 | buttonBox.addButton(text: QLatin1String("Help" ), role: QDialogButtonBox::HelpRole); |
762 | QCOMPARE(buttonBox.standardButtons(), QDialogButtonBox::Save | QDialogButtonBox::Cancel |
763 | | QDialogButtonBox::Discard); |
764 | QCOMPARE(buttonBox.buttons().size(), 4); |
765 | |
766 | // Finally, check if we construct with standard buttons that they show up. |
767 | QDialogButtonBox buttonBox2(QDialogButtonBox::Open | QDialogButtonBox::Reset); |
768 | QCOMPARE(buttonBox2.standardButtons(), QDialogButtonBox::Open | QDialogButtonBox::Reset); |
769 | } |
770 | |
771 | void tst_QDialogButtonBox::testRemove() |
772 | { |
773 | // Make sure that removing a button and clicking it, doesn't trigger any latent signals |
774 | QDialogButtonBox buttonBox; |
775 | QSignalSpy clicked(&buttonBox, &QDialogButtonBox::clicked); |
776 | |
777 | QAbstractButton *button = buttonBox.addButton(button: QDialogButtonBox::Ok); |
778 | |
779 | buttonBox.removeButton(button); |
780 | |
781 | button->click(); |
782 | QTest::qWait(ms: 100); |
783 | QCOMPARE(clicked.count(), 0); |
784 | delete button; |
785 | } |
786 | |
787 | void tst_QDialogButtonBox::testDefaultButton_data() |
788 | { |
789 | QTest::addColumn<int>(name: "whenToSetDefault" ); // -1 Do nothing, 0 after accept, 1 before accept |
790 | QTest::addColumn<int>(name: "buttonToBeDefault" ); |
791 | QTest::addColumn<int>(name: "indexThatIsDefault" ); |
792 | |
793 | QTest::newRow(dataTag: "do nothing First Accept implicit" ) << -1 << -1 << 0; |
794 | QTest::newRow(dataTag: "First accept explicit before add" ) << 1 << 0 << 0; |
795 | QTest::newRow(dataTag: "First accept explicit after add" ) << 0 << 0 << 0; |
796 | QTest::newRow(dataTag: "second accept explicit before add" ) << 1 << 1 << 1; |
797 | QTest::newRow(dataTag: "second accept explicit after add" ) << 0 << 1 << 1; |
798 | QTest::newRow(dataTag: "third accept explicit befare add" ) << 1 << 2 << 2; |
799 | QTest::newRow(dataTag: "third accept explicit after add" ) << 0 << 2 << 2; |
800 | } |
801 | |
802 | void tst_QDialogButtonBox::testDefaultButton() |
803 | { |
804 | QFETCH(int, whenToSetDefault); |
805 | QFETCH(int, buttonToBeDefault); |
806 | QFETCH(int, indexThatIsDefault); |
807 | QDialogButtonBox buttonBox; |
808 | QPushButton *buttonArray[] = { new QPushButton("Foo" ), new QPushButton("Bar" ), new QPushButton("Baz" ) }; |
809 | |
810 | for (int i = 0; i < 3; ++i) { |
811 | if (whenToSetDefault == 1 && i == buttonToBeDefault) |
812 | buttonArray[i]->setDefault(true); |
813 | buttonBox.addButton(button: buttonArray[i], role: QDialogButtonBox::AcceptRole); |
814 | if (whenToSetDefault == 0 && i == buttonToBeDefault) |
815 | buttonArray[i]->setDefault(true); |
816 | } |
817 | buttonBox.show(); |
818 | |
819 | for (int i = 0; i < 3; ++i) { |
820 | if (i == indexThatIsDefault) |
821 | QVERIFY(buttonArray[i]->isDefault()); |
822 | else |
823 | QVERIFY(!buttonArray[i]->isDefault()); |
824 | } |
825 | } |
826 | |
827 | void tst_QDialogButtonBox::task191642_default() |
828 | { |
829 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
830 | QSKIP("Wayland: This fails. Figure out why." ); |
831 | |
832 | QDialog dlg; |
833 | QPushButton *def = new QPushButton(&dlg); |
834 | QSignalSpy clicked(def, &QPushButton::clicked); |
835 | def->setDefault(true); |
836 | QDialogButtonBox *bb = new QDialogButtonBox(&dlg); |
837 | bb->addButton(button: QDialogButtonBox::Ok); |
838 | bb->addButton(button: QDialogButtonBox::Cancel); |
839 | bb->addButton(button: QDialogButtonBox::Help); |
840 | |
841 | dlg.show(); |
842 | QVERIFY(QTest::qWaitForWindowActive(&dlg)); |
843 | QVERIFY(def->isDefault()); |
844 | QTest::keyPress( widget: &dlg, key: Qt::Key_Enter ); |
845 | QCOMPARE(clicked.count(), 1); |
846 | } |
847 | |
848 | void tst_QDialogButtonBox::testDeletedStandardButton() |
849 | { |
850 | QDialogButtonBox buttonBox; |
851 | delete buttonBox.addButton(button: QDialogButtonBox::Ok); |
852 | QPointer<QPushButton> buttonC = buttonBox.addButton(button: QDialogButtonBox::Cancel); |
853 | delete buttonBox.addButton(button: QDialogButtonBox::Cancel); |
854 | QPointer<QPushButton> buttonA = buttonBox.addButton(button: QDialogButtonBox::Apply); |
855 | delete buttonBox.addButton(button: QDialogButtonBox::Help); |
856 | // A few button have been deleted, they should automatically be removed |
857 | QCOMPARE(buttonBox.standardButtons(), QDialogButtonBox::Apply | QDialogButtonBox::Cancel); |
858 | |
859 | buttonBox.setStandardButtons(QDialogButtonBox::Reset | QDialogButtonBox::Cancel); |
860 | // setStanderdButton should delete previous buttons |
861 | QVERIFY(!buttonA); |
862 | QVERIFY(!buttonC); |
863 | } |
864 | |
865 | QTEST_MAIN(tst_QDialogButtonBox) |
866 | #include "tst_qdialogbuttonbox.moc" |
867 | |