/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwizard.h"
#include <QtWidgets/private/qtwidgetsglobal_p.h>

#if QT_CONFIG(spinbox)
#include "qabstractspinbox.h"
#endif
#include "qalgorithms.h"
#include "qapplication.h"
#include "qboxlayout.h"
#include "qlayoutitem.h"
#include "qdesktopwidget.h"
#include <private/qdesktopwidget_p.h>
#include "qevent.h"
#include "qframe.h"
#include "qlabel.h"
#if QT_CONFIG(lineedit)
#include "qlineedit.h"
#endif
#include <qpointer.h>
#include "qpainter.h"
#include "qwindow.h"
#include "qpushbutton.h"
#include "qset.h"
#if QT_CONFIG(shortcut)
#  include "qshortcut.h"
#endif
#include "qstyle.h"
#include "qvarlengtharray.h"
#if defined(Q_OS_MACX)
#include <QtCore/QMetaMethod>
#include <QtGui/QGuiApplication>
#include <qpa/qplatformnativeinterface.h>
#elif QT_CONFIG(style_windowsvista)
#include "qwizard_win_p.h"
#include "qtimer.h"
#endif

#include "private/qdialog_p.h"
#include <qdebug.h>

#include <string.h>     // for memset()
#include <algorithm>

QT_BEGIN_NAMESPACE

// These fudge terms were needed a few places to obtain pixel-perfect results
const int GapBetweenLogoAndRightEdge = 5;
const int ModernHeaderTopMargin = 2;
const int ClassicHMargin = 4;
const int MacButtonTopMargin = 13;
const int MacLayoutLeftMargin = 20;
//const int MacLayoutTopMargin = 14; // Unused. Save some space and avoid warning.
const int MacLayoutRightMargin = 20;
const int MacLayoutBottomMargin = 17;

static void changeSpacerSize(QLayout *layout, int index, int width, int height)
{
    QSpacerItem *spacer = layout->itemAt(index)->spacerItem();
    if (!spacer)
        return;
    spacer->changeSize(width, height);
}

static QWidget *iWantTheFocus(QWidget *ancestor)
{
    const int MaxIterations = 100;

    QWidget *candidate = ancestor;
    for (int i = 0; i < MaxIterations; ++i) {
        candidate = candidate->nextInFocusChain();
        if (!candidate)
            break;

        if (candidate->focusPolicy() & Qt::TabFocus) {
            if (candidate != ancestor && ancestor->isAncestorOf(candidate))
                return candidate;
        }
    }
    return 0;
}

static bool objectInheritsXAndXIsCloserThanY(const QObject *object, const QByteArray &classX,
                                             const QByteArray &classY)
{
    const QMetaObject *metaObject = object->metaObject();
    while (metaObject) {
        if (metaObject->className() == classX)
            return true;
        if (metaObject->className() == classY)
            return false;
        metaObject = metaObject->superClass();
    }
    return false;
}

const struct {
    const char className[16];
    const char property[13];
} fallbackProperties[] = {
    // If you modify this list, make sure to update the documentation (and the auto test)
    { "QAbstractButton", "checked" },
    { "QAbstractSlider", "value" },
    { "QComboBox", "currentIndex" },
    { "QDateTimeEdit", "dateTime" },
    { "QLineEdit", "text" },
    { "QListWidget", "currentRow" },
    { "QSpinBox", "value" },
};
const size_t NFallbackDefaultProperties = sizeof fallbackProperties / sizeof *fallbackProperties;

static const char *changed_signal(int which)
{
    // since it might expand to a runtime function call (to
    // qFlagLocations()), we cannot store the result of SIGNAL() in a
    // character array and expect it to be statically initialized. To
    // avoid the relocations caused by a char pointer table, use a
    // switch statement:
    switch (which) {
    case 0: return SIGNAL(toggled(bool));
    case 1: return SIGNAL(valueChanged(int));
    case 2: return SIGNAL(currentIndexChanged(int));
    case 3: return SIGNAL(dateTimeChanged(QDateTime));
    case 4: return SIGNAL(textChanged(QString));
    case 5: return SIGNAL(currentRowChanged(int));
    case 6: return SIGNAL(valueChanged(int));
    };
    Q_STATIC_ASSERT(7 == NFallbackDefaultProperties);
    Q_UNREACHABLE();
    return 0;
}

class QWizardDefaultProperty
{
public:
    QByteArray className;
    QByteArray property;
    QByteArray changedSignal;

    inline QWizardDefaultProperty() {}
    inline QWizardDefaultProperty(const char *className, const char *property,
                                   const char *changedSignal)
        : className(className), property(property), changedSignal(changedSignal) {}
};
Q_DECLARE_TYPEINFO(QWizardDefaultProperty, Q_MOVABLE_TYPE);

class QWizardField
{
public:
    inline QWizardField() {}
    QWizardField(QWizardPage *page, const QString &spec, QObject *object, const char *property,
                  const char *changedSignal);

    void resolve(const QVector<QWizardDefaultProperty> &defaultPropertyTable);
    void findProperty(const QWizardDefaultProperty *properties, int propertyCount);

    QWizardPage *page;
    QString name;
    bool mandatory;
    QObject *object;
    QByteArray property;
    QByteArray changedSignal;
    QVariant initialValue;
};
Q_DECLARE_TYPEINFO(QWizardField, Q_MOVABLE_TYPE);

QWizardField::QWizardField(QWizardPage *page, const QString &spec, QObject *object,
                           const char *property, const char *changedSignal)
    : page(page), name(spec), mandatory(false), object(object), property(property),
      changedSignal(changedSignal)
{
    if (name.endsWith(QLatin1Char('*'))) {
        name.chop(1);
        mandatory = true;
    }
}

void QWizardField::resolve(const QVector<QWizardDefaultProperty> &defaultPropertyTable)
{
    if (property.isEmpty())
        findProperty(defaultPropertyTable.constData(), defaultPropertyTable.count());
    initialValue = object->property(property);
}

void QWizardField::findProperty(const QWizardDefaultProperty *properties, int propertyCount)
{
    QByteArray className;

    for (int i = 0; i < propertyCount; ++i) {
        if (objectInheritsXAndXIsCloserThanY(object, properties[i].className, className)) {
            className = properties[i].className;
            property = properties[i].property;
            changedSignal = properties[i].changedSignal;
        }
    }
}

class QWizardLayoutInfo
{
public:
    int topLevelMarginLeft = -1;
    int topLevelMarginRight = -1;
    int topLevelMarginTop = -1;
    int topLevelMarginBottom = -1;
    int childMarginLeft = -1;
    int childMarginRight = -1;
    int childMarginTop = -1;
    int childMarginBottom = -1;
    int hspacing = -1;
    int vspacing = -1;
    int buttonSpacing = -1;
    QWizard::WizardStyle wizStyle = QWizard::ClassicStyle;
    bool header = false;
    bool watermark = false;
    bool title = false;
    bool subTitle = false;
    bool extension = false;
    bool sideWidget = false;

    bool operator==(const QWizardLayoutInfo &other);
    inline bool operator!=(const QWizardLayoutInfo &other) { return !operator==(other); }
};

bool QWizardLayoutInfo::operator==(const QWizardLayoutInfo &other)
{
    return topLevelMarginLeft == other.topLevelMarginLeft
           && topLevelMarginRight == other.topLevelMarginRight
           && topLevelMarginTop == other.topLevelMarginTop
           && topLevelMarginBottom == other.topLevelMarginBottom
           && childMarginLeft == other.childMarginLeft
           && childMarginRight == other.childMarginRight
           && childMarginTop == other.childMarginTop
           && childMarginBottom == other.childMarginBottom
           && hspacing == other.hspacing
           && vspacing == other.vspacing
           && buttonSpacing == other.buttonSpacing
           && wizStyle == other.wizStyle
           && header == other.header
           && watermark == other.watermark
           && title == other.title
           && subTitle == other.subTitle
           && extension == other.extension
           && sideWidget == other.sideWidget;
}

class QWizardHeader : public QWidget
{
public:
    enum RulerType { Ruler };

    inline QWizardHeader(RulerType /* ruler */, QWidget *parent = 0)
        : QWidget(parent) { setFixedHeight(2); }
    QWizardHeader(QWidget *parent = 0);

    void setup(const QWizardLayoutInfo &info, const QString &title,
               const QString &subTitle, const QPixmap &logo, const QPixmap &banner,
               Qt::TextFormat titleFormat, Qt::TextFormat subTitleFormat);

protected:
    void paintEvent(QPaintEvent *event) override;
#if QT_CONFIG(style_windowsvista)
private:
    bool vistaDisabled() const;
#endif
private:
    QLabel *titleLabel;
    QLabel *subTitleLabel;
    QLabel *logoLabel;
    QGridLayout *layout;
    QPixmap bannerPixmap;
};

QWizardHeader::QWizardHeader(QWidget *parent)
    : QWidget(parent)
{
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    setBackgroundRole(QPalette::Base);

    titleLabel = new QLabel(this);
    titleLabel->setBackgroundRole(QPalette::Base);

    subTitleLabel = new QLabel(this);
    subTitleLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
    subTitleLabel->setWordWrap(true);

    logoLabel = new QLabel(this);

    QFont font = titleLabel->font();
    font.setBold(true);
    titleLabel->setFont(font);

    layout = new QGridLayout(this);
    layout->setContentsMargins(QMargins());
    layout->setSpacing(0);

    layout->setRowMinimumHeight(3, 1);
    layout->setRowStretch(4, 1);

    layout->setColumnStretch(2, 1);
    layout->setColumnMinimumWidth(4, 2 * GapBetweenLogoAndRightEdge);
    layout->setColumnMinimumWidth(6, GapBetweenLogoAndRightEdge);

    layout->addWidget(titleLabel, 2, 1, 1, 2);
    layout->addWidget(subTitleLabel, 4, 2);
    layout->addWidget(logoLabel, 1, 5, 5, 1);
}

#if QT_CONFIG(style_windowsvista)
bool QWizardHeader::vistaDisabled() const
{
    bool styleDisabled = false;
    QWizard *wiz = parentWidget() ? qobject_cast <QWizard *>(parentWidget()->parentWidget()) : 0;
    if (wiz) {
        // Designer dosen't support the Vista style for Wizards. This property is used to turn
        // off the Vista style.
        const QVariant v = wiz->property("_q_wizard_vista_off");
        styleDisabled = v.isValid() && v.toBool();
    }
    return styleDisabled;
}
#endif

void QWizardHeader::setup(const QWizardLayoutInfo &info, const QString &title,
                          const QString &subTitle, const QPixmap &logo, const QPixmap &banner,
                          Qt::TextFormat titleFormat, Qt::TextFormat subTitleFormat)
{
    bool modern = ((info.wizStyle == QWizard::ModernStyle)
#if QT_CONFIG(style_windowsvista)
        || ((info.wizStyle == QWizard::AeroStyle
            && QVistaHelper::vistaState() == QVistaHelper::Classic) || vistaDisabled())
#endif
    );

    layout->setRowMinimumHeight(0, modern ? ModernHeaderTopMargin : 0);
    layout->setRowMinimumHeight(1, modern ? info.topLevelMarginTop - ModernHeaderTopMargin - 1 : 0);
    layout->setRowMinimumHeight(6, (modern ? 3 : GapBetweenLogoAndRightEdge) + 2);

    int minColumnWidth0 = modern ? info.topLevelMarginLeft + info.topLevelMarginRight : 0;
    int minColumnWidth1 = modern ? info.topLevelMarginLeft + info.topLevelMarginRight + 1
                                 : info.topLevelMarginLeft + ClassicHMargin;
    layout->setColumnMinimumWidth(0, minColumnWidth0);
    layout->setColumnMinimumWidth(1, minColumnWidth1);

    titleLabel->setTextFormat(titleFormat);
    titleLabel->setText(title);
    logoLabel->setPixmap(logo);

    subTitleLabel->setTextFormat(subTitleFormat);
    subTitleLabel->setText(QLatin1String("Pq\nPq"));
    int desiredSubTitleHeight = subTitleLabel->sizeHint().height();
    subTitleLabel->setText(subTitle);

    if (modern) {
        bannerPixmap = banner;
    } else {
        bannerPixmap = QPixmap();
    }

    if (bannerPixmap.isNull()) {
        /*
            There is no widthForHeight() function, so we simulate it with a loop.
        */
        int candidateSubTitleWidth = qMin(512, 2 * QDesktopWidgetPrivate::width() / 3);
        int delta = candidateSubTitleWidth >> 1;
        while (delta > 0) {
            if (subTitleLabel->heightForWidth(candidateSubTitleWidth - delta)
                        <= desiredSubTitleHeight)
                candidateSubTitleWidth -= delta;
            delta >>= 1;
        }

        subTitleLabel->setMinimumSize(candidateSubTitleWidth, desiredSubTitleHeight);

        QSize size = layout->totalMinimumSize();
        setMinimumSize(size);
        setMaximumSize(QWIDGETSIZE_MAX, size.height());
    } else {
        subTitleLabel->setMinimumSize(0, 0);
        setFixedSize(banner.size() + QSize(0, 2));
    }
    updateGeometry();
}

void QWizardHeader::paintEvent(QPaintEvent * /* event */)
{
    QPainter painter(this);
    painter.drawPixmap(0, 0, bannerPixmap);

    int x = width() - 2;
    int y = height() - 2;
    const QPalette &pal = palette();
    painter.setPen(pal.mid().color());
    painter.drawLine(0, y, x, y);
    painter.setPen(pal.base().color());
    painter.drawPoint(x + 1, y);
    painter.drawLine(0, y + 1, x + 1, y + 1);
}

// We save one vtable by basing QWizardRuler on QWizardHeader
class QWizardRuler : public QWizardHeader
{
public:
    inline QWizardRuler(QWidget *parent = 0)
        : QWizardHeader(Ruler, parent) {}
};

class QWatermarkLabel : public QLabel
{
public:
    QWatermarkLabel(QWidget *parent, QWidget *sideWidget) : QLabel(parent), m_sideWidget(sideWidget) {
        m_layout = new QVBoxLayout(this);
        if (m_sideWidget)
            m_layout->addWidget(m_sideWidget);
    }

    QSize minimumSizeHint() const override {
        if (pixmap() && !pixmap()->isNull())
            return pixmap()->size() / pixmap()->devicePixelRatio();
        return QFrame::minimumSizeHint();
    }

    void setSideWidget(QWidget *widget) {
        if (m_sideWidget == widget)
            return;
        if (m_sideWidget) {
            m_layout->removeWidget(m_sideWidget);
            m_sideWidget->hide();
        }
        m_sideWidget = widget;
        if (m_sideWidget)
            m_layout->addWidget(m_sideWidget);
    }
    QWidget *sideWidget() const {
        return m_sideWidget;
    }
private:
    QVBoxLayout *m_layout;
    QWidget *m_sideWidget;
};

class QWizardPagePrivate : public QWidgetPrivate
{
    Q_DECLARE_PUBLIC(QWizardPage)

public:
    enum TriState { Tri_Unknown = -1, Tri_False, Tri_True };

    bool cachedIsComplete() const;
    void _q_maybeEmitCompleteChanged();
    void _q_updateCachedCompleteState();

    QWizard *wizard = nullptr;
    QString title;
    QString subTitle;
    QPixmap pixmaps[QWizard::NPixmaps];
    QVector<QWizardField> pendingFields;
    mutable TriState completeState = Tri_Unknown;
    bool explicitlyFinal = false;
    bool commit = false;
    bool initialized = false;
    QMap<int, QString> buttonCustomTexts;
};

bool QWizardPagePrivate::cachedIsComplete() const
{
    Q_Q(const QWizardPage);
    if (completeState == Tri_Unknown)
        completeState = q->isComplete() ? Tri_True : Tri_False;
    return completeState == Tri_True;
}

void QWizardPagePrivate::_q_maybeEmitCompleteChanged()
{
    Q_Q(QWizardPage);
    TriState newState = q->isComplete() ? Tri_True : Tri_False;
    if (newState != completeState)
        emit q->completeChanged();
}

void QWizardPagePrivate::_q_updateCachedCompleteState()
{
    Q_Q(QWizardPage);
    completeState = q->isComplete() ? Tri_True : Tri_False;
}

class QWizardAntiFlickerWidget : public QWidget
{
public:
#if QT_CONFIG(style_windowsvista)
    QWizardPrivate *wizardPrivate;
    QWizardAntiFlickerWidget(QWizard *wizard, QWizardPrivate *wizardPrivate)
        : QWidget(wizard)
        , wizardPrivate(wizardPrivate) {}
protected:
    void paintEvent(QPaintEvent *);
#else
    QWizardAntiFlickerWidget(QWizard *wizard, QWizardPrivate *)
        : QWidget(wizard)
    {}
#endif
};

class QWizardPrivate : public QDialogPrivate
{
    Q_DECLARE_PUBLIC(QWizard)

public:
    typedef QMap<int, QWizardPage *> PageMap;

    enum Direction {
        Backward,
        Forward
    };

    void init();
    void reset();
    void cleanupPagesNotInHistory();
    void addField(const QWizardField &field);
    void removeFieldAt(int index);
    void switchToPage(int newId, Direction direction);
    QWizardLayoutInfo layoutInfoForCurrentPage();
    void recreateLayout(const QWizardLayoutInfo &info);
    void updateLayout();
    void updateMinMaxSizes(const QWizardLayoutInfo &info);
    void updateCurrentPage();
    bool ensureButton(QWizard::WizardButton which) const;
    void connectButton(QWizard::WizardButton which) const;
    void updateButtonTexts();
    void updateButtonLayout();
    void setButtonLayout(const QWizard::WizardButton *array, int size);
    bool buttonLayoutContains(QWizard::WizardButton which);
    void updatePixmap(QWizard::WizardPixmap which);
#if QT_CONFIG(style_windowsvista)
    bool vistaDisabled() const;
    bool isVistaThemeEnabled(QVistaHelper::VistaState state) const;
    bool handleAeroStyleChange();
#endif
    bool isVistaThemeEnabled() const;
    void disableUpdates();
    void enableUpdates();
    void _q_emitCustomButtonClicked();
    void _q_updateButtonStates();
    void _q_handleFieldObjectDestroyed(QObject *);
    void setStyle(QStyle *style);
#ifdef Q_OS_MACX
    static QPixmap findDefaultBackgroundPixmap();
#endif

    PageMap pageMap;
    QVector<QWizardField> fields;
    QMap<QString, int> fieldIndexMap;
    QVector<QWizardDefaultProperty> defaultPropertyTable;
    QList<int> history;
    int start = -1;
    bool startSetByUser = false;
    int current = -1;
    bool canContinue = false;
    bool canFinish = false;
    QWizardLayoutInfo layoutInfo;
    int disableUpdatesCount = 0;

    QWizard::WizardStyle wizStyle = QWizard::ClassicStyle;
    QWizard::WizardOptions opts;
    QMap<int, QString> buttonCustomTexts;
    bool buttonsHaveCustomLayout = false;
    QList<QWizard::WizardButton> buttonsCustomLayout;
    Qt::TextFormat titleFmt = Qt::AutoText;
    Qt::TextFormat subTitleFmt = Qt::AutoText;
    mutable QPixmap defaultPixmaps[QWizard::NPixmaps];

    union {
        // keep in sync with QWizard::WizardButton
        mutable struct {
            QAbstractButton *back;
            QAbstractButton *next;
            QAbstractButton *commit;
            QAbstractButton *finish;
            QAbstractButton *cancel;
            QAbstractButton *help;
        } btn;
        mutable QAbstractButton *btns[QWizard::NButtons];
    };
    QWizardAntiFlickerWidget *antiFlickerWidget = nullptr;
    QWidget *placeholderWidget1 = nullptr;
    QWidget *placeholderWidget2 = nullptr;
    QWizardHeader *headerWidget = nullptr;
    QWatermarkLabel *watermarkLabel = nullptr;
    QWidget *sideWidget = nullptr;
    QFrame *pageFrame = nullptr;
    QLabel *titleLabel = nullptr;
    QLabel *subTitleLabel = nullptr;
    QWizardRuler *bottomRuler = nullptr;

    QVBoxLayout *pageVBoxLayout = nullptr;
    QHBoxLayout *buttonLayout = nullptr;
    QGridLayout *mainLayout = nullptr;

#if QT_CONFIG(style_windowsvista)
    QVistaHelper *vistaHelper = nullptr;
#  if QT_CONFIG(shortcut)
    QPointer<QShortcut> vistaNextShortcut;
#  endif
    bool vistaInitPending = true;
    QVistaHelper::VistaState vistaState = QVistaHelper::Dirty;
    bool vistaStateChanged = false;
    bool inHandleAeroStyleChange = false;
#endif
    int minimumWidth = 0;
    int minimumHeight = 0;
    int maximumWidth = QWIDGETSIZE_MAX;
    int maximumHeight = QWIDGETSIZE_MAX;
};

static QString buttonDefaultText(int wstyle, int which, const QWizardPrivate *wizardPrivate)
{
#if !QT_CONFIG(style_windowsvista)
    Q_UNUSED(wizardPrivate);
#endif
    const bool macStyle = (wstyle == QWizard::MacStyle);
    switch (which) {
    case QWizard::BackButton:
        return macStyle ? QWizard::tr("Go Back") : QWizard::tr("< &Back");
    case QWizard::NextButton:
        if (macStyle)
            return QWizard::tr("Continue");
        else
            return wizardPrivate->isVistaThemeEnabled()
                ? QWizard::tr("&Next") : QWizard::tr("&Next >");
    case QWizard::CommitButton:
        return QWizard::tr("Commit");
    case QWizard::FinishButton:
        return macStyle ? QWizard::tr("Done") : QWizard::tr("&Finish");
    case QWizard::CancelButton:
        return QWizard::tr("Cancel");
    case QWizard::HelpButton:
        return macStyle ? QWizard::tr("Help") : QWizard::tr("&Help");
    default:
        return QString();
    }
}

void QWizardPrivate::init()
{
    Q_Q(QWizard);

    std::fill(btns, btns + QWizard::NButtons, nullptr);

    antiFlickerWidget = new QWizardAntiFlickerWidget(q, this);
    wizStyle = QWizard::WizardStyle(q->style()->styleHint(QStyle::SH_WizardStyle, 0, q));
    if (wizStyle == QWizard::MacStyle) {
        opts = (QWizard::NoDefaultButton | QWizard::NoCancelButton);
    } else if (wizStyle == QWizard::ModernStyle) {
        opts = QWizard::HelpButtonOnRight;
    }

#if QT_CONFIG(style_windowsvista)
    vistaHelper = new QVistaHelper(q);
#endif

    // create these buttons right away; create the other buttons as necessary
    ensureButton(QWizard::BackButton);
    ensureButton(QWizard::NextButton);
    ensureButton(QWizard::CommitButton);
    ensureButton(QWizard::FinishButton);

    pageFrame = new QFrame(antiFlickerWidget);
    pageFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);

    pageVBoxLayout = new QVBoxLayout(pageFrame);
    pageVBoxLayout->setSpacing(0);
    pageVBoxLayout->addSpacing(0);
    QSpacerItem *spacerItem = new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding);
    pageVBoxLayout->addItem(spacerItem);

    buttonLayout = new QHBoxLayout;
    mainLayout = new QGridLayout(antiFlickerWidget);
    mainLayout->setSizeConstraint(QLayout::SetNoConstraint);

    updateButtonLayout();

    defaultPropertyTable.reserve(NFallbackDefaultProperties);
    for (uint i = 0; i < NFallbackDefaultProperties; ++i)
        defaultPropertyTable.append(QWizardDefaultProperty(fallbackProperties[i].className,
                                                           fallbackProperties[i].property,
                                                           changed_signal(i)));
}

void QWizardPrivate::reset()
{
    Q_Q(QWizard);
    if (current != -1) {
        q->currentPage()->hide();
        cleanupPagesNotInHistory();
        for (int i = history.count() - 1; i >= 0; --i)
            q->cleanupPage(history.at(i));
        history.clear();
        for (QWizardPage *page : qAsConst(pageMap))
            page->d_func()->initialized = false;

        current = -1;
        emit q->currentIdChanged(-1);
    }
}

void QWizardPrivate::cleanupPagesNotInHistory()
{
    Q_Q(QWizard);

    for (auto it = pageMap.begin(), end = pageMap.end(); it != end; ++it) {
        const auto idx = it.key();
        const auto page = it.value()->d_func();
        if (page->initialized && !history.contains(idx)) {
            q->cleanupPage(idx);
            page->initialized = false;
        }
    }
}

void QWizardPrivate::addField(const QWizardField &field)
{
    Q_Q(QWizard);

    QWizardField myField = field;
    myField.resolve(defaultPropertyTable);

    if (Q_UNLIKELY(fieldIndexMap.contains(myField.name))) {
        qWarning("QWizardPage::addField: Duplicate field '%ls'", qUtf16Printable(myField.name));
        return;
    }

    fieldIndexMap.insert(myField.name, fields.count());
    fields += myField;
    if (myField.mandatory && !myField.changedSignal.isEmpty())
        QObject::connect(myField.object, myField.changedSignal,
                         myField.page, SLOT(_q_maybeEmitCompleteChanged()));
    QObject::connect(
        myField.object, SIGNAL(destroyed(QObject*)), q,
        SLOT(_q_handleFieldObjectDestroyed(QObject*)));
}

void QWizardPrivate::removeFieldAt(int index)
{
    Q_Q(QWizard);

    const QWizardField &field = fields.at(index);
    fieldIndexMap.remove(field.name);
    if (field.mandatory && !field.changedSignal.isEmpty())
        QObject::disconnect(field.object, field.changedSignal,
                            field.page, SLOT(_q_maybeEmitCompleteChanged()));
    QObject::disconnect(
        field.object, SIGNAL(destroyed(QObject*)), q,
        SLOT(_q_handleFieldObjectDestroyed(QObject*)));
    fields.remove(index);
}

void QWizardPrivate::switchToPage(int newId, Direction direction)
{
    Q_Q(QWizard);

    disableUpdates();

    int oldId = current;
    if (QWizardPage *oldPage = q->currentPage()) {
        oldPage->hide();

        if (direction == Backward) {
            if (!(opts & QWizard::IndependentPages)) {
                q->cleanupPage(oldId);
                oldPage->d_func()->initialized = false;
            }
            Q_ASSERT(history.constLast() == oldId);
            history.removeLast();
            Q_ASSERT(history.constLast() == newId);
        }
    }

    current = newId;

    QWizardPage *newPage = q->currentPage();
    if (newPage) {
        if (direction == Forward) {
            if (!newPage->d_func()->initialized) {
                newPage->d_func()->initialized = true;
                q->initializePage(current);
            }
            history.append(current);
        }
        newPage->show();
    }

    canContinue = (q->nextId() != -1);
    canFinish = (newPage && newPage->isFinalPage());

    _q_updateButtonStates();
    updateButtonTexts();

    const QWizard::WizardButton nextOrCommit =
        newPage && newPage->isCommitPage() ? QWizard::CommitButton : QWizard::NextButton;
    QAbstractButton *nextOrFinishButton =
        btns[canContinue ? nextOrCommit : QWizard::FinishButton];
    QWidget *candidate = 0;

    /*
        If there is no default button and the Next or Finish button
        is enabled, give focus directly to it as a convenience to the
        user. This is the normal case on OS X.

        Otherwise, give the focus to the new page's first child that
        can handle it. If there is no such child, give the focus to
        Next or Finish.
    */
    if ((opts & QWizard::NoDefaultButton) && nextOrFinishButton->isEnabled()) {
        candidate = nextOrFinishButton;
    } else if (newPage) {
        candidate = iWantTheFocus(newPage);
    }
    if (!candidate)
        candidate = nextOrFinishButton;
    candidate->setFocus();

    if (wizStyle == QWizard::MacStyle)
        q->updateGeometry();

    enableUpdates();
    updateLayout();

    emit q->currentIdChanged(current);
}

// keep in sync with QWizard::WizardButton
static const char * buttonSlots(QWizard::WizardButton which)
{
    switch (which) {
    case QWizard::BackButton:
        return SLOT(back());
    case QWizard::NextButton:
    case QWizard::CommitButton:
        return SLOT(next());
    case QWizard::FinishButton:
        return SLOT(accept());
    case QWizard::CancelButton:
        return SLOT(reject());
    case QWizard::HelpButton:
        return SIGNAL(helpRequested());
    case QWizard::CustomButton1:
    case QWizard::CustomButton2:
    case QWizard::CustomButton3:
    case QWizard::Stretch:
    case QWizard::NoButton:
        Q_UNREACHABLE();
    };
    return 0;
};

QWizardLayoutInfo QWizardPrivate::layoutInfoForCurrentPage()
{
    Q_Q(QWizard);
    QStyle *style = q->style();

    QWizardLayoutInfo info;

    const int layoutHorizontalSpacing = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
    info.topLevelMarginLeft = style->pixelMetric(QStyle::PM_LayoutLeftMargin, 0, q);
    info.topLevelMarginRight = style->pixelMetric(QStyle::PM_LayoutRightMargin, 0, q);
    info.topLevelMarginTop = style->pixelMetric(QStyle::PM_LayoutTopMargin, 0, q);
    info.topLevelMarginBottom = style->pixelMetric(QStyle::PM_LayoutBottomMargin, 0, q);
    info.childMarginLeft = style->pixelMetric(QStyle::PM_LayoutLeftMargin, 0, titleLabel);
    info.childMarginRight = style->pixelMetric(QStyle::PM_LayoutRightMargin, 0, titleLabel);
    info.childMarginTop = style->pixelMetric(QStyle::PM_LayoutTopMargin, 0, titleLabel);
    info.childMarginBottom = style->pixelMetric(QStyle::PM_LayoutBottomMargin, 0, titleLabel);
    info.hspacing = (layoutHorizontalSpacing == -1)
        ? style->layoutSpacing(QSizePolicy::DefaultType, QSizePolicy::DefaultType, Qt::Horizontal)
        : layoutHorizontalSpacing;
    info.vspacing = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing);
    info.buttonSpacing = (layoutHorizontalSpacing == -1)
        ? style->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal)
        : layoutHorizontalSpacing;

    if (wizStyle == QWizard::MacStyle)
        info.buttonSpacing = 12;

    info.wizStyle = wizStyle;
    if (info.wizStyle == QWizard::AeroStyle
#if QT_CONFIG(style_windowsvista)
        && (QVistaHelper::vistaState() == QVistaHelper::Classic || vistaDisabled())
#endif
        )
        info.wizStyle = QWizard::ModernStyle;

    QString titleText;
    QString subTitleText;
    QPixmap backgroundPixmap;
    QPixmap watermarkPixmap;

    if (QWizardPage *page = q->currentPage()) {
        titleText = page->title();
        subTitleText = page->subTitle();
        backgroundPixmap = page->pixmap(QWizard::BackgroundPixmap);
        watermarkPixmap = page->pixmap(QWizard::WatermarkPixmap);
    }

    info.header = (info.wizStyle == QWizard::ClassicStyle || info.wizStyle == QWizard::ModernStyle)
        && !(opts & QWizard::IgnoreSubTitles) && !subTitleText.isEmpty();
    info.sideWidget = sideWidget;
    info.watermark = (info.wizStyle != QWizard::MacStyle) && (info.wizStyle != QWizard::AeroStyle)
        && !watermarkPixmap.isNull();
    info.title = !info.header && !titleText.isEmpty();
    info.subTitle = !(opts & QWizard::IgnoreSubTitles) && !info.header && !subTitleText.isEmpty();
    info.extension = (info.watermark || info.sideWidget) && (opts & QWizard::ExtendedWatermarkPixmap);

    return info;
}

void QWizardPrivate::recreateLayout(const QWizardLayoutInfo &info)
{
    Q_Q(QWizard);

    /*
        Start by undoing the main layout.
    */
    for (int i = mainLayout->count() - 1; i >= 0; --i) {
        QLayoutItem *item = mainLayout->takeAt(i);
        if (item->layout()) {
            item->layout()->setParent(0);
        } else {
            delete item;
        }
    }
    for (int i = mainLayout->columnCount() - 1; i >= 0; --i)
        mainLayout->setColumnMinimumWidth(i, 0);
    for (int i = mainLayout->rowCount() - 1; i >= 0; --i)
        mainLayout->setRowMinimumHeight(i, 0);

    /*
        Now, recreate it.
    */

    bool mac = (info.wizStyle == QWizard::MacStyle);
    bool classic = (info.wizStyle == QWizard::ClassicStyle);
    bool modern = (info.wizStyle == QWizard::ModernStyle);
    bool aero = (info.wizStyle == QWizard::AeroStyle);
    int deltaMarginLeft = info.topLevelMarginLeft - info.childMarginLeft;
    int deltaMarginRight = info.topLevelMarginRight - info.childMarginRight;
    int deltaMarginTop = info.topLevelMarginTop - info.childMarginTop;
    int deltaMarginBottom = info.topLevelMarginBottom - info.childMarginBottom;
    int deltaVSpacing = info.topLevelMarginBottom - info.vspacing;

    int row = 0;
    int numColumns;
    if (mac) {
        numColumns = 3;
    } else if (info.watermark || info.sideWidget) {
        numColumns = 2;
    } else {
        numColumns = 1;
    }
    int pageColumn = qMin(1, numColumns - 1);

    if (mac) {
        mainLayout->setContentsMargins(QMargins());
        mainLayout->setSpacing(0);
        buttonLayout->setContentsMargins(MacLayoutLeftMargin, MacButtonTopMargin, MacLayoutRightMargin, MacLayoutBottomMargin);
        pageVBoxLayout->setContentsMargins(7, 7, 7, 7);
    } else {
        if (modern) {
            mainLayout->setContentsMargins(QMargins());
            mainLayout->setSpacing(0);
            pageVBoxLayout->setContentsMargins(deltaMarginLeft, deltaMarginTop,
                                               deltaMarginRight, deltaMarginBottom);
            buttonLayout->setContentsMargins(info.topLevelMarginLeft, info.topLevelMarginTop,
                                             info.topLevelMarginRight, info.topLevelMarginBottom);
        } else {
            mainLayout->setContentsMargins(info.topLevelMarginLeft, info.topLevelMarginTop,
                                           info.topLevelMarginRight, info.topLevelMarginBottom);
            mainLayout->setHorizontalSpacing(info.hspacing);
            mainLayout->setVerticalSpacing(info.vspacing);
            pageVBoxLayout->setContentsMargins(0, 0, 0, 0);
            buttonLayout->setContentsMargins(0, 0, 0, 0);
        }
    }
    buttonLayout->setSpacing(info.buttonSpacing);

    if (info.header) {
        if (!headerWidget)
            headerWidget = new QWizardHeader(antiFlickerWidget);
        headerWidget->setAutoFillBackground(modern);
        mainLayout->addWidget(headerWidget, row++, 0, 1, numColumns);
    }
    if (headerWidget)
        headerWidget->setVisible(info.header);

    int watermarkStartRow = row;

    if (mac)
        mainLayout->setRowMinimumHeight(row++, 10);

    if (info.title) {
        if (!titleLabel) {
            titleLabel = new QLabel(antiFlickerWidget);
            titleLabel->setBackgroundRole(QPalette::Base);
            titleLabel->setWordWrap(true);
        }

        QFont titleFont = q->font();
        titleFont.setPointSize(titleFont.pointSize() + (mac ? 3 : 4));
        titleFont.setBold(true);
        titleLabel->setPalette(QPalette());

        if (aero) {
            // ### hardcoded for now:
            titleFont = QFont(QLatin1String("Segoe UI"), 12);
            QPalette pal(titleLabel->palette());
            pal.setColor(QPalette::Text, QColor(0x00, 0x33, 0x99));
            titleLabel->setPalette(pal);
        }

        titleLabel->setFont(titleFont);
        const int aeroTitleIndent = 25; // ### hardcoded for now - should be calculated somehow
        if (aero)
            titleLabel->setIndent(aeroTitleIndent);
        else if (mac)
            titleLabel->setIndent(2);
        else if (classic)
            titleLabel->setIndent(info.childMarginLeft);
        else
            titleLabel->setIndent(info.topLevelMarginLeft);
        if (modern) {
            if (!placeholderWidget1) {
                placeholderWidget1 = new QWidget(antiFlickerWidget);
                placeholderWidget1->setBackgroundRole(QPalette::Base);
            }
            placeholderWidget1->setFixedHeight(info.topLevelMarginLeft + 2);
            mainLayout->addWidget(placeholderWidget1, row++, pageColumn);
        }
        mainLayout->addWidget(titleLabel, row++, pageColumn);
        if (modern) {
            if (!placeholderWidget2) {
                placeholderWidget2 = new QWidget(antiFlickerWidget);
                placeholderWidget2->setBackgroundRole(QPalette::Base);
            }
            placeholderWidget2->setFixedHeight(5);
            mainLayout->addWidget(placeholderWidget2, row++, pageColumn);
        }
        if (mac)
            mainLayout->setRowMinimumHeight(row++, 7);
    }
    if (placeholderWidget1)
        placeholderWidget1->setVisible(info.title && modern);
    if (placeholderWidget2)
        placeholderWidget2->setVisible(info.title && modern);

    if (info.subTitle) {
        if (!subTitleLabel) {
            subTitleLabel = new QLabel(pageFrame);
            subTitleLabel->setWordWrap(true);

            subTitleLabel->setContentsMargins(info.childMarginLeft , 0,
                                              info.childMarginRight , 0);

            pageVBoxLayout->insertWidget(1, subTitleLabel);
        }
    }

    // ### try to replace with margin.
    changeSpacerSize(pageVBoxLayout, 0, 0, info.subTitle ? info.childMarginLeft : 0);

    int hMargin = mac ? 1 : 0;
    int vMargin = hMargin;

    pageFrame->setFrameStyle(mac ? (QFrame::Box | QFrame::Raised) : QFrame::NoFrame);
    pageFrame->setLineWidth(0);
    pageFrame->setMidLineWidth(hMargin);

    if (info.header) {
        if (modern) {
            hMargin = info.topLevelMarginLeft;
            vMargin = deltaMarginBottom;
        } else if (classic) {
            hMargin = deltaMarginLeft + ClassicHMargin;
            vMargin = 0;
        }
    }

    if (aero) {
        int leftMargin   = 18; // ### hardcoded for now - should be calculated somehow
        int topMargin    = vMargin;
        int rightMargin  = hMargin; // ### for now
        int bottomMargin = vMargin;
        pageFrame->setContentsMargins(leftMargin, topMargin, rightMargin, bottomMargin);
    } else {
        pageFrame->setContentsMargins(hMargin, vMargin, hMargin, vMargin);
    }

    if ((info.watermark || info.sideWidget) && !watermarkLabel) {
        watermarkLabel = new QWatermarkLabel(antiFlickerWidget, sideWidget);
        watermarkLabel->setBackgroundRole(QPalette::Base);
        watermarkLabel->setMinimumHeight(1);
        watermarkLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
        watermarkLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    }

    //bool wasSemiTransparent = pageFrame->testAttribute(Qt::WA_SetPalette);
    const bool wasSemiTransparent =
        pageFrame->palette().brush(QPalette::Window).color().alpha() < 255
        || pageFrame->palette().brush(QPalette::Base).color().alpha() < 255;
    if (mac) {
        if (!wasSemiTransparent) {
            QPalette pal = pageFrame->palette();
            pal.setBrush(QPalette::Window, QColor(255, 255, 255, 153));
            // ### The next line is required to ensure visual semitransparency when
            // ### switching from ModernStyle to MacStyle. See TAG1 below.
            pal.setBrush(QPalette::Base, QColor(255, 255, 255, 153));
            pageFrame->setPalette(pal);
            pageFrame->setAutoFillBackground(true);
            antiFlickerWidget->setAutoFillBackground(false);
        }
    } else {
        if (wasSemiTransparent)
            pageFrame->setPalette(QPalette());

        bool baseBackground = (modern && !info.header); // ### TAG1
        pageFrame->setBackgroundRole(baseBackground ? QPalette::Base : QPalette::Window);

        if (titleLabel)
            titleLabel->setAutoFillBackground(baseBackground);
        pageFrame->setAutoFillBackground(baseBackground);
        if (watermarkLabel)
            watermarkLabel->setAutoFillBackground(baseBackground);
        if (placeholderWidget1)
            placeholderWidget1->setAutoFillBackground(baseBackground);
        if (placeholderWidget2)
            placeholderWidget2->setAutoFillBackground(baseBackground);

        if (aero) {
            QPalette pal = pageFrame->palette();
            pal.setBrush(QPalette::Window, QColor(255, 255, 255));
            pageFrame->setPalette(pal);
            pageFrame->setAutoFillBackground(true);
            pal = antiFlickerWidget->palette();
            pal.setBrush(QPalette::Window, QColor(255, 255, 255));
            antiFlickerWidget->setPalette(pal);
            antiFlickerWidget->setAutoFillBackground(true);
        }
    }

    mainLayout->addWidget(pageFrame, row++, pageColumn);

    int watermarkEndRow = row;
    if (classic)
        mainLayout->setRowMinimumHeight(row++, deltaVSpacing);

    if (aero) {
        buttonLayout->setContentsMargins(9, 9, 9, 9);
        mainLayout->setContentsMargins(0, 11, 0, 0);
    }

    int buttonStartColumn = info.extension ? 1 : 0;
    int buttonNumColumns = info.extension ? 1 : numColumns;

    if (classic || modern) {
        if (!bottomRuler)
            bottomRuler = new QWizardRuler(antiFlickerWidget);
        mainLayout->addWidget(bottomRuler, row++, buttonStartColumn, 1, buttonNumColumns);
    }

    if (classic)
        mainLayout->setRowMinimumHeight(row++, deltaVSpacing);

    mainLayout->addLayout(buttonLayout, row++, buttonStartColumn, 1, buttonNumColumns);

    if (info.watermark || info.sideWidget) {
        if (info.extension)
            watermarkEndRow = row;
        mainLayout->addWidget(watermarkLabel, watermarkStartRow, 0,
                              watermarkEndRow - watermarkStartRow, 1);
    }

    mainLayout->setColumnMinimumWidth(0, mac && !info.watermark ? 181 : 0);
    if (mac)
        mainLayout->setColumnMinimumWidth(2, 21);

    if (headerWidget)
        headerWidget->setVisible(info.header);
    if (titleLabel)
        titleLabel->setVisible(info.title);
    if (subTitleLabel)
        subTitleLabel->setVisible(info.subTitle);
    if (bottomRuler)
        bottomRuler->setVisible(classic || modern);
    if (watermarkLabel)
        watermarkLabel->setVisible(info.watermark || info.sideWidget);

    layoutInfo = info;
}

void QWizardPrivate::updateLayout()
{
    Q_Q(QWizard);

    disableUpdates();

    QWizardLayoutInfo info = layoutInfoForCurrentPage();
    if (layoutInfo != info)
        recreateLayout(info);
    QWizardPage *page = q->currentPage();

    // If the page can expand vertically, let it stretch "infinitely" more
    // than the QSpacerItem at the bottom. Otherwise, let the QSpacerItem
    // stretch "infinitely" more than the page. Change the bottom item's
    // policy accordingly. The case that the page has no layout is basically
    // for Designer, only.
    if (page) {
        bool expandPage = !page->layout();
        if (!expandPage) {
            const QLayoutItem *pageItem = pageVBoxLayout->itemAt(pageVBoxLayout->indexOf(page));
            expandPage = pageItem->expandingDirections() & Qt::Vertical;
        }
        QSpacerItem *bottomSpacer = pageVBoxLayout->itemAt(pageVBoxLayout->count() -  1)->spacerItem();
        Q_ASSERT(bottomSpacer);
        bottomSpacer->changeSize(0, 0, QSizePolicy::Ignored, expandPage ? QSizePolicy::Ignored : QSizePolicy::MinimumExpanding);
        pageVBoxLayout->invalidate();
    }

    if (info.header) {
        Q_ASSERT(page);
        headerWidget->setup(info, page->title(), page->subTitle(),
                            page->pixmap(QWizard::LogoPixmap), page->pixmap(QWizard::BannerPixmap),
                            titleFmt, subTitleFmt);
    }

    if (info.watermark || info.sideWidget) {
        QPixmap pix;
        if (info.watermark) {
            if (page)
                pix = page->pixmap(QWizard::WatermarkPixmap);
            else
                pix = q->pixmap(QWizard::WatermarkPixmap);
        }
        watermarkLabel->setPixmap(pix); // in case there is no watermark and we show the side widget we need to clear the watermark
    }

    if (info.title) {
        Q_ASSERT(page);
        titleLabel->setTextFormat(titleFmt);
        titleLabel->setText(page->title());
    }
    if (info.subTitle) {
        Q_ASSERT(page);
        subTitleLabel->setTextFormat(subTitleFmt);
        subTitleLabel->setText(page->subTitle());
    }

    enableUpdates();
    updateMinMaxSizes(info);
}

void QWizardPrivate::updateMinMaxSizes(const QWizardLayoutInfo &info)
{
    Q_Q(QWizard);

    int extraHeight = 0;
#if QT_CONFIG(style_windowsvista)
    if (isVistaThemeEnabled())
        extraHeight = vistaHelper->titleBarSize() + vistaHelper->topOffset(q);
#endif
    QSize minimumSize = mainLayout->totalMinimumSize() + QSize(0, extraHeight);
    QSize maximumSize = mainLayout->totalMaximumSize();
    if (info.header && headerWidget->maximumWidth() != QWIDGETSIZE_MAX) {
        minimumSize.setWidth(headerWidget->maximumWidth());
        maximumSize.setWidth(headerWidget->maximumWidth());
    }
    if (info.watermark && !info.sideWidget) {
        minimumSize.setHeight(mainLayout->totalSizeHint().height());
    }
    if (q->minimumWidth() == minimumWidth) {
        minimumWidth = minimumSize.width();
        q->setMinimumWidth(minimumWidth);
    }
    if (q->minimumHeight() == minimumHeight) {
        minimumHeight = minimumSize.height();
        q->setMinimumHeight(minimumHeight);
    }
    if (q->maximumWidth() == maximumWidth) {
        maximumWidth = maximumSize.width();
        q->setMaximumWidth(maximumWidth);
    }
    if (q->maximumHeight() == maximumHeight) {
        maximumHeight = maximumSize.height();
        q->setMaximumHeight(maximumHeight);
    }
}

void QWizardPrivate::updateCurrentPage()
{
    Q_Q(QWizard);
    if (q->currentPage()) {
        canContinue = (q->nextId() != -1);
        canFinish = q->currentPage()->isFinalPage();
    } else {
        canContinue = false;
        canFinish = false;
    }
    _q_updateButtonStates();
    updateButtonTexts();
}

static QString object_name_for_button(QWizard::WizardButton which)
{
    switch (which) {
    case QWizard::CommitButton:
        return QLatin1String("qt_wizard_") + QLatin1String("commit");
    case QWizard::FinishButton:
        return QLatin1String("qt_wizard_") + QLatin1String("finish");
    case QWizard::CancelButton:
        return QLatin1String("qt_wizard_") + QLatin1String("cancel");
    case QWizard::BackButton:
    case QWizard::NextButton:
    case QWizard::HelpButton:
    case QWizard::CustomButton1:
    case QWizard::CustomButton2:
    case QWizard::CustomButton3:
        // Make navigation buttons detectable as passive interactor in designer
        return QLatin1String("__qt__passive_wizardbutton") + QString::number(which);
    case QWizard::Stretch:
    case QWizard::NoButton:
    //case QWizard::NStandardButtons:
    //case QWizard::NButtons:
        ;
    }
    Q_UNREACHABLE();
    return QString();
}

bool QWizardPrivate::ensureButton(QWizard::WizardButton which) const
{
    Q_Q(const QWizard);
    if (uint(which) >= QWizard::NButtons)
        return false;

    if (!btns[which]) {
        QPushButton *pushButton = new QPushButton(antiFlickerWidget);
        QStyle *style = q->style();
        if (style != QApplication::style()) // Propagate style
            pushButton->setStyle(style);
        pushButton->setObjectName(object_name_for_button(which));
#ifdef Q_OS_MACX
        pushButton->setAutoDefault(false);
#endif
        pushButton->hide();
#ifdef Q_CC_HPACC
        const_cast<QWizardPrivate *>(this)->btns[which] = pushButton;
#else
        btns[which] = pushButton;
#endif
        if (which < QWizard::NStandardButtons)
            pushButton->setText(buttonDefaultText(wizStyle, which, this));

        connectButton(which);
    }
    return true;
}

void QWizardPrivate::connectButton(QWizard::WizardButton which) const
{
    Q_Q(const QWizard);
    if (which < QWizard::NStandardButtons) {
        QObject::connect(btns[which], SIGNAL(clicked()), q, buttonSlots(which));
    } else {
        QObject::connect(btns[which], SIGNAL(clicked()), q, SLOT(_q_emitCustomButtonClicked()));
    }
}

void QWizardPrivate::updateButtonTexts()
{
    Q_Q(QWizard);
    for (int i = 0; i < QWizard::NButtons; ++i) {
        if (btns[i]) {
            if (q->currentPage() && (q->currentPage()->d_func()->buttonCustomTexts.contains(i)))
                btns[i]->setText(q->currentPage()->d_func()->buttonCustomTexts.value(i));
            else if (buttonCustomTexts.contains(i))
                btns[i]->setText(buttonCustomTexts.value(i));
            else if (i < QWizard::NStandardButtons)
                btns[i]->setText(buttonDefaultText(wizStyle, i, this));
        }
    }
    // Vista: Add shortcut for 'next'. Note: native dialogs use ALT-Right
    // even in RTL mode, so do the same, even if it might be counter-intuitive.
    // The shortcut for 'back' is set in class QVistaBackButton.
#if QT_CONFIG(shortcut) && QT_CONFIG(style_windowsvista)
    if (btns[QWizard::NextButton] && isVistaThemeEnabled()) {
        if (vistaNextShortcut.isNull()) {
            vistaNextShortcut =
                new QShortcut(QKeySequence(Qt::ALT | Qt::Key_Right),
                              btns[QWizard::NextButton], SLOT(animateClick()));
        }
    } else {
        delete vistaNextShortcut;
    }
#endif // shortcut && style_windowsvista
}

void QWizardPrivate::updateButtonLayout()
{
    if (buttonsHaveCustomLayout) {
        QVarLengthArray<QWizard::WizardButton, QWizard::NButtons> array(buttonsCustomLayout.count());
        for (int i = 0; i < buttonsCustomLayout.count(); ++i)
            array[i] = buttonsCustomLayout.at(i);
        setButtonLayout(array.constData(), array.count());
    } else {
        // Positions:
        //     Help Stretch Custom1 Custom2 Custom3 Cancel Back Next Commit Finish Cancel Help

        const int ArraySize = 12;
        QWizard::WizardButton array[ArraySize];
        memset(array, -1, sizeof(array));
        Q_ASSERT(array[0] == QWizard::NoButton);

        if (opts & QWizard::HaveHelpButton) {
            int i = (opts & QWizard::HelpButtonOnRight) ? 11 : 0;
            array[i] = QWizard::HelpButton;
        }
        array[1] = QWizard::Stretch;
        if (opts & QWizard::HaveCustomButton1)
            array[2] = QWizard::CustomButton1;
        if (opts & QWizard::HaveCustomButton2)
            array[3] = QWizard::CustomButton2;
        if (opts & QWizard::HaveCustomButton3)
            array[4] = QWizard::CustomButton3;

        if (!(opts & QWizard::NoCancelButton)) {
            int i = (opts & QWizard::CancelButtonOnLeft) ? 5 : 10;
            array[i] = QWizard::CancelButton;
        }
        array[6] = QWizard::BackButton;
        array[7] = QWizard::NextButton;
        array[8] = QWizard::CommitButton;
        array[9] = QWizard::FinishButton;

        setButtonLayout(array, ArraySize);
    }
}

void QWizardPrivate::setButtonLayout(const QWizard::WizardButton *array, int size)
{
    QWidget *prev = pageFrame;

    for (int i = buttonLayout->count() - 1; i >= 0; --i) {
        QLayoutItem *item = buttonLayout->takeAt(i);
        if (QWidget *widget = item->widget())
            widget->hide();
        delete item;
    }

    for (int i = 0; i < size; ++i) {
        QWizard::WizardButton which = array[i];
        if (which == QWizard::Stretch) {
            buttonLayout->addStretch(1);
        } else if (which != QWizard::NoButton) {
            ensureButton(which);
            buttonLayout->addWidget(btns[which]);

            // Back, Next, Commit, and Finish are handled in _q_updateButtonStates()
            if (which != QWizard::BackButton && which != QWizard::NextButton
                && which != QWizard::CommitButton && which != QWizard::FinishButton)
                btns[which]->show();

            if (prev)
                QWidget::setTabOrder(prev, btns[which]);
            prev = btns[which];
        }
    }

    _q_updateButtonStates();
}

bool QWizardPrivate::buttonLayoutContains(QWizard::WizardButton which)
{
    return !buttonsHaveCustomLayout || buttonsCustomLayout.contains(which);
}

void QWizardPrivate::updatePixmap(QWizard::WizardPixmap which)
{
    Q_Q(QWizard);
    if (which == QWizard::BackgroundPixmap) {
        if (wizStyle == QWizard::MacStyle) {
            q->update();
            q->updateGeometry();
        }
    } else {
        updateLayout();
    }
}

#if QT_CONFIG(style_windowsvista)
bool QWizardPrivate::vistaDisabled() const
{
    Q_Q(const QWizard);
    const QVariant v = q->property("_q_wizard_vista_off");
    return v.isValid() && v.toBool();
}

bool QWizardPrivate::isVistaThemeEnabled(QVistaHelper::VistaState state) const
{
    return wizStyle == QWizard::AeroStyle
        && QVistaHelper::vistaState() == state
        && !vistaDisabled();
}

bool QWizardPrivate::handleAeroStyleChange()
{
    Q_Q(QWizard);

    if (inHandleAeroStyleChange)
        return false; // prevent recursion
    // For top-level wizards, we need the platform window handle for the
    // DWM changes. Delay aero initialization to the show event handling if
    // it does not exist. If we are a child, skip DWM and just make room by
    // moving the antiFlickerWidget.
    const bool isWindow = q->isWindow();
    if (isWindow && (!q->windowHandle() || !q->windowHandle()->handle()))
        return false;
    inHandleAeroStyleChange = true;

    vistaHelper->disconnectBackButton();
    q->removeEventFilter(vistaHelper);

    bool vistaMargins = false;

    if (isVistaThemeEnabled()) {
        const int topOffset = vistaHelper->topOffset(q);
        const int topPadding = vistaHelper->topPadding(q);
        if (isVistaThemeEnabled(QVistaHelper::VistaAero)) {
            if (isWindow) {
                vistaHelper->setDWMTitleBar(QVistaHelper::ExtendedTitleBar);
                q->installEventFilter(vistaHelper);
            }
            q->setMouseTracking(true);
            antiFlickerWidget->move(0, vistaHelper->titleBarSize() + topOffset);
            vistaHelper->backButton()->move(
                0, topOffset // ### should ideally work without the '+ 1'
                - qMin(topOffset, topPadding + 1));
            vistaMargins = true;
            vistaHelper->backButton()->show();
        } else {
            if (isWindow)
                vistaHelper->setDWMTitleBar(QVistaHelper::NormalTitleBar);
            q->setMouseTracking(true);
            antiFlickerWidget->move(0, topOffset);
            vistaHelper->backButton()->move(0, -1); // ### should ideally work with (0, 0)
        }
        if (isWindow)
            vistaHelper->setTitleBarIconAndCaptionVisible(false);
        QObject::connect(
            vistaHelper->backButton(), SIGNAL(clicked()), q, buttonSlots(QWizard::BackButton));
        vistaHelper->backButton()->show();
    } else {
        q->setMouseTracking(true); // ### original value possibly different
#ifndef QT_NO_CURSOR
        q->unsetCursor(); // ### ditto
#endif
        antiFlickerWidget->move(0, 0);
        vistaHelper->hideBackButton();
        if (isWindow)
            vistaHelper->setTitleBarIconAndCaptionVisible(true);
    }

    _q_updateButtonStates();

    vistaHelper->updateCustomMargins(vistaMargins);

    inHandleAeroStyleChange = false;
    return true;
}
#endif

bool QWizardPrivate::isVistaThemeEnabled() const
{
#if QT_CONFIG(style_windowsvista)
    return isVistaThemeEnabled(QVistaHelper::VistaAero)
        || isVistaThemeEnabled(QVistaHelper::VistaBasic);
#else
    return false;
#endif
}

void QWizardPrivate::disableUpdates()
{
    Q_Q(QWizard);
    if (disableUpdatesCount++ == 0) {
        q->setUpdatesEnabled(false);
        antiFlickerWidget->hide();
    }
}

void QWizardPrivate::enableUpdates()
{
    Q_Q(QWizard);
    if (--disableUpdatesCount == 0) {
        antiFlickerWidget->show();
        q->setUpdatesEnabled(true);
    }
}

void QWizardPrivate::_q_emitCustomButtonClicked()
{
    Q_Q(QWizard);
    QObject *button = q->sender();
    for (int i = QWizard::NStandardButtons; i < QWizard::NButtons; ++i) {
        if (btns[i] == button) {
            emit q->customButtonClicked(QWizard::WizardButton(i));
            break;
        }
    }
}

void QWizardPrivate::_q_updateButtonStates()
{
    Q_Q(QWizard);

    disableUpdates();

    const QWizardPage *page = q->currentPage();
    bool complete = page && page->isComplete();

    btn.back->setEnabled(history.count() > 1
                         && !q->page(history.at(history.count() - 2))->isCommitPage()
                         && (!canFinish || !(opts & QWizard::DisabledBackButtonOnLastPage)));
    btn.next->setEnabled(canContinue && complete);
    btn.commit->setEnabled(canContinue && complete);
    btn.finish->setEnabled(canFinish && complete);

    const bool backButtonVisible = buttonLayoutContains(QWizard::BackButton)
        && (history.count() > 1 || !(opts & QWizard::NoBackButtonOnStartPage))
        && (canContinue || !(opts & QWizard::NoBackButtonOnLastPage));
    bool commitPage = page && page->isCommitPage();
    btn.back->setVisible(backButtonVisible);
    btn.next->setVisible(buttonLayoutContains(QWizard::NextButton) && !commitPage
                         && (canContinue || (opts & QWizard::HaveNextButtonOnLastPage)));
    btn.commit->setVisible(buttonLayoutContains(QWizard::CommitButton) && commitPage
                           && canContinue);
    btn.finish->setVisible(buttonLayoutContains(QWizard::FinishButton)
                           && (canFinish || (opts & QWizard::HaveFinishButtonOnEarlyPages)));

    if (!(opts & QWizard::NoCancelButton))
        btn.cancel->setVisible(buttonLayoutContains(QWizard::CancelButton)
                               && (canContinue || !(opts & QWizard::NoCancelButtonOnLastPage)));

    bool useDefault = !(opts & QWizard::NoDefaultButton);
    if (QPushButton *nextPush = qobject_cast<QPushButton *>(btn.next))
        nextPush->setDefault(canContinue && useDefault && !commitPage);
    if (QPushButton *commitPush = qobject_cast<QPushButton *>(btn.commit))
        commitPush->setDefault(canContinue && useDefault && commitPage);
    if (QPushButton *finishPush = qobject_cast<QPushButton *>(btn.finish))
        finishPush->setDefault(!canContinue && useDefault);

#if QT_CONFIG(style_windowsvista)
    if (isVistaThemeEnabled()) {
        vistaHelper->backButton()->setEnabled(btn.back->isEnabled());
        vistaHelper->backButton()->setVisible(backButtonVisible);
        btn.back->setVisible(false);
    }
#endif

    enableUpdates();
}

void QWizardPrivate::_q_handleFieldObjectDestroyed(QObject *object)
{
    int destroyed_index = -1;
    QVector<QWizardField>::iterator it = fields.begin();
    while (it != fields.end()) {
        const QWizardField &field = *it;
        if (field.object == object) {
            destroyed_index = fieldIndexMap.value(field.name, -1);
            fieldIndexMap.remove(field.name);
            it = fields.erase(it);
        } else {
            ++it;
        }
    }
    if (destroyed_index != -1) {
        QMap<QString, int>::iterator it2 = fieldIndexMap.begin();
        while (it2 != fieldIndexMap.end()) {
            int index = it2.value();
            if (index > destroyed_index) {
                QString field_name = it2.key();
                fieldIndexMap.insert(field_name, index-1);
            }
            ++it2;
        }
    }
}

void QWizardPrivate::setStyle(QStyle *style)
{
    for (int i = 0; i < QWizard::NButtons; i++)
        if (btns[i])
            btns[i]->setStyle(style);
    const PageMap::const_iterator pcend = pageMap.constEnd();
    for (PageMap::const_iterator it = pageMap.constBegin(); it != pcend; ++it)
        it.value()->setStyle(style);
}

#ifdef Q_OS_MACX

QPixmap QWizardPrivate::findDefaultBackgroundPixmap()
{
    QGuiApplication *app = qobject_cast<QGuiApplication *>(QCoreApplication::instance());
    if (!app)
        return QPixmap();
    QPlatformNativeInterface *platformNativeInterface = app->platformNativeInterface();
    int at = platformNativeInterface->metaObject()->indexOfMethod("defaultBackgroundPixmapForQWizard()");
    if (at == -1)
        return QPixmap();
    QMetaMethod defaultBackgroundPixmapForQWizard = platformNativeInterface->metaObject()->method(at);
    QPixmap result;
    if (!defaultBackgroundPixmapForQWizard.invoke(platformNativeInterface, Q_RETURN_ARG(QPixmap, result)))
        return QPixmap();
    return result;
}

#endif

#if QT_CONFIG(style_windowsvista)
void QWizardAntiFlickerWidget::paintEvent(QPaintEvent *)
{
    if (wizardPrivate->isVistaThemeEnabled()) {
        int leftMargin, topMargin, rightMargin, bottomMargin;
        wizardPrivate->buttonLayout->getContentsMargins(
            &leftMargin, &topMargin, &rightMargin, &bottomMargin);
        const int buttonLayoutTop = wizardPrivate->buttonLayout->contentsRect().top() - topMargin;
        QPainter painter(this);
        const QBrush brush(QColor(240, 240, 240)); // ### hardcoded for now
        painter.fillRect(0, buttonLayoutTop, width(), height() - buttonLayoutTop, brush);
        painter.setPen(QPen(QBrush(QColor(223, 223, 223)), 0)); // ### hardcoded for now
        painter.drawLine(0, buttonLayoutTop, width(), buttonLayoutTop);
        if (wizardPrivate->isVistaThemeEnabled(QVistaHelper::VistaBasic)) {
            if (window()->isActiveWindow())
                painter.setPen(QPen(QBrush(QColor(169, 191, 214)), 0)); // ### hardcoded for now
            else
                painter.setPen(QPen(QBrush(QColor(182, 193, 204)), 0)); // ### hardcoded for now
            painter.drawLine(0, 0, width(), 0);
        }
    }
}
#endif

/*!
    \class QWizard
    \since 4.3
    \brief The QWizard class provides a framework for wizards.

    \inmodule QtWidgets

    A wizard (also called an assistant on \macos) is a special type
    of input dialog that consists of a sequence of pages. A wizard's
    purpose is to guide the user through a process step by step.
    Wizards are useful for complex or infrequent tasks that users may
    find difficult to learn.

    QWizard inherits QDialog and represents a wizard. Each page is a
    QWizardPage (a QWidget subclass). To create your own wizards, you
    can use these classes directly, or you can subclass them for more
    control.

    Topics:

    \tableofcontents

    \section1 A Trivial Example

    The following example illustrates how to create wizard pages and
    add them to a wizard. For more advanced examples, see
    \l{dialogs/classwizard}{Class Wizard} and \l{dialogs/licensewizard}{License
    Wizard}.

    \snippet dialogs/trivialwizard/trivialwizard.cpp 1
    \snippet dialogs/trivialwizard/trivialwizard.cpp 3
    \dots
    \snippet dialogs/trivialwizard/trivialwizard.cpp 4
    \codeline
    \snippet dialogs/trivialwizard/trivialwizard.cpp 5
    \snippet dialogs/trivialwizard/trivialwizard.cpp 7
    \dots
    \snippet dialogs/trivialwizard/trivialwizard.cpp 8
    \codeline
    \snippet dialogs/trivialwizard/trivialwizard.cpp 10

    \section1 Wizard Look and Feel

    QWizard supports four wizard looks:

    \list
    \li ClassicStyle
    \li ModernStyle
    \li MacStyle
    \li AeroStyle
    \endlist

    You can explicitly set the look to use using setWizardStyle()
    (e.g., if you want the same look on all platforms).

    \table
    \header \li ClassicStyle
            \li ModernStyle
            \li MacStyle
            \li AeroStyle
    \row    \li \inlineimage qtwizard-classic1.png
            \li \inlineimage qtwizard-modern1.png
            \li \inlineimage qtwizard-mac1.png
            \li \inlineimage qtwizard-aero1.png
    \row    \li \inlineimage qtwizard-classic2.png
            \li \inlineimage qtwizard-modern2.png
            \li \inlineimage qtwizard-mac2.png
            \li \inlineimage qtwizard-aero2.png
    \endtable

    Note: AeroStyle has effect only on a Windows Vista system with alpha compositing enabled.
    ModernStyle is used as a fallback when this condition is not met.

    In addition to the wizard style, there are several options that
    control the look and feel of the wizard. These can be set using
    setOption() or setOptions(). For example, HaveHelpButton makes
    QWizard show a \uicontrol Help button along with the other wizard
    buttons.

    You can even change the order of the wizard buttons to any
    arbitrary order using setButtonLayout(), and you can add up to
    three custom buttons (e.g., a \uicontrol Print button) to the button
    row. This is achieved by calling setButton() or setButtonText()
    with CustomButton1, CustomButton2, or CustomButton3 to set up the
    button, and by enabling the HaveCustomButton1, HaveCustomButton2,
    or HaveCustomButton3 options. Whenever the user clicks a custom
    button, customButtonClicked() is emitted. For example:

    \snippet dialogs/licensewizard/licensewizard.cpp 29

    \section1 Elements of a Wizard Page

    Wizards consist of a sequence of \l{QWizardPage}s. At any time,
    only one page is shown. A page has the following attributes:

    \list
    \li A \l{QWizardPage::}{title}.
    \li A \l{QWizardPage::}{subTitle}.
    \li A set of pixmaps, which may or may not be honored, depending
       on the wizard's style:
        \list
        \li WatermarkPixmap (used by ClassicStyle and ModernStyle)
        \li BannerPixmap (used by ModernStyle)
        \li LogoPixmap (used by ClassicStyle and ModernStyle)
        \li BackgroundPixmap (used by MacStyle)
        \endlist
    \endlist

    The diagram belows shows how QWizard renders these attributes,
    assuming they are all present and ModernStyle is used:

    \image qtwizard-nonmacpage.png

    When a \l{QWizardPage::}{subTitle} is set, QWizard displays it
    in a header, in which case it also uses the BannerPixmap and the
    LogoPixmap to decorate the header. The WatermarkPixmap is
    displayed on the left side, below the header. At the bottom,
    there is a row of buttons allowing the user to navigate through
    the pages.

    The page itself (the \l{QWizardPage} widget) occupies the area
    between the header, the watermark, and the button row. Typically,
    the page is a QWizardPage on which a QGridLayout is installed,
    with standard child widgets (\l{QLabel}s, \l{QLineEdit}s, etc.).

    If the wizard's style is MacStyle, the page looks radically
    different:

    \image qtwizard-macpage.png

    The watermark, banner, and logo pixmaps are ignored by the
    MacStyle. If the BackgroundPixmap is set, it is used as the
    background for the wizard; otherwise, a default "assistant" image
    is used.

    The title and subtitle are set by calling
    QWizardPage::setTitle() and QWizardPage::setSubTitle() on the
    individual pages. They may be plain text or HTML (see titleFormat
    and subTitleFormat). The pixmaps can be set globally for the
    entire wizard using setPixmap(), or on a per-page basis using
    QWizardPage::setPixmap().

    \target field mechanism
    \section1 Registering and Using Fields

    In many wizards, the contents of a page may affect the default
    values of the fields of a later page. To make it easy to
    communicate between pages, QWizard supports a "field" mechanism
    that allows you to register a field (e.g., a QLineEdit) on a page
    and to access its value from any page. It is also possible to
    specify mandatory fields (i.e., fields that must be filled before
    the user can advance to the next page).

    To register a field, call QWizardPage::registerField() field.
    For example:

    \snippet dialogs/classwizard/classwizard.cpp 8
    \dots
    \snippet dialogs/classwizard/classwizard.cpp 10
    \snippet dialogs/classwizard/classwizard.cpp 11
    \dots
    \snippet dialogs/classwizard/classwizard.cpp 13

    The above code registers three fields, \c className, \c
    baseClass, and \c qobjectMacro, which are associated with three
    child widgets. The asterisk (\c *) next to \c className denotes a
    mandatory field.

    \target initialize page
    The fields of any page are accessible from any other page. For
    example:

    \snippet dialogs/classwizard/classwizard.cpp 17

    Here, we call QWizardPage::field() to access the contents of the
    \c className field (which was defined in the \c ClassInfoPage)
    and use it to initialize the \c OutputFilePage. The field's
    contents is returned as a QVariant.

    When we create a field using QWizardPage::registerField(), we
    pass a unique field name and a widget. We can also provide a Qt
    property name and a "changed" signal (a signal that is emitted
    when the property changes) as third and fourth arguments;
    however, this is not necessary for the most common Qt widgets,
    such as QLineEdit, QCheckBox, and QComboBox, because QWizard
    knows which properties to look for.

    \target mandatory fields

    If an asterisk (\c *) is appended to the name when the property
    is registered, the field is a \e{mandatory field}. When a page has
    mandatory fields, the \uicontrol Next and/or \uicontrol Finish buttons are
    enabled only when all mandatory fields are filled.

    To consider a field "filled", QWizard simply checks that the
    field's current value doesn't equal the original value (the value
    it had when initializePage() was called). For QLineEdit and
    QAbstractSpinBox subclasses, QWizard also checks that
    \l{QLineEdit::hasAcceptableInput()}{hasAcceptableInput()} returns
    true, to honor any validator or mask.

    QWizard's mandatory field mechanism is provided for convenience.
    A more powerful (but also more cumbersome) alternative is to
    reimplement QWizardPage::isComplete() and to emit the
    QWizardPage::completeChanged() signal whenever the page becomes
    complete or incomplete.

    The enabled/disabled state of the \uicontrol Next and/or \uicontrol Finish
    buttons is one way to perform validation on the user input.
    Another way is to reimplement validateCurrentPage() (or
    QWizardPage::validatePage()) to perform some last-minute
    validation (and show an error message if the user has entered
    incomplete or invalid information). If the function returns \c true,
    the next page is shown (or the wizard finishes); otherwise, the
    current page stays up.

    \section1 Creating Linear Wizards

    Most wizards have a linear structure, with page 1 followed by
    page 2 and so on until the last page. The \l{dialogs/classwizard}{Class
    Wizard} example is such a wizard. With QWizard, linear wizards
    are created by instantiating the \l{QWizardPage}s and inserting
    them using addPage(). By default, the pages are shown in the
    order in which they were added. For example:

    \snippet dialogs/classwizard/classwizard.cpp 0
    \dots
    \snippet dialogs/classwizard/classwizard.cpp 2

    When a page is about to be shown, QWizard calls initializePage()
    (which in turn calls QWizardPage::initializePage()) to fill the
    page with default values. By default, this function does nothing,
    but it can be reimplemented to initialize the page's contents
    based on other pages' fields (see the \l{initialize page}{example
    above}).

    If the user presses \uicontrol Back, cleanupPage() is called (which in
    turn calls QWizardPage::cleanupPage()). The default
    implementation resets the page's fields to their original values
    (the values they had before initializePage() was called). If you
    want the \uicontrol Back button to be non-destructive and keep the
    values entered by the user, simply enable the IndependentPages
    option.

    \section1 Creating Non-Linear Wizards

    Some wizards are more complex in that they allow different
    traversal paths based on the information provided by the user.
    The \l{dialogs/licensewizard}{License Wizard} example illustrates this.
    It provides five wizard pages; depending on which options are
    selected, the user can reach different pages.

    \image licensewizard-flow.png

    In complex wizards, pages are identified by IDs. These IDs are
    typically defined using an enum. For example:

    \snippet dialogs/licensewizard/licensewizard.h 0
    \dots
    \snippet dialogs/licensewizard/licensewizard.h 2
    \dots
    \snippet dialogs/licensewizard/licensewizard.h 3

    The pages are inserted using setPage(), which takes an ID and an
    instance of QWizardPage (or of a subclass):

    \snippet dialogs/licensewizard/licensewizard.cpp 1
    \dots
    \snippet dialogs/licensewizard/licensewizard.cpp 8

    By default, the pages are shown in increasing ID order. To
    provide a dynamic order that depends on the options chosen by the
    user, we must reimplement QWizardPage::nextId(). For example:

    \snippet dialogs/licensewizard/licensewizard.cpp 18
    \codeline
    \snippet dialogs/licensewizard/licensewizard.cpp 23
    \codeline
    \snippet dialogs/licensewizard/licensewizard.cpp 24
    \codeline
    \snippet dialogs/licensewizard/licensewizard.cpp 25
    \codeline
    \snippet dialogs/licensewizard/licensewizard.cpp 26

    It would also be possible to put all the logic in one place, in a
    QWizard::nextId() reimplementation. For example:

    \snippet code/src_gui_dialogs_qwizard.cpp 0

    To start at another page than the page with the lowest ID, call
    setStartId().

    To test whether a page has been visited or not, call
    hasVisitedPage(). For example:

    \snippet dialogs/licensewizard/licensewizard.cpp 27

    \sa QWizardPage, {Class Wizard Example}, {License Wizard Example}
*/

/*!
    \enum QWizard::WizardButton

    This enum specifies the buttons in a wizard.

    \value BackButton  The \uicontrol Back button (\uicontrol {Go Back} on \macos)
    \value NextButton  The \uicontrol Next button (\uicontrol Continue on \macos)
    \value CommitButton  The \uicontrol Commit button
    \value FinishButton  The \uicontrol Finish button (\uicontrol Done on \macos)
    \value CancelButton  The \uicontrol Cancel button (see also NoCancelButton)
    \value HelpButton    The \uicontrol Help button (see also HaveHelpButton)
    \value CustomButton1  The first user-defined button (see also HaveCustomButton1)
    \value CustomButton2  The second user-defined button (see also HaveCustomButton2)
    \value CustomButton3  The third user-defined button (see also HaveCustomButton3)

    The following value is only useful when calling setButtonLayout():

    \value Stretch  A horizontal stretch in the button layout

    \omitvalue NoButton
    \omitvalue NStandardButtons
    \omitvalue NButtons

    \sa setButton(), setButtonText(), setButtonLayout(), customButtonClicked()
*/

/*!
    \enum QWizard::WizardPixmap

    This enum specifies the pixmaps that can be associated with a page.

    \value WatermarkPixmap  The tall pixmap on the left side of a ClassicStyle or ModernStyle page
    \value LogoPixmap  The small pixmap on the right side of a ClassicStyle or ModernStyle page header
    \value BannerPixmap  The pixmap that occupies the background of a ModernStyle page header
    \value BackgroundPixmap  The pixmap that occupies the background of a MacStyle wizard

    \omitvalue NPixmaps

    \sa setPixmap(), QWizardPage::setPixmap(), {Elements of a Wizard Page}
*/

/*!
    \enum QWizard::WizardStyle

    This enum specifies the different looks supported by QWizard.

    \value ClassicStyle  Classic Windows look
    \value ModernStyle  Modern Windows look
    \value MacStyle  \macos look
    \value AeroStyle  Windows Aero look

    \omitvalue NStyles

    \sa setWizardStyle(), WizardOption, {Wizard Look and Feel}
*/

/*!
    \enum QWizard::WizardOption

    This enum specifies various options that affect the look and feel
    of a wizard.

    \value IndependentPages  The pages are independent of each other
                             (i.e., they don't derive values from each
                             other).
    \value IgnoreSubTitles  Don't show any subtitles, even if they are set.
    \value ExtendedWatermarkPixmap  Extend any WatermarkPixmap all the
                                    way down to the window's edge.
    \value NoDefaultButton  Don't make the \uicontrol Next or \uicontrol Finish button the
                            dialog's \l{QPushButton::setDefault()}{default button}.
    \value NoBackButtonOnStartPage  Don't show the \uicontrol Back button on the start page.
    \value NoBackButtonOnLastPage   Don't show the \uicontrol Back button on the last page.
    \value DisabledBackButtonOnLastPage  Disable the \uicontrol Back button on the last page.
    \value HaveNextButtonOnLastPage  Show the (disabled) \uicontrol Next button on the last page.
    \value HaveFinishButtonOnEarlyPages  Show the (disabled) \uicontrol Finish button on non-final pages.
    \value NoCancelButton  Don't show the \uicontrol Cancel button.
    \value CancelButtonOnLeft  Put the \uicontrol Cancel button on the left of \uicontrol Back (rather than on
                               the right of \uicontrol Finish or \uicontrol Next).
    \value HaveHelpButton  Show the \uicontrol Help button.
    \value HelpButtonOnRight  Put the \uicontrol Help button on the far right of the button layout
                              (rather than on the far left).
    \value HaveCustomButton1  Show the first user-defined button (CustomButton1).
    \value HaveCustomButton2  Show the second user-defined button (CustomButton2).
    \value HaveCustomButton3  Show the third user-defined button (CustomButton3).
    \value NoCancelButtonOnLastPage   Don't show the \uicontrol Cancel button on the last page.

    \sa setOptions(), setOption(), testOption()
*/

/*!
    Constructs a wizard with the given \a parent and window \a flags.

    \sa parent(), windowFlags()
*/
QWizard::QWizard(QWidget *parent, Qt::WindowFlags flags)
    : QDialog(*new QWizardPrivate, parent, flags)
{
    Q_D(QWizard);
    d->init();
}

/*!
    Destroys the wizard and its pages, releasing any allocated resources.
*/
QWizard::~QWizard()
{
    Q_D(QWizard);
    delete d->buttonLayout;
}

/*!
    Adds the given \a page to the wizard, and returns the page's ID.

    The ID is guaranteed to be larger than any other ID in the
    QWizard so far.

    \sa setPage(), page(), pageAdded()
*/
int QWizard::addPage(QWizardPage *page)
{
    Q_D(QWizard);
    int theid = 0;
    if (!d->pageMap.isEmpty())
        theid = (d->pageMap.constEnd() - 1).key() + 1;
    setPage(theid, page);
    return theid;
}

/*!
    \fn void QWizard::setPage(int id, QWizardPage *page)

    Adds the given \a page to the wizard with the given \a id.

    \note Adding a page may influence the value of the startId property
    in case it was not set explicitly.

    \sa addPage(), page(), pageAdded()
*/
void QWizard::setPage(int theid, QWizardPage *page)
{
    Q_D(QWizard);

    if (Q_UNLIKELY(!page)) {
        qWarning("QWizard::setPage: Cannot insert null page");
        return;
    }

    if (Q_UNLIKELY(theid == -1)) {
        qWarning("QWizard::setPage: Cannot insert page with ID -1");
        return;
    }

    if (Q_UNLIKELY(d->pageMap.contains(theid))) {
        qWarning("QWizard::setPage: Page with duplicate ID %d ignored", theid);
        return;
    }

    page->setParent(d->pageFrame);

    QVector<QWizardField> &pendingFields = page->d_func()->pendingFields;
    for (int i = 0; i < pendingFields.count(); ++i)
        d->addField(pendingFields.at(i));
    pendingFields.clear();

    connect(page, SIGNAL(completeChanged()), this, SLOT(_q_updateButtonStates()));

    d->pageMap.insert(theid, page);
    page->d_func()->wizard = this;

    int n = d->pageVBoxLayout->count();

    // disable layout to prevent layout updates while adding
    bool pageVBoxLayoutEnabled = d->pageVBoxLayout->isEnabled();
    d->pageVBoxLayout->setEnabled(false);

    d->pageVBoxLayout->insertWidget(n - 1, page);

    // hide new page and reset layout to old status
    page->hide();
    d->pageVBoxLayout->setEnabled(pageVBoxLayoutEnabled);

    if (!d->startSetByUser && d->pageMap.constBegin().key() == theid)
        d->start = theid;
    emit pageAdded(theid);
}

/*!
    Removes the page with the given \a id. cleanupPage() will be called if necessary.

    \note Removing a page may influence the value of the startId property.

    \since 4.5
    \sa addPage(), setPage(), pageRemoved(), startId()
*/
void QWizard::removePage(int id)
{
    Q_D(QWizard);

    QWizardPage *removedPage = 0;

    // update startItem accordingly
    if (d->pageMap.count() > 0) { // only if we have any pages
        if (d->start == id) {
            const int firstId = d->pageMap.constBegin().key();
            if (firstId == id) {
                if (d->pageMap.count() > 1)
                    d->start = (++d->pageMap.constBegin()).key(); // secondId
                else
                    d->start = -1; // removing the last page
            } else { // startSetByUser has to be "true" here
                d->start = firstId;
            }
            d->startSetByUser = false;
        }
    }

    if (d->pageMap.contains(id))
        emit pageRemoved(id);

    if (!d->history.contains(id)) {
        // Case 1: removing a page not in the history
        removedPage = d->pageMap.take(id);
        d->updateCurrentPage();
    } else if (id != d->current) {
        // Case 2: removing a page in the history before the current page
        removedPage = d->pageMap.take(id);
        d->history.removeOne(id);
        d->_q_updateButtonStates();
    } else if (d->history.count() == 1) {
        // Case 3: removing the current page which is the first (and only) one in the history
        d->reset();
        removedPage = d->pageMap.take(id);
        if (d->pageMap.isEmpty())
            d->updateCurrentPage();
        else
            restart();
    } else {
        // Case 4: removing the current page which is not the first one in the history
        back();
        removedPage = d->pageMap.take(id);
        d->updateCurrentPage();
    }

    if (removedPage) {
        if (removedPage->d_func()->initialized) {
            cleanupPage(id);
            removedPage->d_func()->initialized = false;
        }

        d->pageVBoxLayout->removeWidget(removedPage);

        for (int i = d->fields.count() - 1; i >= 0; --i) {
            if (d->fields.at(i).page == removedPage) {
                removedPage->d_func()->pendingFields += d->fields.at(i);
                d->removeFieldAt(i);
            }
        }
    }
}

/*!
    \fn QWizardPage *QWizard::page(int id) const

    Returns the page with the given \a id, or \nullptr if there is no
    such page.

    \sa addPage(), setPage()
*/
QWizardPage *QWizard::page(int theid) const
{
    Q_D(const QWizard);
    return d->pageMap.value(theid);
}

/*!
    \fn bool QWizard::hasVisitedPage(int id) const

    Returns \c true if the page history contains page \a id; otherwise,
    returns \c false.

    Pressing \uicontrol Back marks the current page as "unvisited" again.

    \sa visitedPages()
*/
bool QWizard::hasVisitedPage(int theid) const
{
    Q_D(const QWizard);
    return d->history.contains(theid);
}

/*!
    Returns the list of IDs of visited pages, in the order in which the pages
    were visited.

    Pressing \uicontrol Back marks the current page as "unvisited" again.

    \sa hasVisitedPage()
*/
QList<int> QWizard::visitedPages() const
{
    Q_D(const QWizard);
    return d->history;
}

/*!
    Returns the list of page IDs.
   \since 4.5
*/
QList<int> QWizard::pageIds() const
{
  Q_D(const QWizard);
  return d->pageMap.keys();
}

/*!
    \property QWizard::startId
    \brief the ID of the first page

    If this property isn't explicitly set, this property defaults to
    the lowest page ID in this wizard, or -1 if no page has been
    inserted yet.

    \sa restart(), nextId()
*/
void QWizard::setStartId(int theid)
{
    Q_D(QWizard);
    int newStart = theid;
    if (theid == -1)
        newStart = d->pageMap.count() ? d->pageMap.constBegin().key() : -1;

    if (d->start == newStart) {
        d->startSetByUser = theid != -1;
        return;
    }

    if (Q_UNLIKELY(!d->pageMap.contains(newStart))) {
        qWarning("QWizard::setStartId: Invalid page ID %d", newStart);
        return;
    }
    d->start = newStart;
    d->startSetByUser = theid != -1;
}

int QWizard::startId() const
{
    Q_D(const QWizard);
    return d->start;
}

/*!
    Returns a pointer to the current page, or \nullptr if there is no
    current page (e.g., before the wizard is shown).

    This is equivalent to calling page(currentId()).

    \sa page(), currentId(), restart()
*/
QWizardPage *QWizard::currentPage() const
{
    Q_D(const QWizard);
    return page(d->current);
}

/*!
    \property QWizard::currentId
    \brief the ID of the current page

    This property cannot be set directly. To change the current page,
    call next(), back(), or restart().

    By default, this property has a value of -1, indicating that no page is
    currently shown.

    \sa currentPage()
*/
int QWizard::currentId() const
{
    Q_D(const QWizard);
    return d->current;
}

/*!
    Sets the value of the field called \a name to \a value.

    This function can be used to set fields on any page of the wizard.

    \sa QWizardPage::registerField(), QWizardPage::setField(), field()
*/
void QWizard::setField(const QString &name, const QVariant &value)
{
    Q_D(QWizard);

    int index = d->fieldIndexMap.value(name, -1);
    if (Q_UNLIKELY(index == -1)) {
        qWarning("QWizard::setField: No such field '%ls'", qUtf16Printable(name));
        return;
    }

    const QWizardField &field = d->fields.at(index);
    if (Q_UNLIKELY(!field.object->setProperty(field.property, value)))
        qWarning("QWizard::setField: Couldn't write to property '%s'",
                 field.property.constData());
}

/*!
    Returns the value of the field called \a name.

    This function can be used to access fields on any page of the wizard.

    \sa QWizardPage::registerField(), QWizardPage::field(), setField()
*/
QVariant QWizard::field(const QString &name) const
{
    Q_D(const QWizard);

    int index = d->fieldIndexMap.value(name, -1);
    if (Q_UNLIKELY(index == -1)) {
        qWarning("QWizard::field: No such field '%ls'", qUtf16Printable(name));
        return QVariant();
    }

    const QWizardField &field = d->fields.at(index);
    return field.object->property(field.property);
}

/*!
    \property QWizard::wizardStyle
    \brief the look and feel of the wizard

    By default, QWizard uses the AeroStyle on a Windows Vista system with alpha compositing
    enabled, regardless of the current widget style. If this is not the case, the default
    wizard style depends on the current widget style as follows: MacStyle is the default if
    the current widget style is QMacStyle, ModernStyle is the default if the current widget
    style is QWindowsStyle, and ClassicStyle is the default in all other cases.

    \sa {Wizard Look and Feel}, options
*/
void QWizard::setWizardStyle(WizardStyle style)
{
    Q_D(QWizard);

    const bool styleChange = style != d->wizStyle;

#if QT_CONFIG(style_windowsvista)
    const bool aeroStyleChange =
        d->vistaInitPending || d->vistaStateChanged || (styleChange && (style == AeroStyle || d->wizStyle == AeroStyle));
    d->vistaStateChanged = false;
    d->vistaInitPending = false;
#endif

    if (styleChange
#if QT_CONFIG(style_windowsvista)
        || aeroStyleChange
#endif
        ) {
        d->disableUpdates();
        d->wizStyle = style;
        d->updateButtonTexts();
#if QT_CONFIG(style_windowsvista)
        if (aeroStyleChange) {
            //Send a resizeevent since the antiflicker widget probably needs a new size
            //because of the backbutton in the window title
            QResizeEvent ev(geometry().size(), geometry().size());
            QCoreApplication::sendEvent(this, &ev);
        }
#endif
        d->updateLayout();
        updateGeometry();
        d->enableUpdates();
#if QT_CONFIG(style_windowsvista)
        // Delay initialization when activating Aero style fails due to missing native window.
        if (aeroStyleChange && !d->handleAeroStyleChange() && d->wizStyle == AeroStyle)
            d->vistaInitPending = true;
#endif
    }
}

QWizard::WizardStyle QWizard::wizardStyle() const
{
    Q_D(const QWizard);
    return d->wizStyle;
}

/*!
    Sets the given \a option to be enabled if \a on is true;
    otherwise, clears the given \a option.

    \sa options, testOption(), setWizardStyle()
*/
void QWizard::setOption(WizardOption option, bool on)
{
    Q_D(QWizard);
    if (!(d->opts & option) != !on)
        setOptions(d->opts ^ option);
}

/*!
    Returns \c true if the given \a option is enabled; otherwise, returns
    false.

    \sa options, setOption(), setWizardStyle()
*/
bool QWizard::testOption(WizardOption option) const
{
    Q_D(const QWizard);
    return (d->opts & option) != 0;
}

/*!
    \property QWizard::options
    \brief the various options that affect the look and feel of the wizard

    By default, the following options are set (depending on the platform):

    \list
    \li Windows: HelpButtonOnRight.
    \li \macos: NoDefaultButton and NoCancelButton.
    \li X11 and QWS (Qt for Embedded Linux): none.
    \endlist

    \sa wizardStyle
*/
void QWizard::setOptions(WizardOptions options)
{
    Q_D(QWizard);

    WizardOptions changed = (options ^ d->opts);
    if (!changed)
        return;

    d->disableUpdates();

    d->opts = options;
    if ((changed & IndependentPages) && !(d->opts & IndependentPages))
        d->cleanupPagesNotInHistory();

    if (changed & (NoDefaultButton | HaveHelpButton | HelpButtonOnRight | NoCancelButton
                   | CancelButtonOnLeft | HaveCustomButton1 | HaveCustomButton2
                   | HaveCustomButton3)) {
        d->updateButtonLayout();
    } else if (changed & (NoBackButtonOnStartPage | NoBackButtonOnLastPage
                          | HaveNextButtonOnLastPage | HaveFinishButtonOnEarlyPages
                          | DisabledBackButtonOnLastPage | NoCancelButtonOnLastPage)) {
        d->_q_updateButtonStates();
    }

    d->enableUpdates();
    d->updateLayout();
}

QWizard::WizardOptions QWizard::options() const
{
    Q_D(const QWizard);
    return d->opts;
}

/*!
    Sets the text on button \a which to be \a text.

    By default, the text on buttons depends on the wizardStyle. For
    example, on \macos, the \uicontrol Next button is called \uicontrol
    Continue.

    To add extra buttons to the wizard (e.g., a \uicontrol Print button),
    one way is to call setButtonText() with CustomButton1,
    CustomButton2, or CustomButton3 to set their text, and make the
    buttons visible using the HaveCustomButton1, HaveCustomButton2,
    and/or HaveCustomButton3 options.

    Button texts may also be set on a per-page basis using QWizardPage::setButtonText().

    \sa setButton(), button(), setButtonLayout(), setOptions(), QWizardPage::setButtonText()
*/
void QWizard::setButtonText(WizardButton which, const QString &text)
{
    Q_D(QWizard);

    if (!d->ensureButton(which))
        return;

    d->buttonCustomTexts.insert(which, text);

    if (!currentPage() || !currentPage()->d_func()->buttonCustomTexts.contains(which))
        d->btns[which]->setText(text);
}

/*!
    Returns the text on button \a which.

    If a text has ben set using setButtonText(), this text is returned.

    By default, the text on buttons depends on the wizardStyle. For
    example, on \macos, the \uicontrol Next button is called \uicontrol
    Continue.

    \sa button(), setButton(), setButtonText(), QWizardPage::buttonText(),
    QWizardPage::setButtonText()
*/
QString QWizard::buttonText(WizardButton which) const
{
    Q_D(const QWizard);

    if (!d->ensureButton(which))
        return QString();

    if (d->buttonCustomTexts.contains(which))
        return d->buttonCustomTexts.value(which);

    const QString defText = buttonDefaultText(d->wizStyle, which, d);
    if(!defText.isNull())
        return defText;

    return d->btns[which]->text();
}

/*!
    Sets the order in which buttons are displayed to \a layout, where
    \a layout is a list of \l{WizardButton}s.

    The default layout depends on the options (e.g., whether
    HelpButtonOnRight) that are set. You can call this function if
    you need more control over the buttons' layout than what \l
    options already provides.

    You can specify horizontal stretches in the layout using \l
    Stretch.

    Example:

    \snippet code/src_gui_dialogs_qwizard.cpp 1

    \sa setButton(), setButtonText(), setOptions()
*/
void QWizard::setButtonLayout(const QList<WizardButton> &layout)
{
    Q_D(QWizard);

    for (int i = 0; i < layout.count(); ++i) {
        WizardButton button1 = layout.at(i);

        if (button1 == NoButton || button1 == Stretch)
            continue;
        if (!d->ensureButton(button1))
            return;

        // O(n^2), but n is very small
        for (int j = 0; j < i; ++j) {
            WizardButton button2 = layout.at(j);
            if (Q_UNLIKELY(button2 == button1)) {
                qWarning("QWizard::setButtonLayout: Duplicate button in layout");
                return;
            }
        }
    }

    d->buttonsHaveCustomLayout = true;
    d->buttonsCustomLayout = layout;
    d->updateButtonLayout();
}

/*!
    Sets the button corresponding to role \a which to \a button.

    To add extra buttons to the wizard (e.g., a \uicontrol Print button),
    one way is to call setButton() with CustomButton1 to
    CustomButton3, and make the buttons visible using the
    HaveCustomButton1 to HaveCustomButton3 options.

    \sa setButtonText(), setButtonLayout(), options
*/
void QWizard::setButton(WizardButton which, QAbstractButton *button)
{
    Q_D(QWizard);

    if (uint(which) >= NButtons || d->btns[which] == button)
        return;

    if (QAbstractButton *oldButton = d->btns[which]) {
        d->buttonLayout->removeWidget(oldButton);
        delete oldButton;
    }

    d->btns[which] = button;
    if (button) {
        button->setParent(d->antiFlickerWidget);
        d->buttonCustomTexts.insert(which, button->text());
        d->connectButton(which);
    } else {
        d->buttonCustomTexts.remove(which); // ### what about page-specific texts set for 'which'
        d->ensureButton(which);             // (QWizardPage::setButtonText())? Clear them as well?
    }

    d->updateButtonLayout();
}

/*!
    Returns the button corresponding to role \a which.

    \sa setButton(), setButtonText()
*/
QAbstractButton *QWizard::button(WizardButton which) const
{
    Q_D(const QWizard);
#if QT_CONFIG(style_windowsvista)
    if (d->wizStyle == AeroStyle && which == BackButton)
        return d->vistaHelper->backButton();
#endif
    if (!d->ensureButton(which))
        return 0;
    return d->btns[which];
}

/*!
    \property QWizard::titleFormat
    \brief the text format used by page titles

    The default format is Qt::AutoText.

    \sa QWizardPage::title, subTitleFormat
*/
void QWizard::setTitleFormat(Qt::TextFormat format)
{
    Q_D(QWizard);
    d->titleFmt = format;
    d->updateLayout();
}

Qt::TextFormat QWizard::titleFormat() const
{
    Q_D(const QWizard);
    return d->titleFmt;
}

/*!
    \property QWizard::subTitleFormat
    \brief the text format used by page subtitles

    The default format is Qt::AutoText.

    \sa QWizardPage::title, titleFormat
*/
void QWizard::setSubTitleFormat(Qt::TextFormat format)
{
    Q_D(QWizard);
    d->subTitleFmt = format;
    d->updateLayout();
}

Qt::TextFormat QWizard::subTitleFormat() const
{
    Q_D(const QWizard);
    return d->subTitleFmt;
}

/*!
    Sets the pixmap for role \a which to \a pixmap.

    The pixmaps are used by QWizard when displaying a page. Which
    pixmaps are actually used depend on the \l{Wizard Look and
    Feel}{wizard style}.

    Pixmaps can also be set for a specific page using
    QWizardPage::setPixmap().

    \sa QWizardPage::setPixmap(), {Elements of a Wizard Page}
*/
void QWizard::setPixmap(WizardPixmap which, const QPixmap &pixmap)
{
    Q_D(QWizard);
    Q_ASSERT(uint(which) < NPixmaps);
    d->defaultPixmaps[which] = pixmap;
    d->updatePixmap(which);
}

/*!
    Returns the pixmap set for role \a which.

    By default, the only pixmap that is set is the BackgroundPixmap on
    \macos version 10.13 and earlier.

    \sa QWizardPage::pixmap(), {Elements of a Wizard Page}
*/
QPixmap QWizard::pixmap(WizardPixmap which) const
{
    Q_D(const QWizard);
    Q_ASSERT(uint(which) < NPixmaps);
#ifdef Q_OS_MACX
    if (which == BackgroundPixmap && d->defaultPixmaps[BackgroundPixmap].isNull())
        d->defaultPixmaps[BackgroundPixmap] = d->findDefaultBackgroundPixmap();
#endif
    return d->defaultPixmaps[which];
}

/*!
    Sets the default property for \a className to be \a property,
    and the associated change signal to be \a changedSignal.

    The default property is used when an instance of \a className (or
    of one of its subclasses) is passed to
    QWizardPage::registerField() and no property is specified.

    QWizard knows the most common Qt widgets. For these (or their
    subclasses), you don't need to specify a \a property or a \a
    changedSignal. The table below lists these widgets:

    \table
    \header \li Widget          \li Property                            \li Change Notification Signal
    \row    \li QAbstractButton \li bool \l{QAbstractButton::}{checked} \li \l{QAbstractButton::}{toggled()}
    \row    \li QAbstractSlider \li int \l{QAbstractSlider::}{value}    \li \l{QAbstractSlider::}{valueChanged()}
    \row    \li QComboBox       \li int \l{QComboBox::}{currentIndex}   \li \l{QComboBox::}{currentIndexChanged()}
    \row    \li QDateTimeEdit   \li QDateTime \l{QDateTimeEdit::}{dateTime} \li \l{QDateTimeEdit::}{dateTimeChanged()}
    \row    \li QLineEdit       \li QString \l{QLineEdit::}{text}       \li \l{QLineEdit::}{textChanged()}
    \row    \li QListWidget     \li int \l{QListWidget::}{currentRow}   \li \l{QListWidget::}{currentRowChanged()}
    \row    \li QSpinBox        \li int \l{QSpinBox::}{value}           \li \l{QSpinBox::}{valueChanged()}
    \endtable

    \sa QWizardPage::registerField()
*/
void QWizard::setDefaultProperty(const char *className, const char *property,
                                 const char *changedSignal)
{
    Q_D(QWizard);
    for (int i = d->defaultPropertyTable.count() - 1; i >= 0; --i) {
        if (qstrcmp(d->defaultPropertyTable.at(i).className, className) == 0) {
            d->defaultPropertyTable.remove(i);
            break;
        }
    }
    d->defaultPropertyTable.append(QWizardDefaultProperty(className, property, changedSignal));
}

/*!
    \since 4.7

    Sets the given \a widget to be shown on the left side of the wizard.
    For styles which use the WatermarkPixmap (ClassicStyle and ModernStyle)
    the side widget is displayed on top of the watermark, for other styles
    or when the watermark is not provided the side widget is displayed
    on the left side of the wizard.

    Passing 0 shows no side widget.

    When the \a widget is not \nullptr the wizard reparents it.

    Any previous side widget is hidden.

    You may call setSideWidget() with the same widget at different
    times.

    All widgets set here will be deleted by the wizard when it is
    destroyed unless you separately reparent the widget after setting
    some other side widget (or \nullptr).

    By default, no side widget is present.
*/
void QWizard::setSideWidget(QWidget *widget)
{
    Q_D(QWizard);

    d->sideWidget = widget;
    if (d->watermarkLabel) {
        d->watermarkLabel->setSideWidget(widget);
        d->updateLayout();
    }
}

/*!
    \since 4.7

    Returns the widget on the left side of the wizard or \nullptr.

    By default, no side widget is present.
*/
QWidget *QWizard::sideWidget() const
{
    Q_D(const QWizard);

    return d->sideWidget;
}

/*!
    \reimp
*/
void QWizard::setVisible(bool visible)
{
    Q_D(QWizard);
    if (visible) {
        if (d->current == -1)
            restart();
    }
    QDialog::setVisible(visible);
}

/*!
    \reimp
*/
QSize QWizard::sizeHint() const
{
    Q_D(const QWizard);
    QSize result = d->mainLayout->totalSizeHint();
    QSize extra(500, 360);
    if (d->wizStyle == MacStyle && d->current != -1) {
        QSize pixmap(currentPage()->pixmap(BackgroundPixmap).size());
        extra.setWidth(616);
        if (!pixmap.isNull()) {
            extra.setHeight(pixmap.height());

            /*
                The width isn't always reliable as a size hint, as
                some wizard backgrounds just cover the leftmost area.
                Use a rule of thumb to determine if the width is
                reliable or not.
            */
            if (pixmap.width() >= pixmap.height())
                extra.setWidth(pixmap.width());
        }
    }
    return result.expandedTo(extra);
}

/*!
    \fn void QWizard::currentIdChanged(int id)

    This signal is emitted when the current page changes, with the new
    current \a id.

    \sa currentId(), currentPage()
*/

/*!
    \fn void QWizard::pageAdded(int id)

    \since 4.7

    This signal is emitted whenever a page is added to the
    wizard. The page's \a id is passed as parameter.

    \sa addPage(), setPage(), startId()
*/

/*!
    \fn void QWizard::pageRemoved(int id)

    \since 4.7

    This signal is emitted whenever a page is removed from the
    wizard. The page's \a id is passed as parameter.

    \sa removePage(), startId()
*/

/*!
    \fn void QWizard::helpRequested()

    This signal is emitted when the user clicks the \uicontrol Help button.

    By default, no \uicontrol Help button is shown. Call
    setOption(HaveHelpButton, true) to have one.

    Example:

    \snippet dialogs/licensewizard/licensewizard.cpp 0
    \dots
    \snippet dialogs/licensewizard/licensewizard.cpp 5
    \snippet dialogs/licensewizard/licensewizard.cpp 7
    \dots
    \snippet dialogs/licensewizard/licensewizard.cpp 8
    \codeline
    \snippet dialogs/licensewizard/licensewizard.cpp 10
    \dots
    \snippet dialogs/licensewizard/licensewizard.cpp 12
    \codeline
    \snippet dialogs/licensewizard/licensewizard.cpp 14
    \codeline
    \snippet dialogs/licensewizard/licensewizard.cpp 15

    \sa customButtonClicked()
*/

/*!
    \fn void QWizard::customButtonClicked(int which)

    This signal is emitted when the user clicks a custom button. \a
    which can be CustomButton1, CustomButton2, or CustomButton3.

    By default, no custom button is shown. Call setOption() with
    HaveCustomButton1, HaveCustomButton2, or HaveCustomButton3 to have
    one, and use setButtonText() or setButton() to configure it.

    \sa helpRequested()
*/

/*!
    Goes back to the previous page.

    This is equivalent to pressing the \uicontrol Back button.

    \sa next(), accept(), reject(), restart()
*/
void QWizard::back()
{
    Q_D(QWizard);
    int n = d->history.count() - 2;
    if (n < 0)
        return;
    d->switchToPage(d->history.at(n), QWizardPrivate::Backward);
}

/*!
    Advances to the next page.

    This is equivalent to pressing the \uicontrol Next or \uicontrol Commit button.

    \sa nextId(), back(), accept(), reject(), restart()
*/
void QWizard::next()
{
    Q_D(QWizard);

    if (d->current == -1)
        return;

    if (validateCurrentPage()) {
        int next = nextId();
        if (next != -1) {
            if (Q_UNLIKELY(d->history.contains(next))) {
                qWarning("QWizard::next: Page %d already met", next);
                return;
            }
            if (Q_UNLIKELY(!d->pageMap.contains(next))) {
                qWarning("QWizard::next: No such page %d", next);
                return;
            }
            d->switchToPage(next, QWizardPrivate::Forward);
        }
    }
}

/*!
    Restarts the wizard at the start page. This function is called automatically when the
    wizard is shown.

    \sa startId()
*/
void QWizard::restart()
{
    Q_D(QWizard);
    d->disableUpdates();
    d->reset();
    d->switchToPage(startId(), QWizardPrivate::Forward);
    d->enableUpdates();
}

/*!
    \reimp
*/
bool QWizard::event(QEvent *event)
{
    Q_D(QWizard);
    if (event->type() == QEvent::StyleChange) { // Propagate style
        d->setStyle(style());
        d->updateLayout();
    }
#if QT_CONFIG(style_windowsvista)
    else if (event->type() == QEvent::Show && d->vistaInitPending) {
        d->vistaInitPending = false;
        // Do not force AeroStyle when in Classic theme.
        // Note that d->handleAeroStyleChange() needs to be called in any case as it does some
        // necessary initialization, like ensures that the Aero specific back button is hidden if
        // Aero theme isn't active.
        if (QVistaHelper::vistaState() != QVistaHelper::Classic)
            d->wizStyle = AeroStyle;
        d->handleAeroStyleChange();
    }
    else if (d->isVistaThemeEnabled()) {
        if (event->type() == QEvent::Resize
                || event->type() == QEvent::LayoutDirectionChange) {
            const int buttonLeft = (layoutDirection() == Qt::RightToLeft
                                    ? width() - d->vistaHelper->backButton()->sizeHint().width()
                                    : 0);

            d->vistaHelper->backButton()->move(buttonLeft,
                                               d->vistaHelper->backButton()->y());
        }

        d->vistaHelper->mouseEvent(event);
    }
#endif
    return QDialog::event(event);
}

/*!
    \reimp
*/
void QWizard::resizeEvent(QResizeEvent *event)
{
    Q_D(QWizard);
    int heightOffset = 0;
#if QT_CONFIG(style_windowsvista)
    if (d->isVistaThemeEnabled()) {
        heightOffset = d->vistaHelper->topOffset(this);
        if (d->isVistaThemeEnabled(QVistaHelper::VistaAero))
            heightOffset += d->vistaHelper->titleBarSize();
    }
#endif
    d->antiFlickerWidget->resize(event->size().width(), event->size().height() - heightOffset);
#if QT_CONFIG(style_windowsvista)
    if (d->isVistaThemeEnabled())
        d->vistaHelper->resizeEvent(event);
#endif
    QDialog::resizeEvent(event);
}

/*!
    \reimp
*/
void QWizard::paintEvent(QPaintEvent * event)
{
    Q_D(QWizard);
    if (d->wizStyle == MacStyle && currentPage()) {
        QPixmap backgroundPixmap = currentPage()->pixmap(BackgroundPixmap);
        if (backgroundPixmap.isNull())
            return;

        QPainter painter(this);
        painter.drawPixmap(0, (height() - backgroundPixmap.height()) / 2, backgroundPixmap);
    }
#if QT_CONFIG(style_windowsvista)
    else if (d->isVistaThemeEnabled()) {
        if (d->isVistaThemeEnabled(QVistaHelper::VistaBasic)) {
            QPainter painter(this);
            QColor color = d->vistaHelper->basicWindowFrameColor();
            painter.fillRect(0, 0, width(), QVistaHelper::topOffset(this), color);
        }
        d->vistaHelper->paintEvent(event);
    }
#else
    Q_UNUSED(event);
#endif
}

#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC)
/*!
    \reimp
*/
#  if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool QWizard::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
#  else
bool QWizard::nativeEvent(const QByteArray &eventType, void *message, long *result)
#  endif
{
#if QT_CONFIG(style_windowsvista)
    Q_D(QWizard);
    if (d->isVistaThemeEnabled() && eventType == "windows_generic_MSG") {
        MSG *windowsMessage = static_cast<MSG *>(message);
        const bool winEventResult = d->vistaHelper->handleWinEvent(windowsMessage, result);
        if (QVistaHelper::vistaState() != d->vistaState) {
            // QTBUG-78300: When Qt::AA_NativeWindows is set, delay further
            // window creation until after the platform window creation events.
            if (windowsMessage->message == WM_GETICON) {
                d->vistaStateChanged = true;
                d->vistaState = QVistaHelper::vistaState();
                setWizardStyle(AeroStyle);
            }
        }
        return winEventResult;
    } else {
        return QDialog::nativeEvent(eventType, message, result);
    }
#else
    return QDialog::nativeEvent(eventType, message, result);
#endif
}
#endif

/*!
    \reimp
*/
void QWizard::done(int result)
{
    Q_D(QWizard);
    // canceling leaves the wizard in a known state
    if (result == Rejected) {
        d->reset();
    } else {
        if (!validateCurrentPage())
            return;
    }
    QDialog::done(result);
}

/*!
    \fn void QWizard::initializePage(int id)

    This virtual function is called by QWizard to prepare page \a id
    just before it is shown either as a result of QWizard::restart()
    being called, or as a result of the user clicking \uicontrol Next. (However, if the \l
    QWizard::IndependentPages option is set, this function is only
    called the first time the page is shown.)

    By reimplementing this function, you can ensure that the page's
    fields are properly initialized based on fields from previous
    pages.

    The default implementation calls QWizardPage::initializePage() on
    page(\a id).

    \sa QWizardPage::initializePage(), cleanupPage()
*/
void QWizard::initializePage(int theid)
{
    QWizardPage *page = this->page(theid);
    if (page)
        page->initializePage();
}

/*!
    \fn void QWizard::cleanupPage(int id)

    This virtual function is called by QWizard to clean up page \a id just before the
    user leaves it by clicking \uicontrol Back (unless the \l QWizard::IndependentPages option is set).

    The default implementation calls QWizardPage::cleanupPage() on
    page(\a id).

    \sa QWizardPage::cleanupPage(), initializePage()
*/
void QWizard::cleanupPage(int theid)
{
    QWizardPage *page = this->page(theid);
    if (page)
        page->cleanupPage();
}

/*!
    This virtual function is called by QWizard when the user clicks
    \uicontrol Next or \uicontrol Finish to perform some last-minute validation.
    If it returns \c true, the next page is shown (or the wizard
    finishes); otherwise, the current page stays up.

    The default implementation calls QWizardPage::validatePage() on
    the currentPage().

    When possible, it is usually better style to disable the \uicontrol
    Next or \uicontrol Finish button (by specifying \l{mandatory fields} or
    by reimplementing QWizardPage::isComplete()) than to reimplement
    validateCurrentPage().

    \sa QWizardPage::validatePage(), currentPage()
*/
bool QWizard::validateCurrentPage()
{
    QWizardPage *page = currentPage();
    if (!page)
        return true;

    return page->validatePage();
}

/*!
    This virtual function is called by QWizard to find out which page
    to show when the user clicks the \uicontrol Next button.

    The return value is the ID of the next page, or -1 if no page follows.

    The default implementation calls QWizardPage::nextId() on the
    currentPage().

    By reimplementing this function, you can specify a dynamic page
    order.

    \sa QWizardPage::nextId(), currentPage()
*/
int QWizard::nextId() const
{
    const QWizardPage *page = currentPage();
    if (!page)
        return -1;

    return page->nextId();
}

/*!
    \class QWizardPage
    \since 4.3
    \brief The QWizardPage class is the base class for wizard pages.

    \inmodule QtWidgets

    QWizard represents a wizard. Each page is a QWizardPage. When
    you create your own wizards, you can use QWizardPage directly,
    or you can subclass it for more control.

    A page has the following attributes, which are rendered by
    QWizard: a \l title, a \l subTitle, and a \l{setPixmap()}{set of
    pixmaps}. See \l{Elements of a Wizard Page} for details. Once a
    page is added to the wizard (using QWizard::addPage() or
    QWizard::setPage()), wizard() returns a pointer to the
    associated QWizard object.

    Page provides five virtual functions that can be reimplemented to
    provide custom behavior:

    \list
    \li initializePage() is called to initialize the page's contents
       when the user clicks the wizard's \uicontrol Next button. If you
       want to derive the page's default from what the user entered
       on previous pages, this is the function to reimplement.
    \li cleanupPage() is called to reset the page's contents when the
       user clicks the wizard's \uicontrol Back button.
    \li validatePage() validates the page when the user clicks \uicontrol
       Next or \uicontrol Finish. It is often used to show an error message
       if the user has entered incomplete or invalid information.
    \li nextId() returns the ID of the next page. It is useful when
       \l{creating non-linear wizards}, which allow different
       traversal paths based on the information provided by the user.
    \li isComplete() is called to determine whether the \uicontrol Next
       and/or \uicontrol Finish button should be enabled or disabled. If
       you reimplement isComplete(), also make sure that
       completeChanged() is emitted whenever the complete state
       changes.
    \endlist

    Normally, the \uicontrol Next button and the \uicontrol Finish button of a
    wizard are mutually exclusive. If isFinalPage() returns \c true, \uicontrol
    Finish is available; otherwise, \uicontrol Next is available. By
    default, isFinalPage() is true only when nextId() returns -1. If
    you want to show \uicontrol Next and \uicontrol Final simultaneously for a
    page (letting the user perform an "early finish"), call
    setFinalPage(true) on that page. For wizards that support early
    finishes, you might also want to set the
    \l{QWizard::}{HaveNextButtonOnLastPage} and
    \l{QWizard::}{HaveFinishButtonOnEarlyPages} options on the
    wizard.

    In many wizards, the contents of a page may affect the default
    values of the fields of a later page. To make it easy to
    communicate between pages, QWizard supports a \l{Registering and
    Using Fields}{"field" mechanism} that allows you to register a
    field (e.g., a QLineEdit) on a page and to access its value from
    any page. Fields are global to the entire wizard and make it easy
    for any single page to access information stored by another page,
    without having to put all the logic in QWizard or having the
    pages know explicitly about each other. Fields are registered
    using registerField() and can be accessed at any time using
    field() and setField().

    \sa QWizard, {Class Wizard Example}, {License Wizard Example}
*/

/*!
    Constructs a wizard page with the given \a parent.

    When the page is inserted into a wizard using QWizard::addPage()
    or QWizard::setPage(), the parent is automatically set to be the
    wizard.

    \sa wizard()
*/
QWizardPage::QWizardPage(QWidget *parent)
    : QWidget(*new QWizardPagePrivate, parent, 0)
{
    connect(this, SIGNAL(completeChanged()), this, SLOT(_q_updateCachedCompleteState()));
}

/*!
    Destructor.
*/
QWizardPage::~QWizardPage()
{
}

/*!
    \property QWizardPage::title
    \brief the title of the page

    The title is shown by the QWizard, above the actual page. All
    pages should have a title.

    The title may be plain text or HTML, depending on the value of the
    \l{QWizard::titleFormat} property.

    By default, this property contains an empty string.

    \sa subTitle, {Elements of a Wizard Page}
*/
void QWizardPage::setTitle(const QString &title)
{
    Q_D(QWizardPage);
    d->title = title;
    if (d->wizard && d->wizard->currentPage() == this)
        d->wizard->d_func()->updateLayout();
}

QString QWizardPage::title() const
{
    Q_D(const QWizardPage);
    return d->title;
}

/*!
    \property QWizardPage::subTitle
    \brief the subtitle of the page

    The subtitle is shown by the QWizard, between the title and the
    actual page. Subtitles are optional. In
    \l{QWizard::ClassicStyle}{ClassicStyle} and
    \l{QWizard::ModernStyle}{ModernStyle}, using subtitles is
    necessary to make the header appear. In
    \l{QWizard::MacStyle}{MacStyle}, the subtitle is shown as a text
    label just above the actual page.

    The subtitle may be plain text or HTML, depending on the value of
    the \l{QWizard::subTitleFormat} property.

    By default, this property contains an empty string.

    \sa title, QWizard::IgnoreSubTitles, {Elements of a Wizard Page}
*/
void QWizardPage::setSubTitle(const QString &subTitle)
{
    Q_D(QWizardPage);
    d->subTitle = subTitle;
    if (d->wizard && d->wizard->currentPage() == this)
        d->wizard->d_func()->updateLayout();
}

QString QWizardPage::subTitle() const
{
    Q_D(const QWizardPage);
    return d->subTitle;
}

/*!
    Sets the pixmap for role \a which to \a pixmap.

    The pixmaps are used by QWizard when displaying a page. Which
    pixmaps are actually used depend on the \l{Wizard Look and
    Feel}{wizard style}.

    Pixmaps can also be set for the entire wizard using
    QWizard::setPixmap(), in which case they apply for all pages that
    don't specify a pixmap.

    \sa QWizard::setPixmap(), {Elements of a Wizard Page}
*/
void QWizardPage::setPixmap(QWizard::WizardPixmap which, const QPixmap &pixmap)
{
    Q_D(QWizardPage);
    Q_ASSERT(uint(which) < QWizard::NPixmaps);
    d->pixmaps[which] = pixmap;
    if (d->wizard && d->wizard->currentPage() == this)
        d->wizard->d_func()->updatePixmap(which);
}

/*!
    Returns the pixmap set for role \a which.

    Pixmaps can also be set for the entire wizard using
    QWizard::setPixmap(), in which case they apply for all pages that
    don't specify a pixmap.

    \sa QWizard::pixmap(), {Elements of a Wizard Page}
*/
QPixmap QWizardPage::pixmap(QWizard::WizardPixmap which) const
{
    Q_D(const QWizardPage);
    Q_ASSERT(uint(which) < QWizard::NPixmaps);

    const QPixmap &pixmap = d->pixmaps[which];
    if (!pixmap.isNull())
        return pixmap;

    if (wizard())
        return wizard()->pixmap(which);

    return pixmap;
}

/*!
    This virtual function is called by QWizard::initializePage() to
    prepare the page just before it is shown either as a result of QWizard::restart()
    being called, or as a result of the user clicking \uicontrol Next.
    (However, if the \l QWizard::IndependentPages option is set, this function is only
    called the first time the page is shown.)

    By reimplementing this function, you can ensure that the page's
    fields are properly initialized based on fields from previous
    pages. For example:

    \snippet dialogs/classwizard/classwizard.cpp 17

    The default implementation does nothing.

    \sa QWizard::initializePage(), cleanupPage(), QWizard::IndependentPages
*/
void QWizardPage::initializePage()
{
}

/*!
    This virtual function is called by QWizard::cleanupPage() when
    the user leaves the page by clicking \uicontrol Back (unless the \l QWizard::IndependentPages
    option is set).

    The default implementation resets the page's fields to their
    original values (the values they had before initializePage() was
    called).

    \sa QWizard::cleanupPage(), initializePage(), QWizard::IndependentPages
*/
void QWizardPage::cleanupPage()
{
    Q_D(QWizardPage);
    if (d->wizard) {
        const QVector<QWizardField> &fields = d->wizard->d_func()->fields;
        for (const auto &field : fields) {
            if (field.page == this)
                field.object->setProperty(field.property, field.initialValue);
        }
    }
}

/*!
    This virtual function is called by QWizard::validateCurrentPage()
    when the user clicks \uicontrol Next or \uicontrol Finish to perform some
    last-minute validation. If it returns \c true, the next page is shown
    (or the wizard finishes); otherwise, the current page stays up.

    The default implementation returns \c true.

    When possible, it is usually better style to disable the \uicontrol
    Next or \uicontrol Finish button (by specifying \l{mandatory fields} or
    reimplementing isComplete()) than to reimplement validatePage().

    \sa QWizard::validateCurrentPage(), isComplete()
*/
bool QWizardPage::validatePage()
{
    return true;
}

/*!
    This virtual function is called by QWizard to determine whether
    the \uicontrol Next or \uicontrol Finish button should be enabled or
    disabled.

    The default implementation returns \c true if all \l{mandatory
    fields} are filled; otherwise, it returns \c false.

    If you reimplement this function, make sure to emit completeChanged(),
    from the rest of your implementation, whenever the value of isComplete()
    changes. This ensures that QWizard updates the enabled or disabled state of
    its buttons. An example of the reimplementation is
    available \l{http://doc.qt.io/archives/qq/qq22-qwizard.html#validatebeforeitstoolate}
    {here}.

    \sa completeChanged(), isFinalPage()
*/
bool QWizardPage::isComplete() const
{
    Q_D(const QWizardPage);

    if (!d->wizard)
        return true;

    const QVector<QWizardField> &wizardFields = d->wizard->d_func()->fields;
    for (int i = wizardFields.count() - 1; i >= 0; --i) {
        const QWizardField &field = wizardFields.at(i);
        if (field.page == this && field.mandatory) {
            QVariant value = field.object->property(field.property);
            if (value == field.initialValue)
                return false;

#if QT_CONFIG(lineedit)
            if (QLineEdit *lineEdit = qobject_cast<QLineEdit *>(field.object)) {
                if (!lineEdit->hasAcceptableInput())
                    return false;
            }
#endif
#if QT_CONFIG(spinbox)
            if (QAbstractSpinBox *spinBox = qobject_cast<QAbstractSpinBox *>(field.object)) {
                if (!spinBox->hasAcceptableInput())
                    return false;
            }
#endif
        }
    }
    return true;
}

/*!
    Explicitly sets this page to be final if \a finalPage is true.

    After calling setFinalPage(true), isFinalPage() returns \c true and the \uicontrol
    Finish button is visible (and enabled if isComplete() returns
    true).

    After calling setFinalPage(false), isFinalPage() returns \c true if
    nextId() returns -1; otherwise, it returns \c false.

    \sa isComplete(), QWizard::HaveFinishButtonOnEarlyPages
*/
void QWizardPage::setFinalPage(bool finalPage)
{
    Q_D(QWizardPage);
    d->explicitlyFinal = finalPage;
    QWizard *wizard = this->wizard();
    if (wizard && wizard->currentPage() == this)
        wizard->d_func()->updateCurrentPage();
}

/*!
    This function is called by QWizard to determine whether the \uicontrol
    Finish button should be shown for this page or not.

    By default, it returns \c true if there is no next page
    (i.e., nextId() returns -1); otherwise, it returns \c false.

    By explicitly calling setFinalPage(true), you can let the user perform an
    "early finish".

    \sa isComplete(), QWizard::HaveFinishButtonOnEarlyPages
*/
bool QWizardPage::isFinalPage() const
{
    Q_D(const QWizardPage);
    if (d->explicitlyFinal)
        return true;

    QWizard *wizard = this->wizard();
    if (wizard && wizard->currentPage() == this) {
        // try to use the QWizard implementation if possible
        return wizard->nextId() == -1;
    } else {
        return nextId() == -1;
    }
}

/*!
    Sets this page to be a commit page if \a commitPage is true; otherwise,
    sets it to be a normal page.

    A commit page is a page that represents an action which cannot be undone
    by clicking \uicontrol Back or \uicontrol Cancel.

    A \uicontrol Commit button replaces the \uicontrol Next button on a commit page. Clicking this
    button simply calls QWizard::next() just like clicking \uicontrol Next does.

    A page entered directly from a commit page has its \uicontrol Back button disabled.

    \sa isCommitPage()
*/
void QWizardPage::setCommitPage(bool commitPage)
{
    Q_D(QWizardPage);
    d->commit = commitPage;
    QWizard *wizard = this->wizard();
    if (wizard && wizard->currentPage() == this)
        wizard->d_func()->updateCurrentPage();
}

/*!
    Returns \c true if this page is a commit page; otherwise returns \c false.

    \sa setCommitPage()
*/
bool QWizardPage::isCommitPage() const
{
    Q_D(const QWizardPage);
    return d->commit;
}

/*!
    Sets the text on button \a which to be \a text on this page.

    By default, the text on buttons depends on the QWizard::wizardStyle,
    but may be redefined for the wizard as a whole using QWizard::setButtonText().

    \sa buttonText(), QWizard::setButtonText(), QWizard::buttonText()
*/
void QWizardPage::setButtonText(QWizard::WizardButton which, const QString &text)
{
    Q_D(QWizardPage);
    d->buttonCustomTexts.insert(which, text);
    if (wizard() && wizard()->currentPage() == this && wizard()->d_func()->btns[which])
        wizard()->d_func()->btns[which]->setText(text);
}

/*!
    Returns the text on button \a which on this page.

    If a text has ben set using setButtonText(), this text is returned.
    Otherwise, if a text has been set using QWizard::setButtonText(),
    this text is returned.

    By default, the text on buttons depends on the QWizard::wizardStyle.
    For example, on \macos, the \uicontrol Next button is called \uicontrol
    Continue.

    \sa setButtonText(), QWizard::buttonText(), QWizard::setButtonText()
*/
QString QWizardPage::buttonText(QWizard::WizardButton which) const
{
    Q_D(const QWizardPage);

    if (d->buttonCustomTexts.contains(which))
        return d->buttonCustomTexts.value(which);

    if (wizard())
        return wizard()->buttonText(which);

    return QString();
}

/*!
    This virtual function is called by QWizard::nextId() to find
    out which page to show when the user clicks the \uicontrol Next button.

    The return value is the ID of the next page, or -1 if no page follows.

    By default, this function returns the lowest ID greater than the ID
    of the current page, or -1 if there is no such ID.

    By reimplementing this function, you can specify a dynamic page
    order. For example:

    \snippet dialogs/licensewizard/licensewizard.cpp 18

    \sa QWizard::nextId()
*/
int QWizardPage::nextId() const
{
    Q_D(const QWizardPage);

    if (!d->wizard)
        return -1;

    bool foundCurrentPage = false;

    const QWizardPrivate::PageMap &pageMap = d->wizard->d_func()->pageMap;
    QWizardPrivate::PageMap::const_iterator i = pageMap.constBegin();
    QWizardPrivate::PageMap::const_iterator end = pageMap.constEnd();

    for (; i != end; ++i) {
        if (i.value() == this) {
            foundCurrentPage = true;
        } else if (foundCurrentPage) {
            return i.key();
        }
    }
    return -1;
}

/*!
    \fn void QWizardPage::completeChanged()

    This signal is emitted whenever the complete state of the page
    (i.e., the value of isComplete()) changes.

    If you reimplement isComplete(), make sure to emit
    completeChanged() whenever the value of isComplete() changes, to
    ensure that QWizard updates the enabled or disabled state of its
    buttons.

    \sa isComplete()
*/

/*!
    Sets the value of the field called \a name to \a value.

    This function can be used to set fields on any page of the wizard.
    It is equivalent to calling
    wizard()->\l{QWizard::setField()}{setField(\a name, \a value)}.

    \sa QWizard::setField(), field(), registerField()
*/
void QWizardPage::setField(const QString &name, const QVariant &value)
{
    Q_D(QWizardPage);
    if (!d->wizard)
        return;
    d->wizard->setField(name, value);
}

/*!
    Returns the value of the field called \a name.

    This function can be used to access fields on any page of the
    wizard. It is equivalent to calling
    wizard()->\l{QWizard::field()}{field(\a name)}.

    Example:

    \snippet dialogs/classwizard/classwizard.cpp 17

    \sa QWizard::field(), setField(), registerField()
*/
QVariant QWizardPage::field(const QString &name) const
{
    Q_D(const QWizardPage);
    if (!d->wizard)
        return QVariant();
    return d->wizard->field(name);
}

/*!
    Creates a field called \a name associated with the given \a
    property of the given \a widget. From then on, that property
    becomes accessible using field() and setField().

    Fields are global to the entire wizard and make it easy for any
    single page to access information stored by another page, without
    having to put all the logic in QWizard or having the pages know
    explicitly about each other.

    If \a name ends with an asterisk (\c *), the field is a mandatory
    field. When a page has mandatory fields, the \uicontrol Next and/or
    \uicontrol Finish buttons are enabled only when all mandatory fields
    are filled. This requires a \a changedSignal to be specified, to
    tell QWizard to recheck the value stored by the mandatory field.

    QWizard knows the most common Qt widgets. For these (or their
    subclasses), you don't need to specify a \a property or a \a
    changedSignal. The table below lists these widgets:

    \table
    \header \li Widget          \li Property                            \li Change Notification Signal
    \row    \li QAbstractButton \li bool \l{QAbstractButton::}{checked} \li \l{QAbstractButton::}{toggled()}
    \row    \li QAbstractSlider \li int \l{QAbstractSlider::}{value}    \li \l{QAbstractSlider::}{valueChanged()}
    \row    \li QComboBox       \li int \l{QComboBox::}{currentIndex}   \li \l{QComboBox::}{currentIndexChanged()}
    \row    \li QDateTimeEdit   \li QDateTime \l{QDateTimeEdit::}{dateTime} \li \l{QDateTimeEdit::}{dateTimeChanged()}
    \row    \li QLineEdit       \li QString \l{QLineEdit::}{text}       \li \l{QLineEdit::}{textChanged()}
    \row    \li QListWidget     \li int \l{QListWidget::}{currentRow}   \li \l{QListWidget::}{currentRowChanged()}
    \row    \li QSpinBox        \li int \l{QSpinBox::}{value}           \li \l{QSpinBox::}{valueChanged()}
    \endtable

    You can use QWizard::setDefaultProperty() to add entries to this
    table or to override existing entries.

    To consider a field "filled", QWizard simply checks that their
    current value doesn't equal their original value (the value they
    had before initializePage() was called). For QLineEdit, it also
    checks that
    \l{QLineEdit::hasAcceptableInput()}{hasAcceptableInput()} returns
    true, to honor any validator or mask.

    QWizard's mandatory field mechanism is provided for convenience.
    It can be bypassed by reimplementing QWizardPage::isComplete().

    \sa field(), setField(), QWizard::setDefaultProperty()
*/
void QWizardPage::registerField(const QString &name, QWidget *widget, const char *property,
                                const char *changedSignal)
{
    Q_D(QWizardPage);
    QWizardField field(this, name, widget, property, changedSignal);
    if (d->wizard) {
        d->wizard->d_func()->addField(field);
    } else {
        d->pendingFields += field;
    }
}

/*!
    Returns the wizard associated with this page, or \nullptr if this page
    hasn't been inserted into a QWizard yet.

    \sa QWizard::addPage(), QWizard::setPage()
*/
QWizard *QWizardPage::wizard() const
{
    Q_D(const QWizardPage);
    return d->wizard;
}

QT_END_NAMESPACE

#include "moc_qwizard.cpp"
