diff -r 000000000000 -r 1918ee327afb tests/auto/qwizard/tst_qwizard.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/auto/qwizard/tst_qwizard.cpp Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,2543 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//TESTED_CLASS= +//TESTED_FILES= + +static QImage grabWidget(QWidget *window) +{ + return QPixmap::grabWidget(window).toImage(); +} + +class tst_QWizard : public QObject +{ + Q_OBJECT + +public: + tst_QWizard(); + +public slots: + void init(); + void cleanup(); + +private slots: + void buttonText(); + void setButtonLayout(); + void setButton(); + void setTitleFormatEtc(); + void setPixmap(); + void setDefaultProperty(); + void addPage(); + void setPage(); + void setStartId(); + void setOption_IndependentPages(); + void setOption_IgnoreSubTitles(); + void setOption_ExtendedWatermarkPixmap(); + void setOption_NoDefaultButton(); + void setOption_NoBackButtonOnStartPage(); + void setOption_NoBackButtonOnLastPage(); + void setOption_DisabledBackButtonOnLastPage(); + void setOption_HaveNextButtonOnLastPage(); + void setOption_HaveFinishButtonOnEarlyPages(); + void setOption_NoCancelButton(); + void setOption_CancelButtonOnLeft(); + void setOption_HaveHelpButton(); + void setOption_HelpButtonOnRight(); + void setOption_HaveCustomButtonX(); + void combinations_data(); + void combinations(); + void showCurrentPageOnly(); + void setButtonText(); + void setCommitPage(); + void setWizardStyle(); + void removePage(); + + // task-specific tests below me: + void task161660_buttonSpacing(); + void task177716_disableCommitButton(); + void task183550_stretchFactor(); + void task161658_alignments(); + void task177022_setFixedSize(); + void task248107_backButton(); + void task255350_fieldObjectDestroyed(); + + /* + Things that could be added: + + 1. Test virtual functions that are called, signals that are + emitted, etc. + + 2. Test QWizardPage more thorougly. + + 3. Test the look and field a bit more (especially the + different wizard styles, and how they interact with + pixmaps, titles, subtitles, etc.). + + 4. Test minimum sizes, sizes, maximum sizes, resizing, etc. + + 5. Try setting various options and wizard styles in various + orders and check that the results are the same every time, + no matter the order in which the properties were set. + + -> Initial version done (tst_QWizard::combinations()) + + 6. Test done() and restart(). + + 7. Test default properties of built-in widgets. + + 8. Test mutual exclusiveness of Next and Commit buttons. + */ +}; + +tst_QWizard::tst_QWizard() +{ +} + +void tst_QWizard::init() +{ +#ifdef Q_OS_WINCE //disable magic for WindowsCE + qApp->setAutoMaximizeThreshold(-1); +#endif +} + +void tst_QWizard::cleanup() +{ +} + +void tst_QWizard::buttonText() +{ + QWizard wizard; + wizard.setWizardStyle(QWizard::ClassicStyle); + + // Check the buttons' original text in Classic and Modern styles. + for (int pass = 0; pass < 2; ++pass) { + QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("< &Back")); + QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next")); + QVERIFY(wizard.buttonText(QWizard::FinishButton).endsWith("Finish")); + QVERIFY(wizard.buttonText(QWizard::CancelButton).endsWith("Cancel")); + QVERIFY(wizard.buttonText(QWizard::HelpButton).endsWith("Help")); + + QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::CustomButton2).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty()); + + // robustness + QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty()); + + wizard.setWizardStyle(QWizard::ModernStyle); + } + + // Check the buttons' original text in Mac style. + wizard.setWizardStyle(QWizard::MacStyle); + + QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("Go Back")); + QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("Continue")); + QCOMPARE(wizard.buttonText(QWizard::FinishButton), QString("Done")); + QCOMPARE(wizard.buttonText(QWizard::CancelButton), QString("Cancel")); + QCOMPARE(wizard.buttonText(QWizard::HelpButton), QString("Help")); + + QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::CustomButton2).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty()); + + // robustness + QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty()); + + // Modify the buttons' text and see what happens. + wizard.setButtonText(QWizard::NextButton, "N&este"); + wizard.setButtonText(QWizard::CustomButton2, "&Cucu"); + wizard.setButtonText(QWizard::Stretch, "Stretch"); + + QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("Go Back")); + QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("N&este")); + QCOMPARE(wizard.buttonText(QWizard::FinishButton), QString("Done")); + QCOMPARE(wizard.buttonText(QWizard::CancelButton), QString("Cancel")); + QCOMPARE(wizard.buttonText(QWizard::HelpButton), QString("Help")); + + QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty()); + QCOMPARE(wizard.buttonText(QWizard::CustomButton2), QString("&Cucu")); + QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty()); + + // robustness + QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty()); + + // Switch back to Classic style and see what happens. + wizard.setWizardStyle(QWizard::ClassicStyle); + + for (int pass = 0; pass < 2; ++pass) { + QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("< &Back")); + QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("N&este")); + QVERIFY(wizard.buttonText(QWizard::FinishButton).endsWith("Finish")); + QVERIFY(wizard.buttonText(QWizard::CancelButton).endsWith("Cancel")); + QVERIFY(wizard.buttonText(QWizard::HelpButton).endsWith("Help")); + + QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty()); + QCOMPARE(wizard.buttonText(QWizard::CustomButton2), QString("&Cucu")); + QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty()); + + // robustness + QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty()); + QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty()); + + wizard.setOptions(QWizard::NoDefaultButton + | QWizard::NoBackButtonOnStartPage + | QWizard::NoBackButtonOnLastPage + | QWizard::DisabledBackButtonOnLastPage + | QWizard::NoCancelButton + | QWizard::CancelButtonOnLeft + | QWizard::HaveHelpButton + | QWizard::HelpButtonOnRight + | QWizard::HaveCustomButton1 + | QWizard::HaveCustomButton2 + | QWizard::HaveCustomButton3); + } +} + +void tst_QWizard::setButtonLayout() +{ + QList layout; + + QWizard wizard; + wizard.setWizardStyle(QWizard::ClassicStyle); + wizard.setOptions(0); + wizard.setButtonLayout(layout); + wizard.show(); + qApp->processEvents(); + + // if these crash, this means there's a bug in QWizard + QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next")); + QVERIFY(wizard.button(QWizard::BackButton)->text().contains("Back")); + QVERIFY(wizard.button(QWizard::FinishButton)->text().contains("Finish")); + QVERIFY(wizard.button(QWizard::CancelButton)->text().contains("Cancel")); + QVERIFY(wizard.button(QWizard::HelpButton)->text().contains("Help")); + QVERIFY(wizard.button(QWizard::CustomButton1)->text().isEmpty()); + QVERIFY(wizard.button(QWizard::CustomButton2)->text().isEmpty()); + QVERIFY(wizard.button(QWizard::CustomButton3)->text().isEmpty()); + QVERIFY(!wizard.button(QWizard::Stretch)); + QVERIFY(!wizard.button(QWizard::NoButton)); + + QVERIFY(!wizard.button(QWizard::NextButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible()); + + layout << QWizard::NextButton << QWizard::HelpButton; + wizard.setButtonLayout(layout); + qApp->processEvents(); + + QVERIFY(!wizard.button(QWizard::NextButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); + QVERIFY(wizard.button(QWizard::HelpButton)->isVisible()); + + wizard.addPage(new QWizardPage); + wizard.addPage(new QWizardPage); + qApp->processEvents(); + + QVERIFY(!wizard.button(QWizard::NextButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); + QVERIFY(wizard.button(QWizard::HelpButton)->isVisible()); + + wizard.restart(); + qApp->processEvents(); + + QVERIFY(wizard.button(QWizard::NextButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); + QVERIFY(wizard.button(QWizard::HelpButton)->isVisible()); + + layout.clear(); + layout << QWizard::NextButton << QWizard::HelpButton << QWizard::BackButton + << QWizard::FinishButton << QWizard::CancelButton << QWizard::Stretch + << QWizard::CustomButton2; + + // Turn on all the button-related wizard options. Some of these + // should have no impact on a custom layout; others should. + wizard.setButtonLayout(layout); + wizard.setOptions(QWizard::NoDefaultButton + | QWizard::NoBackButtonOnStartPage + | QWizard::NoBackButtonOnLastPage + | QWizard::DisabledBackButtonOnLastPage + | QWizard::HaveNextButtonOnLastPage + | QWizard::HaveFinishButtonOnEarlyPages + | QWizard::NoCancelButton + | QWizard::CancelButtonOnLeft + | QWizard::HaveHelpButton + | QWizard::HelpButtonOnRight + | QWizard::HaveCustomButton1 + | QWizard::HaveCustomButton2 + | QWizard::HaveCustomButton3); + qApp->processEvents(); + + // we're on first page + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); + QVERIFY(wizard.button(QWizard::FinishButton)->isVisible()); + QVERIFY(wizard.button(QWizard::CancelButton)->isVisible()); // NoCancelButton overridden + QVERIFY(wizard.button(QWizard::HelpButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::CustomButton1)->isVisible()); + QVERIFY(wizard.button(QWizard::CustomButton2)->isVisible()); // HaveCustomButton2 overridden + QVERIFY(!wizard.button(QWizard::CustomButton3)->isVisible()); + + wizard.next(); + qApp->processEvents(); + + // we're on last page + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); + QVERIFY(wizard.button(QWizard::NextButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled()); + QVERIFY(wizard.button(QWizard::FinishButton)->isVisible()); + QVERIFY(wizard.button(QWizard::FinishButton)->isEnabled()); + QVERIFY(wizard.button(QWizard::CancelButton)->isVisible()); // NoCancelButton overridden + QVERIFY(wizard.button(QWizard::HelpButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::CustomButton1)->isVisible()); + QVERIFY(wizard.button(QWizard::CustomButton2)->isVisible()); // HaveCustomButton2 overridden + QVERIFY(!wizard.button(QWizard::CustomButton3)->isVisible()); + + // Check that the buttons are in the right order on screen. + for (int pass = 0; pass < 2; ++pass) { + wizard.setLayoutDirection(pass == 0 ? Qt::LeftToRight : Qt::RightToLeft); + qApp->processEvents(); + + int sign = (pass == 0) ? +1 : -1; + + int p[5]; + p[0] = sign * wizard.button(QWizard::NextButton)->x(); + p[1] = sign * wizard.button(QWizard::HelpButton)->x(); + p[2] = sign * wizard.button(QWizard::FinishButton)->x(); + p[3] = sign * wizard.button(QWizard::CancelButton)->x(); + p[4] = sign * wizard.button(QWizard::CustomButton2)->x(); + + QVERIFY(p[0] < p[1]); + QVERIFY(p[1] < p[2]); + QVERIFY(p[2] < p[3]); + QVERIFY(p[3] < p[4]); + } + + layout.clear(); + wizard.setButtonLayout(layout); + qApp->processEvents(); + + for (int i = -1; i < 50; ++i) { + QAbstractButton *button = wizard.button(QWizard::WizardButton(i)); + QVERIFY(!button || !button->isVisible()); + } +} + +void tst_QWizard::setButton() +{ + QPointer toolButton = new QToolButton; + + QWizard wizard; + wizard.setWizardStyle(QWizard::ClassicStyle); + wizard.setButton(QWizard::NextButton, toolButton); + wizard.setButton(QWizard::CustomButton2, new QCheckBox("Kustom 2")); + + QVERIFY(qobject_cast(wizard.button(QWizard::NextButton))); + QVERIFY(qobject_cast(wizard.button(QWizard::CustomButton2))); + QVERIFY(qobject_cast(wizard.button(QWizard::CustomButton1))); + + QVERIFY(toolButton != 0); + + // resetting the same button does nothing + wizard.setButton(QWizard::NextButton, toolButton); + QVERIFY(toolButton != 0); + + // revert to default button + wizard.setButton(QWizard::NextButton, 0); + QVERIFY(toolButton == 0); + QVERIFY(qobject_cast(wizard.button(QWizard::NextButton))); + QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next")); +} + +void tst_QWizard::setTitleFormatEtc() +{ + QWizard wizard; + QVERIFY(wizard.titleFormat() == Qt::AutoText); + QVERIFY(wizard.subTitleFormat() == Qt::AutoText); + + wizard.setTitleFormat(Qt::RichText); + QVERIFY(wizard.titleFormat() == Qt::RichText); + QVERIFY(wizard.subTitleFormat() == Qt::AutoText); + + wizard.setSubTitleFormat(Qt::PlainText); + QVERIFY(wizard.titleFormat() == Qt::RichText); + QVERIFY(wizard.subTitleFormat() == Qt::PlainText); +} + +void tst_QWizard::setPixmap() +{ + QPixmap p1(1, 1); + QPixmap p2(2, 2); + QPixmap p3(3, 3); + QPixmap p4(4, 4); + QPixmap p5(5, 5); + + QWizard wizard; + QWizardPage *page = new QWizardPage; + QWizardPage *page2 = new QWizardPage; + + wizard.addPage(page); + wizard.addPage(page2); + + QVERIFY(wizard.pixmap(QWizard::BannerPixmap).isNull()); + QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull()); + QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull()); +#ifdef Q_WS_MAC + if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_3) + QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull() == false); + else // fall through since the image doesn't exist on a 10.3 system. + QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull()); +#else + QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull()); +#endif + + QVERIFY(page->pixmap(QWizard::BannerPixmap).isNull()); + QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull()); + QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull()); +#ifdef Q_WS_MAC + if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_3) + QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull() == false); + else // fall through since the image doesn't exist on a 10.3 system. + QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull()); +#else + QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull()); +#endif + wizard.setPixmap(QWizard::BannerPixmap, p1); + wizard.setPixmap(QWizard::LogoPixmap, p2); + wizard.setPixmap(QWizard::WatermarkPixmap, p3); + wizard.setPixmap(QWizard::BackgroundPixmap, p4); + + page->setPixmap(QWizard::LogoPixmap, p5); + + QVERIFY(wizard.pixmap(QWizard::BannerPixmap).size() == p1.size()); + QVERIFY(wizard.pixmap(QWizard::LogoPixmap).size() == p2.size()); + QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).size() == p3.size()); + QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).size() == p4.size()); + + QVERIFY(page->pixmap(QWizard::BannerPixmap).size() == p1.size()); + QVERIFY(page->pixmap(QWizard::LogoPixmap).size() == p5.size()); + QVERIFY(page->pixmap(QWizard::WatermarkPixmap).size() == p3.size()); + QVERIFY(page->pixmap(QWizard::BackgroundPixmap).size() == p4.size()); + + QVERIFY(page2->pixmap(QWizard::BannerPixmap).size() == p1.size()); + QVERIFY(page2->pixmap(QWizard::LogoPixmap).size() == p2.size()); + QVERIFY(page2->pixmap(QWizard::WatermarkPixmap).size() == p3.size()); + QVERIFY(page2->pixmap(QWizard::BackgroundPixmap).size() == p4.size()); +} + +class MyPage1 : public QWizardPage +{ +public: + MyPage1() { + edit1 = new QLineEdit("Bla 1", this); + + edit2 = new QLineEdit("Bla 2", this); + edit2->setInputMask("Mask"); + + edit3 = new QLineEdit("Bla 3", this); + edit3->setMaxLength(25); + + edit4 = new QLineEdit("Bla 4", this); + } + + void registerField(const QString &name, QWidget *widget, + const char *property = 0, + const char *changedSignal = 0) + { QWizardPage::registerField(name, widget, property, changedSignal); } + + QLineEdit *edit1; + QLineEdit *edit2; + QLineEdit *edit3; + QLineEdit *edit4; +}; + +void tst_QWizard::setDefaultProperty() +{ + QWizard wizard; + MyPage1 *page = new MyPage1; + wizard.addPage(page); + + page->registerField("edit1", page->edit1); + + wizard.setDefaultProperty("QLineEdit", "inputMask", 0); + page->registerField("edit2", page->edit2); + + wizard.setDefaultProperty("QLineEdit", "maxLength", 0); + page->registerField("edit3", page->edit3); + + wizard.setDefaultProperty("QLineEdit", "text", SIGNAL(textChanged(QString))); + page->registerField("edit3bis", page->edit3); + + wizard.setDefaultProperty("QWidget", "enabled", 0); // less specific, i.e. ignored + page->registerField("edit4", page->edit4); + QTest::ignoreMessage(QtWarningMsg,"QWizard::setField: Couldn't write to property 'customProperty'"); + wizard.setDefaultProperty("QLineEdit", "customProperty", 0); + page->registerField("edit4bis", page->edit4); + + QCOMPARE(wizard.field("edit1").toString(), QString("Bla 1")); + QCOMPARE(wizard.field("edit2").toString(), page->edit2->inputMask()); + QCOMPARE(wizard.field("edit3").toInt(), 25); + QCOMPARE(wizard.field("edit3bis").toString(), QString("Bla 3")); + QCOMPARE(wizard.field("edit4").toString(), QString("Bla 4")); + QCOMPARE(wizard.field("edit4bis").toString(), QString()); + + wizard.setField("edit1", "Alpha"); + wizard.setField("edit2", "Beta"); + wizard.setField("edit3", 50); + wizard.setField("edit3bis", "Gamma"); + wizard.setField("edit4", "Delta"); + wizard.setField("edit4bis", "Epsilon"); + + QCOMPARE(wizard.field("edit1").toString(), QString("Alpha")); + QVERIFY(wizard.field("edit2").toString().contains("Beta")); + QCOMPARE(wizard.field("edit3").toInt(), 50); + QCOMPARE(wizard.field("edit3bis").toString(), QString("Gamma")); + QCOMPARE(wizard.field("edit4").toString(), QString("Delta")); + QCOMPARE(wizard.field("edit4bis").toString(), QString("Epsilon")); + + // make sure the data structure is reasonable + for (int i = 0; i < 200000; ++i) { + wizard.setDefaultProperty("QLineEdit", "x" + QByteArray::number(i), 0); + wizard.setDefaultProperty("QLabel", "y" + QByteArray::number(i), 0); + } +} + +void tst_QWizard::addPage() +{ + QWidget *parent = new QWidget; + QWizard wizard; + const int N = 100; + QWizardPage *pages[N]; + + for (int i = 0; i < N; ++i) { + pages[i] = new QWizardPage(parent); + QCOMPARE(wizard.addPage(pages[i]), i); + QCOMPARE(pages[i]->window(), (QWidget *)&wizard); + QCOMPARE(wizard.startId(), 0); + } + + for (int i = 0; i < N; ++i) { + QVERIFY(pages[i] == wizard.page(i)); + } + QVERIFY(!wizard.page(-1)); + QVERIFY(!wizard.page(N)); + QVERIFY(!wizard.page(N + 1)); + + wizard.setPage(N + 50, new QWizardPage); + wizard.setPage(-3000, new QWizardPage); + + QWizardPage *pageX = new QWizardPage; + QCOMPARE(wizard.addPage(pageX), N + 51); + QCOMPARE(wizard.page(N + 51), pageX); + + QCOMPARE(wizard.addPage(new QWizardPage), N + 52); + + QTest::ignoreMessage(QtWarningMsg,"QWizard::setPage: Cannot insert null page"); + wizard.addPage(0); // generates a warning + delete parent; +} + +#define CHECK_VISITED(wizard, list) \ + do { \ + QList myList = list; \ + QCOMPARE((wizard).visitedPages(), myList); \ + Q_FOREACH(int id, myList) \ + QVERIFY((wizard).hasVisitedPage(id)); \ + } while (0) + +void tst_QWizard::setPage() +{ + QWidget *parent = new QWidget; + QWizard wizard; + QWizardPage *page; + + QCOMPARE(wizard.startId(), -1); + QCOMPARE(wizard.currentId(), -1); + QVERIFY(!wizard.currentPage()); + QCOMPARE(wizard.nextId(), -1); + + page = new QWizardPage(parent); + QTest::ignoreMessage(QtWarningMsg,"QWizard::setPage: Cannot insert page with ID -1"); + wizard.setPage(-1, page); // gives a warning and does nothing + QVERIFY(!wizard.page(-2)); + QVERIFY(!wizard.page(-1)); + QVERIFY(!wizard.page(0)); + QCOMPARE(wizard.startId(), -1); + QCOMPARE(wizard.currentId(), -1); + QVERIFY(!wizard.currentPage()); + QCOMPARE(wizard.nextId(), -1); + CHECK_VISITED(wizard, QList()); + + page = new QWizardPage(parent); + wizard.setPage(0, page); + QCOMPARE(page->window(), (QWidget *)&wizard); + QCOMPARE(wizard.page(0), page); + QCOMPARE(wizard.startId(), 0); + QCOMPARE(wizard.currentId(), -1); + QVERIFY(!wizard.currentPage()); + QCOMPARE(wizard.nextId(), -1); + CHECK_VISITED(wizard, QList()); + + page = new QWizardPage(parent); + wizard.setPage(-2, page); + QCOMPARE(page->window(), (QWidget *)&wizard); + QCOMPARE(wizard.page(-2), page); + QCOMPARE(wizard.startId(), -2); + QCOMPARE(wizard.currentId(), -1); + QVERIFY(!wizard.currentPage()); + QCOMPARE(wizard.nextId(), -1); + CHECK_VISITED(wizard, QList()); + + wizard.restart(); + QCOMPARE(wizard.page(-2), page); + QCOMPARE(wizard.startId(), -2); + QCOMPARE(wizard.currentId(), -2); + QVERIFY(wizard.currentPage() == page); + QCOMPARE(wizard.nextId(), 0); + CHECK_VISITED(wizard, QList() << -2); + + page = new QWizardPage(parent); + wizard.setPage(2, page); + QCOMPARE(wizard.page(2), page); + QCOMPARE(wizard.startId(), -2); + QCOMPARE(wizard.currentId(), -2); + QVERIFY(wizard.currentPage() == wizard.page(-2)); + QCOMPARE(wizard.nextId(), 0); + CHECK_VISITED(wizard, QList() << -2); + + wizard.restart(); + QCOMPARE(wizard.startId(), -2); + QCOMPARE(wizard.currentId(), -2); + QVERIFY(wizard.currentPage() == wizard.page(-2)); + QCOMPARE(wizard.nextId(), 0); + CHECK_VISITED(wizard, QList() << -2); + + page = new QWizardPage(parent); + wizard.setPage(-3, page); + QCOMPARE(wizard.page(-3), page); + QCOMPARE(wizard.startId(), -3); + QCOMPARE(wizard.currentId(), -2); + QVERIFY(wizard.currentPage() == wizard.page(-2)); + QCOMPARE(wizard.nextId(), 0); + CHECK_VISITED(wizard, QList() << -2); + + wizard.restart(); + QCOMPARE(wizard.startId(), -3); + QCOMPARE(wizard.currentId(), -3); + QVERIFY(wizard.currentPage() == wizard.page(-3)); + QCOMPARE(wizard.nextId(), -2); + CHECK_VISITED(wizard, QList() << -3); + + wizard.next(); + QCOMPARE(wizard.startId(), -3); + QCOMPARE(wizard.currentId(), -2); + QVERIFY(wizard.currentPage() == wizard.page(-2)); + QCOMPARE(wizard.nextId(), 0); + CHECK_VISITED(wizard, QList() << -3 << -2); + + wizard.next(); + QCOMPARE(wizard.startId(), -3); + QCOMPARE(wizard.currentId(), 0); + QVERIFY(wizard.currentPage() == wizard.page(0)); + QCOMPARE(wizard.nextId(), 2); + CHECK_VISITED(wizard, QList() << -3 << -2 << 0); + + for (int i = 0; i < 100; ++i) { + wizard.next(); + QCOMPARE(wizard.startId(), -3); + QCOMPARE(wizard.currentId(), 2); + QVERIFY(wizard.currentPage() == wizard.page(2)); + QCOMPARE(wizard.nextId(), -1); + CHECK_VISITED(wizard, QList() << -3 << -2 << 0 << 2); + } + + wizard.back(); + QCOMPARE(wizard.startId(), -3); + QCOMPARE(wizard.currentId(), 0); + QVERIFY(wizard.currentPage() == wizard.page(0)); + QCOMPARE(wizard.nextId(), 2); + CHECK_VISITED(wizard, QList() << -3 << -2 << 0); + + wizard.back(); + QCOMPARE(wizard.startId(), -3); + QCOMPARE(wizard.currentId(), -2); + QVERIFY(wizard.currentPage() == wizard.page(-2)); + QCOMPARE(wizard.nextId(), 0); + CHECK_VISITED(wizard, QList() << -3 << -2); + + for (int i = 0; i < 100; ++i) { + wizard.back(); + QCOMPARE(wizard.startId(), -3); + QCOMPARE(wizard.currentId(), -3); + QVERIFY(wizard.currentPage() == wizard.page(-3)); + QCOMPARE(wizard.nextId(), -2); + CHECK_VISITED(wizard, QList() << -3); + } + + for (int i = 0; i < 100; ++i) { + wizard.restart(); + QCOMPARE(wizard.startId(), -3); + QCOMPARE(wizard.currentId(), -3); + QVERIFY(wizard.currentPage() == wizard.page(-3)); + QCOMPARE(wizard.nextId(), -2); + CHECK_VISITED(wizard, QList() << -3); + } + delete parent; +} + +void tst_QWizard::setStartId() +{ + QWizard wizard; + QCOMPARE(wizard.startId(), -1); + + wizard.setPage(INT_MIN, new QWizardPage); + QCOMPARE(wizard.startId(), INT_MIN); + + wizard.setPage(-2, new QWizardPage); + QCOMPARE(wizard.startId(), INT_MIN); + + wizard.setPage(0, new QWizardPage); + QCOMPARE(wizard.startId(), INT_MIN); + + wizard.setPage(1, new QWizardPage); + QCOMPARE(wizard.startId(), INT_MIN); + + wizard.setPage(INT_MAX, new QWizardPage); + QCOMPARE(wizard.startId(), INT_MIN); + + QTest::ignoreMessage(QtWarningMsg,"QWizard::setStartId: Invalid page ID -1"); + wizard.setStartId(-1); + QCOMPARE(wizard.startId(), INT_MIN); + + wizard.setStartId(-2); + QCOMPARE(wizard.startId(), -2); + QCOMPARE(wizard.nextId(), -1); + + wizard.restart(); + QCOMPARE(wizard.startId(), -2); + QCOMPARE(wizard.currentId(), -2); + QVERIFY(wizard.currentPage() == wizard.page(-2)); + QCOMPARE(wizard.nextId(), 0); + + wizard.next(); + QCOMPARE(wizard.startId(), -2); + QCOMPARE(wizard.currentId(), 0); + QVERIFY(wizard.currentPage() == wizard.page(0)); + QCOMPARE(wizard.nextId(), 1); + + wizard.setStartId(INT_MIN); + QCOMPARE(wizard.startId(), INT_MIN); + QCOMPARE(wizard.currentId(), 0); + QVERIFY(wizard.currentPage() == wizard.page(0)); + QCOMPARE(wizard.nextId(), 1); + + wizard.next(); + QCOMPARE(wizard.startId(), INT_MIN); + QCOMPARE(wizard.currentId(), 1); + QVERIFY(wizard.currentPage() == wizard.page(1)); + QCOMPARE(wizard.nextId(), INT_MAX); + + wizard.next(); + QCOMPARE(wizard.startId(), INT_MIN); + QCOMPARE(wizard.currentId(), INT_MAX); + QVERIFY(wizard.currentPage() == wizard.page(INT_MAX)); + QCOMPARE(wizard.nextId(), -1); + CHECK_VISITED(wizard, QList() << -2 << 0 << 1 << INT_MAX); +} + +struct MyPage2 : public QWizardPage +{ +public: + MyPage2() : init(0), cleanup(0), validate(0) {} + + void initializePage() { ++init; QWizardPage::initializePage(); checkInvariant(); } + void cleanupPage() { ++cleanup; QWizardPage::cleanupPage(); checkInvariant(); } + bool validatePage() { ++validate; return QWizardPage::validatePage(); } + + void check(int init, int cleanup) + { Q_ASSERT(init == this->init && cleanup == this->cleanup); Q_UNUSED(init); Q_UNUSED(cleanup); } + + int init; + int cleanup; + int validate; + +private: + void checkInvariant() { Q_ASSERT(init == cleanup || init - 1 == cleanup); } +}; + +#define CHECK_PAGE_INIT(i0, c0, i1, c1, i2, c2) \ + page0->check((i0), (c0)); \ + page1->check((i1), (c1)); \ + page2->check((i2), (c2)); + +void tst_QWizard::setOption_IndependentPages() +{ + MyPage2 *page0 = new MyPage2; + MyPage2 *page1 = new MyPage2; + MyPage2 *page2 = new MyPage2; + + QWizard wizard; + wizard.addPage(page0); + wizard.addPage(page1); + wizard.addPage(page2); + + QVERIFY(!wizard.testOption(QWizard::IndependentPages)); + + wizard.restart(); + + // Make sure initializePage() and cleanupPage() are called are + // they should when the + // wizard.testOption(QWizard::IndependentPages option is off. + for (int i = 0; i < 10; ++i) { + CHECK_PAGE_INIT(i + 1, i, i, i, i, i); + + wizard.next(); + CHECK_PAGE_INIT(i + 1, i, i + 1, i, i, i); + + wizard.next(); + CHECK_PAGE_INIT(i + 1, i, i + 1, i, i + 1, i); + + wizard.next(); + CHECK_PAGE_INIT(i + 1, i, i + 1, i, i + 1, i); + + wizard.back(); + CHECK_PAGE_INIT(i + 1, i, i + 1, i, i + 1, i + 1); + + wizard.back(); + CHECK_PAGE_INIT(i + 1, i, i + 1, i + 1, i + 1, i + 1); + + wizard.back(); + CHECK_PAGE_INIT(i + 1, i, i + 1, i + 1, i + 1, i + 1); + + wizard.restart(); + } + + CHECK_PAGE_INIT(11, 10, 10, 10, 10, 10); + + wizard.next(); + CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10); + + // Now, turn on the option and check that they're called at the + // appropiate times (which aren't the same). + wizard.setOption(QWizard::IndependentPages, true); + CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10); + + wizard.back(); + CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10); + + wizard.next(); + CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10); + + wizard.next(); + CHECK_PAGE_INIT(11, 10, 11, 10, 11, 10); + + wizard.next(); + CHECK_PAGE_INIT(11, 10, 11, 10, 11, 10); + + wizard.back(); + CHECK_PAGE_INIT(11, 10, 11, 10, 11, 10); + + wizard.setStartId(2); + + wizard.restart(); + CHECK_PAGE_INIT(11, 11, 11, 11, 12, 11); + + wizard.back(); + CHECK_PAGE_INIT(11, 11, 11, 11, 12, 11); + + wizard.next(); + CHECK_PAGE_INIT(11, 11, 11, 11, 12, 11); + + wizard.setStartId(0); + wizard.restart(); + CHECK_PAGE_INIT(12, 11, 11, 11, 12, 12); + + wizard.next(); + CHECK_PAGE_INIT(12, 11, 12, 11, 12, 12); + + wizard.next(); + CHECK_PAGE_INIT(12, 11, 12, 11, 13, 12); + + wizard.back(); + CHECK_PAGE_INIT(12, 11, 12, 11, 13, 12); + + // Fun stuff here. + + wizard.setOption(QWizard::IndependentPages, false); + CHECK_PAGE_INIT(12, 11, 12, 11, 13, 13); + + wizard.setOption(QWizard::IndependentPages, true); + CHECK_PAGE_INIT(12, 11, 12, 11, 13, 13); + + wizard.setOption(QWizard::IndependentPages, false); + CHECK_PAGE_INIT(12, 11, 12, 11, 13, 13); + + wizard.back(); + CHECK_PAGE_INIT(12, 11, 12, 12, 13, 13); + + wizard.back(); + CHECK_PAGE_INIT(12, 11, 12, 12, 13, 13); +} + +void tst_QWizard::setOption_IgnoreSubTitles() +{ +#if defined(Q_OS_WINCE) + QSKIP("Skipped because of limited resources and potential crash. (Task: 166824)", SkipAll); +#endif + QWizard wizard1; + wizard1.setButtonLayout(QList() << QWizard::CancelButton); + wizard1.resize(500, 500); + QVERIFY(!wizard1.testOption(QWizard::IgnoreSubTitles)); + QWizardPage *page11 = new QWizardPage; + page11->setTitle("Page X"); + page11->setSubTitle("Some subtitle"); + + QWizardPage *page12 = new QWizardPage; + page12->setTitle("Page X"); + + wizard1.addPage(page11); + wizard1.addPage(page12); + + QWizard wizard2; + wizard2.setButtonLayout(QList() << QWizard::CancelButton); + wizard2.resize(500, 500); + wizard2.setOption(QWizard::IgnoreSubTitles, true); + QWizardPage *page21 = new QWizardPage; + page21->setTitle("Page X"); + page21->setSubTitle("Some subtitle"); + + QWizardPage *page22 = new QWizardPage; + page22->setTitle("Page X"); + + wizard2.addPage(page21); + wizard2.addPage(page22); + + wizard1.show(); + wizard2.show(); + + // Check that subtitles are shown when they should (i.e., + // they're set and IgnoreSubTitles is off). + + qApp->setActiveWindow(0); // ensure no focus rectangle around cancel button + QImage i11 = grabWidget(&wizard1); + QImage i21 = grabWidget(&wizard2); + QVERIFY(i11 != i21); + + wizard1.next(); + wizard2.next(); + + QImage i12 = grabWidget(&wizard1); + QImage i22 = grabWidget(&wizard2); + QVERIFY(i12 == i22); + QVERIFY(i21 == i22); + + wizard1.back(); + wizard2.back(); + + QImage i13 = grabWidget(&wizard1); + QImage i23 = grabWidget(&wizard2); + QVERIFY(i13 == i11); + QVERIFY(i23 == i21); + + wizard1.setOption(QWizard::IgnoreSubTitles, true); + wizard2.setOption(QWizard::IgnoreSubTitles, false); + + QImage i14 = grabWidget(&wizard1); + QImage i24 = grabWidget(&wizard2); + QVERIFY(i14 == i21); + QVERIFY(i24 == i11); + + // Check the impact of subtitles on the rest of the layout, by + // using a subtitle that looks empty (but that isn't). In + // Classic and Modern styles, this should be enough to trigger a + // "header"; in Mac style, this only creates a QLabel, with no + // text, i.e. it doesn't affect the layout. + + page11->setSubTitle(""); // not quite empty, but looks empty + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 2; ++j) { + wizard1.setOption(QWizard::IgnoreSubTitles, j == 0); + + wizard1.setWizardStyle(i == 0 ? QWizard::ClassicStyle + : i == 1 ? QWizard::ModernStyle + : QWizard::MacStyle); + wizard1.restart(); + QImage i1 = grabWidget(&wizard1); + + wizard1.next(); + QImage i2 = grabWidget(&wizard1); + + if (j == 0 || wizard1.wizardStyle() == QWizard::MacStyle) { + QVERIFY(i1 == i2); + } else { + QVERIFY(i1 != i2); + } + } + } +} + +void tst_QWizard::setOption_ExtendedWatermarkPixmap() +{ +#if defined(Q_OS_WINCE) + QSKIP("Skipped because of limited resources and potential crash. (Task: 166824)", SkipAll); +#endif + QPixmap watermarkPixmap(200, 400); + watermarkPixmap.fill(Qt::black); + + QWizard wizard1; + wizard1.setButtonLayout(QList() << QWizard::CancelButton); + QVERIFY(!wizard1.testOption(QWizard::ExtendedWatermarkPixmap)); + QWizardPage *page11 = new QWizardPage; + page11->setTitle("Page X"); + page11->setPixmap(QWizard::WatermarkPixmap, watermarkPixmap); + + QWizardPage *page12 = new QWizardPage; + page12->setTitle("Page X"); + + wizard1.addPage(page11); + wizard1.addPage(page12); + + QWizard wizard2; + wizard2.setButtonLayout(QList() << QWizard::CancelButton); + wizard2.setOption(QWizard::ExtendedWatermarkPixmap, true); + QWizardPage *page21 = new QWizardPage; + page21->setTitle("Page X"); + page21->setPixmap(QWizard::WatermarkPixmap, watermarkPixmap); + + QWizardPage *page22 = new QWizardPage; + page22->setTitle("Page X"); + + wizard2.addPage(page21); + wizard2.addPage(page22); + + wizard1.show(); + wizard2.show(); + + // Check the impact of watermark pixmaps on the rest of the layout. + + for (int i = 0; i < 3; ++i) { + QImage i1[2]; + QImage i2[2]; + for (int j = 0; j < 2; ++j) { + wizard1.setOption(QWizard::ExtendedWatermarkPixmap, j == 0); + + wizard1.setWizardStyle(i == 0 ? QWizard::ClassicStyle + : i == 1 ? QWizard::ModernStyle + : QWizard::MacStyle); + wizard1.restart(); + wizard1.setMaximumSize(1000, 1000); + wizard1.resize(600, 600); + i1[j] = grabWidget(&wizard1); + + wizard1.next(); + wizard1.setMaximumSize(1000, 1000); + wizard1.resize(600, 600); + i2[j] = grabWidget(&wizard1); + } + + if (wizard1.wizardStyle() == QWizard::MacStyle) { + QVERIFY(i1[0] == i1[1]); + QVERIFY(i2[0] == i2[1]); + QVERIFY(i1[0] == i2[0]); + } else { + QVERIFY(i1[0] != i1[1]); + QVERIFY(i2[0] == i2[1]); + QVERIFY(i1[0] != i2[0]); + QVERIFY(i1[1] != i2[1]); + } + } +} + +void tst_QWizard::setOption_NoDefaultButton() +{ + QWizard wizard; + wizard.setOption(QWizard::NoDefaultButton, false); + wizard.setOption(QWizard::HaveFinishButtonOnEarlyPages, true); + wizard.addPage(new QWizardPage); + wizard.page(0)->setFinalPage(true); + wizard.addPage(new QWizardPage); + + if (QPushButton *pb = qobject_cast(wizard.button(QWizard::NextButton))) + pb->setAutoDefault(false); + if (QPushButton *pb = qobject_cast(wizard.button(QWizard::FinishButton))) + pb->setAutoDefault(false); + + wizard.show(); + qApp->processEvents(); + QVERIFY(qobject_cast(wizard.button(QWizard::NextButton))->isDefault()); + QVERIFY(wizard.button(QWizard::FinishButton)->isEnabled()); + + wizard.next(); + QVERIFY(qobject_cast(wizard.button(QWizard::FinishButton))->isDefault()); + + wizard.back(); + QVERIFY(qobject_cast(wizard.button(QWizard::NextButton))->isDefault()); + + wizard.setOption(QWizard::NoDefaultButton, true); + QVERIFY(!qobject_cast(wizard.button(QWizard::NextButton))->isDefault()); + QVERIFY(!qobject_cast(wizard.button(QWizard::FinishButton))->isDefault()); + + wizard.next(); + QVERIFY(!qobject_cast(wizard.button(QWizard::NextButton))->isDefault()); + QVERIFY(!qobject_cast(wizard.button(QWizard::FinishButton))->isDefault()); + + wizard.back(); + QVERIFY(!qobject_cast(wizard.button(QWizard::NextButton))->isDefault()); + QVERIFY(!qobject_cast(wizard.button(QWizard::FinishButton))->isDefault()); + + wizard.setOption(QWizard::NoDefaultButton, false); + QVERIFY(qobject_cast(wizard.button(QWizard::NextButton))->isDefault()); +} + +void tst_QWizard::setOption_NoBackButtonOnStartPage() +{ + QWizard wizard; + wizard.setOption(QWizard::NoBackButtonOnStartPage, true); + wizard.addPage(new QWizardPage); + wizard.addPage(new QWizardPage); + wizard.addPage(new QWizardPage); + + wizard.setStartId(1); + wizard.show(); + qApp->processEvents(); + + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); + + wizard.setOption(QWizard::NoBackButtonOnStartPage, false); + qApp->processEvents(); + QVERIFY(wizard.button(QWizard::BackButton)->isVisible()); + + wizard.setOption(QWizard::NoBackButtonOnStartPage, true); + qApp->processEvents(); + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); + + wizard.next(); + qApp->processEvents(); + QVERIFY(wizard.button(QWizard::BackButton)->isVisible()); + + wizard.setOption(QWizard::NoBackButtonOnStartPage, false); + QVERIFY(wizard.button(QWizard::BackButton)->isVisible()); + + wizard.setOption(QWizard::NoBackButtonOnStartPage, true); + QVERIFY(wizard.button(QWizard::BackButton)->isVisible()); + + wizard.back(); + qApp->processEvents(); + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); +} + +void tst_QWizard::setOption_NoBackButtonOnLastPage() +{ + for (int i = 0; i < 2; ++i) { + QWizard wizard; + wizard.setOption(QWizard::NoBackButtonOnStartPage, false); + wizard.setOption(QWizard::NoBackButtonOnLastPage, true); + wizard.setOption(QWizard::DisabledBackButtonOnLastPage, i == 0); // changes nothing + wizard.addPage(new QWizardPage); + wizard.addPage(new QWizardPage); + wizard.page(1)->setFinalPage(true); // changes nothing (final != last in general) + wizard.addPage(new QWizardPage); + + wizard.setStartId(1); + wizard.show(); + qApp->processEvents(); + + QVERIFY(wizard.button(QWizard::BackButton)->isVisible()); + + wizard.next(); + qApp->processEvents(); + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); + + wizard.next(); + qApp->processEvents(); + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); + + wizard.back(); + qApp->processEvents(); + QVERIFY(wizard.button(QWizard::BackButton)->isVisible()); + + wizard.next(); + qApp->processEvents(); + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); + + wizard.setOption(QWizard::NoBackButtonOnLastPage, false); + QVERIFY(wizard.button(QWizard::BackButton)->isVisible()); + + wizard.setOption(QWizard::NoBackButtonOnLastPage, true); + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); + + wizard.addPage(new QWizardPage); + QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); // this is maybe wrong + } +} + +void tst_QWizard::setOption_DisabledBackButtonOnLastPage() +{ + QWizard wizard; + wizard.setOption(QWizard::NoBackButtonOnStartPage, false); + wizard.setOption(QWizard::DisabledBackButtonOnLastPage, true); + wizard.addPage(new QWizardPage); + wizard.addPage(new QWizardPage); + wizard.page(1)->setFinalPage(true); // changes nothing (final != last in general) + wizard.addPage(new QWizardPage); + + wizard.setStartId(1); + wizard.show(); + qApp->processEvents(); + + QVERIFY(wizard.button(QWizard::BackButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); + + wizard.next(); + qApp->processEvents(); + QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); + + wizard.next(); + qApp->processEvents(); + QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); + + wizard.back(); + qApp->processEvents(); + QVERIFY(wizard.button(QWizard::BackButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); + + wizard.next(); + qApp->processEvents(); + QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); + + wizard.setOption(QWizard::DisabledBackButtonOnLastPage, false); + QVERIFY(wizard.button(QWizard::BackButton)->isEnabled()); + + wizard.setOption(QWizard::DisabledBackButtonOnLastPage, true); + QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); + + wizard.addPage(new QWizardPage); + QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); // this is maybe wrong +} + +void tst_QWizard::setOption_HaveNextButtonOnLastPage() +{ + QWizard wizard; + wizard.setOption(QWizard::HaveNextButtonOnLastPage, false); + wizard.addPage(new QWizardPage); + wizard.addPage(new QWizardPage); + wizard.page(1)->setFinalPage(true); // changes nothing (final != last in general) + wizard.addPage(new QWizardPage); + + wizard.setStartId(1); + wizard.show(); + qApp->processEvents(); + + QVERIFY(wizard.button(QWizard::NextButton)->isVisible()); + QVERIFY(wizard.button(QWizard::NextButton)->isEnabled()); + + wizard.next(); + QVERIFY(!wizard.button(QWizard::NextButton)->isVisible()); + + wizard.setOption(QWizard::HaveNextButtonOnLastPage, true); + QVERIFY(wizard.button(QWizard::NextButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled()); + + wizard.next(); + QVERIFY(wizard.button(QWizard::NextButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled()); + + wizard.back(); + QVERIFY(wizard.button(QWizard::NextButton)->isVisible()); + QVERIFY(wizard.button(QWizard::NextButton)->isEnabled()); + + wizard.setOption(QWizard::HaveNextButtonOnLastPage, false); + QVERIFY(wizard.button(QWizard::NextButton)->isVisible()); + QVERIFY(wizard.button(QWizard::NextButton)->isEnabled()); + + wizard.next(); + QVERIFY(!wizard.button(QWizard::NextButton)->isVisible()); + + wizard.setOption(QWizard::HaveNextButtonOnLastPage, true); + QVERIFY(wizard.button(QWizard::NextButton)->isVisible()); + QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled()); +} + +void tst_QWizard::setOption_HaveFinishButtonOnEarlyPages() +{ + QWizard wizard; + QVERIFY(!wizard.testOption(QWizard::HaveFinishButtonOnEarlyPages)); + wizard.addPage(new QWizardPage); + wizard.addPage(new QWizardPage); + wizard.page(1)->setFinalPage(true); + wizard.addPage(new QWizardPage); + + wizard.show(); + qApp->processEvents(); + + QVERIFY(!wizard.button(QWizard::FinishButton)->isVisible()); + + wizard.next(); + QVERIFY(wizard.button(QWizard::FinishButton)->isVisible()); + + wizard.next(); + QVERIFY(wizard.button(QWizard::FinishButton)->isVisible()); + + wizard.back(); + QVERIFY(wizard.button(QWizard::FinishButton)->isVisible()); + + wizard.back(); + QVERIFY(!wizard.button(QWizard::FinishButton)->isVisible()); + + wizard.setOption(QWizard::HaveFinishButtonOnEarlyPages, true); + QVERIFY(wizard.button(QWizard::FinishButton)->isVisible()); + + wizard.next(); + QVERIFY(wizard.button(QWizard::FinishButton)->isVisible()); + + wizard.setOption(QWizard::HaveFinishButtonOnEarlyPages, false); + QVERIFY(wizard.button(QWizard::FinishButton)->isVisible()); + + wizard.back(); + QVERIFY(!wizard.button(QWizard::FinishButton)->isVisible()); +} + +void tst_QWizard::setOption_NoCancelButton() +{ + for (int i = 0; i < 2; ++i) { + QWizard wizard; + wizard.setOption(QWizard::NoCancelButton, true); + wizard.setOption(QWizard::CancelButtonOnLeft, i == 0); + wizard.addPage(new QWizardPage); + wizard.addPage(new QWizardPage); + wizard.show(); + qApp->processEvents(); + + QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible()); + + wizard.next(); + QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible()); + + wizard.setOption(QWizard::NoCancelButton, false); + QVERIFY(wizard.button(QWizard::CancelButton)->isVisible()); + + wizard.back(); + QVERIFY(wizard.button(QWizard::CancelButton)->isVisible()); + + wizard.setOption(QWizard::NoCancelButton, true); + QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible()); + } +} + +void tst_QWizard::setOption_CancelButtonOnLeft() +{ + for (int i = 0; i < 2; ++i) { + int sign = (i == 0) ? +1 : -1; + + QWizard wizard; + wizard.setLayoutDirection(i == 0 ? Qt::LeftToRight : Qt::RightToLeft); + wizard.setOption(QWizard::NoCancelButton, false); + wizard.setOption(QWizard::CancelButtonOnLeft, true); + wizard.setOption(QWizard::NoBackButtonOnStartPage, false); + wizard.addPage(new QWizardPage); + wizard.addPage(new QWizardPage); + wizard.show(); + qApp->processEvents(); + + const QAbstractButton *refButton = wizard.button((wizard.wizardStyle() == QWizard::AeroStyle) + ? QWizard::NextButton : QWizard::BackButton); + const QAbstractButton *refButton2 = wizard.button((wizard.wizardStyle() == QWizard::AeroStyle) + ? QWizard::FinishButton : QWizard::BackButton); + + QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() < sign * refButton->x()); + + wizard.next(); + qApp->processEvents(); + QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() < sign * refButton->x()); + + wizard.setOption(QWizard::CancelButtonOnLeft, false); + qApp->processEvents(); + QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() > sign * refButton2->x()); + + wizard.back(); + qApp->processEvents(); + QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() > sign * refButton->x()); + } +} + +void tst_QWizard::setOption_HaveHelpButton() +{ + for (int i = 0; i < 2; ++i) { + QWizard wizard; + QVERIFY(!wizard.testOption(QWizard::HaveHelpButton)); + wizard.setOption(QWizard::HaveHelpButton, false); + wizard.setOption(QWizard::HelpButtonOnRight, i == 0); + wizard.addPage(new QWizardPage); + wizard.addPage(new QWizardPage); + wizard.show(); + qApp->processEvents(); + + QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible()); + + wizard.next(); + QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible()); + + wizard.setOption(QWizard::HaveHelpButton, true); + QVERIFY(wizard.button(QWizard::HelpButton)->isVisible()); + + wizard.back(); + QVERIFY(wizard.button(QWizard::HelpButton)->isVisible()); + + wizard.setOption(QWizard::HaveHelpButton, false); + QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible()); + } +} + +void tst_QWizard::setOption_HelpButtonOnRight() +{ + for (int i = 0; i < 2; ++i) { + int sign = (i == 0) ? +1 : -1; + + QWizard wizard; + wizard.setLayoutDirection(i == 0 ? Qt::LeftToRight : Qt::RightToLeft); + wizard.setOption(QWizard::HaveHelpButton, true); + wizard.setOption(QWizard::HelpButtonOnRight, false); + wizard.setOption(QWizard::NoBackButtonOnStartPage, false); + wizard.addPage(new QWizardPage); + wizard.addPage(new QWizardPage); + wizard.show(); + qApp->processEvents(); + + const QAbstractButton *refButton = wizard.button((wizard.wizardStyle() == QWizard::AeroStyle) + ? QWizard::NextButton : QWizard::BackButton); + + QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() < sign * refButton->x()); + + wizard.next(); + qApp->processEvents(); + QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() < sign * refButton->x()); + + wizard.setOption(QWizard::HelpButtonOnRight, true); + qApp->processEvents(); + QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() > sign * refButton->x()); + + wizard.back(); + qApp->processEvents(); + QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() > sign * refButton->x()); + } +} + +void tst_QWizard::setOption_HaveCustomButtonX() +{ + for (int i = 0; i < 2; ++i) { + for (int j = 0; j < 2; ++j) { + for (int k = 0; k < 2; ++k) { + QWizard wizard; + wizard.setLayoutDirection(Qt::LeftToRight); + wizard.addPage(new QWizardPage); + wizard.addPage(new QWizardPage); + wizard.show(); + + wizard.setButtonText(QWizard::CustomButton1, "Foo"); + wizard.setButton(QWizard::CustomButton2, new QCheckBox("Bar")); + wizard.button(QWizard::CustomButton3)->setText("Baz"); + + wizard.setOption(QWizard::HaveCustomButton1, i == 0); + wizard.setOption(QWizard::HaveCustomButton2, j == 0); + wizard.setOption(QWizard::HaveCustomButton3, k == 0); + + QVERIFY(wizard.button(QWizard::CustomButton1)->isHidden() == (i != 0)); + QVERIFY(wizard.button(QWizard::CustomButton2)->isHidden() == (j != 0)); + QVERIFY(wizard.button(QWizard::CustomButton3)->isHidden() == (k != 0)); + + if (i + j + k == 0) { + qApp->processEvents(); + QVERIFY(wizard.button(QWizard::CustomButton1)->x() + < wizard.button(QWizard::CustomButton2)->x()); + QVERIFY(wizard.button(QWizard::CustomButton2)->x() + < wizard.button(QWizard::CustomButton3)->x()); + } + } + } + } +} + +class Operation +{ +public: + virtual void apply(QWizard *) const = 0; + virtual QString describe() const = 0; +protected: + virtual ~Operation() {} +}; + +class SetPage : public Operation +{ + void apply(QWizard *wizard) const + { + wizard->restart(); + for (int j = 0; j < page; ++j) + wizard->next(); + } + QString describe() const { return QString("set page %1").arg(page); } + const int page; +public: + SetPage(int page) : page(page) {} +}; + +class SetStyle : public Operation +{ + void apply(QWizard *wizard) const { wizard->setWizardStyle(style); } + QString describe() const { return QString("set style %1").arg(style); } + const QWizard::WizardStyle style; +public: + SetStyle(QWizard::WizardStyle style) : style(style) {} +}; + +class SetOption : public Operation +{ + void apply(QWizard *wizard) const { wizard->setOption(option, on); } + QString describe() const; + const QWizard::WizardOption option; + const bool on; +public: + SetOption(QWizard::WizardOption option, bool on) : option(option), on(on) {} +}; + +class OptionInfo +{ + OptionInfo() + { + tags[QWizard::IndependentPages] = "0/IPP"; + tags[QWizard::IgnoreSubTitles] = "1/IST"; + tags[QWizard::ExtendedWatermarkPixmap] = "2/EWP"; + tags[QWizard::NoDefaultButton] = "3/NDB"; + tags[QWizard::NoBackButtonOnStartPage] = "4/BSP"; + tags[QWizard::NoBackButtonOnLastPage] = "5/BLP"; + tags[QWizard::DisabledBackButtonOnLastPage] = "6/DLP"; + tags[QWizard::HaveNextButtonOnLastPage] = "7/NLP"; + tags[QWizard::HaveFinishButtonOnEarlyPages] = "8/FEP"; + tags[QWizard::NoCancelButton] = "9/NCB"; + tags[QWizard::CancelButtonOnLeft] = "10/CBL"; + tags[QWizard::HaveHelpButton] = "11/HHB"; + tags[QWizard::HelpButtonOnRight] = "12/HBR"; + tags[QWizard::HaveCustomButton1] = "13/CB1"; + tags[QWizard::HaveCustomButton2] = "14/CB2"; + tags[QWizard::HaveCustomButton3] = "15/CB3"; + + for (int i = 0; i < 2; ++i) { + QMap operations_; + foreach (QWizard::WizardOption option, tags.keys()) + operations_[option] = new SetOption(option, i == 1); + operations << operations_; + } + } + OptionInfo(OptionInfo const&); + OptionInfo& operator=(OptionInfo const&); + QMap tags; + QList > operations; +public: + static OptionInfo &instance() + { + static OptionInfo optionInfo; + return optionInfo; + } + + QString tag(QWizard::WizardOption option) const { return tags.value(option); } + Operation * operation(QWizard::WizardOption option, bool on) const + { return operations.at(on).value(option); } + QList options() const { return tags.keys(); } +}; + +QString SetOption::describe() const +{ + return QString("set opt %1 %2").arg(OptionInfo::instance().tag(option)).arg(on); +} + +Q_DECLARE_METATYPE(Operation *) +Q_DECLARE_METATYPE(SetPage *) +Q_DECLARE_METATYPE(SetStyle *) +Q_DECLARE_METATYPE(SetOption *) +Q_DECLARE_METATYPE(QList) + +class TestGroup +{ +public: + enum Type {Equality, NonEquality}; + + TestGroup(const QString &name = QString("no name"), Type type = Equality) + : name(name), type(type), nRows_(0) {} + + void reset(const QString &name, Type type = Equality) + { + this->name = name; + this->type = type; + combinations.clear(); + } + + QList &add() + { combinations << new QList; return *(combinations.last()); } + + void createTestRows() + { + for (int i = 0; i < combinations.count(); ++i) { + QTest::newRow((name + QString(", row %1").arg(i)).toLatin1().data()) + << (i == 0) << (type == Equality) << *(combinations.at(i)); + ++nRows_; + } + } + + int nRows() const { return nRows_; } + +private: + QString name; + Type type; + int nRows_; + QList *> combinations; +}; + +class IntroPage : public QWizardPage +{ + Q_OBJECT +public: + IntroPage() + { + setTitle(tr("Intro")); + setSubTitle(tr("Intro Subtitle")); + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(new QLabel(tr("Intro Label"))); + setLayout(layout); + } +}; + +class MiddlePage : public QWizardPage +{ + Q_OBJECT +public: + MiddlePage() + { + setTitle(tr("Middle")); + setSubTitle(tr("Middle Subtitle")); + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(new QLabel(tr("Middle Label"))); + setLayout(layout); + } +}; + +class ConclusionPage : public QWizardPage +{ + Q_OBJECT +public: + ConclusionPage() + { + setTitle(tr("Conclusion")); + setSubTitle(tr("Conclusion Subtitle")); + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(new QLabel(tr("Conclusion Label"))); + setLayout(layout); + } +}; + +class TestWizard : public QWizard +{ + Q_OBJECT + QList pageIds; + QString opsDescr; +public: + TestWizard() + { + setPixmap(QWizard::BannerPixmap, QPixmap(":/images/banner.png")); + setPixmap(QWizard::BackgroundPixmap, QPixmap(":/images/background.png")); + setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark.png")); + setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo.png")); + setButtonText(QWizard::CustomButton1, "custom 1"); + setButtonText(QWizard::CustomButton2, "custom 2"); + setButtonText(QWizard::CustomButton3, "custom 3"); + pageIds << addPage(new IntroPage); + pageIds << addPage(new MiddlePage); + pageIds << addPage(new ConclusionPage); + + // Disable antialiased font rendering since this may sometimes result in tiny + // and (apparent) non-deterministic pixel variations between images expected to be + // identical. This may only be a problem on X11. + QFont f = font(); + f.setStyleStrategy(QFont::NoAntialias); + setFont(f); + + // ### Required to work with a deficiency(?) in QWizard: +// setFixedSize(800, 600); + } + + ~TestWizard() + { + foreach (int id, pageIds) + delete page(id); + } + + void applyOperations(const QList &operations) + { + foreach (Operation * op, operations) { + if (op) { + op->apply(this); + opsDescr += QString("(%1) ").arg(op->describe()); + } + } + } + + QImage createImage() const + { + return QPixmap::grabWidget(const_cast(this)) + .toImage().convertToFormat(QImage::Format_ARGB32); + } + + QString operationsDescription() const { return opsDescr; } +}; + +class CombinationsTestData +{ + TestGroup testGroup; + QList pageOps; + QList styleOps; + QMap *> setAllOptions; +public: + CombinationsTestData() + { + QTest::addColumn("ref"); + QTest::addColumn("testEquality"); + QTest::addColumn >("operations"); + pageOps << new SetPage(0) << new SetPage(1) << new SetPage(2); + styleOps << new SetStyle(QWizard::ClassicStyle) << new SetStyle(QWizard::ModernStyle) + << new SetStyle(QWizard::MacStyle); +#define SETPAGE(page) pageOps.at(page) +#define SETSTYLE(style) styleOps.at(style) +#define OPT(option, on) OptionInfo::instance().operation(option, on) +#define CLROPT(option) OPT(option, false) +#define SETOPT(option) OPT(option, true) + setAllOptions[false] = new QList; + setAllOptions[true] = new QList; + foreach (QWizard::WizardOption option, OptionInfo::instance().options()) { + *setAllOptions.value(false) << CLROPT(option); + *setAllOptions.value(true) << SETOPT(option); + } +#define CLRALLOPTS *setAllOptions.value(false) +#define SETALLOPTS *setAllOptions.value(true) + } + + int nRows() const { return testGroup.nRows(); } + + // Creates "all" possible test rows. (WARNING: This typically makes the test take too long!) + void createAllTestRows() + { + testGroup.reset("testAll 1.1"); + testGroup.add(); // i.e. no operations applied! + testGroup.add() << SETPAGE(0); + testGroup.add() << SETSTYLE(0); + testGroup.add() << SETPAGE(0) << SETSTYLE(0); + testGroup.add() << SETSTYLE(0) << SETPAGE(0); + testGroup.createTestRows(); + + testGroup.reset("testAll 2.1"); + testGroup.add(); + testGroup.add() << CLRALLOPTS; + testGroup.createTestRows(); + + testGroup.reset("testAll 2.2"); + testGroup.add() << SETALLOPTS; + testGroup.add() << SETALLOPTS << SETALLOPTS; + testGroup.createTestRows(); + + testGroup.reset("testAll 2.3"); + testGroup.add() << CLRALLOPTS; + testGroup.add() << CLRALLOPTS << CLRALLOPTS; + testGroup.createTestRows(); + + testGroup.reset("testAll 2.4"); + testGroup.add() << CLRALLOPTS; + testGroup.add() << SETALLOPTS << CLRALLOPTS; + testGroup.createTestRows(); + + testGroup.reset("testAll 2.5"); + testGroup.add() << SETALLOPTS; + testGroup.add() << CLRALLOPTS << SETALLOPTS; + testGroup.createTestRows(); + + testGroup.reset("testAll 2.6"); + testGroup.add() << SETALLOPTS; + testGroup.add() << SETALLOPTS << CLRALLOPTS << SETALLOPTS; + testGroup.createTestRows(); + + testGroup.reset("testAll 2.7"); + testGroup.add() << CLRALLOPTS; + testGroup.add() << CLRALLOPTS << SETALLOPTS << CLRALLOPTS; + testGroup.createTestRows(); + + for (int i = 0; i < 2; ++i) { + QList setOptions = *setAllOptions.value(i == 1); + + testGroup.reset("testAll 3.1"); + testGroup.add() << setOptions; + testGroup.add() << SETPAGE(0) << setOptions; + testGroup.add() << setOptions << SETPAGE(0); + testGroup.add() << SETSTYLE(0) << setOptions; + testGroup.add() << setOptions << SETSTYLE(0); + testGroup.add() << setOptions << SETPAGE(0) << SETSTYLE(0); + testGroup.add() << SETPAGE(0) << setOptions << SETSTYLE(0); + testGroup.add() << SETPAGE(0) << SETSTYLE(0) << setOptions; + testGroup.add() << setOptions << SETSTYLE(0) << SETPAGE(0); + testGroup.add() << SETSTYLE(0) << setOptions << SETPAGE(0); + testGroup.add() << SETSTYLE(0) << SETPAGE(0) << setOptions; + testGroup.createTestRows(); + } + + foreach (Operation *pageOp, pageOps) { + testGroup.reset("testAll 4.1"); + testGroup.add() << pageOp; + testGroup.add() << pageOp << pageOp; + testGroup.createTestRows(); + + for (int i = 0; i < 2; ++i) { + QList optionOps = *setAllOptions.value(i == 1); + testGroup.reset("testAll 4.2"); + testGroup.add() << optionOps << pageOp; + testGroup.add() << pageOp << optionOps; + testGroup.createTestRows(); + + foreach (QWizard::WizardOption option, OptionInfo::instance().options()) { + Operation *optionOp = OPT(option, i == 1); + testGroup.reset("testAll 4.3"); + testGroup.add() << optionOp << pageOp; + testGroup.add() << pageOp << optionOp; + testGroup.createTestRows(); + } + } + } + + foreach (Operation *styleOp, styleOps) { + testGroup.reset("testAll 5.1"); + testGroup.add() << styleOp; + testGroup.add() << styleOp << styleOp; + testGroup.createTestRows(); + + for (int i = 0; i < 2; ++i) { + QList optionOps = *setAllOptions.value(i == 1); + testGroup.reset("testAll 5.2"); + testGroup.add() << optionOps << styleOp; + testGroup.add() << styleOp << optionOps; + testGroup.createTestRows(); + + foreach (QWizard::WizardOption option, OptionInfo::instance().options()) { + Operation *optionOp = OPT(option, i == 1); + testGroup.reset("testAll 5.3"); + testGroup.add() << optionOp << styleOp; + testGroup.add() << styleOp << optionOp; + testGroup.createTestRows(); + } + } + } + + foreach (Operation *pageOp, pageOps) { + foreach (Operation *styleOp, styleOps) { + + testGroup.reset("testAll 6.1"); + testGroup.add() << pageOp; + testGroup.add() << pageOp << pageOp; + testGroup.createTestRows(); + + testGroup.reset("testAll 6.2"); + testGroup.add() << styleOp; + testGroup.add() << styleOp << styleOp; + testGroup.createTestRows(); + + testGroup.reset("testAll 6.3"); + testGroup.add() << pageOp << styleOp; + testGroup.add() << styleOp << pageOp; + testGroup.createTestRows(); + + for (int i = 0; i < 2; ++i) { + QList optionOps = *setAllOptions.value(i == 1); + testGroup.reset("testAll 6.4"); + testGroup.add() << optionOps << pageOp << styleOp; + testGroup.add() << pageOp << optionOps << styleOp; + testGroup.add() << pageOp << styleOp << optionOps; + testGroup.add() << optionOps << styleOp << pageOp; + testGroup.add() << styleOp << optionOps << pageOp; + testGroup.add() << styleOp << pageOp << optionOps; + testGroup.createTestRows(); + + foreach (QWizard::WizardOption option, OptionInfo::instance().options()) { + Operation *optionOp = OPT(option, i == 1); + testGroup.reset("testAll 6.5"); + testGroup.add() << optionOp << pageOp << styleOp; + testGroup.add() << pageOp << optionOp << styleOp; + testGroup.add() << pageOp << styleOp << optionOp; + testGroup.add() << optionOp << styleOp << pageOp; + testGroup.add() << styleOp << optionOp << pageOp; + testGroup.add() << styleOp << pageOp << optionOp; + testGroup.createTestRows(); + } + } + } + } + + testGroup.reset("testAll 7.1", TestGroup::NonEquality); + testGroup.add() << SETPAGE(0); + testGroup.add() << SETPAGE(1); + testGroup.add() << SETPAGE(2); + testGroup.createTestRows(); + + testGroup.reset("testAll 7.2", TestGroup::NonEquality); + testGroup.add() << SETSTYLE(0); + testGroup.add() << SETSTYLE(1); + testGroup.add() << SETSTYLE(2); + testGroup.createTestRows(); + + // more to follow ... + } + + // Creates a "small" number of interesting test rows. + void createTestRows1() + { + testGroup.reset("test1 1"); + testGroup.add() << SETPAGE(0) << SETOPT(QWizard::HaveCustomButton3); + testGroup.add() << SETOPT(QWizard::HaveCustomButton3); + testGroup.createTestRows(); + + testGroup.reset("test1 2"); + testGroup.add() << SETOPT(QWizard::HaveFinishButtonOnEarlyPages) << SETPAGE(0); + testGroup.add() << SETPAGE(0) << SETOPT(QWizard::HaveFinishButtonOnEarlyPages); + testGroup.createTestRows(); + + testGroup.reset("test1 3"); + testGroup.add() << SETPAGE(2) << SETOPT(QWizard::HaveNextButtonOnLastPage); + testGroup.add() << SETOPT(QWizard::HaveNextButtonOnLastPage) << SETPAGE(2); + testGroup.createTestRows(); + } +}; + +void tst_QWizard::combinations_data() +{ + CombinationsTestData combTestData; +// combTestData.createAllTestRows(); + combTestData.createTestRows1(); + +// qDebug() << "test rows:" << combTestData.nRows(); +} + +void tst_QWizard::combinations() +{ +#ifdef Q_OS_WINCE + QSKIP("Too much memory usage for testing on CE emulator", SkipAll); +#endif + + QFETCH(bool, ref); + QFETCH(bool, testEquality); + QFETCH(QList, operations); + + TestWizard wizard; +#if !defined(QT_NO_STYLE_WINDOWSVISTA) + if (wizard.wizardStyle() == QWizard::AeroStyle) + return; // ### TODO: passes/fails in a unpredictable way, so disable for now +#endif + wizard.applyOperations(operations); + wizard.show(); // ### TODO: Required, but why? Should wizard.createImage() care? + + static QImage refImage; + static QSize refMinSize; + static QString refDescr; + + if (ref) { + refImage = wizard.createImage(); + refMinSize = wizard.minimumSizeHint(); + refDescr = wizard.operationsDescription(); + return; + } + + QImage image = wizard.createImage(); + + bool minSizeTest = wizard.minimumSizeHint() != refMinSize; + bool imageTest = image != refImage; + QLatin1String otor("!="); + QLatin1String reason("differ"); + + if (!testEquality) { + minSizeTest = false; // the image test is sufficient! + imageTest = !imageTest; + otor = QLatin1String("=="); + reason = QLatin1String("are equal"); + } + + if (minSizeTest) + qDebug() << "minimum sizes" << reason.latin1() << ";" << wizard.minimumSizeHint() + << otor.latin1() << refMinSize; + + if (imageTest) + qDebug() << "images" << reason.latin1(); + + if (minSizeTest || imageTest) { + qDebug() << "\t row 0 operations:" << refDescr.toLatin1(); + qDebug() << "\tcurrent row operations:" << wizard.operationsDescription().toLatin1(); + QVERIFY(false); + } +} + +class WizardPage : public QWizardPage +{ + Q_OBJECT + bool shown_; + void showEvent(QShowEvent *) { shown_ = true; } + void hideEvent(QHideEvent *) { shown_ = false; } +public: + WizardPage() : shown_(false) {} + bool shown() const { return shown_; } +}; + +class WizardPages +{ + QList pages; +public: + void add(WizardPage *page) { pages << page; } + QList all() const { return pages; } + QList shown() const + { + QList result; + foreach (WizardPage *page, pages) + if (page->shown()) + result << page; + return result; + } +}; + +void tst_QWizard::showCurrentPageOnly() +{ + QWizard wizard; + WizardPages pages; + for (int i = 0; i < 5; ++i) { + pages.add(new WizardPage); + wizard.addPage(pages.all().last()); + } + + wizard.show(); + + QCOMPARE(pages.shown().count(), 1); + QCOMPARE(pages.shown().first(), pages.all().first()); + + const int steps = 2; + for (int i = 0; i < steps; ++i) + wizard.next(); + + QCOMPARE(pages.shown().count(), 1); + QCOMPARE(pages.shown().first(), pages.all().at(steps)); + + wizard.restart(); + + QCOMPARE(pages.shown().count(), 1); + QCOMPARE(pages.shown().first(), pages.all().first()); +} + +void tst_QWizard::setButtonText() +{ + QWizard wizard; + wizard.setWizardStyle(QWizard::ClassicStyle); + QWizardPage* page1 = new QWizardPage; + QWizardPage* page2 = new QWizardPage; + wizard.addPage(page1); + wizard.addPage(page2); + + wizard.show(); + qApp->processEvents(); + QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next")); + QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next")); + QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next")); + QVERIFY(page2->buttonText(QWizard::NextButton).contains("Next")); + + page2->setButtonText(QWizard::NextButton, "Page2"); + QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next")); + QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next")); + QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next")); + QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2")); + + wizard.next(); + qApp->processEvents(); + QCOMPARE(wizard.button(QWizard::NextButton)->text(), QString("Page2")); + QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next")); + QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next")); + QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2")); + + wizard.back(); + qApp->processEvents(); + QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next")); + QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next")); + QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next")); + QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2")); + + wizard.setButtonText(QWizard::NextButton, "Wizard"); + QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Wizard")); + QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("Wizard")); + QCOMPARE(page1->buttonText(QWizard::NextButton), QString("Wizard")); + QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2")); + + wizard.next(); + qApp->processEvents(); + QCOMPARE(wizard.button(QWizard::NextButton)->text(), QString("Page2")); + QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Wizard")); + QCOMPARE(page1->buttonText(QWizard::NextButton), QString("Wizard")); + QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2")); +} + +void tst_QWizard::setCommitPage() +{ + QWizard wizard; + QWizardPage* page1 = new QWizardPage; + QWizardPage* page2 = new QWizardPage; + wizard.addPage(page1); + wizard.addPage(page2); + wizard.show(); + qApp->processEvents(); + + QVERIFY(!page1->isCommitPage()); + QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); + + wizard.next(); + QVERIFY(wizard.button(QWizard::BackButton)->isEnabled()); + + page1->setCommitPage(true); + QVERIFY(page1->isCommitPage()); + + wizard.back(); + QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); + + wizard.next(); + QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); + + page1->setCommitPage(false); + QVERIFY(!page1->isCommitPage()); + + wizard.back(); + QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); + + wizard.next(); + QVERIFY(wizard.button(QWizard::BackButton)->isEnabled()); + + // ### test relabeling of the Cancel button to "Close" once this is implemented +} + +void tst_QWizard::setWizardStyle() +{ + QWizard wizard; + wizard.addPage(new QWizardPage); + wizard.show(); + qApp->processEvents(); + + // defaults + const bool styleHintMatch = + wizard.wizardStyle() == + QWizard::WizardStyle(wizard.style()->styleHint(QStyle::SH_WizardStyle, 0, &wizard)); +#if !defined(QT_NO_STYLE_WINDOWSVISTA) + QVERIFY(styleHintMatch || wizard.wizardStyle() == QWizard::AeroStyle); +#else + QVERIFY(styleHintMatch); +#endif + + // set/get consistency + for (int wstyle = 0; wstyle < QWizard::NStyles; ++wstyle) { + wizard.setWizardStyle((QWizard::WizardStyle)wstyle); + QCOMPARE((int)wizard.wizardStyle(), wstyle); + } +} + +void tst_QWizard::removePage() +{ + QWizard wizard; + QWizardPage *page0 = new QWizardPage; + QWizardPage *page1 = new QWizardPage; + QWizardPage *page2 = new QWizardPage; + QWizardPage *page3 = new QWizardPage; + + wizard.setPage(0, page0); + wizard.setPage(1, page1); + wizard.setPage(2, page2); + wizard.setPage(3, page3); + + wizard.restart(); + QCOMPARE(wizard.pageIds().size(), 4); + QCOMPARE(wizard.visitedPages().size(), 1); + + // Removing a non-existent page + wizard.removePage(4); + QCOMPARE(wizard.pageIds().size(), 4); + + // Removing and then reinserting a page + QCOMPARE(wizard.pageIds().size(), 4); + QVERIFY(wizard.pageIds().contains(2)); + wizard.removePage(2); + QCOMPARE(wizard.pageIds().size(), 3); + QVERIFY(!wizard.pageIds().contains(2)); + wizard.setPage(2, page2); + QCOMPARE(wizard.pageIds().size(), 4); + QVERIFY(wizard.pageIds().contains(2)); + + // Removing the same page twice + wizard.removePage(2); // restore + QCOMPARE(wizard.pageIds().size(), 3); + QVERIFY(!wizard.pageIds().contains(2)); + wizard.removePage(2); + QCOMPARE(wizard.pageIds().size(), 3); + QVERIFY(!wizard.pageIds().contains(2)); + + // Removing a page not in the history + wizard.setPage(2, page2); // restore + wizard.restart(); + wizard.next(); + QCOMPARE(wizard.visitedPages().size(), 2); + QCOMPARE(wizard.currentPage(), page1); + wizard.removePage(2); + QCOMPARE(wizard.visitedPages().size(), 2); + QVERIFY(!wizard.pageIds().contains(2)); + QCOMPARE(wizard.currentPage(), page1); + + // Removing a page in the history before the current page + wizard.setPage(2, page2); // restore + wizard.restart(); + wizard.next(); + QCOMPARE(wizard.visitedPages().size(), 2); + QCOMPARE(wizard.currentPage(), page1); + wizard.removePage(0); + QCOMPARE(wizard.visitedPages().size(), 1); + QVERIFY(!wizard.visitedPages().contains(0)); + QVERIFY(!wizard.pageIds().contains(0)); + QCOMPARE(wizard.currentPage(), page1); + + // Remove the current page which is not the first one in the history + wizard.setPage(0, page0); // restore + wizard.restart(); + wizard.next(); + QCOMPARE(wizard.visitedPages().size(), 2); + QCOMPARE(wizard.currentPage(), page1); + wizard.removePage(1); + QCOMPARE(wizard.visitedPages().size(), 1); + QVERIFY(!wizard.visitedPages().contains(1)); + QVERIFY(!wizard.pageIds().contains(1)); + QCOMPARE(wizard.currentPage(), page0); + + // Remove the current page which is the first (and only) one in the history + wizard.removePage(0); + QCOMPARE(wizard.visitedPages().size(), 1); + QVERIFY(!wizard.visitedPages().contains(0)); + QCOMPARE(wizard.pageIds().size(), 2); + QVERIFY(!wizard.pageIds().contains(0)); + QCOMPARE(wizard.currentPage(), page2); + // + wizard.removePage(2); + QCOMPARE(wizard.visitedPages().size(), 1); + QVERIFY(!wizard.visitedPages().contains(2)); + QCOMPARE(wizard.pageIds().size(), 1); + QVERIFY(!wizard.pageIds().contains(2)); + QCOMPARE(wizard.currentPage(), page3); + // + wizard.removePage(3); + QVERIFY(wizard.visitedPages().empty()); + QVERIFY(wizard.pageIds().empty()); + QCOMPARE(wizard.currentPage(), static_cast(0)); +} + +void tst_QWizard::task161660_buttonSpacing() +{ +#ifndef QT_NO_STYLE_PLASTIQUE + QString origStyle = QApplication::style()->objectName(); + QApplication::setStyle(new QPlastiqueStyle); + QWizard wizard; + wizard.addPage(new QWizardPage); + wizard.show(); + const QAbstractButton *finishButton = wizard.button(QWizard::FinishButton); + const QAbstractButton *cancelButton = wizard.button(QWizard::CancelButton); + const int spacing = cancelButton->geometry().left() - finishButton->geometry().right() - 1; + QCOMPARE(spacing, wizard.style()->layoutSpacing( + QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal)); + QApplication::setStyle(origStyle); +#endif +} + +class task177716_CommitPage : public QWizardPage +{ + Q_OBJECT +public: + task177716_CommitPage() + { + setCommitPage(true); + QVBoxLayout *layout = new QVBoxLayout; + ledit = new QLineEdit(this); + registerField("foo*", ledit); + layout->addWidget(ledit); + setLayout(layout); + } + QLineEdit *ledit; +}; + +void tst_QWizard::task177716_disableCommitButton() +{ + QWizard wizard; + task177716_CommitPage *commitPage = new task177716_CommitPage; + wizard.addPage(commitPage); + // the following page must be there to prevent the first page from replacing the Commit button + // with the Finish button: + wizard.addPage(new QWizardPage); + wizard.show(); + QVERIFY(!wizard.button(QWizard::CommitButton)->isEnabled()); + commitPage->ledit->setText("some non-empty text"); + QVERIFY(wizard.button(QWizard::CommitButton)->isEnabled()); + commitPage->ledit->setText(""); + QVERIFY(!wizard.button(QWizard::CommitButton)->isEnabled()); +} + +class WizardPage_task183550 : public QWizardPage +{ +public: + WizardPage_task183550(QWidget *parent = 0) + : QWizardPage(parent) + , treeWidget(new QTreeWidget) + , verticalPolicy(QSizePolicy::MinimumExpanding) {} + void enableVerticalExpansion() { verticalPolicy = QSizePolicy::MinimumExpanding; } + void disableVerticalExpansion() { verticalPolicy = QSizePolicy::Preferred; } + int treeWidgetHeight() const { return treeWidget->height(); } + int treeWidgetSizeHintHeight() const { return treeWidget->sizeHint().height(); } + +private: + QTreeWidget *treeWidget; + QSizePolicy::Policy verticalPolicy; + + void initializePage() + { + if (layout()) + delete layout(); + if (treeWidget) + delete treeWidget; + + QLayout *layout_ = new QVBoxLayout(this); + layout_->addWidget(treeWidget = new QTreeWidget); + + QSizePolicy policy = sizePolicy(); + policy.setVerticalPolicy(verticalPolicy); + treeWidget->setSizePolicy(policy); + } +}; + +void tst_QWizard::task183550_stretchFactor() +{ + QWizard wizard; + WizardPage_task183550 *page1 = new WizardPage_task183550; + WizardPage_task183550 *page2 = new WizardPage_task183550; + wizard.addPage(page1); + wizard.addPage(page2); + wizard.resize(500, 2 * page2->treeWidgetSizeHintHeight()); + wizard.show(); + + QCOMPARE(wizard.currentPage(), static_cast(page1)); + + // ---- + page2->disableVerticalExpansion(); + wizard.next(); + QCOMPARE(wizard.currentPage(), static_cast(page2)); + QVERIFY(page2->treeWidgetHeight() == page2->treeWidgetSizeHintHeight()); + + wizard.back(); + QCOMPARE(wizard.currentPage(), static_cast(page1)); + + // ---- + page2->enableVerticalExpansion(); + wizard.next(); + QCOMPARE(wizard.currentPage(), static_cast(page2)); + QVERIFY(page2->treeWidgetHeight() > page2->treeWidgetSizeHintHeight()); + + wizard.back(); + QCOMPARE(wizard.currentPage(), static_cast(page1)); + + // ---- + page2->disableVerticalExpansion(); + wizard.next(); + QCOMPARE(wizard.currentPage(), static_cast(page2)); + QVERIFY(page2->treeWidgetHeight() == page2->treeWidgetSizeHintHeight()); +} + +void tst_QWizard::task161658_alignments() +{ + QWizard wizard; + wizard.setWizardStyle(QWizard::MacStyle); + + QWizardPage page; + page.setTitle("Title"); + page.setSubTitle("SUBTITLE#: The subtitle bust be alligned with the rest of the widget"); + + QLabel label1("Field:"); + QLineEdit lineEdit1; + QGridLayout *layout = new QGridLayout; + layout->addWidget(&label1, 0, 0); + layout->addWidget(&lineEdit1, 0, 1); + page.setLayout(layout); + + int idx = wizard.addPage(&page); + wizard.setStartId(idx); + wizard.show(); + QTest::qWait(100); + + foreach (QLabel *subtitleLabel, qFindChildren(&wizard)) { + if (subtitleLabel->text().startsWith("SUBTITLE#")) { + QCOMPARE(lineEdit1.mapToGlobal(lineEdit1.contentsRect().bottomRight()).x(), + subtitleLabel->mapToGlobal(subtitleLabel->contentsRect().bottomRight()).x()); + return; + } + } + QFAIL("Subtitle label not found"); +} + +void tst_QWizard::task177022_setFixedSize() +{ + int width = 300; + int height = 200; + QWizard wiz; + QWizardPage page1; + QWizardPage page2; + wiz.addPage(&page1); + wiz.addPage(&page2); + wiz.setFixedSize(width, height); + if (wiz.wizardStyle() == QWizard::AeroStyle) + QEXPECT_FAIL("", "this probably relates to non-client area hack for AeroStyle titlebar " + "effect; not sure if it qualifies as a bug or not", Continue); + QCOMPARE(wiz.size(), QSize(width, height)); + QCOMPARE(wiz.minimumWidth(), width); + QCOMPARE(wiz.minimumHeight(), height); + QCOMPARE(wiz.maximumWidth(), width); + QCOMPARE(wiz.maximumHeight(), height); + + wiz.show(); + QTest::qWait(100); + QCOMPARE(wiz.size(), QSize(width, height)); + QCOMPARE(wiz.minimumWidth(), width); + QCOMPARE(wiz.minimumHeight(), height); + QCOMPARE(wiz.maximumWidth(), width); + QCOMPARE(wiz.maximumHeight(), height); + + wiz.next(); + QTest::qWait(100); + QCOMPARE(wiz.size(), QSize(width, height)); + QCOMPARE(wiz.minimumWidth(), width); + QCOMPARE(wiz.minimumHeight(), height); + QCOMPARE(wiz.maximumWidth(), width); + QCOMPARE(wiz.maximumHeight(), height); + +} + +void tst_QWizard::task248107_backButton() +{ + QWizard wizard; + QWizardPage page1; + QWizardPage page2; + QWizardPage page3; + QWizardPage page4; + wizard.addPage(&page1); + wizard.addPage(&page2); + wizard.addPage(&page3); + wizard.addPage(&page4); + + wizard.show(); + QTest::qWait(100); + QCOMPARE(wizard.currentPage(), &page1); + + QTest::mouseClick(wizard.button(QWizard::NextButton), Qt::LeftButton); + QCOMPARE(wizard.currentPage(), &page2); + + QTest::mouseClick(wizard.button(QWizard::NextButton), Qt::LeftButton); + QCOMPARE(wizard.currentPage(), &page3); + + QTest::mouseClick(wizard.button(QWizard::NextButton), Qt::LeftButton); + QCOMPARE(wizard.currentPage(), &page4); + + QTest::mouseClick(wizard.button(QWizard::BackButton), Qt::LeftButton); + QCOMPARE(wizard.currentPage(), &page3); + + QTest::mouseClick(wizard.button(QWizard::BackButton), Qt::LeftButton); + QCOMPARE(wizard.currentPage(), &page2); + + QTest::mouseClick(wizard.button(QWizard::BackButton), Qt::LeftButton); + QCOMPARE(wizard.currentPage(), &page1); +} + +class WizardPage_task255350 : public QWizardPage +{ +public: + QLineEdit *lineEdit; + WizardPage_task255350() + : lineEdit(new QLineEdit) + { + registerField("dummy*", lineEdit); + } +}; + +void tst_QWizard::task255350_fieldObjectDestroyed() +{ + QWizard wizard; + WizardPage_task255350 *page = new WizardPage_task255350; + int id = wizard.addPage(page); + delete page->lineEdit; + wizard.removePage(id); // don't crash! + delete page; +} + +QTEST_MAIN(tst_QWizard) +#include "tst_qwizard.moc"