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
29
30#include <QFont>
31#include <QtTest/QtTest>
32#include <QCheckBox>
33#include <QLabel>
34#include <QLineEdit>
35#include <QList>
36#include <QPushButton>
37#include <QToolButton>
38#include <QVBoxLayout>
39#include <QWizard>
40#include <QTreeWidget>
41#include <QScreen>
42
43Q_DECLARE_METATYPE(QWizard::WizardButton);
44
45static QImage grabWidget(QWidget *window)
46{
47 return window->grab().toImage();
48}
49
50class tst_QWizard : public QObject
51{
52 Q_OBJECT
53
54private slots:
55 void cleanup();
56 void buttonText();
57 void setButtonLayout();
58 void setButton();
59 void setTitleFormatEtc();
60 void setPixmap();
61 void setDefaultProperty();
62 void addPage();
63 void setPage();
64 void setStartId();
65 void setOption_IndependentPages();
66 void setOption_IgnoreSubTitles();
67 void setOption_ExtendedWatermarkPixmap();
68 void setOption_NoDefaultButton();
69 void setOption_NoBackButtonOnStartPage();
70 void setOption_NoBackButtonOnLastPage();
71 void setOption_DisabledBackButtonOnLastPage();
72 void setOption_HaveNextButtonOnLastPage();
73 void setOption_HaveFinishButtonOnEarlyPages();
74 void setOption_NoCancelButton();
75 void setOption_NoCancelButtonOnLastPage();
76 void setOption_CancelButtonOnLeft();
77 void setOption_HaveHelpButton();
78 void setOption_HelpButtonOnRight();
79 void setOption_HaveCustomButtonX();
80 void combinations_data();
81 void combinations();
82 void showCurrentPageOnly();
83 void setButtonText();
84 void setCommitPage();
85 void setWizardStyle();
86 void removePage();
87 void sideWidget();
88 void objectNames_data();
89 void objectNames();
90
91 // task-specific tests below me:
92 void task177716_disableCommitButton();
93 void task183550_stretchFactor();
94 void task161658_alignments();
95 void task177022_setFixedSize();
96 void task248107_backButton();
97 void task255350_fieldObjectDestroyed();
98 void taskQTBUG_25691_fieldObjectDestroyed2();
99 void taskQTBUG_46894_nextButtonShortcut();
100
101 /*
102 Things that could be added:
103
104 1. Test virtual functions that are called, signals that are
105 emitted, etc.
106
107 2. Test QWizardPage more thorougly.
108
109 3. Test the look and field a bit more (especially the
110 different wizard styles, and how they interact with
111 pixmaps, titles, subtitles, etc.).
112
113 4. Test minimum sizes, sizes, maximum sizes, resizing, etc.
114
115 5. Try setting various options and wizard styles in various
116 orders and check that the results are the same every time,
117 no matter the order in which the properties were set.
118
119 -> Initial version done (tst_QWizard::combinations())
120
121 6. Test done() and restart().
122
123 7. Test default properties of built-in widgets.
124
125 8. Test mutual exclusiveness of Next and Commit buttons.
126 */
127};
128
129void tst_QWizard::cleanup()
130{
131 QVERIFY(QApplication::topLevelWidgets().isEmpty());
132}
133
134void tst_QWizard::buttonText()
135{
136 QWizard wizard;
137 wizard.setWizardStyle(QWizard::ClassicStyle);
138
139 // Check the buttons' original text in Classic and Modern styles.
140 for (int pass = 0; pass < 2; ++pass) {
141 QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("< &Back"));
142 QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
143 QVERIFY(wizard.buttonText(QWizard::FinishButton).endsWith("Finish"));
144 QVERIFY(wizard.buttonText(QWizard::CancelButton).endsWith("Cancel"));
145 QVERIFY(wizard.buttonText(QWizard::HelpButton).endsWith("Help"));
146
147 QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty());
148 QVERIFY(wizard.buttonText(QWizard::CustomButton2).isEmpty());
149 QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty());
150
151 // robustness
152 QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty());
153 QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty());
154 QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty());
155 QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty());
156
157 wizard.setWizardStyle(QWizard::ModernStyle);
158 }
159
160 // Check the buttons' original text in Mac style.
161 wizard.setWizardStyle(QWizard::MacStyle);
162
163 QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("Go Back"));
164 QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("Continue"));
165 QCOMPARE(wizard.buttonText(QWizard::FinishButton), QString("Done"));
166 QCOMPARE(wizard.buttonText(QWizard::CancelButton), QString("Cancel"));
167 QCOMPARE(wizard.buttonText(QWizard::HelpButton), QString("Help"));
168
169 QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty());
170 QVERIFY(wizard.buttonText(QWizard::CustomButton2).isEmpty());
171 QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty());
172
173 // robustness
174 QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty());
175 QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty());
176 QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty());
177 QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty());
178
179 // Modify the buttons' text and see what happens.
180 wizard.setButtonText(which: QWizard::NextButton, text: "N&este");
181 wizard.setButtonText(which: QWizard::CustomButton2, text: "&Cucu");
182 wizard.setButtonText(which: QWizard::Stretch, text: "Stretch");
183
184 QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("Go Back"));
185 QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("N&este"));
186 QCOMPARE(wizard.buttonText(QWizard::FinishButton), QString("Done"));
187 QCOMPARE(wizard.buttonText(QWizard::CancelButton), QString("Cancel"));
188 QCOMPARE(wizard.buttonText(QWizard::HelpButton), QString("Help"));
189
190 QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty());
191 QCOMPARE(wizard.buttonText(QWizard::CustomButton2), QString("&Cucu"));
192 QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty());
193
194 // robustness
195 QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty());
196 QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty());
197 QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty());
198 QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty());
199
200 // Switch back to Classic style and see what happens.
201 wizard.setWizardStyle(QWizard::ClassicStyle);
202
203 for (int pass = 0; pass < 2; ++pass) {
204 QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("< &Back"));
205 QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("N&este"));
206 QVERIFY(wizard.buttonText(QWizard::FinishButton).endsWith("Finish"));
207 QVERIFY(wizard.buttonText(QWizard::CancelButton).endsWith("Cancel"));
208 QVERIFY(wizard.buttonText(QWizard::HelpButton).endsWith("Help"));
209
210 QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty());
211 QCOMPARE(wizard.buttonText(QWizard::CustomButton2), QString("&Cucu"));
212 QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty());
213
214 // robustness
215 QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty());
216 QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty());
217 QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty());
218 QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty());
219
220 wizard.setOptions(QWizard::NoDefaultButton
221 | QWizard::NoBackButtonOnStartPage
222 | QWizard::NoBackButtonOnLastPage
223 | QWizard::DisabledBackButtonOnLastPage
224 | QWizard::NoCancelButton
225 | QWizard::CancelButtonOnLeft
226 | QWizard::HaveHelpButton
227 | QWizard::HelpButtonOnRight
228 | QWizard::HaveCustomButton1
229 | QWizard::HaveCustomButton2
230 | QWizard::HaveCustomButton3);
231 }
232}
233
234void tst_QWizard::setButtonLayout()
235{
236 QList<QWizard::WizardButton> layout;
237
238 QWizard wizard;
239 wizard.setWizardStyle(QWizard::ClassicStyle);
240 wizard.setOptions({});
241 wizard.setButtonLayout(layout);
242 wizard.show();
243 qApp->processEvents();
244
245 // if these crash, this means there's a bug in QWizard
246 QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
247 QVERIFY(wizard.button(QWizard::BackButton)->text().contains("Back"));
248 QVERIFY(wizard.button(QWizard::FinishButton)->text().contains("Finish"));
249 QVERIFY(wizard.button(QWizard::CancelButton)->text().contains("Cancel"));
250 QVERIFY(wizard.button(QWizard::HelpButton)->text().contains("Help"));
251 QVERIFY(wizard.button(QWizard::CustomButton1)->text().isEmpty());
252 QVERIFY(wizard.button(QWizard::CustomButton2)->text().isEmpty());
253 QVERIFY(wizard.button(QWizard::CustomButton3)->text().isEmpty());
254 QVERIFY(!wizard.button(QWizard::Stretch));
255 QVERIFY(!wizard.button(QWizard::NoButton));
256
257 QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
258 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
259 QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible());
260
261 layout << QWizard::NextButton << QWizard::HelpButton;
262 wizard.setButtonLayout(layout);
263 qApp->processEvents();
264
265 QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
266 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
267 QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
268
269 wizard.addPage(page: new QWizardPage);
270 wizard.addPage(page: new QWizardPage);
271 qApp->processEvents();
272
273 QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
274 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
275 QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
276
277 wizard.restart();
278 qApp->processEvents();
279
280 QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
281 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
282 QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
283
284 layout.clear();
285 layout << QWizard::NextButton << QWizard::HelpButton << QWizard::BackButton
286 << QWizard::FinishButton << QWizard::CancelButton << QWizard::Stretch
287 << QWizard::CustomButton2;
288
289 // Turn on all the button-related wizard options. Some of these
290 // should have no impact on a custom layout; others should.
291 wizard.setButtonLayout(layout);
292 wizard.setOptions(QWizard::NoDefaultButton
293 | QWizard::NoBackButtonOnStartPage
294 | QWizard::NoBackButtonOnLastPage
295 | QWizard::DisabledBackButtonOnLastPage
296 | QWizard::HaveNextButtonOnLastPage
297 | QWizard::HaveFinishButtonOnEarlyPages
298 | QWizard::NoCancelButton
299 | QWizard::CancelButtonOnLeft
300 | QWizard::HaveHelpButton
301 | QWizard::HelpButtonOnRight
302 | QWizard::HaveCustomButton1
303 | QWizard::HaveCustomButton2
304 | QWizard::HaveCustomButton3);
305 qApp->processEvents();
306
307 // we're on first page
308 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
309 QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
310 QVERIFY(wizard.button(QWizard::CancelButton)->isVisible()); // NoCancelButton overridden
311 QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
312 QVERIFY(!wizard.button(QWizard::CustomButton1)->isVisible());
313 QVERIFY(wizard.button(QWizard::CustomButton2)->isVisible()); // HaveCustomButton2 overridden
314 QVERIFY(!wizard.button(QWizard::CustomButton3)->isVisible());
315
316 wizard.next();
317 qApp->processEvents();
318
319 // we're on last page
320 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
321 QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
322 QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled());
323 QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
324 QVERIFY(wizard.button(QWizard::FinishButton)->isEnabled());
325 QVERIFY(wizard.button(QWizard::CancelButton)->isVisible()); // NoCancelButton overridden
326 QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
327 QVERIFY(!wizard.button(QWizard::CustomButton1)->isVisible());
328 QVERIFY(wizard.button(QWizard::CustomButton2)->isVisible()); // HaveCustomButton2 overridden
329 QVERIFY(!wizard.button(QWizard::CustomButton3)->isVisible());
330
331 // Check that the buttons are in the right order on screen.
332 for (int pass = 0; pass < 2; ++pass) {
333 wizard.setLayoutDirection(pass == 0 ? Qt::LeftToRight : Qt::RightToLeft);
334 qApp->processEvents();
335
336 int sign = (pass == 0) ? +1 : -1;
337
338 int p[5];
339 p[0] = sign * wizard.button(which: QWizard::NextButton)->x();
340 p[1] = sign * wizard.button(which: QWizard::HelpButton)->x();
341 p[2] = sign * wizard.button(which: QWizard::FinishButton)->x();
342 p[3] = sign * wizard.button(which: QWizard::CancelButton)->x();
343 p[4] = sign * wizard.button(which: QWizard::CustomButton2)->x();
344
345 QVERIFY(p[0] < p[1]);
346 QVERIFY(p[1] < p[2]);
347 QVERIFY(p[2] < p[3]);
348 QVERIFY(p[3] < p[4]);
349 }
350
351 layout.clear();
352 wizard.setButtonLayout(layout);
353 qApp->processEvents();
354
355 for (int i = -1; i < 50; ++i) {
356 QAbstractButton *button = wizard.button(which: QWizard::WizardButton(i));
357 QVERIFY(!button || !button->isVisible());
358 }
359}
360
361void tst_QWizard::setButton()
362{
363 QPointer<QToolButton> toolButton = new QToolButton;
364
365 QWizard wizard;
366 wizard.setWizardStyle(QWizard::ClassicStyle);
367 wizard.setButton(which: QWizard::NextButton, button: toolButton);
368 wizard.setButton(which: QWizard::CustomButton2, button: new QCheckBox("Kustom 2"));
369
370 QVERIFY(qobject_cast<QToolButton *>(wizard.button(QWizard::NextButton)));
371 QVERIFY(qobject_cast<QCheckBox *>(wizard.button(QWizard::CustomButton2)));
372 QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::CustomButton1)));
373
374 QVERIFY(toolButton != 0);
375
376 // resetting the same button does nothing
377 wizard.setButton(which: QWizard::NextButton, button: toolButton);
378 QVERIFY(toolButton != 0);
379
380 // revert to default button
381 wizard.setButton(which: QWizard::NextButton, button: 0);
382 QVERIFY(toolButton.isNull());
383 QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton)));
384 QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
385}
386
387void tst_QWizard::setTitleFormatEtc()
388{
389 QWizard wizard;
390 QCOMPARE(wizard.titleFormat(), Qt::AutoText);
391 QCOMPARE(wizard.subTitleFormat(), Qt::AutoText);
392
393 wizard.setTitleFormat(Qt::RichText);
394 QCOMPARE(wizard.titleFormat(), Qt::RichText);
395 QCOMPARE(wizard.subTitleFormat(), Qt::AutoText);
396
397 wizard.setSubTitleFormat(Qt::PlainText);
398 QCOMPARE(wizard.titleFormat(), Qt::RichText);
399 QCOMPARE(wizard.subTitleFormat(), Qt::PlainText);
400}
401
402void tst_QWizard::setPixmap()
403{
404 QPixmap p1(1, 1);
405 QPixmap p2(2, 2);
406 QPixmap p3(3, 3);
407 QPixmap p4(4, 4);
408 QPixmap p5(5, 5);
409
410 QWizard wizard;
411 QWizardPage *page = new QWizardPage;
412 QWizardPage *page2 = new QWizardPage;
413
414 wizard.addPage(page);
415 wizard.addPage(page: page2);
416
417 QVERIFY(wizard.pixmap(QWizard::BannerPixmap).isNull());
418 QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull());
419 QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull());
420 if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::MacOSHighSierra)
421 QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull());
422 else
423 QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull());
424
425 QVERIFY(page->pixmap(QWizard::BannerPixmap).isNull());
426 QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull());
427 QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull());
428 if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::MacOSHighSierra)
429 QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull());
430 else
431 QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull());
432
433 wizard.setPixmap(which: QWizard::BannerPixmap, pixmap: p1);
434 wizard.setPixmap(which: QWizard::LogoPixmap, pixmap: p2);
435 wizard.setPixmap(which: QWizard::WatermarkPixmap, pixmap: p3);
436 wizard.setPixmap(which: QWizard::BackgroundPixmap, pixmap: p4);
437
438 page->setPixmap(which: QWizard::LogoPixmap, pixmap: p5);
439
440 QCOMPARE(wizard.pixmap(QWizard::BannerPixmap).size(), p1.size());
441 QCOMPARE(wizard.pixmap(QWizard::LogoPixmap).size(), p2.size());
442 QCOMPARE(wizard.pixmap(QWizard::WatermarkPixmap).size(), p3.size());
443 QCOMPARE(wizard.pixmap(QWizard::BackgroundPixmap).size(), p4.size());
444
445 QCOMPARE(page->pixmap(QWizard::BannerPixmap).size(), p1.size());
446 QCOMPARE(page->pixmap(QWizard::LogoPixmap).size(), p5.size());
447 QCOMPARE(page->pixmap(QWizard::WatermarkPixmap).size(), p3.size());
448 QCOMPARE(page->pixmap(QWizard::BackgroundPixmap).size(), p4.size());
449
450 QCOMPARE(page2->pixmap(QWizard::BannerPixmap).size(), p1.size());
451 QCOMPARE(page2->pixmap(QWizard::LogoPixmap).size(), p2.size());
452 QCOMPARE(page2->pixmap(QWizard::WatermarkPixmap).size(), p3.size());
453 QCOMPARE(page2->pixmap(QWizard::BackgroundPixmap).size(), p4.size());
454}
455
456class MyPage1 : public QWizardPage
457{
458public:
459 MyPage1() {
460 edit1 = new QLineEdit("Bla 1", this);
461
462 edit2 = new QLineEdit("Bla 2", this);
463 edit2->setInputMask("Mask");
464
465 edit3 = new QLineEdit("Bla 3", this);
466 edit3->setMaxLength(25);
467
468 edit4 = new QLineEdit("Bla 4", this);
469 }
470
471 void registerField(const QString &name, QWidget *widget,
472 const char *property = 0,
473 const char *changedSignal = 0)
474 { QWizardPage::registerField(name, widget, property, changedSignal); }
475
476 QLineEdit *edit1;
477 QLineEdit *edit2;
478 QLineEdit *edit3;
479 QLineEdit *edit4;
480};
481
482void tst_QWizard::setDefaultProperty()
483{
484 QWizard wizard;
485 MyPage1 *page = new MyPage1;
486 wizard.addPage(page);
487
488 page->registerField(name: "edit1", widget: page->edit1);
489
490 wizard.setDefaultProperty(className: "QLineEdit", property: "inputMask", changedSignal: 0);
491 page->registerField(name: "edit2", widget: page->edit2);
492
493 wizard.setDefaultProperty(className: "QLineEdit", property: "maxLength", changedSignal: 0);
494 page->registerField(name: "edit3", widget: page->edit3);
495
496 wizard.setDefaultProperty(className: "QLineEdit", property: "text", SIGNAL(textChanged(QString)));
497 page->registerField(name: "edit3bis", widget: page->edit3);
498
499 wizard.setDefaultProperty(className: "QWidget", property: "enabled", changedSignal: 0); // less specific, i.e. ignored
500 page->registerField(name: "edit4", widget: page->edit4);
501 QTest::ignoreMessage(type: QtWarningMsg,message: "QWizard::setField: Couldn't write to property 'customProperty'");
502 wizard.setDefaultProperty(className: "QLineEdit", property: "customProperty", changedSignal: 0);
503 page->registerField(name: "edit4bis", widget: page->edit4);
504
505 QCOMPARE(wizard.field("edit1").toString(), QString("Bla 1"));
506 QCOMPARE(wizard.field("edit2").toString(), page->edit2->inputMask());
507 QCOMPARE(wizard.field("edit3").toInt(), 25);
508 QCOMPARE(wizard.field("edit3bis").toString(), QString("Bla 3"));
509 QCOMPARE(wizard.field("edit4").toString(), QString("Bla 4"));
510 QCOMPARE(wizard.field("edit4bis").toString(), QString());
511
512 wizard.setField(name: "edit1", value: "Alpha");
513 wizard.setField(name: "edit2", value: "Beta");
514 wizard.setField(name: "edit3", value: 50);
515 wizard.setField(name: "edit3bis", value: "Gamma");
516 wizard.setField(name: "edit4", value: "Delta");
517 wizard.setField(name: "edit4bis", value: "Epsilon");
518
519 QCOMPARE(wizard.field("edit1").toString(), QString("Alpha"));
520 QVERIFY(wizard.field("edit2").toString().contains("Beta"));
521 QCOMPARE(wizard.field("edit3").toInt(), 50);
522 QCOMPARE(wizard.field("edit3bis").toString(), QString("Gamma"));
523 QCOMPARE(wizard.field("edit4").toString(), QString("Delta"));
524 QCOMPARE(wizard.field("edit4bis").toString(), QString("Epsilon"));
525
526 // make sure the data structure is reasonable
527 for (int i = 0; i < 200000; ++i) {
528 wizard.setDefaultProperty(className: "QLineEdit", property: QByteArray('x' + QByteArray::number(i)).constData(), changedSignal: 0);
529 wizard.setDefaultProperty(className: "QLabel", property: QByteArray('y' + QByteArray::number(i)).constData(), changedSignal: 0);
530 }
531}
532
533void tst_QWizard::addPage()
534{
535 QWidget *parent = new QWidget;
536 QWizard wizard;
537 const int N = 100;
538 QWizardPage *pages[N];
539 QSignalSpy spy(&wizard, SIGNAL(pageAdded(int)));
540
541 for (int i = 0; i < N; ++i) {
542 pages[i] = new QWizardPage(parent);
543 QCOMPARE(wizard.addPage(pages[i]), i);
544 QCOMPARE(pages[i]->window(), (QWidget *)&wizard);
545 QCOMPARE(wizard.startId(), 0);
546 QCOMPARE(spy.count(), 1);
547 QList<QVariant> arguments = spy.takeFirst();
548 QCOMPARE(arguments.at(0).toInt(), i);
549 }
550
551 for (int i = 0; i < N; ++i) {
552 QCOMPARE(pages[i], wizard.page(i));
553 }
554 QVERIFY(!wizard.page(-1));
555 QVERIFY(!wizard.page(N));
556 QVERIFY(!wizard.page(N + 1));
557
558 wizard.setPage(id: N + 50, page: new QWizardPage);
559 QCOMPARE(spy.count(), 1);
560 QList<QVariant> arguments = spy.takeFirst();
561 QCOMPARE(arguments.at(0).toInt(), N + 50);
562 wizard.setPage(id: -3000, page: new QWizardPage);
563 QCOMPARE(spy.count(), 1);
564 arguments = spy.takeFirst();
565 QCOMPARE(arguments.at(0).toInt(), -3000);
566
567 QWizardPage *pageX = new QWizardPage;
568 QCOMPARE(wizard.addPage(pageX), N + 51);
569 QCOMPARE(wizard.page(N + 51), pageX);
570 QCOMPARE(spy.count(), 1);
571 arguments = spy.takeFirst();
572 QCOMPARE(arguments.at(0).toInt(), N + 51);
573
574 QCOMPARE(wizard.addPage(new QWizardPage), N + 52);
575 QCOMPARE(spy.count(), 1);
576 arguments = spy.takeFirst();
577 QCOMPARE(arguments.at(0).toInt(), N + 52);
578
579 QTest::ignoreMessage(type: QtWarningMsg,message: "QWizard::setPage: Cannot insert null page");
580 wizard.addPage(page: 0); // generates a warning
581 QCOMPARE(spy.count(), 0);
582 delete parent;
583}
584
585#define CHECK_VISITED(wizard, list) \
586 do { \
587 QList<int> myList = list; \
588 QCOMPARE((wizard).visitedIds(), myList); \
589 Q_FOREACH(int id, myList) \
590 QVERIFY((wizard).hasVisitedPage(id)); \
591 } while (0)
592
593void tst_QWizard::setPage()
594{
595 QWidget *parent = new QWidget;
596 QWizard wizard;
597 QWizardPage *page;
598 QSignalSpy spy(&wizard, SIGNAL(pageAdded(int)));
599
600 QCOMPARE(wizard.startId(), -1);
601 QCOMPARE(wizard.currentId(), -1);
602 QVERIFY(!wizard.currentPage());
603 QCOMPARE(wizard.nextId(), -1);
604
605 page = new QWizardPage(parent);
606 QTest::ignoreMessage(type: QtWarningMsg,message: "QWizard::setPage: Cannot insert page with ID -1");
607 wizard.setPage(id: -1, page); // gives a warning and does nothing
608 QCOMPARE(spy.count(), 0);
609 QVERIFY(!wizard.page(-2));
610 QVERIFY(!wizard.page(-1));
611 QVERIFY(!wizard.page(0));
612 QCOMPARE(wizard.startId(), -1);
613 QCOMPARE(wizard.currentId(), -1);
614 QVERIFY(!wizard.currentPage());
615 QCOMPARE(wizard.nextId(), -1);
616 CHECK_VISITED(wizard, QList<int>());
617
618 page = new QWizardPage(parent);
619 wizard.setPage(id: 0, page);
620 QCOMPARE(spy.count(), 1);
621 QList<QVariant> arguments = spy.takeFirst();
622 QCOMPARE(arguments.at(0).toInt(), 0);
623 QCOMPARE(page->window(), (QWidget *)&wizard);
624 QCOMPARE(wizard.page(0), page);
625 QCOMPARE(wizard.startId(), 0);
626 QCOMPARE(wizard.currentId(), -1);
627 QVERIFY(!wizard.currentPage());
628 QCOMPARE(wizard.nextId(), -1);
629 CHECK_VISITED(wizard, QList<int>());
630
631 page = new QWizardPage(parent);
632 wizard.setPage(id: -2, page);
633 QCOMPARE(spy.count(), 1);
634 arguments = spy.takeFirst();
635 QCOMPARE(arguments.at(0).toInt(), -2);
636 QCOMPARE(page->window(), (QWidget *)&wizard);
637 QCOMPARE(wizard.page(-2), page);
638 QCOMPARE(wizard.startId(), -2);
639 QCOMPARE(wizard.currentId(), -1);
640 QVERIFY(!wizard.currentPage());
641 QCOMPARE(wizard.nextId(), -1);
642 CHECK_VISITED(wizard, QList<int>());
643
644 wizard.restart();
645 QCOMPARE(wizard.page(-2), page);
646 QCOMPARE(wizard.startId(), -2);
647 QCOMPARE(wizard.currentId(), -2);
648 QCOMPARE(wizard.currentPage(), page);
649 QCOMPARE(wizard.nextId(), 0);
650 CHECK_VISITED(wizard, QList<int>() << -2);
651
652 page = new QWizardPage(parent);
653 wizard.setPage(id: 2, page);
654 QCOMPARE(spy.count(), 1);
655 arguments = spy.takeFirst();
656 QCOMPARE(arguments.at(0).toInt(), 2);
657 QCOMPARE(wizard.page(2), page);
658 QCOMPARE(wizard.startId(), -2);
659 QCOMPARE(wizard.currentId(), -2);
660 QCOMPARE(wizard.currentPage(), wizard.page(-2));
661 QCOMPARE(wizard.nextId(), 0);
662 CHECK_VISITED(wizard, QList<int>() << -2);
663
664 wizard.restart();
665 QCOMPARE(wizard.startId(), -2);
666 QCOMPARE(wizard.currentId(), -2);
667 QCOMPARE(wizard.currentPage(), wizard.page(-2));
668 QCOMPARE(wizard.nextId(), 0);
669 CHECK_VISITED(wizard, QList<int>() << -2);
670
671 page = new QWizardPage(parent);
672 wizard.setPage(id: -3, page);
673 QCOMPARE(spy.count(), 1);
674 arguments = spy.takeFirst();
675 QCOMPARE(arguments.at(0).toInt(), -3);
676 QCOMPARE(wizard.page(-3), page);
677 QCOMPARE(wizard.startId(), -3);
678 QCOMPARE(wizard.currentId(), -2);
679 QCOMPARE(wizard.currentPage(), wizard.page(-2));
680 QCOMPARE(wizard.nextId(), 0);
681 CHECK_VISITED(wizard, QList<int>() << -2);
682
683 wizard.restart();
684 QCOMPARE(wizard.startId(), -3);
685 QCOMPARE(wizard.currentId(), -3);
686 QCOMPARE(wizard.currentPage(), wizard.page(-3));
687 QCOMPARE(wizard.nextId(), -2);
688 CHECK_VISITED(wizard, QList<int>() << -3);
689
690 wizard.next();
691 QCOMPARE(wizard.startId(), -3);
692 QCOMPARE(wizard.currentId(), -2);
693 QCOMPARE(wizard.currentPage(), wizard.page(-2));
694 QCOMPARE(wizard.nextId(), 0);
695 CHECK_VISITED(wizard, QList<int>() << -3 << -2);
696
697 wizard.next();
698 QCOMPARE(wizard.startId(), -3);
699 QCOMPARE(wizard.currentId(), 0);
700 QCOMPARE(wizard.currentPage(), wizard.page(0));
701 QCOMPARE(wizard.nextId(), 2);
702 CHECK_VISITED(wizard, QList<int>() << -3 << -2 << 0);
703
704 for (int i = 0; i < 100; ++i) {
705 wizard.next();
706 QCOMPARE(wizard.startId(), -3);
707 QCOMPARE(wizard.currentId(), 2);
708 QCOMPARE(wizard.currentPage(), wizard.page(2));
709 QCOMPARE(wizard.nextId(), -1);
710 CHECK_VISITED(wizard, QList<int>() << -3 << -2 << 0 << 2);
711 }
712
713 wizard.back();
714 QCOMPARE(wizard.startId(), -3);
715 QCOMPARE(wizard.currentId(), 0);
716 QCOMPARE(wizard.currentPage(), wizard.page(0));
717 QCOMPARE(wizard.nextId(), 2);
718 CHECK_VISITED(wizard, QList<int>() << -3 << -2 << 0);
719
720 wizard.back();
721 QCOMPARE(wizard.startId(), -3);
722 QCOMPARE(wizard.currentId(), -2);
723 QCOMPARE(wizard.currentPage(), wizard.page(-2));
724 QCOMPARE(wizard.nextId(), 0);
725 CHECK_VISITED(wizard, QList<int>() << -3 << -2);
726
727 for (int i = 0; i < 100; ++i) {
728 wizard.back();
729 QCOMPARE(wizard.startId(), -3);
730 QCOMPARE(wizard.currentId(), -3);
731 QCOMPARE(wizard.currentPage(), wizard.page(-3));
732 QCOMPARE(wizard.nextId(), -2);
733 CHECK_VISITED(wizard, QList<int>() << -3);
734 }
735
736 for (int i = 0; i < 100; ++i) {
737 wizard.restart();
738 QCOMPARE(wizard.startId(), -3);
739 QCOMPARE(wizard.currentId(), -3);
740 QCOMPARE(wizard.currentPage(), wizard.page(-3));
741 QCOMPARE(wizard.nextId(), -2);
742 CHECK_VISITED(wizard, QList<int>() << -3);
743 }
744 QCOMPARE(spy.count(), 0);
745 delete parent;
746}
747
748void tst_QWizard::setStartId()
749{
750 QWizard wizard;
751 QCOMPARE(wizard.startId(), -1);
752
753 wizard.setPage(INT_MIN, page: new QWizardPage);
754 QCOMPARE(wizard.startId(), INT_MIN);
755
756 wizard.setPage(id: -2, page: new QWizardPage);
757 QCOMPARE(wizard.startId(), INT_MIN);
758
759 wizard.setPage(id: 0, page: new QWizardPage);
760 QCOMPARE(wizard.startId(), INT_MIN);
761
762 wizard.setPage(id: 1, page: new QWizardPage);
763 QCOMPARE(wizard.startId(), INT_MIN);
764
765 wizard.setPage(INT_MAX, page: new QWizardPage);
766 QCOMPARE(wizard.startId(), INT_MIN);
767
768 QTest::ignoreMessage(type: QtWarningMsg,message: "QWizard::setStartId: Invalid page ID 123");
769 wizard.setStartId(123);
770 QCOMPARE(wizard.startId(), INT_MIN);
771
772 wizard.setStartId(-1);
773 QCOMPARE(wizard.startId(), INT_MIN);
774
775 wizard.setStartId(-2);
776 QCOMPARE(wizard.startId(), -2);
777 QCOMPARE(wizard.nextId(), -1);
778
779 wizard.setStartId(-1);
780 QCOMPARE(wizard.startId(), INT_MIN);
781
782 wizard.setStartId(-2);
783 QCOMPARE(wizard.startId(), -2);
784 QCOMPARE(wizard.nextId(), -1);
785
786 wizard.restart();
787 QCOMPARE(wizard.startId(), -2);
788 QCOMPARE(wizard.currentId(), -2);
789 QCOMPARE(wizard.currentPage(), wizard.page(-2));
790 QCOMPARE(wizard.nextId(), 0);
791
792 wizard.next();
793 QCOMPARE(wizard.startId(), -2);
794 QCOMPARE(wizard.currentId(), 0);
795 QCOMPARE(wizard.currentPage(), wizard.page(0));
796 QCOMPARE(wizard.nextId(), 1);
797
798 wizard.setStartId(INT_MIN);
799 QCOMPARE(wizard.startId(), INT_MIN);
800 QCOMPARE(wizard.currentId(), 0);
801 QCOMPARE(wizard.currentPage(), wizard.page(0));
802 QCOMPARE(wizard.nextId(), 1);
803
804 wizard.next();
805 QCOMPARE(wizard.startId(), INT_MIN);
806 QCOMPARE(wizard.currentId(), 1);
807 QCOMPARE(wizard.currentPage(), wizard.page(1));
808 QCOMPARE(wizard.nextId(), INT_MAX);
809
810 wizard.next();
811 QCOMPARE(wizard.startId(), INT_MIN);
812 QCOMPARE(wizard.currentId(), INT_MAX);
813 QCOMPARE(wizard.currentPage(), wizard.page(INT_MAX));
814 QCOMPARE(wizard.nextId(), -1);
815 CHECK_VISITED(wizard, QList<int>() << -2 << 0 << 1 << INT_MAX);
816}
817
818struct MyPage2 : public QWizardPage
819{
820public:
821 MyPage2() : init(0), cleanup(0), validate(0) {}
822
823 void initializePage() { ++init; QWizardPage::initializePage(); }
824 void cleanupPage() { ++cleanup; QWizardPage::cleanupPage(); }
825 bool validatePage() { ++validate; return QWizardPage::validatePage(); }
826
827 bool sanityCheck(int init, int cleanup)
828 {
829 return init == this->init
830 && cleanup == this->cleanup
831 && (this->init == this->cleanup || this->init - 1 == this->cleanup);
832 }
833
834 int init;
835 int cleanup;
836 int validate;
837};
838
839#define CHECK_PAGE_INIT(i0, c0, i1, c1, i2, c2) \
840 QVERIFY(page0->sanityCheck((i0), (c0))); \
841 QVERIFY(page1->sanityCheck((i1), (c1))); \
842 QVERIFY(page2->sanityCheck((i2), (c2)));
843
844void tst_QWizard::setOption_IndependentPages()
845{
846 MyPage2 *page0 = new MyPage2;
847 MyPage2 *page1 = new MyPage2;
848 MyPage2 *page2 = new MyPage2;
849
850 QWizard wizard;
851 wizard.addPage(page: page0);
852 wizard.addPage(page: page1);
853 wizard.addPage(page: page2);
854
855 QVERIFY(!wizard.testOption(QWizard::IndependentPages));
856
857 wizard.restart();
858
859 // Make sure initializePage() and cleanupPage() are called are
860 // they should when the
861 // wizard.testOption(QWizard::IndependentPages option is off.
862 for (int i = 0; i < 10; ++i) {
863 CHECK_PAGE_INIT(i + 1, i, i, i, i, i);
864
865 wizard.next();
866 CHECK_PAGE_INIT(i + 1, i, i + 1, i, i, i);
867
868 wizard.next();
869 CHECK_PAGE_INIT(i + 1, i, i + 1, i, i + 1, i);
870
871 wizard.next();
872 CHECK_PAGE_INIT(i + 1, i, i + 1, i, i + 1, i);
873
874 wizard.back();
875 CHECK_PAGE_INIT(i + 1, i, i + 1, i, i + 1, i + 1);
876
877 wizard.back();
878 CHECK_PAGE_INIT(i + 1, i, i + 1, i + 1, i + 1, i + 1);
879
880 wizard.back();
881 CHECK_PAGE_INIT(i + 1, i, i + 1, i + 1, i + 1, i + 1);
882
883 wizard.restart();
884 }
885
886 CHECK_PAGE_INIT(11, 10, 10, 10, 10, 10);
887
888 wizard.next();
889 CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10);
890
891 // Now, turn on the option and check that they're called at the
892 // appropriate times (which aren't the same).
893 wizard.setOption(option: QWizard::IndependentPages, on: true);
894 CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10);
895
896 wizard.back();
897 CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10);
898
899 wizard.next();
900 CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10);
901
902 wizard.next();
903 CHECK_PAGE_INIT(11, 10, 11, 10, 11, 10);
904
905 wizard.next();
906 CHECK_PAGE_INIT(11, 10, 11, 10, 11, 10);
907
908 wizard.back();
909 CHECK_PAGE_INIT(11, 10, 11, 10, 11, 10);
910
911 wizard.setStartId(2);
912
913 wizard.restart();
914 CHECK_PAGE_INIT(11, 11, 11, 11, 12, 11);
915
916 wizard.back();
917 CHECK_PAGE_INIT(11, 11, 11, 11, 12, 11);
918
919 wizard.next();
920 CHECK_PAGE_INIT(11, 11, 11, 11, 12, 11);
921
922 wizard.setStartId(0);
923 wizard.restart();
924 CHECK_PAGE_INIT(12, 11, 11, 11, 12, 12);
925
926 wizard.next();
927 CHECK_PAGE_INIT(12, 11, 12, 11, 12, 12);
928
929 wizard.next();
930 CHECK_PAGE_INIT(12, 11, 12, 11, 13, 12);
931
932 wizard.back();
933 CHECK_PAGE_INIT(12, 11, 12, 11, 13, 12);
934
935 // Fun stuff here.
936
937 wizard.setOption(option: QWizard::IndependentPages, on: false);
938 CHECK_PAGE_INIT(12, 11, 12, 11, 13, 13);
939
940 wizard.setOption(option: QWizard::IndependentPages, on: true);
941 CHECK_PAGE_INIT(12, 11, 12, 11, 13, 13);
942
943 wizard.setOption(option: QWizard::IndependentPages, on: false);
944 CHECK_PAGE_INIT(12, 11, 12, 11, 13, 13);
945
946 wizard.back();
947 CHECK_PAGE_INIT(12, 11, 12, 12, 13, 13);
948
949 wizard.back();
950 CHECK_PAGE_INIT(12, 11, 12, 12, 13, 13);
951}
952
953void tst_QWizard::setOption_IgnoreSubTitles()
954{
955 const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
956 const int kPixels = (availableGeometry.width() + 500) / 1000;
957 const int frame = 50 * kPixels;
958 const int size = 400 * kPixels;
959 QWizard wizard1;
960#ifdef Q_OS_WIN
961 wizard1.setWizardStyle(QWizard::ClassicStyle); // Avoid Vista style focus animations, etc.
962#endif
963 wizard1.setButtonLayout(QList<QWizard::WizardButton>() << QWizard::CancelButton);
964 wizard1.resize(w: size, h: size);
965 wizard1.move(ax: availableGeometry.left() + frame, ay: availableGeometry.top() + frame);
966 QVERIFY(!wizard1.testOption(QWizard::IgnoreSubTitles));
967 QWizardPage *page11 = new QWizardPage;
968 page11->setTitle("Page X");
969 page11->setSubTitle("Some subtitle");
970
971 QWizardPage *page12 = new QWizardPage;
972 page12->setTitle("Page X");
973
974 wizard1.addPage(page: page11);
975 wizard1.addPage(page: page12);
976
977 QWizard wizard2;
978#ifdef Q_OS_WIN
979 wizard2.setWizardStyle(QWizard::ClassicStyle); // Avoid Vista style focus animations, etc.
980#endif
981 wizard2.setButtonLayout(QList<QWizard::WizardButton>() << QWizard::CancelButton);
982 wizard2.resize(w: size, h: size);
983 wizard2.move(ax: availableGeometry.left() + 2 * frame + size, ay: availableGeometry.top() + frame);
984 wizard2.setOption(option: QWizard::IgnoreSubTitles, on: true);
985 QWizardPage *page21 = new QWizardPage;
986 page21->setTitle("Page X");
987 page21->setSubTitle("Some subtitle");
988
989 QWizardPage *page22 = new QWizardPage;
990 page22->setTitle("Page X");
991
992 wizard2.addPage(page: page21);
993 wizard2.addPage(page: page22);
994
995 wizard1.show();
996 wizard2.show();
997 QVERIFY(QTest::qWaitForWindowExposed(&wizard2));
998
999 // Check that subtitles are shown when they should (i.e.,
1000 // they're set and IgnoreSubTitles is off).
1001
1002 qApp->setActiveWindow(0); // ensure no focus rectangle around cancel button
1003 QImage i11 = grabWidget(window: &wizard1);
1004 QImage i21 = grabWidget(window: &wizard2);
1005 QVERIFY(i11 != i21);
1006
1007 wizard1.next();
1008 wizard2.next();
1009
1010 QImage i12 = grabWidget(window: &wizard1);
1011 QImage i22 = grabWidget(window: &wizard2);
1012 QCOMPARE(i12, i22);
1013 QCOMPARE(i21, i22);
1014
1015 wizard1.back();
1016 wizard2.back();
1017
1018 QImage i13 = grabWidget(window: &wizard1);
1019 QImage i23 = grabWidget(window: &wizard2);
1020 QCOMPARE(i13, i11);
1021 QCOMPARE(i23, i21);
1022
1023 wizard1.setOption(option: QWizard::IgnoreSubTitles, on: true);
1024 wizard2.setOption(option: QWizard::IgnoreSubTitles, on: false);
1025
1026 QImage i14 = grabWidget(window: &wizard1);
1027 QImage i24 = grabWidget(window: &wizard2);
1028 QCOMPARE(i14, i21);
1029 QCOMPARE(i24, i11);
1030
1031 // Check the impact of subtitles on the rest of the layout, by
1032 // using a subtitle that looks empty (but that isn't). In
1033 // Classic and Modern styles, this should be enough to trigger a
1034 // "header"; in Mac style, this only creates a QLabel, with no
1035 // text, i.e. it doesn't affect the layout.
1036
1037 page11->setSubTitle("<b></b>"); // not quite empty, but looks empty
1038
1039 for (int i = 0; i < 3; ++i) {
1040 for (int j = 0; j < 2; ++j) {
1041 wizard1.setOption(option: QWizard::IgnoreSubTitles, on: j == 0);
1042
1043 wizard1.setWizardStyle(i == 0 ? QWizard::ClassicStyle
1044 : i == 1 ? QWizard::ModernStyle
1045 : QWizard::MacStyle);
1046 wizard1.restart();
1047 QImage i1 = grabWidget(window: &wizard1);
1048
1049 wizard1.next();
1050 QImage i2 = grabWidget(window: &wizard1);
1051
1052 if (j == 0 || wizard1.wizardStyle() == QWizard::MacStyle) {
1053 QCOMPARE(i1, i2);
1054 } else {
1055 QVERIFY(i1 != i2);
1056 }
1057 }
1058 }
1059}
1060
1061void tst_QWizard::setOption_ExtendedWatermarkPixmap()
1062{
1063 QPixmap watermarkPixmap(200, 400);
1064 watermarkPixmap.fill(fillColor: Qt::black);
1065
1066 QWizard wizard1;
1067 wizard1.setButtonLayout(QList<QWizard::WizardButton>() << QWizard::CancelButton);
1068 QVERIFY(!wizard1.testOption(QWizard::ExtendedWatermarkPixmap));
1069 QWizardPage *page11 = new QWizardPage;
1070 page11->setTitle("Page X");
1071 page11->setPixmap(which: QWizard::WatermarkPixmap, pixmap: watermarkPixmap);
1072
1073 QWizardPage *page12 = new QWizardPage;
1074 page12->setTitle("Page X");
1075
1076 wizard1.addPage(page: page11);
1077 wizard1.addPage(page: page12);
1078
1079 QWizard wizard2;
1080 wizard2.setButtonLayout(QList<QWizard::WizardButton>() << QWizard::CancelButton);
1081 wizard2.setOption(option: QWizard::ExtendedWatermarkPixmap, on: true);
1082 QWizardPage *page21 = new QWizardPage;
1083 page21->setTitle("Page X");
1084 page21->setPixmap(which: QWizard::WatermarkPixmap, pixmap: watermarkPixmap);
1085
1086 QWizardPage *page22 = new QWizardPage;
1087 page22->setTitle("Page X");
1088
1089 wizard2.addPage(page: page21);
1090 wizard2.addPage(page: page22);
1091
1092 wizard1.show();
1093 wizard2.show();
1094
1095 // Check the impact of watermark pixmaps on the rest of the layout.
1096
1097 for (int i = 0; i < 3; ++i) {
1098 QImage i1[2];
1099 QImage i2[2];
1100 for (int j = 0; j < 2; ++j) {
1101 wizard1.setOption(option: QWizard::ExtendedWatermarkPixmap, on: j == 0);
1102
1103 wizard1.setWizardStyle(i == 0 ? QWizard::ClassicStyle
1104 : i == 1 ? QWizard::ModernStyle
1105 : QWizard::MacStyle);
1106 wizard1.restart();
1107 wizard1.setMaximumSize(maxw: 1000, maxh: 1000);
1108 wizard1.resize(w: 600, h: 600);
1109 i1[j] = grabWidget(window: &wizard1);
1110
1111 wizard1.next();
1112 wizard1.setMaximumSize(maxw: 1000, maxh: 1000);
1113 wizard1.resize(w: 600, h: 600);
1114 i2[j] = grabWidget(window: &wizard1);
1115 }
1116
1117 if (wizard1.wizardStyle() == QWizard::MacStyle) {
1118 QCOMPARE(i1[0], i1[1]);
1119 QCOMPARE(i2[0], i2[1]);
1120 QCOMPARE(i1[0], i2[0]);
1121 } else {
1122 QVERIFY(i1[0] != i1[1]);
1123 QCOMPARE(i2[0], i2[1]);
1124 QVERIFY(i1[0] != i2[0]);
1125 QVERIFY(i1[1] != i2[1]);
1126 }
1127 }
1128}
1129
1130void tst_QWizard::setOption_NoDefaultButton()
1131{
1132 QWizard wizard;
1133 wizard.setOption(option: QWizard::NoDefaultButton, on: false);
1134 wizard.setOption(option: QWizard::HaveFinishButtonOnEarlyPages, on: true);
1135 wizard.addPage(page: new QWizardPage);
1136 wizard.page(id: 0)->setFinalPage(true);
1137 wizard.addPage(page: new QWizardPage);
1138
1139 if (QPushButton *pb = qobject_cast<QPushButton *>(object: wizard.button(which: QWizard::NextButton)))
1140 pb->setAutoDefault(false);
1141 if (QPushButton *pb = qobject_cast<QPushButton *>(object: wizard.button(which: QWizard::FinishButton)))
1142 pb->setAutoDefault(false);
1143
1144 wizard.show();
1145 qApp->processEvents();
1146 QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
1147 QVERIFY(wizard.button(QWizard::FinishButton)->isEnabled());
1148
1149 wizard.next();
1150 QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton))->isDefault());
1151
1152 wizard.back();
1153 QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
1154
1155 wizard.setOption(option: QWizard::NoDefaultButton, on: true);
1156 QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
1157 QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton))->isDefault());
1158
1159 wizard.next();
1160 QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
1161 QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton))->isDefault());
1162
1163 wizard.back();
1164 QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
1165 QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton))->isDefault());
1166
1167 wizard.setOption(option: QWizard::NoDefaultButton, on: false);
1168 QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
1169}
1170
1171void tst_QWizard::setOption_NoBackButtonOnStartPage()
1172{
1173 QWizard wizard;
1174 wizard.setOption(option: QWizard::NoBackButtonOnStartPage, on: true);
1175 wizard.addPage(page: new QWizardPage);
1176 wizard.addPage(page: new QWizardPage);
1177 wizard.addPage(page: new QWizardPage);
1178
1179 wizard.setStartId(1);
1180 wizard.show();
1181 qApp->processEvents();
1182
1183 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
1184
1185 wizard.setOption(option: QWizard::NoBackButtonOnStartPage, on: false);
1186 qApp->processEvents();
1187 QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
1188
1189 wizard.setOption(option: QWizard::NoBackButtonOnStartPage, on: true);
1190 qApp->processEvents();
1191 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
1192
1193 wizard.next();
1194 qApp->processEvents();
1195 QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
1196
1197 wizard.setOption(option: QWizard::NoBackButtonOnStartPage, on: false);
1198 QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
1199
1200 wizard.setOption(option: QWizard::NoBackButtonOnStartPage, on: true);
1201 QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
1202
1203 wizard.back();
1204 qApp->processEvents();
1205 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
1206}
1207
1208void tst_QWizard::setOption_NoBackButtonOnLastPage()
1209{
1210 for (int i = 0; i < 2; ++i) {
1211 QWizard wizard;
1212 wizard.setOption(option: QWizard::NoBackButtonOnStartPage, on: false);
1213 wizard.setOption(option: QWizard::NoBackButtonOnLastPage, on: true);
1214 wizard.setOption(option: QWizard::DisabledBackButtonOnLastPage, on: i == 0); // changes nothing
1215 wizard.addPage(page: new QWizardPage);
1216 wizard.addPage(page: new QWizardPage);
1217 wizard.page(id: 1)->setFinalPage(true); // changes nothing (final != last in general)
1218 wizard.addPage(page: new QWizardPage);
1219
1220 wizard.setStartId(1);
1221 wizard.show();
1222 qApp->processEvents();
1223
1224 QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
1225
1226 wizard.next();
1227 qApp->processEvents();
1228 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
1229
1230 wizard.next();
1231 qApp->processEvents();
1232 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
1233
1234 wizard.back();
1235 qApp->processEvents();
1236 QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
1237
1238 wizard.next();
1239 qApp->processEvents();
1240 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
1241
1242 wizard.setOption(option: QWizard::NoBackButtonOnLastPage, on: false);
1243 QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
1244
1245 wizard.setOption(option: QWizard::NoBackButtonOnLastPage, on: true);
1246 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
1247
1248 wizard.addPage(page: new QWizardPage);
1249 QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); // this is maybe wrong
1250 }
1251}
1252
1253void tst_QWizard::setOption_DisabledBackButtonOnLastPage()
1254{
1255 QWizard wizard;
1256 wizard.setOption(option: QWizard::NoBackButtonOnStartPage, on: false);
1257 wizard.setOption(option: QWizard::DisabledBackButtonOnLastPage, on: true);
1258 wizard.addPage(page: new QWizardPage);
1259 wizard.addPage(page: new QWizardPage);
1260 wizard.page(id: 1)->setFinalPage(true); // changes nothing (final != last in general)
1261 wizard.addPage(page: new QWizardPage);
1262
1263 wizard.setStartId(1);
1264 wizard.show();
1265 qApp->processEvents();
1266
1267 QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
1268 QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
1269
1270 wizard.next();
1271 qApp->processEvents();
1272 QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
1273
1274 wizard.next();
1275 qApp->processEvents();
1276 QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
1277
1278 wizard.back();
1279 qApp->processEvents();
1280 QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
1281 QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
1282
1283 wizard.next();
1284 qApp->processEvents();
1285 QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
1286
1287 wizard.setOption(option: QWizard::DisabledBackButtonOnLastPage, on: false);
1288 QVERIFY(wizard.button(QWizard::BackButton)->isEnabled());
1289
1290 wizard.setOption(option: QWizard::DisabledBackButtonOnLastPage, on: true);
1291 QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
1292
1293 wizard.addPage(page: new QWizardPage);
1294 QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); // this is maybe wrong
1295}
1296
1297void tst_QWizard::setOption_HaveNextButtonOnLastPage()
1298{
1299 QWizard wizard;
1300 wizard.setOption(option: QWizard::HaveNextButtonOnLastPage, on: false);
1301 wizard.addPage(page: new QWizardPage);
1302 wizard.addPage(page: new QWizardPage);
1303 wizard.page(id: 1)->setFinalPage(true); // changes nothing (final != last in general)
1304 wizard.addPage(page: new QWizardPage);
1305
1306 wizard.setStartId(1);
1307 wizard.show();
1308 qApp->processEvents();
1309
1310 QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
1311 QVERIFY(wizard.button(QWizard::NextButton)->isEnabled());
1312
1313 wizard.next();
1314 QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
1315
1316 wizard.setOption(option: QWizard::HaveNextButtonOnLastPage, on: true);
1317 QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
1318 QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled());
1319
1320 wizard.next();
1321 QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
1322 QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled());
1323
1324 wizard.back();
1325 QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
1326 QVERIFY(wizard.button(QWizard::NextButton)->isEnabled());
1327
1328 wizard.setOption(option: QWizard::HaveNextButtonOnLastPage, on: false);
1329 QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
1330 QVERIFY(wizard.button(QWizard::NextButton)->isEnabled());
1331
1332 wizard.next();
1333 QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
1334
1335 wizard.setOption(option: QWizard::HaveNextButtonOnLastPage, on: true);
1336 QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
1337 QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled());
1338}
1339
1340void tst_QWizard::setOption_HaveFinishButtonOnEarlyPages()
1341{
1342 QWizard wizard;
1343 QVERIFY(!wizard.testOption(QWizard::HaveFinishButtonOnEarlyPages));
1344 wizard.addPage(page: new QWizardPage);
1345 wizard.addPage(page: new QWizardPage);
1346 wizard.page(id: 1)->setFinalPage(true);
1347 wizard.addPage(page: new QWizardPage);
1348
1349 wizard.show();
1350 qApp->processEvents();
1351
1352 QVERIFY(!wizard.button(QWizard::FinishButton)->isVisible());
1353
1354 wizard.next();
1355 QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
1356
1357 wizard.next();
1358 QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
1359
1360 wizard.back();
1361 QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
1362
1363 wizard.back();
1364 QVERIFY(!wizard.button(QWizard::FinishButton)->isVisible());
1365
1366 wizard.setOption(option: QWizard::HaveFinishButtonOnEarlyPages, on: true);
1367 QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
1368
1369 wizard.next();
1370 QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
1371
1372 wizard.setOption(option: QWizard::HaveFinishButtonOnEarlyPages, on: false);
1373 QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
1374
1375 wizard.back();
1376 QVERIFY(!wizard.button(QWizard::FinishButton)->isVisible());
1377}
1378
1379void tst_QWizard::setOption_NoCancelButton()
1380{
1381 for (int i = 0; i < 2; ++i) {
1382 QWizard wizard;
1383 wizard.setOption(option: QWizard::NoCancelButton, on: true);
1384 wizard.setOption(option: QWizard::CancelButtonOnLeft, on: i == 0);
1385 wizard.addPage(page: new QWizardPage);
1386 wizard.addPage(page: new QWizardPage);
1387 wizard.show();
1388 qApp->processEvents();
1389
1390 QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
1391
1392 wizard.next();
1393 QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
1394
1395 wizard.setOption(option: QWizard::NoCancelButton, on: false);
1396 QVERIFY(wizard.button(QWizard::CancelButton)->isVisible());
1397
1398 wizard.back();
1399 QVERIFY(wizard.button(QWizard::CancelButton)->isVisible());
1400
1401 wizard.setOption(option: QWizard::NoCancelButton, on: true);
1402 QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
1403 }
1404}
1405
1406void tst_QWizard::setOption_NoCancelButtonOnLastPage()
1407{
1408 for (int i = 0; i < 2; ++i) {
1409 QWizard wizard;
1410 wizard.setOption(option: QWizard::NoCancelButton, on: false);
1411 wizard.setOption(option: QWizard::NoCancelButtonOnLastPage, on: true);
1412 wizard.addPage(page: new QWizardPage);
1413 wizard.addPage(page: new QWizardPage);
1414 wizard.page(id: 1)->setFinalPage(true); // changes nothing (final != last in general)
1415 wizard.addPage(page: new QWizardPage);
1416
1417 wizard.setStartId(1);
1418 wizard.show();
1419 qApp->processEvents();
1420
1421 QVERIFY(wizard.button(QWizard::CancelButton)->isVisible());
1422
1423 wizard.next();
1424 qApp->processEvents();
1425 QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
1426
1427 wizard.next();
1428 qApp->processEvents();
1429 QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
1430
1431 wizard.back();
1432 qApp->processEvents();
1433 QVERIFY(wizard.button(QWizard::CancelButton)->isVisible());
1434
1435 wizard.next();
1436 qApp->processEvents();
1437 QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
1438
1439 wizard.setOption(option: QWizard::NoCancelButtonOnLastPage, on: false);
1440 QVERIFY(wizard.button(QWizard::CancelButton)->isVisible());
1441
1442 wizard.setOption(option: QWizard::NoCancelButtonOnLastPage, on: true);
1443 QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
1444
1445 wizard.addPage(page: new QWizardPage);
1446 QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible()); // this is maybe wrong
1447 }
1448}
1449
1450void tst_QWizard::setOption_CancelButtonOnLeft()
1451{
1452 for (int i = 0; i < 2; ++i) {
1453 int sign = (i == 0) ? +1 : -1;
1454
1455 QWizard wizard;
1456 wizard.setLayoutDirection(i == 0 ? Qt::LeftToRight : Qt::RightToLeft);
1457 wizard.setOption(option: QWizard::NoCancelButton, on: false);
1458 wizard.setOption(option: QWizard::CancelButtonOnLeft, on: true);
1459 wizard.setOption(option: QWizard::NoBackButtonOnStartPage, on: false);
1460 wizard.addPage(page: new QWizardPage);
1461 wizard.addPage(page: new QWizardPage);
1462 wizard.show();
1463 qApp->processEvents();
1464
1465 const QAbstractButton *refButton = wizard.button(which: (wizard.wizardStyle() == QWizard::AeroStyle)
1466 ? QWizard::NextButton : QWizard::BackButton);
1467 const QAbstractButton *refButton2 = wizard.button(which: (wizard.wizardStyle() == QWizard::AeroStyle)
1468 ? QWizard::FinishButton : QWizard::BackButton);
1469
1470 QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() < sign * refButton->x());
1471
1472 wizard.next();
1473 qApp->processEvents();
1474 QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() < sign * refButton->x());
1475
1476 wizard.setOption(option: QWizard::CancelButtonOnLeft, on: false);
1477 qApp->processEvents();
1478 QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() > sign * refButton2->x());
1479
1480 wizard.back();
1481 qApp->processEvents();
1482 QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() > sign * refButton->x());
1483 }
1484}
1485
1486void tst_QWizard::setOption_HaveHelpButton()
1487{
1488 for (int i = 0; i < 2; ++i) {
1489 QWizard wizard;
1490 QVERIFY(!wizard.testOption(QWizard::HaveHelpButton));
1491 wizard.setOption(option: QWizard::HaveHelpButton, on: false);
1492 wizard.setOption(option: QWizard::HelpButtonOnRight, on: i == 0);
1493 wizard.addPage(page: new QWizardPage);
1494 wizard.addPage(page: new QWizardPage);
1495 wizard.show();
1496 qApp->processEvents();
1497
1498 QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible());
1499
1500 wizard.next();
1501 QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible());
1502
1503 wizard.setOption(option: QWizard::HaveHelpButton, on: true);
1504 QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
1505
1506 wizard.back();
1507 QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
1508
1509 wizard.setOption(option: QWizard::HaveHelpButton, on: false);
1510 QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible());
1511 }
1512}
1513
1514void tst_QWizard::setOption_HelpButtonOnRight()
1515{
1516 for (int i = 0; i < 2; ++i) {
1517 int sign = (i == 0) ? +1 : -1;
1518
1519 QWizard wizard;
1520 wizard.setLayoutDirection(i == 0 ? Qt::LeftToRight : Qt::RightToLeft);
1521 wizard.setOption(option: QWizard::HaveHelpButton, on: true);
1522 wizard.setOption(option: QWizard::HelpButtonOnRight, on: false);
1523 wizard.setOption(option: QWizard::NoBackButtonOnStartPage, on: false);
1524 wizard.addPage(page: new QWizardPage);
1525 wizard.addPage(page: new QWizardPage);
1526 wizard.show();
1527 qApp->processEvents();
1528
1529 const QAbstractButton *refButton = wizard.button(which: (wizard.wizardStyle() == QWizard::AeroStyle)
1530 ? QWizard::NextButton : QWizard::BackButton);
1531
1532 QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() < sign * refButton->x());
1533
1534 wizard.next();
1535 qApp->processEvents();
1536 QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() < sign * refButton->x());
1537
1538 wizard.setOption(option: QWizard::HelpButtonOnRight, on: true);
1539 qApp->processEvents();
1540 QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() > sign * refButton->x());
1541
1542 wizard.back();
1543 qApp->processEvents();
1544 QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() > sign * refButton->x());
1545 }
1546}
1547
1548void tst_QWizard::setOption_HaveCustomButtonX()
1549{
1550 for (int i = 0; i < 2; ++i) {
1551 for (int j = 0; j < 2; ++j) {
1552 for (int k = 0; k < 2; ++k) {
1553 QWizard wizard;
1554 wizard.setLayoutDirection(Qt::LeftToRight);
1555 wizard.addPage(page: new QWizardPage);
1556 wizard.addPage(page: new QWizardPage);
1557 wizard.show();
1558
1559 wizard.setButtonText(which: QWizard::CustomButton1, text: "Foo");
1560 wizard.setButton(which: QWizard::CustomButton2, button: new QCheckBox("Bar"));
1561 wizard.button(which: QWizard::CustomButton3)->setText("Baz");
1562
1563 wizard.setOption(option: QWizard::HaveCustomButton1, on: i == 0);
1564 wizard.setOption(option: QWizard::HaveCustomButton2, on: j == 0);
1565 wizard.setOption(option: QWizard::HaveCustomButton3, on: k == 0);
1566
1567 QVERIFY(wizard.button(QWizard::CustomButton1)->isHidden() == (i != 0));
1568 QVERIFY(wizard.button(QWizard::CustomButton2)->isHidden() == (j != 0));
1569 QVERIFY(wizard.button(QWizard::CustomButton3)->isHidden() == (k != 0));
1570
1571 if (i + j + k == 0) {
1572 qApp->processEvents();
1573 QVERIFY(wizard.button(QWizard::CustomButton1)->x()
1574 < wizard.button(QWizard::CustomButton2)->x());
1575 QVERIFY(wizard.button(QWizard::CustomButton2)->x()
1576 < wizard.button(QWizard::CustomButton3)->x());
1577 }
1578 }
1579 }
1580 }
1581}
1582
1583class Operation
1584{
1585public:
1586 virtual void apply(QWizard *) const = 0;
1587 virtual QString describe() const = 0;
1588protected:
1589 virtual ~Operation() {}
1590};
1591
1592class SetPage : public Operation
1593{
1594 void apply(QWizard *wizard) const
1595 {
1596 wizard->restart();
1597 for (int j = 0; j < page; ++j)
1598 wizard->next();
1599 }
1600 QString describe() const { return QLatin1String("set page ") + QString::number(page); }
1601 int page;
1602public:
1603 static QSharedPointer<SetPage> create(int page)
1604 {
1605 QSharedPointer<SetPage> o = QSharedPointer<SetPage>::create();
1606 o->page = page;
1607 return o;
1608 }
1609};
1610
1611class SetStyle : public Operation
1612{
1613 void apply(QWizard *wizard) const { wizard->setWizardStyle(style); }
1614 QString describe() const { return QLatin1String("set style ") + QString::number(style); }
1615 QWizard::WizardStyle style;
1616public:
1617 static QSharedPointer<SetStyle> create(QWizard::WizardStyle style)
1618 {
1619 QSharedPointer<SetStyle> o = QSharedPointer<SetStyle>::create();
1620 o->style = style;
1621 return o;
1622 }
1623};
1624
1625class SetOption : public Operation
1626{
1627 void apply(QWizard *wizard) const { wizard->setOption(option, on); }
1628 QString describe() const;
1629 QWizard::WizardOption option;
1630 bool on;
1631public:
1632 static QSharedPointer<SetOption> create(QWizard::WizardOption option, bool on)
1633 {
1634 QSharedPointer<SetOption> o = QSharedPointer<SetOption>::create();
1635 o->option = option;
1636 o->on = on;
1637 return o;
1638 }
1639};
1640
1641class OptionInfo
1642{
1643 OptionInfo()
1644 {
1645 tags[QWizard::IndependentPages] = "0/IPP";
1646 tags[QWizard::IgnoreSubTitles] = "1/IST";
1647 tags[QWizard::ExtendedWatermarkPixmap] = "2/EWP";
1648 tags[QWizard::NoDefaultButton] = "3/NDB";
1649 tags[QWizard::NoBackButtonOnStartPage] = "4/BSP";
1650 tags[QWizard::NoBackButtonOnLastPage] = "5/BLP";
1651 tags[QWizard::DisabledBackButtonOnLastPage] = "6/DLP";
1652 tags[QWizard::HaveNextButtonOnLastPage] = "7/NLP";
1653 tags[QWizard::HaveFinishButtonOnEarlyPages] = "8/FEP";
1654 tags[QWizard::NoCancelButton] = "9/NCB";
1655 tags[QWizard::CancelButtonOnLeft] = "10/CBL";
1656 tags[QWizard::HaveHelpButton] = "11/HHB";
1657 tags[QWizard::HelpButtonOnRight] = "12/HBR";
1658 tags[QWizard::HaveCustomButton1] = "13/CB1";
1659 tags[QWizard::HaveCustomButton2] = "14/CB2";
1660 tags[QWizard::HaveCustomButton3] = "15/CB3";
1661
1662 for (int i = 0; i < 2; ++i) {
1663 QMap<QWizard::WizardOption, QSharedPointer<Operation> > operations_;
1664 foreach (QWizard::WizardOption option, tags.keys())
1665 operations_[option] = SetOption::create(option, on: i == 1);
1666 operations << operations_;
1667 }
1668 }
1669 OptionInfo(OptionInfo const&);
1670 OptionInfo& operator=(OptionInfo const&);
1671 QMap<QWizard::WizardOption, QString> tags;
1672 QList<QMap<QWizard::WizardOption, QSharedPointer<Operation> > > operations;
1673public:
1674 static OptionInfo &instance()
1675 {
1676 static OptionInfo optionInfo;
1677 return optionInfo;
1678 }
1679
1680 QString tag(QWizard::WizardOption option) const { return tags.value(akey: option); }
1681 QSharedPointer<Operation> operation(QWizard::WizardOption option, bool on) const
1682 { return operations.at(i: on).value(akey: option); }
1683 QList<QWizard::WizardOption> options() const { return tags.keys(); }
1684};
1685
1686QString SetOption::describe() const
1687{
1688 return QLatin1String("set opt ") + OptionInfo::instance().tag(option)
1689 + QLatin1Char(on ? '1' : '0');
1690}
1691
1692Q_DECLARE_METATYPE(QVector<QSharedPointer<Operation> >)
1693
1694class TestGroup
1695{
1696public:
1697 enum Type {Equality, NonEquality};
1698
1699 TestGroup(const QString &name = QString("no name"), Type type = Equality)
1700 : name(name), type(type), nRows_(0) {}
1701
1702 void reset(const QString &name, Type type = Equality)
1703 {
1704 this->name = name;
1705 this->type = type;
1706 combinations.clear();
1707 }
1708
1709 QVector<QSharedPointer<Operation> > &add()
1710 {
1711 combinations.resize(size: combinations.size() + 1);
1712 return combinations.last();
1713 }
1714
1715 void createTestRows()
1716 {
1717 for (int i = 0; i < combinations.count(); ++i) {
1718 QTest::newRow(dataTag: (name.toLatin1() + ", row " + QByteArray::number(i)).constData())
1719 << (i == 0) << (type == Equality) << combinations.at(i);
1720 ++nRows_;
1721 }
1722 }
1723
1724 int nRows() const { return nRows_; }
1725
1726private:
1727 QString name;
1728 Type type;
1729 int nRows_;
1730 QVector<QVector<QSharedPointer<Operation> > > combinations;
1731};
1732
1733class IntroPage : public QWizardPage
1734{
1735 Q_OBJECT
1736public:
1737 IntroPage()
1738 {
1739 setTitle(tr(s: "Intro"));
1740 setSubTitle(tr(s: "Intro Subtitle"));
1741 QVBoxLayout *layout = new QVBoxLayout;
1742 layout->addWidget(new QLabel(tr(s: "Intro Label")));
1743 setLayout(layout);
1744 }
1745};
1746
1747class MiddlePage : public QWizardPage
1748{
1749 Q_OBJECT
1750public:
1751 MiddlePage()
1752 {
1753 setTitle(tr(s: "Middle"));
1754 setSubTitle(tr(s: "Middle Subtitle"));
1755 QVBoxLayout *layout = new QVBoxLayout;
1756 layout->addWidget(new QLabel(tr(s: "Middle Label")));
1757 setLayout(layout);
1758 }
1759};
1760
1761class ConclusionPage : public QWizardPage
1762{
1763 Q_OBJECT
1764public:
1765 ConclusionPage()
1766 {
1767 setTitle(tr(s: "Conclusion"));
1768 setSubTitle(tr(s: "Conclusion Subtitle"));
1769 QVBoxLayout *layout = new QVBoxLayout;
1770 layout->addWidget(new QLabel(tr(s: "Conclusion Label")));
1771 setLayout(layout);
1772 }
1773};
1774
1775class TestWizard : public QWizard
1776{
1777 Q_OBJECT
1778 QList<int> pageIds;
1779 QString opsDescr;
1780public:
1781 TestWizard()
1782 {
1783 setPixmap(which: QWizard::BannerPixmap, pixmap: QPixmap(":/images/banner.png"));
1784 setPixmap(which: QWizard::BackgroundPixmap, pixmap: QPixmap(":/images/background.png"));
1785 setPixmap(which: QWizard::WatermarkPixmap, pixmap: QPixmap(":/images/watermark.png"));
1786 setPixmap(which: QWizard::LogoPixmap, pixmap: QPixmap(":/images/logo.png"));
1787 setButtonText(which: QWizard::CustomButton1, text: "custom 1");
1788 setButtonText(which: QWizard::CustomButton2, text: "custom 2");
1789 setButtonText(which: QWizard::CustomButton3, text: "custom 3");
1790 pageIds << addPage(page: new IntroPage);
1791 pageIds << addPage(page: new MiddlePage);
1792 pageIds << addPage(page: new ConclusionPage);
1793
1794 // Disable antialiased font rendering since this may sometimes result in tiny
1795 // and (apparent) non-deterministic pixel variations between images expected to be
1796 // identical. This may only be a problem on X11.
1797 QFont f = font();
1798 f.setStyleStrategy(QFont::NoAntialias);
1799 setFont(f);
1800
1801 // ### Required to work with a deficiency(?) in QWizard:
1802// setFixedSize(800, 600);
1803 }
1804
1805 ~TestWizard()
1806 {
1807 foreach (int id, pageIds) {
1808 QWizardPage *page_to_delete = page(id);
1809 removePage(id);
1810 delete page_to_delete;
1811 }
1812 }
1813
1814 void applyOperations(const QVector<QSharedPointer<Operation> > &operations)
1815 {
1816 foreach (const QSharedPointer<Operation> &op, operations) {
1817 if (op) {
1818 op->apply(this);
1819 opsDescr += QLatin1Char('(') + op->describe() + QLatin1String(") ");
1820 }
1821 }
1822 }
1823
1824 QImage createImage() const
1825 {
1826 return const_cast<TestWizard *>(this)->grab()
1827 .toImage().convertToFormat(f: QImage::Format_ARGB32);
1828 }
1829
1830 QString operationsDescription() const { return opsDescr; }
1831};
1832
1833class CombinationsTestData
1834{
1835 TestGroup testGroup;
1836 QVector<QSharedPointer<Operation> > pageOps;
1837 QVector<QSharedPointer<Operation> > styleOps;
1838 QMap<bool, QVector<QSharedPointer<Operation> > > setAllOptions;
1839public:
1840 CombinationsTestData()
1841 {
1842 QTest::addColumn<bool>(name: "ref");
1843 QTest::addColumn<bool>(name: "testEquality");
1844 QTest::addColumn<QVector<QSharedPointer<Operation> > >(name: "operations");
1845 pageOps << SetPage::create(page: 0) << SetPage::create(page: 1) << SetPage::create(page: 2);
1846 styleOps << SetStyle::create(style: QWizard::ClassicStyle) << SetStyle::create(style: QWizard::ModernStyle)
1847 << SetStyle::create(style: QWizard::MacStyle);
1848#define SETPAGE(page) pageOps.at(page)
1849#define SETSTYLE(style) styleOps.at(style)
1850#define OPT(option, on) OptionInfo::instance().operation(option, on)
1851#define CLROPT(option) OPT(option, false)
1852#define SETOPT(option) OPT(option, true)
1853 foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
1854 setAllOptions[false] << CLROPT(option);
1855 setAllOptions[true] << SETOPT(option);
1856 }
1857#define CLRALLOPTS setAllOptions.value(false)
1858#define SETALLOPTS setAllOptions.value(true)
1859 }
1860
1861 int nRows() const { return testGroup.nRows(); }
1862
1863 // Creates "all" possible test rows. (WARNING: This typically makes the test take too long!)
1864 void createAllTestRows()
1865 {
1866 testGroup.reset(name: "testAll 1.1");
1867 testGroup.add(); // i.e. no operations applied!
1868 testGroup.add() << SETPAGE(0);
1869 testGroup.add() << SETSTYLE(0);
1870 testGroup.add() << SETPAGE(0) << SETSTYLE(0);
1871 testGroup.add() << SETSTYLE(0) << SETPAGE(0);
1872 testGroup.createTestRows();
1873
1874 testGroup.reset(name: "testAll 2.1");
1875 testGroup.add();
1876 testGroup.add() << CLRALLOPTS;
1877 testGroup.createTestRows();
1878
1879 testGroup.reset(name: "testAll 2.2");
1880 testGroup.add() << SETALLOPTS;
1881 testGroup.add() << SETALLOPTS << SETALLOPTS;
1882 testGroup.createTestRows();
1883
1884 testGroup.reset(name: "testAll 2.3");
1885 testGroup.add() << CLRALLOPTS;
1886 testGroup.add() << CLRALLOPTS << CLRALLOPTS;
1887 testGroup.createTestRows();
1888
1889 testGroup.reset(name: "testAll 2.4");
1890 testGroup.add() << CLRALLOPTS;
1891 testGroup.add() << SETALLOPTS << CLRALLOPTS;
1892 testGroup.createTestRows();
1893
1894 testGroup.reset(name: "testAll 2.5");
1895 testGroup.add() << SETALLOPTS;
1896 testGroup.add() << CLRALLOPTS << SETALLOPTS;
1897 testGroup.createTestRows();
1898
1899 testGroup.reset(name: "testAll 2.6");
1900 testGroup.add() << SETALLOPTS;
1901 testGroup.add() << SETALLOPTS << CLRALLOPTS << SETALLOPTS;
1902 testGroup.createTestRows();
1903
1904 testGroup.reset(name: "testAll 2.7");
1905 testGroup.add() << CLRALLOPTS;
1906 testGroup.add() << CLRALLOPTS << SETALLOPTS << CLRALLOPTS;
1907 testGroup.createTestRows();
1908
1909 for (int i = 0; i < 2; ++i) {
1910 QVector<QSharedPointer<Operation> > setOptions = setAllOptions.value(akey: i == 1);
1911
1912 testGroup.reset(name: "testAll 3.1");
1913 testGroup.add() << setOptions;
1914 testGroup.add() << SETPAGE(0) << setOptions;
1915 testGroup.add() << setOptions << SETPAGE(0);
1916 testGroup.add() << SETSTYLE(0) << setOptions;
1917 testGroup.add() << setOptions << SETSTYLE(0);
1918 testGroup.add() << setOptions << SETPAGE(0) << SETSTYLE(0);
1919 testGroup.add() << SETPAGE(0) << setOptions << SETSTYLE(0);
1920 testGroup.add() << SETPAGE(0) << SETSTYLE(0) << setOptions;
1921 testGroup.add() << setOptions << SETSTYLE(0) << SETPAGE(0);
1922 testGroup.add() << SETSTYLE(0) << setOptions << SETPAGE(0);
1923 testGroup.add() << SETSTYLE(0) << SETPAGE(0) << setOptions;
1924 testGroup.createTestRows();
1925 }
1926
1927 foreach (const QSharedPointer<Operation> &pageOp, pageOps) {
1928 testGroup.reset(name: "testAll 4.1");
1929 testGroup.add() << pageOp;
1930 testGroup.add() << pageOp << pageOp;
1931 testGroup.createTestRows();
1932
1933 for (int i = 0; i < 2; ++i) {
1934 QVector<QSharedPointer<Operation> > optionOps = setAllOptions.value(akey: i == 1);
1935 testGroup.reset(name: "testAll 4.2");
1936 testGroup.add() << optionOps << pageOp;
1937 testGroup.add() << pageOp << optionOps;
1938 testGroup.createTestRows();
1939
1940 foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
1941 QSharedPointer<Operation> optionOp = OPT(option, i == 1);
1942 testGroup.reset(name: "testAll 4.3");
1943 testGroup.add() << optionOp << pageOp;
1944 testGroup.add() << pageOp << optionOp;
1945 testGroup.createTestRows();
1946 }
1947 }
1948 }
1949
1950 foreach (const QSharedPointer<Operation> &styleOp, styleOps) {
1951 testGroup.reset(name: "testAll 5.1");
1952 testGroup.add() << styleOp;
1953 testGroup.add() << styleOp << styleOp;
1954 testGroup.createTestRows();
1955
1956 for (int i = 0; i < 2; ++i) {
1957 QVector<QSharedPointer<Operation> > optionOps = setAllOptions.value(akey: i == 1);
1958 testGroup.reset(name: "testAll 5.2");
1959 testGroup.add() << optionOps << styleOp;
1960 testGroup.add() << styleOp << optionOps;
1961 testGroup.createTestRows();
1962
1963 foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
1964 QSharedPointer<Operation> optionOp = OPT(option, i == 1);
1965 testGroup.reset(name: "testAll 5.3");
1966 testGroup.add() << optionOp << styleOp;
1967 testGroup.add() << styleOp << optionOp;
1968 testGroup.createTestRows();
1969 }
1970 }
1971 }
1972
1973 foreach (const QSharedPointer<Operation> &pageOp, pageOps) {
1974 foreach (const QSharedPointer<Operation> &styleOp, styleOps) {
1975
1976 testGroup.reset(name: "testAll 6.1");
1977 testGroup.add() << pageOp;
1978 testGroup.add() << pageOp << pageOp;
1979 testGroup.createTestRows();
1980
1981 testGroup.reset(name: "testAll 6.2");
1982 testGroup.add() << styleOp;
1983 testGroup.add() << styleOp << styleOp;
1984 testGroup.createTestRows();
1985
1986 testGroup.reset(name: "testAll 6.3");
1987 testGroup.add() << pageOp << styleOp;
1988 testGroup.add() << styleOp << pageOp;
1989 testGroup.createTestRows();
1990
1991 for (int i = 0; i < 2; ++i) {
1992 QVector<QSharedPointer<Operation> > optionOps = setAllOptions.value(akey: i == 1);
1993 testGroup.reset(name: "testAll 6.4");
1994 testGroup.add() << optionOps << pageOp << styleOp;
1995 testGroup.add() << pageOp << optionOps << styleOp;
1996 testGroup.add() << pageOp << styleOp << optionOps;
1997 testGroup.add() << optionOps << styleOp << pageOp;
1998 testGroup.add() << styleOp << optionOps << pageOp;
1999 testGroup.add() << styleOp << pageOp << optionOps;
2000 testGroup.createTestRows();
2001
2002 foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
2003 QSharedPointer<Operation> optionOp = OPT(option, i == 1);
2004 testGroup.reset(name: "testAll 6.5");
2005 testGroup.add() << optionOp << pageOp << styleOp;
2006 testGroup.add() << pageOp << optionOp << styleOp;
2007 testGroup.add() << pageOp << styleOp << optionOp;
2008 testGroup.add() << optionOp << styleOp << pageOp;
2009 testGroup.add() << styleOp << optionOp << pageOp;
2010 testGroup.add() << styleOp << pageOp << optionOp;
2011 testGroup.createTestRows();
2012 }
2013 }
2014 }
2015 }
2016
2017 testGroup.reset(name: "testAll 7.1", type: TestGroup::NonEquality);
2018 testGroup.add() << SETPAGE(0);
2019 testGroup.add() << SETPAGE(1);
2020 testGroup.add() << SETPAGE(2);
2021 testGroup.createTestRows();
2022
2023 testGroup.reset(name: "testAll 7.2", type: TestGroup::NonEquality);
2024 testGroup.add() << SETSTYLE(0);
2025 testGroup.add() << SETSTYLE(1);
2026 testGroup.add() << SETSTYLE(2);
2027 testGroup.createTestRows();
2028
2029 // more to follow ...
2030 }
2031
2032 // Creates a "small" number of interesting test rows.
2033 void createTestRows1()
2034 {
2035 testGroup.reset(name: "test1 1");
2036 testGroup.add() << SETPAGE(0) << SETOPT(QWizard::HaveCustomButton3);
2037 testGroup.add() << SETOPT(QWizard::HaveCustomButton3);
2038 testGroup.createTestRows();
2039
2040 testGroup.reset(name: "test1 2");
2041 testGroup.add() << SETOPT(QWizard::HaveFinishButtonOnEarlyPages) << SETPAGE(0);
2042 testGroup.add() << SETPAGE(0) << SETOPT(QWizard::HaveFinishButtonOnEarlyPages);
2043 testGroup.createTestRows();
2044
2045 testGroup.reset(name: "test1 3");
2046 testGroup.add() << SETPAGE(2) << SETOPT(QWizard::HaveNextButtonOnLastPage);
2047 testGroup.add() << SETOPT(QWizard::HaveNextButtonOnLastPage) << SETPAGE(2);
2048 testGroup.createTestRows();
2049 }
2050};
2051
2052void tst_QWizard::combinations_data()
2053{
2054 CombinationsTestData combTestData;
2055// combTestData.createAllTestRows();
2056 combTestData.createTestRows1();
2057
2058// qDebug() << "test rows:" << combTestData.nRows();
2059}
2060
2061void tst_QWizard::combinations()
2062{
2063 QFETCH(bool, ref);
2064 QFETCH(bool, testEquality);
2065 QFETCH(QVector<QSharedPointer<Operation> >, operations);
2066
2067 TestWizard wizard;
2068#if !defined(QT_NO_STYLE_WINDOWSVISTA)
2069 if (wizard.wizardStyle() == QWizard::AeroStyle)
2070 return; // ### TODO: passes/fails in a unpredictable way, so disable for now
2071#endif
2072 wizard.applyOperations(operations);
2073 wizard.show(); // ### TODO: Required, but why? Should wizard.createImage() care?
2074
2075 static QImage refImage;
2076 static QSize refMinSize;
2077 static QString refDescr;
2078
2079 if (ref) {
2080 refImage = wizard.createImage();
2081 refMinSize = wizard.minimumSizeHint();
2082 refDescr = wizard.operationsDescription();
2083 return;
2084 }
2085
2086 QImage image = wizard.createImage();
2087
2088 bool minSizeTest = wizard.minimumSizeHint() != refMinSize;
2089 bool imageTest = image != refImage;
2090 QLatin1String otor("!=");
2091 QLatin1String reason("differ");
2092
2093 if (!testEquality) {
2094 minSizeTest = false; // the image test is sufficient!
2095 imageTest = !imageTest;
2096 otor = QLatin1String("==");
2097 reason = QLatin1String("are equal");
2098 }
2099
2100 if (minSizeTest)
2101 qDebug() << "minimum sizes" << reason.latin1() << ';' << wizard.minimumSizeHint()
2102 << otor.latin1() << refMinSize;
2103
2104 if (imageTest)
2105 qDebug() << "images" << reason.latin1();
2106
2107 if (minSizeTest || imageTest) {
2108 qDebug() << "\t row 0 operations:" << refDescr.toLatin1();
2109 qDebug() << "\tcurrent row operations:" << wizard.operationsDescription().toLatin1();
2110 QVERIFY(false);
2111 }
2112}
2113
2114class WizardPage : public QWizardPage
2115{
2116 Q_OBJECT
2117 bool shown_;
2118 void showEvent(QShowEvent *) { shown_ = true; }
2119 void hideEvent(QHideEvent *) { shown_ = false; }
2120public:
2121 WizardPage() : shown_(false) {}
2122 bool shown() const { return shown_; }
2123};
2124
2125class WizardPages
2126{
2127 QList<WizardPage *> pages;
2128public:
2129 void add(WizardPage *page) { pages << page; }
2130 QList<WizardPage *> all() const { return pages; }
2131 QList<WizardPage *> shown() const
2132 {
2133 QList<WizardPage *> result;
2134 foreach (WizardPage *page, pages)
2135 if (page->shown())
2136 result << page;
2137 return result;
2138 }
2139};
2140
2141void tst_QWizard::showCurrentPageOnly()
2142{
2143 QWizard wizard;
2144 WizardPages pages;
2145 for (int i = 0; i < 5; ++i) {
2146 pages.add(page: new WizardPage);
2147 wizard.addPage(page: pages.all().last());
2148 }
2149
2150 wizard.show();
2151
2152 QCOMPARE(pages.shown().count(), 1);
2153 QCOMPARE(pages.shown().first(), pages.all().first());
2154
2155 const int steps = 2;
2156 for (int i = 0; i < steps; ++i)
2157 wizard.next();
2158
2159 QCOMPARE(pages.shown().count(), 1);
2160 QCOMPARE(pages.shown().first(), pages.all().at(steps));
2161
2162 wizard.restart();
2163
2164 QCOMPARE(pages.shown().count(), 1);
2165 QCOMPARE(pages.shown().first(), pages.all().first());
2166}
2167
2168void tst_QWizard::setButtonText()
2169{
2170 QWizard wizard;
2171 wizard.setWizardStyle(QWizard::ClassicStyle);
2172 QWizardPage* page1 = new QWizardPage;
2173 QWizardPage* page2 = new QWizardPage;
2174 wizard.addPage(page: page1);
2175 wizard.addPage(page: page2);
2176
2177 wizard.show();
2178 qApp->processEvents();
2179 QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
2180 QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
2181 QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next"));
2182 QVERIFY(page2->buttonText(QWizard::NextButton).contains("Next"));
2183
2184 page2->setButtonText(which: QWizard::NextButton, text: "Page2");
2185 QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
2186 QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
2187 QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next"));
2188 QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
2189
2190 wizard.next();
2191 qApp->processEvents();
2192 QCOMPARE(wizard.button(QWizard::NextButton)->text(), QString("Page2"));
2193 QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
2194 QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next"));
2195 QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
2196
2197 wizard.back();
2198 qApp->processEvents();
2199 QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
2200 QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
2201 QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next"));
2202 QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
2203
2204 wizard.setButtonText(which: QWizard::NextButton, text: "Wizard");
2205 QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Wizard"));
2206 QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("Wizard"));
2207 QCOMPARE(page1->buttonText(QWizard::NextButton), QString("Wizard"));
2208 QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
2209
2210 wizard.next();
2211 qApp->processEvents();
2212 QCOMPARE(wizard.button(QWizard::NextButton)->text(), QString("Page2"));
2213 QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Wizard"));
2214 QCOMPARE(page1->buttonText(QWizard::NextButton), QString("Wizard"));
2215 QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
2216}
2217
2218void tst_QWizard::setCommitPage()
2219{
2220 QWizard wizard;
2221 QWizardPage* page1 = new QWizardPage;
2222 QWizardPage* page2 = new QWizardPage;
2223 wizard.addPage(page: page1);
2224 wizard.addPage(page: page2);
2225 wizard.show();
2226 qApp->processEvents();
2227
2228 QVERIFY(!page1->isCommitPage());
2229 QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
2230
2231 wizard.next();
2232 QVERIFY(wizard.button(QWizard::BackButton)->isEnabled());
2233
2234 page1->setCommitPage(true);
2235 QVERIFY(page1->isCommitPage());
2236
2237 wizard.back();
2238 QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
2239
2240 wizard.next();
2241 QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
2242
2243 page1->setCommitPage(false);
2244 QVERIFY(!page1->isCommitPage());
2245
2246 wizard.back();
2247 QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
2248
2249 wizard.next();
2250 QVERIFY(wizard.button(QWizard::BackButton)->isEnabled());
2251
2252 // ### test relabeling of the Cancel button to "Close" once this is implemented
2253}
2254
2255void tst_QWizard::setWizardStyle()
2256{
2257 QWizard wizard;
2258 wizard.addPage(page: new QWizardPage);
2259 wizard.show();
2260 qApp->processEvents();
2261
2262 // defaults
2263 const bool styleHintMatch =
2264 wizard.wizardStyle() ==
2265 QWizard::WizardStyle(wizard.style()->styleHint(stylehint: QStyle::SH_WizardStyle, opt: 0, widget: &wizard));
2266#if !defined(QT_NO_STYLE_WINDOWSVISTA)
2267 QVERIFY(styleHintMatch || wizard.wizardStyle() == QWizard::AeroStyle);
2268#else
2269 QVERIFY(styleHintMatch);
2270#endif
2271
2272 // set/get consistency
2273 for (int wstyle = 0; wstyle < QWizard::NStyles; ++wstyle) {
2274 wizard.setWizardStyle((QWizard::WizardStyle)wstyle);
2275 QCOMPARE((int)wizard.wizardStyle(), wstyle);
2276 }
2277}
2278
2279void tst_QWizard::removePage()
2280{
2281 QWizard wizard;
2282 QWizardPage *page0 = new QWizardPage;
2283 QWizardPage *page1 = new QWizardPage;
2284 QWizardPage *page2 = new QWizardPage;
2285 QWizardPage *page3 = new QWizardPage;
2286 QSignalSpy spy(&wizard, SIGNAL(pageRemoved(int)));
2287
2288 wizard.setPage(id: 0, page: page0);
2289 wizard.setPage(id: 1, page: page1);
2290 wizard.setPage(id: 2, page: page2);
2291 wizard.setPage(id: 3, page: page3);
2292
2293 wizard.restart();
2294 QCOMPARE(wizard.pageIds().size(), 4);
2295 QCOMPARE(wizard.visitedIds().size(), 1);
2296 QCOMPARE(spy.count(), 0);
2297
2298 // Removing a non-existent page
2299 wizard.removePage(id: 4);
2300 QCOMPARE(wizard.pageIds().size(), 4);
2301 QCOMPARE(spy.count(), 0);
2302
2303 // Removing and then reinserting a page
2304 QCOMPARE(wizard.pageIds().size(), 4);
2305 QVERIFY(wizard.pageIds().contains(2));
2306 wizard.removePage(id: 2);
2307 QCOMPARE(spy.count(), 1);
2308 QList<QVariant> arguments = spy.takeFirst();
2309 QCOMPARE(arguments.at(0).toInt(), 2);
2310 QCOMPARE(wizard.pageIds().size(), 3);
2311 QVERIFY(!wizard.pageIds().contains(2));
2312 wizard.setPage(id: 2, page: page2);
2313 QCOMPARE(spy.count(), 0);
2314 QCOMPARE(wizard.pageIds().size(), 4);
2315 QVERIFY(wizard.pageIds().contains(2));
2316
2317 // Removing the same page twice
2318 wizard.removePage(id: 2); // restore
2319 QCOMPARE(spy.count(), 1);
2320 arguments = spy.takeFirst();
2321 QCOMPARE(arguments.at(0).toInt(), 2);
2322 QCOMPARE(wizard.pageIds().size(), 3);
2323 QVERIFY(!wizard.pageIds().contains(2));
2324 wizard.removePage(id: 2);
2325 QCOMPARE(spy.count(), 0);
2326 QCOMPARE(wizard.pageIds().size(), 3);
2327 QVERIFY(!wizard.pageIds().contains(2));
2328
2329 // Removing a page not in the history
2330 wizard.setPage(id: 2, page: page2); // restore
2331 wizard.restart();
2332 wizard.next();
2333 QCOMPARE(wizard.visitedIds().size(), 2);
2334 QCOMPARE(wizard.currentPage(), page1);
2335 QCOMPARE(spy.count(), 0);
2336 wizard.removePage(id: 2);
2337 QCOMPARE(spy.count(), 1);
2338 arguments = spy.takeFirst();
2339 QCOMPARE(arguments.at(0).toInt(), 2);
2340 QCOMPARE(wizard.visitedIds().size(), 2);
2341 QVERIFY(!wizard.pageIds().contains(2));
2342 QCOMPARE(wizard.currentPage(), page1);
2343
2344 // Removing a page in the history before the current page
2345 wizard.setPage(id: 2, page: page2); // restore
2346 wizard.restart();
2347 wizard.next();
2348 QCOMPARE(spy.count(), 0);
2349 QCOMPARE(wizard.visitedIds().size(), 2);
2350 QCOMPARE(wizard.currentPage(), page1);
2351 wizard.removePage(id: 0);
2352 QCOMPARE(spy.count(), 1);
2353 arguments = spy.takeFirst();
2354 QCOMPARE(arguments.at(0).toInt(), 0);
2355 QCOMPARE(wizard.visitedIds().size(), 1);
2356 QVERIFY(!wizard.visitedIds().contains(0));
2357 QVERIFY(!wizard.pageIds().contains(0));
2358 QCOMPARE(wizard.currentPage(), page1);
2359
2360 // Remove the current page which is not the first one in the history
2361 wizard.setPage(id: 0, page: page0); // restore
2362 wizard.restart();
2363 wizard.next();
2364 QCOMPARE(spy.count(), 0);
2365 QCOMPARE(wizard.visitedIds().size(), 2);
2366 QCOMPARE(wizard.currentPage(), page1);
2367 wizard.removePage(id: 1);
2368 QCOMPARE(spy.count(), 1);
2369 arguments = spy.takeFirst();
2370 QCOMPARE(arguments.at(0).toInt(), 1);
2371 QCOMPARE(wizard.visitedIds().size(), 1);
2372 QVERIFY(!wizard.visitedIds().contains(1));
2373 QVERIFY(!wizard.pageIds().contains(1));
2374 QCOMPARE(wizard.currentPage(), page0);
2375
2376 // Remove the current page which is the first (and only) one in the history
2377 wizard.removePage(id: 0);
2378 QCOMPARE(spy.count(), 1);
2379 arguments = spy.takeFirst();
2380 QCOMPARE(arguments.at(0).toInt(), 0);
2381 QCOMPARE(wizard.visitedIds().size(), 1);
2382 QVERIFY(!wizard.visitedIds().contains(0));
2383 QCOMPARE(wizard.pageIds().size(), 2);
2384 QVERIFY(!wizard.pageIds().contains(0));
2385 QCOMPARE(wizard.currentPage(), page2);
2386 //
2387 wizard.removePage(id: 2);
2388 QCOMPARE(spy.count(), 1);
2389 arguments = spy.takeFirst();
2390 QCOMPARE(arguments.at(0).toInt(), 2);
2391 QCOMPARE(wizard.visitedIds().size(), 1);
2392 QVERIFY(!wizard.visitedIds().contains(2));
2393 QCOMPARE(wizard.pageIds().size(), 1);
2394 QVERIFY(!wizard.pageIds().contains(2));
2395 QCOMPARE(wizard.currentPage(), page3);
2396 //
2397 wizard.removePage(id: 3);
2398 QCOMPARE(spy.count(), 1);
2399 arguments = spy.takeFirst();
2400 QCOMPARE(arguments.at(0).toInt(), 3);
2401 QVERIFY(wizard.visitedIds().empty());
2402 QVERIFY(wizard.pageIds().empty());
2403 QCOMPARE(wizard.currentPage(), nullptr);
2404}
2405
2406void tst_QWizard::sideWidget()
2407{
2408 QWizard wizard;
2409
2410 wizard.setSideWidget(0);
2411 QVERIFY(!wizard.sideWidget());
2412 QScopedPointer<QWidget> w1(new QWidget(&wizard));
2413 wizard.setSideWidget(w1.data());
2414 QCOMPARE(wizard.sideWidget(), w1.data());
2415 QWidget *w2 = new QWidget(&wizard);
2416 wizard.setSideWidget(w2);
2417 QCOMPARE(wizard.sideWidget(), w2);
2418 QVERIFY(w1->parent() != 0);
2419 QCOMPARE(w1->window(), static_cast<QWidget *>(&wizard));
2420 QCOMPARE(w2->window(), static_cast<QWidget *>(&wizard));
2421 w1->setParent(0);
2422 wizard.setSideWidget(0);
2423 QVERIFY(!wizard.sideWidget());
2424}
2425
2426void tst_QWizard::objectNames_data()
2427{
2428 QTest::addColumn<QWizard::WizardButton>(name: "wizardButton");
2429 QTest::addColumn<QString>(name: "buttonName");
2430
2431 QTest::newRow(dataTag: "BackButton") << QWizard::BackButton << QStringLiteral("__qt__passive_wizardbutton0");
2432 QTest::newRow(dataTag: "NextButton") << QWizard::NextButton << QStringLiteral("__qt__passive_wizardbutton1");
2433 QTest::newRow(dataTag: "CommitButton") << QWizard::CommitButton << QStringLiteral("qt_wizard_commit");
2434 QTest::newRow(dataTag: "FinishButton") << QWizard::FinishButton << QStringLiteral("qt_wizard_finish");
2435 QTest::newRow(dataTag: "CancelButton") << QWizard::CancelButton << QStringLiteral("qt_wizard_cancel");
2436 QTest::newRow(dataTag: "HelpButton") << QWizard::HelpButton << QStringLiteral("__qt__passive_wizardbutton5");
2437 QTest::newRow(dataTag: "CustomButton1") << QWizard::CustomButton1 << QStringLiteral("__qt__passive_wizardbutton6");
2438 QTest::newRow(dataTag: "CustomButton2") << QWizard::CustomButton2 << QStringLiteral("__qt__passive_wizardbutton7");
2439 QTest::newRow(dataTag: "CustomButton3") << QWizard::CustomButton3 << QStringLiteral("__qt__passive_wizardbutton8");
2440}
2441
2442void tst_QWizard::objectNames()
2443{
2444 QFETCH(QWizard::WizardButton, wizardButton);
2445 QFETCH(QString, buttonName);
2446
2447 QWizard wizard;
2448 QList<QWizard::WizardButton> buttons = QList<QWizard::WizardButton>()
2449 << QWizard::BackButton
2450 << QWizard::NextButton
2451 << QWizard::CommitButton
2452 << QWizard::FinishButton
2453 << QWizard::CancelButton
2454 << QWizard::HelpButton
2455 << QWizard::CustomButton1
2456 << QWizard::CustomButton2
2457 << QWizard::CustomButton3
2458 ;
2459 QVERIFY(buttons.contains(wizardButton));
2460 QVERIFY(wizard.button(wizardButton));
2461 QCOMPARE(wizard.button(wizardButton)->objectName(), buttonName);
2462}
2463
2464class task177716_CommitPage : public QWizardPage
2465{
2466 Q_OBJECT
2467public:
2468 task177716_CommitPage()
2469 {
2470 setCommitPage(true);
2471 QVBoxLayout *layout = new QVBoxLayout;
2472 ledit = new QLineEdit(this);
2473 registerField(name: "foo*", widget: ledit);
2474 layout->addWidget(ledit);
2475 setLayout(layout);
2476 }
2477 QLineEdit *ledit;
2478};
2479
2480void tst_QWizard::task177716_disableCommitButton()
2481{
2482 QWizard wizard;
2483 task177716_CommitPage *commitPage = new task177716_CommitPage;
2484 wizard.addPage(page: commitPage);
2485 // the following page must be there to prevent the first page from replacing the Commit button
2486 // with the Finish button:
2487 wizard.addPage(page: new QWizardPage);
2488 wizard.show();
2489 QVERIFY(!wizard.button(QWizard::CommitButton)->isEnabled());
2490 commitPage->ledit->setText("some non-empty text");
2491 QVERIFY(wizard.button(QWizard::CommitButton)->isEnabled());
2492 commitPage->ledit->setText("");
2493 QVERIFY(!wizard.button(QWizard::CommitButton)->isEnabled());
2494}
2495
2496class WizardPage_task183550 : public QWizardPage
2497{
2498public:
2499 WizardPage_task183550(QWidget *parent = 0)
2500 : QWizardPage(parent)
2501 , treeWidget(new QTreeWidget)
2502 , verticalPolicy(QSizePolicy::MinimumExpanding) {}
2503 void enableVerticalExpansion() { verticalPolicy = QSizePolicy::MinimumExpanding; }
2504 void disableVerticalExpansion() { verticalPolicy = QSizePolicy::Preferred; }
2505 int treeWidgetHeight() const { return treeWidget->height(); }
2506 int treeWidgetSizeHintHeight() const { return treeWidget->sizeHint().height(); }
2507
2508private:
2509 QTreeWidget *treeWidget;
2510 QSizePolicy::Policy verticalPolicy;
2511
2512 void initializePage()
2513 {
2514 if (layout())
2515 delete layout();
2516 if (treeWidget)
2517 delete treeWidget;
2518
2519 QLayout *layout_ = new QVBoxLayout(this);
2520 layout_->addWidget(w: treeWidget = new QTreeWidget);
2521
2522 QSizePolicy policy = sizePolicy();
2523 policy.setVerticalPolicy(verticalPolicy);
2524 treeWidget->setSizePolicy(policy);
2525 }
2526};
2527
2528void tst_QWizard::task183550_stretchFactor()
2529{
2530 QWizard wizard;
2531 WizardPage_task183550 *page1 = new WizardPage_task183550;
2532 WizardPage_task183550 *page2 = new WizardPage_task183550;
2533 wizard.addPage(page: page1);
2534 wizard.addPage(page: page2);
2535 wizard.resize(w: 500, h: 2 * page2->treeWidgetSizeHintHeight());
2536 wizard.show();
2537
2538 QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page1));
2539
2540 // ----
2541 page2->disableVerticalExpansion();
2542 wizard.next();
2543 QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page2));
2544 QCOMPARE(page2->treeWidgetHeight(), page2->treeWidgetSizeHintHeight());
2545
2546 wizard.back();
2547 QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page1));
2548
2549 // ----
2550 page2->enableVerticalExpansion();
2551 wizard.next();
2552 QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page2));
2553 QVERIFY(page2->treeWidgetHeight() >= page2->treeWidgetSizeHintHeight());
2554
2555 wizard.back();
2556 QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page1));
2557
2558 // ----
2559 page2->disableVerticalExpansion();
2560 wizard.next();
2561 QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page2));
2562 QCOMPARE(page2->treeWidgetHeight(), page2->treeWidgetSizeHintHeight());
2563}
2564
2565void tst_QWizard::task161658_alignments()
2566{
2567 QWizard wizard;
2568 wizard.setWizardStyle(QWizard::MacStyle);
2569
2570 QWizardPage page;
2571 page.setTitle("Title");
2572 page.setSubTitle("SUBTITLE#: The subtitle bust be aligned with the rest of the widget");
2573
2574 QLabel label1("Field:");
2575 QLineEdit lineEdit1;
2576 QGridLayout *layout = new QGridLayout;
2577 layout->addWidget(&label1, row: 0, column: 0);
2578 layout->addWidget(&lineEdit1, row: 0, column: 1);
2579 page.setLayout(layout);
2580
2581 int idx = wizard.addPage(page: &page);
2582 wizard.setStartId(idx);
2583 wizard.show();
2584 QVERIFY(QTest::qWaitForWindowExposed(&wizard));
2585
2586 foreach (QLabel *subtitleLabel, wizard.findChildren<QLabel *>()) {
2587 if (subtitleLabel->text().startsWith(s: "SUBTITLE#")) {
2588 QCOMPARE(lineEdit1.mapToGlobal(lineEdit1.contentsRect().bottomRight()).x(),
2589 subtitleLabel->mapToGlobal(subtitleLabel->contentsRect().bottomRight()).x());
2590 return;
2591 }
2592 }
2593 QFAIL("Subtitle label not found");
2594}
2595
2596void tst_QWizard::task177022_setFixedSize()
2597{
2598#ifdef Q_OS_WINRT
2599 QSKIP("Widgets cannot have a fixed size on WinRT.");
2600#endif
2601 int width = 300;
2602 int height = 200;
2603 QWizard wiz;
2604 QWizardPage page1;
2605 QWizardPage page2;
2606 int page1_id = wiz.addPage(page: &page1);
2607 int page2_id = wiz.addPage(page: &page2);
2608 wiz.setFixedSize(w: width, h: height);
2609 if (wiz.wizardStyle() == QWizard::AeroStyle)
2610 QEXPECT_FAIL("", "this probably relates to non-client area hack for AeroStyle titlebar "
2611 "effect; not sure if it qualifies as a bug or not", Continue);
2612 QCOMPARE(wiz.size(), QSize(width, height));
2613 QCOMPARE(wiz.minimumWidth(), width);
2614 QCOMPARE(wiz.minimumHeight(), height);
2615 QCOMPARE(wiz.maximumWidth(), width);
2616 QCOMPARE(wiz.maximumHeight(), height);
2617
2618 wiz.showNormal();
2619 QVERIFY(QTest::qWaitForWindowExposed(&wiz));
2620
2621 QCOMPARE(wiz.size(), QSize(width, height));
2622 QCOMPARE(wiz.minimumWidth(), width);
2623 QCOMPARE(wiz.minimumHeight(), height);
2624 QCOMPARE(wiz.maximumWidth(), width);
2625 QCOMPARE(wiz.maximumHeight(), height);
2626
2627 wiz.next();
2628 QTest::qWait(ms: 100);
2629 QCOMPARE(wiz.size(), QSize(width, height));
2630 QCOMPARE(wiz.minimumWidth(), width);
2631 QCOMPARE(wiz.minimumHeight(), height);
2632 QCOMPARE(wiz.maximumWidth(), width);
2633 QCOMPARE(wiz.maximumHeight(), height);
2634
2635 wiz.removePage(id: page1_id);
2636 wiz.removePage(id: page2_id);
2637}
2638
2639void tst_QWizard::task248107_backButton()
2640{
2641 QWizard wizard;
2642 QWizardPage page1;
2643 QWizardPage page2;
2644 QWizardPage page3;
2645 QWizardPage page4;
2646 wizard.addPage(page: &page1);
2647 wizard.addPage(page: &page2);
2648 wizard.addPage(page: &page3);
2649 wizard.addPage(page: &page4);
2650
2651 wizard.show();
2652 QVERIFY(QTest::qWaitForWindowExposed(&wizard));
2653
2654 QCOMPARE(wizard.currentPage(), &page1);
2655
2656 QTest::mouseClick(widget: wizard.button(which: QWizard::NextButton), button: Qt::LeftButton);
2657 QCOMPARE(wizard.currentPage(), &page2);
2658
2659 QTest::mouseClick(widget: wizard.button(which: QWizard::NextButton), button: Qt::LeftButton);
2660 QCOMPARE(wizard.currentPage(), &page3);
2661
2662 QTest::mouseClick(widget: wizard.button(which: QWizard::NextButton), button: Qt::LeftButton);
2663 QCOMPARE(wizard.currentPage(), &page4);
2664
2665 QTest::mouseClick(widget: wizard.button(which: QWizard::BackButton), button: Qt::LeftButton);
2666 QCOMPARE(wizard.currentPage(), &page3);
2667
2668 QTest::mouseClick(widget: wizard.button(which: QWizard::BackButton), button: Qt::LeftButton);
2669 QCOMPARE(wizard.currentPage(), &page2);
2670
2671 QTest::mouseClick(widget: wizard.button(which: QWizard::BackButton), button: Qt::LeftButton);
2672 QCOMPARE(wizard.currentPage(), &page1);
2673}
2674
2675class WizardPage_task255350 : public QWizardPage
2676{
2677public:
2678 QLineEdit *lineEdit;
2679 WizardPage_task255350()
2680 : lineEdit(new QLineEdit)
2681 {
2682 registerField(name: "dummy*", widget: lineEdit);
2683 }
2684};
2685
2686void tst_QWizard::task255350_fieldObjectDestroyed()
2687{
2688 QWizard wizard;
2689 WizardPage_task255350 *page = new WizardPage_task255350;
2690 int id = wizard.addPage(page);
2691 delete page->lineEdit;
2692 wizard.removePage(id); // don't crash!
2693 delete page;
2694}
2695
2696// Global taskQTBUG_25691_fieldObjectDestroyed2 is defined in
2697// tst_qwizard_2.cpp to avoid cluttering up this file with
2698// the QWizardPage subclasses, etc. required to complete this
2699// test.
2700void taskQTBUG_25691_fieldObjectDestroyed2(void);
2701void tst_QWizard::taskQTBUG_25691_fieldObjectDestroyed2()
2702{
2703 ::taskQTBUG_25691_fieldObjectDestroyed2();
2704}
2705
2706void tst_QWizard::taskQTBUG_46894_nextButtonShortcut()
2707{
2708 for (int i = 0; i < QWizard::NStyles; ++i) {
2709 QWizard wizard;
2710 QWizard::WizardStyle style = static_cast<QWizard::WizardStyle>(i);
2711 wizard.setWizardStyle(style);
2712 wizard.show();
2713 QVERIFY(QTest::qWaitForWindowExposed(&wizard));
2714
2715 QCOMPARE(wizard.button(QWizard::NextButton)->shortcut(),
2716 QKeySequence::mnemonic(wizard.button(QWizard::NextButton)->text()));
2717 }
2718}
2719
2720QTEST_MAIN(tst_QWizard)
2721#include "tst_qwizard.moc"
2722

source code of qtbase/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp