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
37Q_DECLARE_METATYPE(QDialogButtonBox::ButtonRole)
38Q_DECLARE_METATYPE(QDialogButtonBox::StandardButton)
39Q_DECLARE_METATYPE(QDialogButtonBox::StandardButtons)
40
41class tst_QDialogButtonBox : public QObject
42{
43 Q_OBJECT
44public:
45 tst_QDialogButtonBox();
46 ~tst_QDialogButtonBox();
47
48
49public slots:
50 void buttonClicked1(QAbstractButton *);
51 void acceptClicked();
52 void rejectClicked();
53 void helpRequestedClicked();
54
55private 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
102private:
103 qint64 timeStamp;
104 qint64 buttonClicked1TimeStamp;
105 qint64 acceptTimeStamp;
106 qint64 rejectTimeStamp;
107 qint64 helpRequestedTimeStamp;
108};
109
110tst_QDialogButtonBox::tst_QDialogButtonBox()
111{
112 qRegisterMetaType<QAbstractButton *>();
113}
114
115tst_QDialogButtonBox::~tst_QDialogButtonBox()
116{
117}
118
119void tst_QDialogButtonBox::testConstructor1()
120{
121 QDialogButtonBox buttonbox;
122 QCOMPARE(buttonbox.orientation(), Qt::Horizontal);
123
124 QCOMPARE(buttonbox.buttons().count(), 0);
125}
126
127void 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
142void 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
150void 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
160void 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
187void 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
197void 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
223void 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
232void 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
240void 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/*
251void 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
262void 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
274void 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
288void 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
301void 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
315void 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
327void 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
343void 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
354void 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
363void 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
376void 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
384void 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
399void 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
416class ObjectDeleter : public QObject
417{
418 Q_OBJECT
419public slots:
420 void deleteButton(QAbstractButton *button)
421 {
422 delete button;
423 }
424
425 void deleteSender()
426 {
427 delete sender();
428 }
429};
430
431void 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
480void 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
505void 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
516void 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
524void 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
572void 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
583void 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
599void 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
630void 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
675void tst_QDialogButtonBox::buttonClicked1(QAbstractButton *)
676{
677 buttonClicked1TimeStamp = ++timeStamp;
678}
679
680void tst_QDialogButtonBox::acceptClicked()
681{
682 acceptTimeStamp = ++timeStamp;
683}
684
685void tst_QDialogButtonBox::rejectClicked()
686{
687 rejectTimeStamp = ++timeStamp;
688}
689
690void tst_QDialogButtonBox::helpRequestedClicked()
691{
692 helpRequestedTimeStamp = ++timeStamp;
693}
694
695void 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
728void tst_QDialogButtonBox::setStandardButtons()
729{
730 QFETCH(QDialogButtonBox::StandardButtons, buttonsToAdd);
731 QDialogButtonBox buttonBox;
732 buttonBox.setStandardButtons(buttonsToAdd);
733 QTEST(buttonBox.standardButtons(), "expectedResult");
734}
735
736void 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
771void 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
787void 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
802void 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
827void 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
848void 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
865QTEST_MAIN(tst_QDialogButtonBox)
866#include "tst_qdialogbuttonbox.moc"
867

source code of qtbase/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp