qwizard.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/dialogs/qwizard.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtWidgets module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qwizard.h"-
41-
42#ifndef QT_NO_WIZARD-
43-
44#include "qabstractspinbox.h"-
45#include "qalgorithms.h"-
46#include "qapplication.h"-
47#include "qboxlayout.h"-
48#include "qlayoutitem.h"-
49#include "qdesktopwidget.h"-
50#include "qevent.h"-
51#include "qframe.h"-
52#include "qlabel.h"-
53#include "qlineedit.h"-
54#include "qpainter.h"-
55#include "qwindow.h"-
56#include "qpushbutton.h"-
57#include "qset.h"-
58#include "qstyle.h"-
59#include "qvarlengtharray.h"-
60#if defined(Q_OS_MACX)-
61#include <QtCore/QMetaMethod>-
62#include <QtGui/QGuiApplication>-
63#include <qpa/qplatformnativeinterface.h>-
64#elif !defined(QT_NO_STYLE_WINDOWSVISTA)-
65#include "qwizard_win_p.h"-
66#include "qtimer.h"-
67#endif-
68-
69#include "private/qdialog_p.h"-
70#include <qdebug.h>-
71-
72#ifdef Q_OS_WINCE-
73extern bool qt_wince_is_mobile(); //defined in qguifunctions_wce.cpp-
74#endif-
75-
76#include <string.h> // for memset()-
77#include <algorithm>-
78-
79QT_BEGIN_NAMESPACE-
80-
81// These fudge terms were needed a few places to obtain pixel-perfect results-
82const int GapBetweenLogoAndRightEdge = 5;-
83const int ModernHeaderTopMargin = 2;-
84const int ClassicHMargin = 4;-
85const int MacButtonTopMargin = 13;-
86const int MacLayoutLeftMargin = 20;-
87//const int MacLayoutTopMargin = 14; // Unused. Save some space and avoid warning.-
88const int MacLayoutRightMargin = 20;-
89const int MacLayoutBottomMargin = 17;-
90-
91static void changeSpacerSize(QLayout *layout, int index, int width, int height)-
92{-
93 QSpacerItem *spacer = layout->itemAt(index)->spacerItem();-
94 if (!spacer)-
95 return;-
96 spacer->changeSize(width, height);-
97}-
98-
99static QWidget *iWantTheFocus(QWidget *ancestor)-
100{-
101 const int MaxIterations = 100;-
102-
103 QWidget *candidate = ancestor;-
104 for (int i = 0; i < MaxIterations; ++i) {-
105 candidate = candidate->nextInFocusChain();-
106 if (!candidate)-
107 break;-
108-
109 if (candidate->focusPolicy() & Qt::TabFocus) {-
110 if (candidate != ancestor && ancestor->isAncestorOf(candidate))-
111 return candidate;-
112 }-
113 }-
114 return 0;-
115}-
116-
117static bool objectInheritsXAndXIsCloserThanY(const QObject *object, const QByteArray &classX,-
118 const QByteArray &classY)-
119{-
120 const QMetaObject *metaObject = object->metaObject();-
121 while (metaObject) {-
122 if (metaObject->className() == classX)-
123 return true;-
124 if (metaObject->className() == classY)-
125 return false;-
126 metaObject = metaObject->superClass();-
127 }-
128 return false;-
129}-
130-
131const struct {-
132 const char className[16];-
133 const char property[13];-
134} fallbackProperties[] = {-
135 // If you modify this list, make sure to update the documentation (and the auto test)-
136 { "QAbstractButton", "checked" },-
137 { "QAbstractSlider", "value" },-
138 { "QComboBox", "currentIndex" },-
139 { "QDateTimeEdit", "dateTime" },-
140 { "QLineEdit", "text" },-
141 { "QListWidget", "currentRow" },-
142 { "QSpinBox", "value" },-
143};-
144const size_t NFallbackDefaultProperties = sizeof fallbackProperties / sizeof *fallbackProperties;-
145-
146static const char *changed_signal(int which)-
147{-
148 // since it might expand to a runtime function call (to-
149 // qFlagLocations()), we cannot store the result of SIGNAL() in a-
150 // character array and expect it to be statically initialized. To-
151 // avoid the relocations caused by a char pointer table, use a-
152 // switch statement:-
153 switch (which) {-
154 case 0: return SIGNAL(toggled(bool));-
155 case 1: return SIGNAL(valueChanged(int));-
156 case 2: return SIGNAL(currentIndexChanged(int));-
157 case 3: return SIGNAL(dateTimeChanged(QDateTime));-
158 case 4: return SIGNAL(textChanged(QString));-
159 case 5: return SIGNAL(currentRowChanged(int));-
160 case 6: return SIGNAL(valueChanged(int));-
161 };-
162 Q_STATIC_ASSERT(7 == NFallbackDefaultProperties);-
163 Q_UNREACHABLE();-
164 return 0;-
165}-
166-
167class QWizardDefaultProperty-
168{-
169public:-
170 QByteArray className;-
171 QByteArray property;-
172 QByteArray changedSignal;-
173-
174 inline QWizardDefaultProperty() {}-
175 inline QWizardDefaultProperty(const char *className, const char *property,-
176 const char *changedSignal)-
177 : className(className), property(property), changedSignal(changedSignal) {}-
178};-
179Q_DECLARE_TYPEINFO(QWizardDefaultProperty, Q_MOVABLE_TYPE);-
180-
181class QWizardField-
182{-
183public:-
184 inline QWizardField() {}-
185 QWizardField(QWizardPage *page, const QString &spec, QObject *object, const char *property,-
186 const char *changedSignal);-
187-
188 void resolve(const QVector<QWizardDefaultProperty> &defaultPropertyTable);-
189 void findProperty(const QWizardDefaultProperty *properties, int propertyCount);-
190-
191 QWizardPage *page;-
192 QString name;-
193 bool mandatory;-
194 QObject *object;-
195 QByteArray property;-
196 QByteArray changedSignal;-
197 QVariant initialValue;-
198};-
199Q_DECLARE_TYPEINFO(QWizardField, Q_MOVABLE_TYPE);-
200-
201QWizardField::QWizardField(QWizardPage *page, const QString &spec, QObject *object,-
202 const char *property, const char *changedSignal)-
203 : page(page), name(spec), mandatory(false), object(object), property(property),-
204 changedSignal(changedSignal)-
205{-
206 if (name.endsWith(QLatin1Char('*'))) {-
207 name.chop(1);-
208 mandatory = true;-
209 }-
210}-
211-
212void QWizardField::resolve(const QVector<QWizardDefaultProperty> &defaultPropertyTable)-
213{-
214 if (property.isEmpty())-
215 findProperty(defaultPropertyTable.constData(), defaultPropertyTable.count());-
216 initialValue = object->property(property);-
217}-
218-
219void QWizardField::findProperty(const QWizardDefaultProperty *properties, int propertyCount)-
220{-
221 QByteArray className;-
222-
223 for (int i = 0; i < propertyCount; ++i) {-
224 if (objectInheritsXAndXIsCloserThanY(object, properties[i].className, className)) {-
225 className = properties[i].className;-
226 property = properties[i].property;-
227 changedSignal = properties[i].changedSignal;-
228 }-
229 }-
230}-
231-
232class QWizardLayoutInfo-
233{-
234public:-
235 inline QWizardLayoutInfo()-
236 : topLevelMarginLeft(-1), topLevelMarginRight(-1), topLevelMarginTop(-1),-
237 topLevelMarginBottom(-1), childMarginLeft(-1), childMarginRight(-1),-
238 childMarginTop(-1), childMarginBottom(-1), hspacing(-1), vspacing(-1),-
239 wizStyle(QWizard::ClassicStyle), header(false), watermark(false), title(false),-
240 subTitle(false), extension(false), sideWidget(false) {}-
241-
242 int topLevelMarginLeft;-
243 int topLevelMarginRight;-
244 int topLevelMarginTop;-
245 int topLevelMarginBottom;-
246 int childMarginLeft;-
247 int childMarginRight;-
248 int childMarginTop;-
249 int childMarginBottom;-
250 int hspacing;-
251 int vspacing;-
252 int buttonSpacing;-
253 QWizard::WizardStyle wizStyle;-
254 bool header;-
255 bool watermark;-
256 bool title;-
257 bool subTitle;-
258 bool extension;-
259 bool sideWidget;-
260-
261 bool operator==(const QWizardLayoutInfo &other);-
262 inline bool operator!=(const QWizardLayoutInfo &other) { return !operator==(other); }-
263};-
264-
265bool QWizardLayoutInfo::operator==(const QWizardLayoutInfo &other)-
266{-
267 return topLevelMarginLeft == other.topLevelMarginLeft-
268 && topLevelMarginRight == other.topLevelMarginRight-
269 && topLevelMarginTop == other.topLevelMarginTop-
270 && topLevelMarginBottom == other.topLevelMarginBottom-
271 && childMarginLeft == other.childMarginLeft-
272 && childMarginRight == other.childMarginRight-
273 && childMarginTop == other.childMarginTop-
274 && childMarginBottom == other.childMarginBottom-
275 && hspacing == other.hspacing-
276 && vspacing == other.vspacing-
277 && buttonSpacing == other.buttonSpacing-
278 && wizStyle == other.wizStyle-
279 && header == other.header-
280 && watermark == other.watermark-
281 && title == other.title-
282 && subTitle == other.subTitle-
283 && extension == other.extension-
284 && sideWidget == other.sideWidget;-
285}-
286-
287class QWizardHeader : public QWidget-
288{-
289public:-
290 enum RulerType { Ruler };-
291-
292 inline QWizardHeader(RulerType /* ruler */, QWidget *parent = 0)-
293 : QWidget(parent) { setFixedHeight(2); }-
294 QWizardHeader(QWidget *parent = 0);-
295-
296 void setup(const QWizardLayoutInfo &info, const QString &title,-
297 const QString &subTitle, const QPixmap &logo, const QPixmap &banner,-
298 Qt::TextFormat titleFormat, Qt::TextFormat subTitleFormat);-
299-
300protected:-
301 void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;-
302#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
303private:-
304 bool vistaDisabled() const;-
305#endif-
306private:-
307 QLabel *titleLabel;-
308 QLabel *subTitleLabel;-
309 QLabel *logoLabel;-
310 QGridLayout *layout;-
311 QPixmap bannerPixmap;-
312};-
313-
314QWizardHeader::QWizardHeader(QWidget *parent)-
315 : QWidget(parent)-
316{-
317 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);-
318 setBackgroundRole(QPalette::Base);-
319-
320 titleLabel = new QLabel(this);-
321 titleLabel->setBackgroundRole(QPalette::Base);-
322-
323 subTitleLabel = new QLabel(this);-
324 subTitleLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);-
325 subTitleLabel->setWordWrap(true);-
326-
327 logoLabel = new QLabel(this);-
328-
329 QFont font = titleLabel->font();-
330 font.setBold(true);-
331 titleLabel->setFont(font);-
332-
333 layout = new QGridLayout(this);-
334 layout->setMargin(0);-
335 layout->setSpacing(0);-
336-
337 layout->setRowMinimumHeight(3, 1);-
338 layout->setRowStretch(4, 1);-
339-
340 layout->setColumnStretch(2, 1);-
341 layout->setColumnMinimumWidth(4, 2 * GapBetweenLogoAndRightEdge);-
342 layout->setColumnMinimumWidth(6, GapBetweenLogoAndRightEdge);-
343-
344 layout->addWidget(titleLabel, 2, 1, 1, 2);-
345 layout->addWidget(subTitleLabel, 4, 2);-
346 layout->addWidget(logoLabel, 1, 5, 5, 1);-
347}-
348-
349#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
350bool QWizardHeader::vistaDisabled() const-
351{-
352 bool styleDisabled = false;-
353 QWizard *wiz = parentWidget() ? qobject_cast <QWizard *>(parentWidget()->parentWidget()) : 0;-
354 if (wiz) {-
355 // Designer dosen't support the Vista style for Wizards. This property is used to turn-
356 // off the Vista style.-
357 const QVariant v = wiz->property("_q_wizard_vista_off");-
358 styleDisabled = v.isValid() && v.toBool();-
359 }-
360 return styleDisabled;-
361}-
362#endif-
363-
364void QWizardHeader::setup(const QWizardLayoutInfo &info, const QString &title,-
365 const QString &subTitle, const QPixmap &logo, const QPixmap &banner,-
366 Qt::TextFormat titleFormat, Qt::TextFormat subTitleFormat)-
367{-
368 bool modern = ((info.wizStyle == QWizard::ModernStyle)-
369#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
370 || ((info.wizStyle == QWizard::AeroStyle-
371 && QVistaHelper::vistaState() == QVistaHelper::Classic) || vistaDisabled())-
372#endif-
373 );-
374-
375 layout->setRowMinimumHeight(0, modern ? ModernHeaderTopMargin : 0);-
376 layout->setRowMinimumHeight(1, modern ? info.topLevelMarginTop - ModernHeaderTopMargin - 1 : 0);-
377 layout->setRowMinimumHeight(6, (modern ? 3 : GapBetweenLogoAndRightEdge) + 2);-
378-
379 int minColumnWidth0 = modern ? info.topLevelMarginLeft + info.topLevelMarginRight : 0;-
380 int minColumnWidth1 = modern ? info.topLevelMarginLeft + info.topLevelMarginRight + 1-
381 : info.topLevelMarginLeft + ClassicHMargin;-
382 layout->setColumnMinimumWidth(0, minColumnWidth0);-
383 layout->setColumnMinimumWidth(1, minColumnWidth1);-
384-
385 titleLabel->setTextFormat(titleFormat);-
386 titleLabel->setText(title);-
387 logoLabel->setPixmap(logo);-
388-
389 subTitleLabel->setTextFormat(subTitleFormat);-
390 subTitleLabel->setText(QLatin1String("Pq\nPq"));-
391 int desiredSubTitleHeight = subTitleLabel->sizeHint().height();-
392 subTitleLabel->setText(subTitle);-
393-
394 if (modern) {-
395 bannerPixmap = banner;-
396 } else {-
397 bannerPixmap = QPixmap();-
398 }-
399-
400 if (bannerPixmap.isNull()) {-
401 /*-
402 There is no widthForHeight() function, so we simulate it with a loop.-
403 */-
404 int candidateSubTitleWidth = qMin(512, 2 * QApplication::desktop()->width() / 3);-
405 int delta = candidateSubTitleWidth >> 1;-
406 while (delta > 0) {-
407 if (subTitleLabel->heightForWidth(candidateSubTitleWidth - delta)-
408 <= desiredSubTitleHeight)-
409 candidateSubTitleWidth -= delta;-
410 delta >>= 1;-
411 }-
412-
413 subTitleLabel->setMinimumSize(candidateSubTitleWidth, desiredSubTitleHeight);-
414-
415 QSize size = layout->totalMinimumSize();-
416 setMinimumSize(size);-
417 setMaximumSize(QWIDGETSIZE_MAX, size.height());-
418 } else {-
419 subTitleLabel->setMinimumSize(0, 0);-
420 setFixedSize(banner.size() + QSize(0, 2));-
421 }-
422 updateGeometry();-
423}-
424-
425void QWizardHeader::paintEvent(QPaintEvent * /* event */)-
426{-
427 QPainter painter(this);-
428 painter.drawPixmap(0, 0, bannerPixmap);-
429-
430 int x = width() - 2;-
431 int y = height() - 2;-
432 const QPalette &pal = palette();-
433 painter.setPen(pal.mid().color());-
434 painter.drawLine(0, y, x, y);-
435 painter.setPen(pal.base().color());-
436 painter.drawPoint(x + 1, y);-
437 painter.drawLine(0, y + 1, x + 1, y + 1);-
438}-
439-
440// We save one vtable by basing QWizardRuler on QWizardHeader-
441class QWizardRuler : public QWizardHeader-
442{-
443public:-
444 inline QWizardRuler(QWidget *parent = 0)-
445 : QWizardHeader(Ruler, parent) {}-
446};-
447-
448class QWatermarkLabel : public QLabel-
449{-
450public:-
451 QWatermarkLabel(QWidget *parent, QWidget *sideWidget) : QLabel(parent), m_sideWidget(sideWidget) {-
452 m_layout = new QVBoxLayout(this);-
453 if (m_sideWidget)-
454 m_layout->addWidget(m_sideWidget);-
455 }-
456-
457 QSize minimumSizeHint() const Q_DECL_OVERRIDE {-
458 if (!pixmap() && !pixmap()->isNull())-
459 return pixmap()->size();-
460 return QFrame::minimumSizeHint();-
461 }-
462-
463 void setSideWidget(QWidget *widget) {-
464 if (m_sideWidget == widget)-
465 return;-
466 if (m_sideWidget) {-
467 m_layout->removeWidget(m_sideWidget);-
468 m_sideWidget->hide();-
469 }-
470 m_sideWidget = widget;-
471 if (m_sideWidget)-
472 m_layout->addWidget(m_sideWidget);-
473 }-
474 QWidget *sideWidget() const {-
475 return m_sideWidget;-
476 }-
477private:-
478 QVBoxLayout *m_layout;-
479 QWidget *m_sideWidget;-
480};-
481-
482class QWizardPagePrivate : public QWidgetPrivate-
483{-
484 Q_DECLARE_PUBLIC(QWizardPage)-
485-
486public:-
487 enum TriState { Tri_Unknown = -1, Tri_False, Tri_True };-
488-
489 inline QWizardPagePrivate()-
490 : wizard(0), completeState(Tri_Unknown), explicitlyFinal(false), commit(false) {}-
491-
492 bool cachedIsComplete() const;-
493 void _q_maybeEmitCompleteChanged();-
494 void _q_updateCachedCompleteState();-
495-
496 QWizard *wizard;-
497 QString title;-
498 QString subTitle;-
499 QPixmap pixmaps[QWizard::NPixmaps];-
500 QVector<QWizardField> pendingFields;-
501 mutable TriState completeState;-
502 bool explicitlyFinal;-
503 bool commit;-
504 QMap<int, QString> buttonCustomTexts;-
505};-
506-
507bool QWizardPagePrivate::cachedIsComplete() const-
508{-
509 Q_Q(const QWizardPage);-
510 if (completeState == Tri_Unknown)-
511 completeState = q->isComplete() ? Tri_True : Tri_False;-
512 return completeState == Tri_True;-
513}-
514-
515void QWizardPagePrivate::_q_maybeEmitCompleteChanged()-
516{-
517 Q_Q(QWizardPage);-
518 TriState newState = q->isComplete() ? Tri_True : Tri_False;-
519 if (newState != completeState)-
520 emit q->completeChanged();-
521}-
522-
523void QWizardPagePrivate::_q_updateCachedCompleteState()-
524{-
525 Q_Q(QWizardPage);-
526 completeState = q->isComplete() ? Tri_True : Tri_False;-
527}-
528-
529class QWizardAntiFlickerWidget : public QWidget-
530{-
531public:-
532#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
533 QWizardPrivate *wizardPrivate;-
534 QWizardAntiFlickerWidget(QWizard *wizard, QWizardPrivate *wizardPrivate)-
535 : QWidget(wizard)-
536 , wizardPrivate(wizardPrivate) {}-
537protected:-
538 void paintEvent(QPaintEvent *);-
539#else-
540 QWizardAntiFlickerWidget(QWizard *wizard, QWizardPrivate *)-
541 : QWidget(wizard)-
542 {}-
543#endif-
544};-
545-
546class QWizardPrivate : public QDialogPrivate-
547{-
548 Q_DECLARE_PUBLIC(QWizard)-
549-
550public:-
551 typedef QMap<int, QWizardPage *> PageMap;-
552-
553 enum Direction {-
554 Backward,-
555 Forward-
556 };-
557-
558 inline QWizardPrivate()-
559 : start(-1)-
560 , startSetByUser(false)-
561 , current(-1)-
562 , canContinue(false)-
563 , canFinish(false)-
564 , disableUpdatesCount(0)-
565 , wizStyle(QWizard::ClassicStyle)-
566 , opts(0)-
567 , buttonsHaveCustomLayout(false)-
568 , titleFmt(Qt::AutoText)-
569 , subTitleFmt(Qt::AutoText)-
570 , placeholderWidget1(0)-
571 , placeholderWidget2(0)-
572 , headerWidget(0)-
573 , watermarkLabel(0)-
574 , sideWidget(0)-
575 , pageFrame(0)-
576 , titleLabel(0)-
577 , subTitleLabel(0)-
578 , bottomRuler(0)-
579#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
580 , vistaHelper(0)-
581 , vistaInitPending(false)-
582 , vistaState(QVistaHelper::Dirty)-
583 , vistaStateChanged(false)-
584 , inHandleAeroStyleChange(false)-
585#endif-
586 , minimumWidth(0)-
587 , minimumHeight(0)-
588 , maximumWidth(QWIDGETSIZE_MAX)-
589 , maximumHeight(QWIDGETSIZE_MAX)-
590 {-
591 std::fill(btns, btns + QWizard::NButtons, static_cast<QAbstractButton *>(0));-
592-
593#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
594 if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA-
595 && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based))-
596 vistaInitPending = true;-
597#endif-
598 }-
599-
600 void init();-
601 void reset();-
602 void cleanupPagesNotInHistory();-
603 void addField(const QWizardField &field);-
604 void removeFieldAt(int index);-
605 void switchToPage(int newId, Direction direction);-
606 QWizardLayoutInfo layoutInfoForCurrentPage();-
607 void recreateLayout(const QWizardLayoutInfo &info);-
608 void updateLayout();-
609 void updateMinMaxSizes(const QWizardLayoutInfo &info);-
610 void updateCurrentPage();-
611 bool ensureButton(QWizard::WizardButton which) const;-
612 void connectButton(QWizard::WizardButton which) const;-
613 void updateButtonTexts();-
614 void updateButtonLayout();-
615 void setButtonLayout(const QWizard::WizardButton *array, int size);-
616 bool buttonLayoutContains(QWizard::WizardButton which);-
617 void updatePixmap(QWizard::WizardPixmap which);-
618#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
619 bool vistaDisabled() const;-
620 bool isVistaThemeEnabled(QVistaHelper::VistaState state) const;-
621 bool handleAeroStyleChange();-
622#endif-
623 bool isVistaThemeEnabled() const;-
624 void disableUpdates();-
625 void enableUpdates();-
626 void _q_emitCustomButtonClicked();-
627 void _q_updateButtonStates();-
628 void _q_handleFieldObjectDestroyed(QObject *);-
629 void setStyle(QStyle *style);-
630#ifdef Q_OS_MACX-
631 static QPixmap findDefaultBackgroundPixmap();-
632#endif-
633-
634 PageMap pageMap;-
635 QVector<QWizardField> fields;-
636 QMap<QString, int> fieldIndexMap;-
637 QVector<QWizardDefaultProperty> defaultPropertyTable;-
638 QList<int> history;-
639 QSet<int> initialized; // ### remove and move bit to QWizardPage?-
640 int start;-
641 bool startSetByUser;-
642 int current;-
643 bool canContinue;-
644 bool canFinish;-
645 QWizardLayoutInfo layoutInfo;-
646 int disableUpdatesCount;-
647-
648 QWizard::WizardStyle wizStyle;-
649 QWizard::WizardOptions opts;-
650 QMap<int, QString> buttonCustomTexts;-
651 bool buttonsHaveCustomLayout;-
652 QList<QWizard::WizardButton> buttonsCustomLayout;-
653 Qt::TextFormat titleFmt;-
654 Qt::TextFormat subTitleFmt;-
655 mutable QPixmap defaultPixmaps[QWizard::NPixmaps];-
656-
657 union {-
658 // keep in sync with QWizard::WizardButton-
659 mutable struct {-
660 QAbstractButton *back;-
661 QAbstractButton *next;-
662 QAbstractButton *commit;-
663 QAbstractButton *finish;-
664 QAbstractButton *cancel;-
665 QAbstractButton *help;-
666 } btn;-
667 mutable QAbstractButton *btns[QWizard::NButtons];-
668 };-
669 QWizardAntiFlickerWidget *antiFlickerWidget;-
670 QWidget *placeholderWidget1;-
671 QWidget *placeholderWidget2;-
672 QWizardHeader *headerWidget;-
673 QWatermarkLabel *watermarkLabel;-
674 QWidget *sideWidget;-
675 QFrame *pageFrame;-
676 QLabel *titleLabel;-
677 QLabel *subTitleLabel;-
678 QWizardRuler *bottomRuler;-
679-
680 QVBoxLayout *pageVBoxLayout;-
681 QHBoxLayout *buttonLayout;-
682 QGridLayout *mainLayout;-
683-
684#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
685 QVistaHelper *vistaHelper;-
686 bool vistaInitPending;-
687 QVistaHelper::VistaState vistaState;-
688 bool vistaStateChanged;-
689 bool inHandleAeroStyleChange;-
690#endif-
691 int minimumWidth;-
692 int minimumHeight;-
693 int maximumWidth;-
694 int maximumHeight;-
695};-
696-
697static QString buttonDefaultText(int wstyle, int which, const QWizardPrivate *wizardPrivate)-
698{-
699#if defined(QT_NO_STYLE_WINDOWSVISTA)-
700 Q_UNUSED(wizardPrivate);-
701#endif-
702 const bool macStyle = (wstyle == QWizard::MacStyle);-
703 switch (which) {-
704 case QWizard::BackButton:-
705 return macStyle ? QWizard::tr("Go Back") : QWizard::tr("< &Back");-
706 case QWizard::NextButton:-
707 if (macStyle)-
708 return QWizard::tr("Continue");-
709 else-
710 return wizardPrivate->isVistaThemeEnabled()-
711 ? QWizard::tr("&Next") : QWizard::tr("&Next >");-
712 case QWizard::CommitButton:-
713 return QWizard::tr("Commit");-
714 case QWizard::FinishButton:-
715 return macStyle ? QWizard::tr("Done") : QWizard::tr("&Finish");-
716 case QWizard::CancelButton:-
717 return QWizard::tr("Cancel");-
718 case QWizard::HelpButton:-
719 return macStyle ? QWizard::tr("Help") : QWizard::tr("&Help");-
720 default:-
721 return QString();-
722 }-
723}-
724-
725void QWizardPrivate::init()-
726{-
727 Q_Q(QWizard);-
728-
729 antiFlickerWidget = new QWizardAntiFlickerWidget(q, this);-
730 wizStyle = QWizard::WizardStyle(q->style()->styleHint(QStyle::SH_WizardStyle, 0, q));-
731 if (wizStyle == QWizard::MacStyle) {-
732 opts = (QWizard::NoDefaultButton | QWizard::NoCancelButton);-
733 } else if (wizStyle == QWizard::ModernStyle) {-
734 opts = QWizard::HelpButtonOnRight;-
735 }-
736-
737#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
738 vistaHelper = new QVistaHelper(q);-
739#endif-
740-
741 // create these buttons right away; create the other buttons as necessary-
742 ensureButton(QWizard::BackButton);-
743 ensureButton(QWizard::NextButton);-
744 ensureButton(QWizard::CommitButton);-
745 ensureButton(QWizard::FinishButton);-
746-
747 pageFrame = new QFrame(antiFlickerWidget);-
748 pageFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);-
749-
750 pageVBoxLayout = new QVBoxLayout(pageFrame);-
751 pageVBoxLayout->setSpacing(0);-
752 pageVBoxLayout->addSpacing(0);-
753 QSpacerItem *spacerItem = new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding);-
754 pageVBoxLayout->addItem(spacerItem);-
755-
756 buttonLayout = new QHBoxLayout;-
757 mainLayout = new QGridLayout(antiFlickerWidget);-
758 mainLayout->setSizeConstraint(QLayout::SetNoConstraint);-
759-
760 updateButtonLayout();-
761-
762 defaultPropertyTable.reserve(NFallbackDefaultProperties);-
763 for (uint i = 0; i < NFallbackDefaultProperties; ++i)-
764 defaultPropertyTable.append(QWizardDefaultProperty(fallbackProperties[i].className,-
765 fallbackProperties[i].property,-
766 changed_signal(i)));-
767}-
768-
769void QWizardPrivate::reset()-
770{-
771 Q_Q(QWizard);-
772 if (current != -1) {-
773 q->currentPage()->hide();-
774 cleanupPagesNotInHistory();-
775 for (int i = history.count() - 1; i >= 0; --i)-
776 q->cleanupPage(history.at(i));-
777 history.clear();-
778 initialized.clear();-
779-
780 current = -1;-
781 emit q->currentIdChanged(-1);-
782 }-
783}-
784-
785void QWizardPrivate::cleanupPagesNotInHistory()-
786{-
787 Q_Q(QWizard);-
788-
789 const QSet<int> original = initialized;-
790 QSet<int>::const_iterator i = original.constBegin();-
791 QSet<int>::const_iterator end = original.constEnd();-
792-
793 for (; i != end; ++i) {-
794 if (!history.contains(*i)) {-
795 q->cleanupPage(*i);-
796 initialized.remove(*i);-
797 }-
798 }-
799}-
800-
801void QWizardPrivate::addField(const QWizardField &field)-
802{-
803 Q_Q(QWizard);-
804-
805 QWizardField myField = field;-
806 myField.resolve(defaultPropertyTable);-
807-
808 if (Q_UNLIKELY(fieldIndexMap.contains(myField.name))))) {
__builtin_expe...name)), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
809 qWarning("QWizardPage::addField: Duplicate field '%s'"'%ls'", qPrintableqUtf16Printable(myField.name));-
810 return;
never executed: return;
0
811 }-
812-
813 fieldIndexMap.insert(myField.name, fields.count());-
814 fields += myField;-
815 if (myField.mandatory && !myField.changedSignal.isEmpty())
myField.mandatoryDescription
TRUEnever evaluated
FALSEnever evaluated
!myField.chang...gnal.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
816 QObject::connect(myField.object, myField.changedSignal,
never executed: QObject::connect(myField.object, myField.changedSignal, myField.page, qFlagLocation("1""_q_maybeEmitCompleteChanged()" "\0" __FILE__ ":" "817"));
0
817 myField.page, SLOT(_q_maybeEmitCompleteChanged()));
never executed: QObject::connect(myField.object, myField.changedSignal, myField.page, qFlagLocation("1""_q_maybeEmitCompleteChanged()" "\0" __FILE__ ":" "817"));
0
818 QObject::connect(-
819 myField.object, SIGNAL(destroyed(QObject*)), q,-
820 SLOT(_q_handleFieldObjectDestroyed(QObject*)));-
821}
never executed: end of block
0
822-
823void QWizardPrivate::removeFieldAt(int index)-
824{-
825 Q_Q(QWizard);-
826-
827 const QWizardField &field = fields.at(index);-
828 fieldIndexMap.remove(field.name);-
829 if (field.mandatory && !field.changedSignal.isEmpty())-
830 QObject::disconnect(field.object, field.changedSignal,-
831 field.page, SLOT(_q_maybeEmitCompleteChanged()));-
832 QObject::disconnect(-
833 field.object, SIGNAL(destroyed(QObject*)), q,-
834 SLOT(_q_handleFieldObjectDestroyed(QObject*)));-
835 fields.remove(index);-
836}-
837-
838void QWizardPrivate::switchToPage(int newId, Direction direction)-
839{-
840 Q_Q(QWizard);-
841-
842 disableUpdates();-
843-
844 int oldId = current;-
845 if (QWizardPage *oldPage = q->currentPage()) {
QWizardPage *o...>currentPage()Description
TRUEnever evaluated
FALSEnever evaluated
0
846 oldPage->hide();-
847-
848 if (direction == Backward) {
direction == BackwardDescription
TRUEnever evaluated
FALSEnever evaluated
0
849 if (!(opts & QWizard::IndependentPages)) {
!(opts & QWiza...ependentPages)Description
TRUEnever evaluated
FALSEnever evaluated
0
850 q->cleanupPage(oldId);-
851 initialized.remove(oldId);-
852 }
never executed: end of block
0
853 Q_ASSERT(history.lastconstLast() == oldId);-
854 history.removeLast();-
855 Q_ASSERT(history.lastconstLast() == newId);-
856 }
never executed: end of block
0
857 }
never executed: end of block
0
858-
859 current = newId;-
860-
861 QWizardPage *newPage = q->currentPage();-
862 if (newPage) {
newPageDescription
TRUEnever evaluated
FALSEnever evaluated
0
863 if (direction == Forward) {
direction == ForwardDescription
TRUEnever evaluated
FALSEnever evaluated
0
864 if (!initialized.contains(current)) {
!initialized.contains(current)Description
TRUEnever evaluated
FALSEnever evaluated
0
865 initialized.insert(current);-
866 q->initializePage(current);-
867 }
never executed: end of block
0
868 history.append(current);-
869 }
never executed: end of block
0
870 newPage->show();-
871 }
never executed: end of block
0
872-
873 canContinue = (q->nextId() != -1);-
874 canFinish = (newPage && newPage->isFinalPage());
newPageDescription
TRUEnever evaluated
FALSEnever evaluated
newPage->isFinalPage()Description
TRUEnever evaluated
FALSEnever evaluated
0
875-
876 _q_updateButtonStates();-
877 updateButtonTexts();-
878-
879 const QWizard::WizardButton nextOrCommit =-
880 newPage && newPage->isCommitPage() ? QWizard::CommitButton : QWizard::NextButton;
newPageDescription
TRUEnever evaluated
FALSEnever evaluated
newPage->isCommitPage()Description
TRUEnever evaluated
FALSEnever evaluated
0
881 QAbstractButton *nextOrFinishButton =-
882 btns[canContinue ? nextOrCommit : QWizard::FinishButton];-
883 QWidget *candidate = 0;-
884-
885 /*-
886 If there is no default button and the Next or Finish button-
887 is enabled, give focus directly to it as a convenience to the-
888 user. This is the normal case on OS X.-
889-
890 Otherwise, give the focus to the new page's first child that-
891 can handle it. If there is no such child, give the focus to-
892 Next or Finish.-
893 */-
894 if ((opts & QWizard::NoDefaultButton) && nextOrFinishButton->isEnabled()) {
(opts & QWizar...DefaultButton)Description
TRUEnever evaluated
FALSEnever evaluated
nextOrFinishBu...n->isEnabled()Description
TRUEnever evaluated
FALSEnever evaluated
0
895 candidate = nextOrFinishButton;-
896 } else if (newPage) {
never executed: end of block
newPageDescription
TRUEnever evaluated
FALSEnever evaluated
0
897 candidate = iWantTheFocus(newPage);-
898 }
never executed: end of block
0
899 if (!candidate)
!candidateDescription
TRUEnever evaluated
FALSEnever evaluated
0
900 candidate = nextOrFinishButton;
never executed: candidate = nextOrFinishButton;
0
901 candidate->setFocus();-
902-
903 if (wizStyle == QWizard::MacStyle)
wizStyle == QWizard::MacStyleDescription
TRUEnever evaluated
FALSEnever evaluated
0
904 q->updateGeometry();
never executed: q->updateGeometry();
0
905-
906 enableUpdates();-
907 updateLayout();-
908-
909 emit q->currentIdChanged(current);-
910}
never executed: end of block
0
911-
912// keep in sync with QWizard::WizardButton-
913static const char * buttonSlots(QWizard::WizardButton which)-
914{-
915 switch (which) {-
916 case QWizard::BackButton:-
917 return SLOT(back());-
918 case QWizard::NextButton:-
919 case QWizard::CommitButton:-
920 return SLOT(next());-
921 case QWizard::FinishButton:-
922 return SLOT(accept());-
923 case QWizard::CancelButton:-
924 return SLOT(reject());-
925 case QWizard::HelpButton:-
926 return SIGNAL(helpRequested());-
927 case QWizard::CustomButton1:-
928 case QWizard::CustomButton2:-
929 case QWizard::CustomButton3:-
930 case QWizard::Stretch:-
931 case QWizard::NoButton:-
932 Q_UNREACHABLE();-
933 };-
934 return 0;-
935};-
936-
937QWizardLayoutInfo QWizardPrivate::layoutInfoForCurrentPage()-
938{-
939 Q_Q(QWizard);-
940 QStyle *style = q->style();-
941-
942 QWizardLayoutInfo info;-
943-
944 const int layoutHorizontalSpacing = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);-
945 info.topLevelMarginLeft = style->pixelMetric(QStyle::PM_LayoutLeftMargin, 0, q);-
946 info.topLevelMarginRight = style->pixelMetric(QStyle::PM_LayoutRightMargin, 0, q);-
947 info.topLevelMarginTop = style->pixelMetric(QStyle::PM_LayoutTopMargin, 0, q);-
948 info.topLevelMarginBottom = style->pixelMetric(QStyle::PM_LayoutBottomMargin, 0, q);-
949 info.childMarginLeft = style->pixelMetric(QStyle::PM_LayoutLeftMargin, 0, titleLabel);-
950 info.childMarginRight = style->pixelMetric(QStyle::PM_LayoutRightMargin, 0, titleLabel);-
951 info.childMarginTop = style->pixelMetric(QStyle::PM_LayoutTopMargin, 0, titleLabel);-
952 info.childMarginBottom = style->pixelMetric(QStyle::PM_LayoutBottomMargin, 0, titleLabel);-
953 info.hspacing = (layoutHorizontalSpacing == -1)-
954 ? style->layoutSpacing(QSizePolicy::DefaultType, QSizePolicy::DefaultType, Qt::Horizontal)-
955 : layoutHorizontalSpacing;-
956 info.vspacing = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing);-
957 info.buttonSpacing = (layoutHorizontalSpacing == -1)-
958 ? style->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal)-
959 : layoutHorizontalSpacing;-
960-
961 if (wizStyle == QWizard::MacStyle)-
962 info.buttonSpacing = 12;-
963-
964 info.wizStyle = wizStyle;-
965 if (info.wizStyle == QWizard::AeroStyle-
966#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
967 && (QVistaHelper::vistaState() == QVistaHelper::Classic || vistaDisabled())-
968#endif-
969 )-
970 info.wizStyle = QWizard::ModernStyle;-
971-
972 QString titleText;-
973 QString subTitleText;-
974 QPixmap backgroundPixmap;-
975 QPixmap watermarkPixmap;-
976-
977 if (QWizardPage *page = q->currentPage()) {-
978 titleText = page->title();-
979 subTitleText = page->subTitle();-
980 backgroundPixmap = page->pixmap(QWizard::BackgroundPixmap);-
981 watermarkPixmap = page->pixmap(QWizard::WatermarkPixmap);-
982 }-
983-
984 info.header = (info.wizStyle == QWizard::ClassicStyle || info.wizStyle == QWizard::ModernStyle)-
985 && !(opts & QWizard::IgnoreSubTitles) && !subTitleText.isEmpty();-
986 info.sideWidget = sideWidget;-
987 info.watermark = (info.wizStyle != QWizard::MacStyle) && (info.wizStyle != QWizard::AeroStyle)-
988 && !watermarkPixmap.isNull();-
989 info.title = !info.header && !titleText.isEmpty();-
990 info.subTitle = !(opts & QWizard::IgnoreSubTitles) && !info.header && !subTitleText.isEmpty();-
991 info.extension = (info.watermark || info.sideWidget) && (opts & QWizard::ExtendedWatermarkPixmap);-
992-
993 return info;-
994}-
995-
996void QWizardPrivate::recreateLayout(const QWizardLayoutInfo &info)-
997{-
998 Q_Q(QWizard);-
999-
1000 /*-
1001 Start by undoing the main layout.-
1002 */-
1003 for (int i = mainLayout->count() - 1; i >= 0; --i) {-
1004 QLayoutItem *item = mainLayout->takeAt(i);-
1005 if (item->layout()) {-
1006 item->layout()->setParent(0);-
1007 } else {-
1008 delete item;-
1009 }-
1010 }-
1011 for (int i = mainLayout->columnCount() - 1; i >= 0; --i)-
1012 mainLayout->setColumnMinimumWidth(i, 0);-
1013 for (int i = mainLayout->rowCount() - 1; i >= 0; --i)-
1014 mainLayout->setRowMinimumHeight(i, 0);-
1015-
1016 /*-
1017 Now, recreate it.-
1018 */-
1019-
1020 bool mac = (info.wizStyle == QWizard::MacStyle);-
1021 bool classic = (info.wizStyle == QWizard::ClassicStyle);-
1022 bool modern = (info.wizStyle == QWizard::ModernStyle);-
1023 bool aero = (info.wizStyle == QWizard::AeroStyle);-
1024 int deltaMarginLeft = info.topLevelMarginLeft - info.childMarginLeft;-
1025 int deltaMarginRight = info.topLevelMarginRight - info.childMarginRight;-
1026 int deltaMarginTop = info.topLevelMarginTop - info.childMarginTop;-
1027 int deltaMarginBottom = info.topLevelMarginBottom - info.childMarginBottom;-
1028 int deltaVSpacing = info.topLevelMarginBottom - info.vspacing;-
1029-
1030 int row = 0;-
1031 int numColumns;-
1032 if (mac) {-
1033 numColumns = 3;-
1034 } else if (info.watermark || info.sideWidget) {-
1035 numColumns = 2;-
1036 } else {-
1037 numColumns = 1;-
1038 }-
1039 int pageColumn = qMin(1, numColumns - 1);-
1040-
1041 if (mac) {-
1042 mainLayout->setMargin(0);-
1043 mainLayout->setSpacing(0);-
1044 buttonLayout->setContentsMargins(MacLayoutLeftMargin, MacButtonTopMargin, MacLayoutRightMargin, MacLayoutBottomMargin);-
1045 pageVBoxLayout->setMargin(7);-
1046 } else {-
1047 if (modern) {-
1048 mainLayout->setMargin(0);-
1049 mainLayout->setSpacing(0);-
1050 pageVBoxLayout->setContentsMargins(deltaMarginLeft, deltaMarginTop,-
1051 deltaMarginRight, deltaMarginBottom);-
1052 buttonLayout->setContentsMargins(info.topLevelMarginLeft, info.topLevelMarginTop,-
1053 info.topLevelMarginRight, info.topLevelMarginBottom);-
1054 } else {-
1055 mainLayout->setContentsMargins(info.topLevelMarginLeft, info.topLevelMarginTop,-
1056 info.topLevelMarginRight, info.topLevelMarginBottom);-
1057 mainLayout->setHorizontalSpacing(info.hspacing);-
1058 mainLayout->setVerticalSpacing(info.vspacing);-
1059 pageVBoxLayout->setContentsMargins(0, 0, 0, 0);-
1060 buttonLayout->setContentsMargins(0, 0, 0, 0);-
1061 }-
1062 }-
1063 buttonLayout->setSpacing(info.buttonSpacing);-
1064-
1065 if (info.header) {-
1066 if (!headerWidget)-
1067 headerWidget = new QWizardHeader(antiFlickerWidget);-
1068 headerWidget->setAutoFillBackground(modern);-
1069 mainLayout->addWidget(headerWidget, row++, 0, 1, numColumns);-
1070 }-
1071 if (headerWidget)-
1072 headerWidget->setVisible(info.header);-
1073-
1074 int watermarkStartRow = row;-
1075-
1076 if (mac)-
1077 mainLayout->setRowMinimumHeight(row++, 10);-
1078-
1079 if (info.title) {-
1080 if (!titleLabel) {-
1081 titleLabel = new QLabel(antiFlickerWidget);-
1082 titleLabel->setBackgroundRole(QPalette::Base);-
1083 titleLabel->setWordWrap(true);-
1084 }-
1085-
1086 QFont titleFont = q->font();-
1087 titleFont.setPointSize(titleFont.pointSize() + (mac ? 3 : 4));-
1088 titleFont.setBold(true);-
1089 titleLabel->setPalette(QPalette());-
1090-
1091 if (aero) {-
1092 // ### hardcoded for now:-
1093 titleFont = QFont(QLatin1String("Segoe UI"), 12);-
1094 QPalette pal(titleLabel->palette());-
1095 pal.setColor(QPalette::Text, "#003399");-
1096 titleLabel->setPalette(pal);-
1097 }-
1098-
1099 titleLabel->setFont(titleFont);-
1100 const int aeroTitleIndent = 25; // ### hardcoded for now - should be calculated somehow-
1101 if (aero)-
1102 titleLabel->setIndent(aeroTitleIndent);-
1103 else if (mac)-
1104 titleLabel->setIndent(2);-
1105 else if (classic)-
1106 titleLabel->setIndent(info.childMarginLeft);-
1107 else-
1108 titleLabel->setIndent(info.topLevelMarginLeft);-
1109 if (modern) {-
1110 if (!placeholderWidget1) {-
1111 placeholderWidget1 = new QWidget(antiFlickerWidget);-
1112 placeholderWidget1->setBackgroundRole(QPalette::Base);-
1113 }-
1114 placeholderWidget1->setFixedHeight(info.topLevelMarginLeft + 2);-
1115 mainLayout->addWidget(placeholderWidget1, row++, pageColumn);-
1116 }-
1117 mainLayout->addWidget(titleLabel, row++, pageColumn);-
1118 if (modern) {-
1119 if (!placeholderWidget2) {-
1120 placeholderWidget2 = new QWidget(antiFlickerWidget);-
1121 placeholderWidget2->setBackgroundRole(QPalette::Base);-
1122 }-
1123 placeholderWidget2->setFixedHeight(5);-
1124 mainLayout->addWidget(placeholderWidget2, row++, pageColumn);-
1125 }-
1126 if (mac)-
1127 mainLayout->setRowMinimumHeight(row++, 7);-
1128 }-
1129 if (placeholderWidget1)-
1130 placeholderWidget1->setVisible(info.title && modern);-
1131 if (placeholderWidget2)-
1132 placeholderWidget2->setVisible(info.title && modern);-
1133-
1134 if (info.subTitle) {-
1135 if (!subTitleLabel) {-
1136 subTitleLabel = new QLabel(pageFrame);-
1137 subTitleLabel->setWordWrap(true);-
1138-
1139 subTitleLabel->setContentsMargins(info.childMarginLeft , 0,-
1140 info.childMarginRight , 0);-
1141-
1142 pageVBoxLayout->insertWidget(1, subTitleLabel);-
1143 }-
1144 }-
1145-
1146 // ### try to replace with margin.-
1147 changeSpacerSize(pageVBoxLayout, 0, 0, info.subTitle ? info.childMarginLeft : 0);-
1148-
1149 int hMargin = mac ? 1 : 0;-
1150 int vMargin = hMargin;-
1151-
1152 pageFrame->setFrameStyle(mac ? (QFrame::Box | QFrame::Raised) : QFrame::NoFrame);-
1153 pageFrame->setLineWidth(0);-
1154 pageFrame->setMidLineWidth(hMargin);-
1155-
1156 if (info.header) {-
1157 if (modern) {-
1158 hMargin = info.topLevelMarginLeft;-
1159 vMargin = deltaMarginBottom;-
1160 } else if (classic) {-
1161 hMargin = deltaMarginLeft + ClassicHMargin;-
1162 vMargin = 0;-
1163 }-
1164 }-
1165-
1166 if (aero) {-
1167 int leftMargin = 18; // ### hardcoded for now - should be calculated somehow-
1168 int topMargin = vMargin;-
1169 int rightMargin = hMargin; // ### for now-
1170 int bottomMargin = vMargin;-
1171 pageFrame->setContentsMargins(leftMargin, topMargin, rightMargin, bottomMargin);-
1172 } else {-
1173 pageFrame->setContentsMargins(hMargin, vMargin, hMargin, vMargin);-
1174 }-
1175-
1176 if ((info.watermark || info.sideWidget) && !watermarkLabel) {-
1177 watermarkLabel = new QWatermarkLabel(antiFlickerWidget, sideWidget);-
1178 watermarkLabel->setBackgroundRole(QPalette::Base);-
1179 watermarkLabel->setMinimumHeight(1);-
1180 watermarkLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);-
1181 watermarkLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);-
1182 }-
1183-
1184 //bool wasSemiTransparent = pageFrame->testAttribute(Qt::WA_SetPalette);-
1185 const bool wasSemiTransparent =-
1186 pageFrame->palette().brush(QPalette::Window).color().alpha() < 255-
1187 || pageFrame->palette().brush(QPalette::Base).color().alpha() < 255;-
1188 if (mac) {-
1189 if (!wasSemiTransparent) {-
1190 QPalette pal = pageFrame->palette();-
1191 pal.setBrush(QPalette::Window, QColor(255, 255, 255, 153));-
1192 // ### The next line is required to ensure visual semitransparency when-
1193 // ### switching from ModernStyle to MacStyle. See TAG1 below.-
1194 pal.setBrush(QPalette::Base, QColor(255, 255, 255, 153));-
1195 pageFrame->setPalette(pal);-
1196 pageFrame->setAutoFillBackground(true);-
1197 antiFlickerWidget->setAutoFillBackground(false);-
1198 }-
1199 } else {-
1200 if (wasSemiTransparent)-
1201 pageFrame->setPalette(QPalette());-
1202-
1203 bool baseBackground = (modern && !info.header); // ### TAG1-
1204 pageFrame->setBackgroundRole(baseBackground ? QPalette::Base : QPalette::Window);-
1205-
1206 if (titleLabel)-
1207 titleLabel->setAutoFillBackground(baseBackground);-
1208 pageFrame->setAutoFillBackground(baseBackground);-
1209 if (watermarkLabel)-
1210 watermarkLabel->setAutoFillBackground(baseBackground);-
1211 if (placeholderWidget1)-
1212 placeholderWidget1->setAutoFillBackground(baseBackground);-
1213 if (placeholderWidget2)-
1214 placeholderWidget2->setAutoFillBackground(baseBackground);-
1215-
1216 if (aero) {-
1217 QPalette pal = pageFrame->palette();-
1218 pal.setBrush(QPalette::Window, QColor(255, 255, 255));-
1219 pageFrame->setPalette(pal);-
1220 pageFrame->setAutoFillBackground(true);-
1221 pal = antiFlickerWidget->palette();-
1222 pal.setBrush(QPalette::Window, QColor(255, 255, 255));-
1223 antiFlickerWidget->setPalette(pal);-
1224 antiFlickerWidget->setAutoFillBackground(true);-
1225 }-
1226 }-
1227-
1228 mainLayout->addWidget(pageFrame, row++, pageColumn);-
1229-
1230 int watermarkEndRow = row;-
1231 if (classic)-
1232 mainLayout->setRowMinimumHeight(row++, deltaVSpacing);-
1233-
1234 if (aero) {-
1235 buttonLayout->setContentsMargins(9, 9, 9, 9);-
1236 mainLayout->setContentsMargins(0, 11, 0, 0);-
1237 }-
1238-
1239 int buttonStartColumn = info.extension ? 1 : 0;-
1240 int buttonNumColumns = info.extension ? 1 : numColumns;-
1241-
1242 if (classic || modern) {-
1243 if (!bottomRuler)-
1244 bottomRuler = new QWizardRuler(antiFlickerWidget);-
1245 mainLayout->addWidget(bottomRuler, row++, buttonStartColumn, 1, buttonNumColumns);-
1246 }-
1247-
1248 if (classic)-
1249 mainLayout->setRowMinimumHeight(row++, deltaVSpacing);-
1250-
1251 mainLayout->addLayout(buttonLayout, row++, buttonStartColumn, 1, buttonNumColumns);-
1252-
1253 if (info.watermark || info.sideWidget) {-
1254 if (info.extension)-
1255 watermarkEndRow = row;-
1256 mainLayout->addWidget(watermarkLabel, watermarkStartRow, 0,-
1257 watermarkEndRow - watermarkStartRow, 1);-
1258 }-
1259-
1260 mainLayout->setColumnMinimumWidth(0, mac && !info.watermark ? 181 : 0);-
1261 if (mac)-
1262 mainLayout->setColumnMinimumWidth(2, 21);-
1263-
1264 if (headerWidget)-
1265 headerWidget->setVisible(info.header);-
1266 if (titleLabel)-
1267 titleLabel->setVisible(info.title);-
1268 if (subTitleLabel)-
1269 subTitleLabel->setVisible(info.subTitle);-
1270 if (bottomRuler)-
1271 bottomRuler->setVisible(classic || modern);-
1272 if (watermarkLabel)-
1273 watermarkLabel->setVisible(info.watermark || info.sideWidget);-
1274-
1275 layoutInfo = info;-
1276}-
1277-
1278void QWizardPrivate::updateLayout()-
1279{-
1280 Q_Q(QWizard);-
1281-
1282 disableUpdates();-
1283-
1284 QWizardLayoutInfo info = layoutInfoForCurrentPage();-
1285 if (layoutInfo != info)-
1286 recreateLayout(info);-
1287 QWizardPage *page = q->currentPage();-
1288-
1289 // If the page can expand vertically, let it stretch "infinitely" more-
1290 // than the QSpacerItem at the bottom. Otherwise, let the QSpacerItem-
1291 // stretch "infinitely" more than the page. Change the bottom item's-
1292 // policy accordingly. The case that the page has no layout is basically-
1293 // for Designer, only.-
1294 if (page) {-
1295 bool expandPage = !page->layout();-
1296 if (!expandPage) {-
1297 const QLayoutItem *pageItem = pageVBoxLayout->itemAt(pageVBoxLayout->indexOf(page));-
1298 expandPage = pageItem->expandingDirections() & Qt::Vertical;-
1299 }-
1300 QSpacerItem *bottomSpacer = pageVBoxLayout->itemAt(pageVBoxLayout->count() - 1)->spacerItem();-
1301 Q_ASSERT(bottomSpacer);-
1302 bottomSpacer->changeSize(0, 0, QSizePolicy::Ignored, expandPage ? QSizePolicy::Ignored : QSizePolicy::MinimumExpanding);-
1303 pageVBoxLayout->invalidate();-
1304 }-
1305-
1306 if (info.header) {-
1307 Q_ASSERT(page);-
1308 headerWidget->setup(info, page->title(), page->subTitle(),-
1309 page->pixmap(QWizard::LogoPixmap), page->pixmap(QWizard::BannerPixmap),-
1310 titleFmt, subTitleFmt);-
1311 }-
1312-
1313 if (info.watermark || info.sideWidget) {-
1314 QPixmap pix;-
1315 if (info.watermark) {-
1316 if (page)-
1317 pix = page->pixmap(QWizard::WatermarkPixmap);-
1318 else-
1319 pix = q->pixmap(QWizard::WatermarkPixmap);-
1320 }-
1321 watermarkLabel->setPixmap(pix); // in case there is no watermark and we show the side widget we need to clear the watermark-
1322 }-
1323-
1324 if (info.title) {-
1325 Q_ASSERT(page);-
1326 titleLabel->setTextFormat(titleFmt);-
1327 titleLabel->setText(page->title());-
1328 }-
1329 if (info.subTitle) {-
1330 Q_ASSERT(page);-
1331 subTitleLabel->setTextFormat(subTitleFmt);-
1332 subTitleLabel->setText(page->subTitle());-
1333 }-
1334-
1335 enableUpdates();-
1336 updateMinMaxSizes(info);-
1337}-
1338-
1339void QWizardPrivate::updateMinMaxSizes(const QWizardLayoutInfo &info)-
1340{-
1341 Q_Q(QWizard);-
1342-
1343 int extraHeight = 0;-
1344#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
1345 if (isVistaThemeEnabled())-
1346 extraHeight = vistaHelper->titleBarSize() + vistaHelper->topOffset();-
1347#endif-
1348 QSize minimumSize = mainLayout->totalMinimumSize() + QSize(0, extraHeight);-
1349 QSize maximumSize = mainLayout->totalMaximumSize();-
1350 if (info.header && headerWidget->maximumWidth() != QWIDGETSIZE_MAX) {-
1351 minimumSize.setWidth(headerWidget->maximumWidth());-
1352 maximumSize.setWidth(headerWidget->maximumWidth());-
1353 }-
1354 if (info.watermark && !info.sideWidget) {-
1355 minimumSize.setHeight(mainLayout->totalSizeHint().height());-
1356 }-
1357 if (q->minimumWidth() == minimumWidth) {-
1358 minimumWidth = minimumSize.width();-
1359 q->setMinimumWidth(minimumWidth);-
1360 }-
1361 if (q->minimumHeight() == minimumHeight) {-
1362 minimumHeight = minimumSize.height();-
1363 q->setMinimumHeight(minimumHeight);-
1364 }-
1365 if (q->maximumWidth() == maximumWidth) {-
1366 maximumWidth = maximumSize.width();-
1367 q->setMaximumWidth(maximumWidth);-
1368 }-
1369 if (q->maximumHeight() == maximumHeight) {-
1370 maximumHeight = maximumSize.height();-
1371 q->setMaximumHeight(maximumHeight);-
1372 }-
1373}-
1374-
1375void QWizardPrivate::updateCurrentPage()-
1376{-
1377 Q_Q(QWizard);-
1378 if (q->currentPage()) {-
1379 canContinue = (q->nextId() != -1);-
1380 canFinish = q->currentPage()->isFinalPage();-
1381 } else {-
1382 canContinue = false;-
1383 canFinish = false;-
1384 }-
1385 _q_updateButtonStates();-
1386 updateButtonTexts();-
1387}-
1388-
1389static QString object_name_for_button(QWizard::WizardButton which)-
1390{-
1391 switch (which) {-
1392 case QWizard::CommitButton:-
1393 return QLatin1String("qt_wizard_") + QLatin1String("commit");-
1394 case QWizard::FinishButton:-
1395 return QLatin1String("qt_wizard_") + QLatin1String("finish");-
1396 case QWizard::CancelButton:-
1397 return QLatin1String("qt_wizard_") + QLatin1String("cancel");-
1398 case QWizard::BackButton:-
1399 case QWizard::NextButton:-
1400 case QWizard::HelpButton:-
1401 case QWizard::CustomButton1:-
1402 case QWizard::CustomButton2:-
1403 case QWizard::CustomButton3:-
1404 // Make navigation buttons detectable as passive interactor in designer-
1405 return QLatin1String("__qt__passive_wizardbutton") + QString::number(which);-
1406 case QWizard::Stretch:-
1407 case QWizard::NoButton:-
1408 //case QWizard::NStandardButtons:-
1409 //case QWizard::NButtons:-
1410 ;-
1411 }-
1412 Q_UNREACHABLE();-
1413 return QString();-
1414}-
1415-
1416bool QWizardPrivate::ensureButton(QWizard::WizardButton which) const-
1417{-
1418 Q_Q(const QWizard);-
1419 if (uint(which) >= QWizard::NButtons)-
1420 return false;-
1421-
1422 if (!btns[which]) {-
1423 QPushButton *pushButton = new QPushButton(antiFlickerWidget);-
1424 QStyle *style = q->style();-
1425 if (style != QApplication::style()) // Propagate style-
1426 pushButton->setStyle(style);-
1427 pushButton->setObjectName(object_name_for_button(which));-
1428#ifdef Q_OS_MACX-
1429 pushButton->setAutoDefault(false);-
1430#endif-
1431 pushButton->hide();-
1432#ifdef Q_CC_HPACC-
1433 const_cast<QWizardPrivate *>(this)->btns[which] = pushButton;-
1434#else-
1435 btns[which] = pushButton;-
1436#endif-
1437 if (which < QWizard::NStandardButtons)-
1438 pushButton->setText(buttonDefaultText(wizStyle, which, this));-
1439-
1440 connectButton(which);-
1441 }-
1442 return true;-
1443}-
1444-
1445void QWizardPrivate::connectButton(QWizard::WizardButton which) const-
1446{-
1447 Q_Q(const QWizard);-
1448 if (which < QWizard::NStandardButtons) {-
1449 QObject::connect(btns[which], SIGNAL(clicked()), q, buttonSlots(which));-
1450 } else {-
1451 QObject::connect(btns[which], SIGNAL(clicked()), q, SLOT(_q_emitCustomButtonClicked()));-
1452 }-
1453}-
1454-
1455void QWizardPrivate::updateButtonTexts()-
1456{-
1457 Q_Q(QWizard);-
1458 for (int i = 0; i < QWizard::NButtons; ++i) {-
1459 if (btns[i]) {-
1460 if (q->currentPage() && (q->currentPage()->d_func()->buttonCustomTexts.contains(i)))-
1461 btns[i]->setText(q->currentPage()->d_func()->buttonCustomTexts.value(i));-
1462 else if (buttonCustomTexts.contains(i))-
1463 btns[i]->setText(buttonCustomTexts.value(i));-
1464 else if (i < QWizard::NStandardButtons)-
1465 btns[i]->setText(buttonDefaultText(wizStyle, i, this));-
1466 }-
1467 }-
1468 // Vista: Add shortcut for 'next'. Note: native dialogs use ALT-Right-
1469 // even in RTL mode, so do the same, even if it might be counter-intuitive.-
1470 // The shortcut for 'back' is set in class QVistaBackButton.-
1471 if (btns[QWizard::NextButton])-
1472 btns[QWizard::NextButton]->setShortcut(isVistaThemeEnabled() ? QKeySequence(Qt::ALT | Qt::Key_Right) : QKeySequence());-
1473}-
1474-
1475void QWizardPrivate::updateButtonLayout()-
1476{-
1477 if (buttonsHaveCustomLayout) {-
1478 QVarLengthArray<QWizard::WizardButton, QWizard::NButtons> array(buttonsCustomLayout.count());-
1479 for (int i = 0; i < buttonsCustomLayout.count(); ++i)-
1480 array[i] = buttonsCustomLayout.at(i);-
1481 setButtonLayout(array.constData(), array.count());-
1482 } else {-
1483 // Positions:-
1484 // Help Stretch Custom1 Custom2 Custom3 Cancel Back Next Commit Finish Cancel Help-
1485-
1486 const int ArraySize = 12;-
1487 QWizard::WizardButton array[ArraySize];-
1488 memset(array, -1, sizeof(array));-
1489 Q_ASSERT(array[0] == QWizard::NoButton);-
1490-
1491 if (opts & QWizard::HaveHelpButton) {-
1492 int i = (opts & QWizard::HelpButtonOnRight) ? 11 : 0;-
1493 array[i] = QWizard::HelpButton;-
1494 }-
1495 array[1] = QWizard::Stretch;-
1496 if (opts & QWizard::HaveCustomButton1)-
1497 array[2] = QWizard::CustomButton1;-
1498 if (opts & QWizard::HaveCustomButton2)-
1499 array[3] = QWizard::CustomButton2;-
1500 if (opts & QWizard::HaveCustomButton3)-
1501 array[4] = QWizard::CustomButton3;-
1502-
1503 if (!(opts & QWizard::NoCancelButton)) {-
1504 int i = (opts & QWizard::CancelButtonOnLeft) ? 5 : 10;-
1505 array[i] = QWizard::CancelButton;-
1506 }-
1507 array[6] = QWizard::BackButton;-
1508 array[7] = QWizard::NextButton;-
1509 array[8] = QWizard::CommitButton;-
1510 array[9] = QWizard::FinishButton;-
1511-
1512 setButtonLayout(array, ArraySize);-
1513 }-
1514}-
1515-
1516void QWizardPrivate::setButtonLayout(const QWizard::WizardButton *array, int size)-
1517{-
1518 QWidget *prev = pageFrame;-
1519-
1520 for (int i = buttonLayout->count() - 1; i >= 0; --i) {-
1521 QLayoutItem *item = buttonLayout->takeAt(i);-
1522 if (QWidget *widget = item->widget())-
1523 widget->hide();-
1524 delete item;-
1525 }-
1526-
1527 for (int i = 0; i < size; ++i) {-
1528 QWizard::WizardButton which = array[i];-
1529 if (which == QWizard::Stretch) {-
1530 buttonLayout->addStretch(1);-
1531 } else if (which != QWizard::NoButton) {-
1532 ensureButton(which);-
1533 buttonLayout->addWidget(btns[which]);-
1534-
1535 // Back, Next, Commit, and Finish are handled in _q_updateButtonStates()-
1536 if (which != QWizard::BackButton && which != QWizard::NextButton-
1537 && which != QWizard::CommitButton && which != QWizard::FinishButton)-
1538 btns[which]->show();-
1539-
1540 if (prev)-
1541 QWidget::setTabOrder(prev, btns[which]);-
1542 prev = btns[which];-
1543 }-
1544 }-
1545-
1546 _q_updateButtonStates();-
1547}-
1548-
1549bool QWizardPrivate::buttonLayoutContains(QWizard::WizardButton which)-
1550{-
1551 return !buttonsHaveCustomLayout || buttonsCustomLayout.contains(which);-
1552}-
1553-
1554void QWizardPrivate::updatePixmap(QWizard::WizardPixmap which)-
1555{-
1556 Q_Q(QWizard);-
1557 if (which == QWizard::BackgroundPixmap) {-
1558 if (wizStyle == QWizard::MacStyle) {-
1559 q->update();-
1560 q->updateGeometry();-
1561 }-
1562 } else {-
1563 updateLayout();-
1564 }-
1565}-
1566-
1567#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
1568bool QWizardPrivate::vistaDisabled() const-
1569{-
1570 Q_Q(const QWizard);-
1571 const QVariant v = q->property("_q_wizard_vista_off");-
1572 return v.isValid() && v.toBool();-
1573}-
1574-
1575bool QWizardPrivate::isVistaThemeEnabled(QVistaHelper::VistaState state) const-
1576{-
1577 return wizStyle == QWizard::AeroStyle-
1578 && QVistaHelper::vistaState() == state-
1579 && !vistaDisabled();-
1580}-
1581-
1582bool QWizardPrivate::handleAeroStyleChange()-
1583{-
1584 Q_Q(QWizard);-
1585-
1586 if (inHandleAeroStyleChange)-
1587 return false; // prevent recursion-
1588 // For top-level wizards, we need the platform window handle for the-
1589 // DWM changes. Delay aero initialization to the show event handling if-
1590 // it does not exist. If we are a child, skip DWM and just make room by-
1591 // moving the antiFlickerWidget.-
1592 const bool isWindow = q->isWindow();-
1593 if (isWindow && (!q->windowHandle() || !q->windowHandle()->handle()))-
1594 return false;-
1595 inHandleAeroStyleChange = true;-
1596-
1597 vistaHelper->disconnectBackButton();-
1598 q->removeEventFilter(vistaHelper);-
1599-
1600 bool vistaMargins = false;-
1601-
1602 if (isVistaThemeEnabled()) {-
1603 if (isVistaThemeEnabled(QVistaHelper::VistaAero)) {-
1604 if (isWindow) {-
1605 vistaHelper->setDWMTitleBar(QVistaHelper::ExtendedTitleBar);-
1606 q->installEventFilter(vistaHelper);-
1607 }-
1608 q->setMouseTracking(true);-
1609 antiFlickerWidget->move(0, vistaHelper->titleBarSize() + vistaHelper->topOffset());-
1610 vistaHelper->backButton()->move(-
1611 0, vistaHelper->topOffset() // ### should ideally work without the '+ 1'-
1612 - qMin(vistaHelper->topOffset(), vistaHelper->topPadding() + 1));-
1613 vistaMargins = true;-
1614 vistaHelper->backButton()->show();-
1615 } else {-
1616 if (isWindow)-
1617 vistaHelper->setDWMTitleBar(QVistaHelper::NormalTitleBar);-
1618 q->setMouseTracking(true);-
1619 antiFlickerWidget->move(0, vistaHelper->topOffset());-
1620 vistaHelper->backButton()->move(0, -1); // ### should ideally work with (0, 0)-
1621 }-
1622 if (isWindow)-
1623 vistaHelper->setTitleBarIconAndCaptionVisible(false);-
1624 QObject::connect(-
1625 vistaHelper->backButton(), SIGNAL(clicked()), q, buttonSlots(QWizard::BackButton));-
1626 vistaHelper->backButton()->show();-
1627 } else {-
1628 q->setMouseTracking(true); // ### original value possibly different-
1629#ifndef QT_NO_CURSOR-
1630 q->unsetCursor(); // ### ditto-
1631#endif-
1632 antiFlickerWidget->move(0, 0);-
1633 vistaHelper->hideBackButton();-
1634 if (isWindow)-
1635 vistaHelper->setTitleBarIconAndCaptionVisible(true);-
1636 }-
1637-
1638 _q_updateButtonStates();-
1639-
1640 vistaHelper->updateCustomMargins(vistaMargins);-
1641-
1642 inHandleAeroStyleChange = false;-
1643 return true;-
1644}-
1645#endif-
1646-
1647bool QWizardPrivate::isVistaThemeEnabled() const-
1648{-
1649#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
1650 return isVistaThemeEnabled(QVistaHelper::VistaAero)-
1651 || isVistaThemeEnabled(QVistaHelper::VistaBasic);-
1652#else-
1653 return false;-
1654#endif-
1655}-
1656-
1657void QWizardPrivate::disableUpdates()-
1658{-
1659 Q_Q(QWizard);-
1660 if (disableUpdatesCount++ == 0) {-
1661 q->setUpdatesEnabled(false);-
1662 antiFlickerWidget->hide();-
1663 }-
1664}-
1665-
1666void QWizardPrivate::enableUpdates()-
1667{-
1668 Q_Q(QWizard);-
1669 if (--disableUpdatesCount == 0) {-
1670 antiFlickerWidget->show();-
1671 q->setUpdatesEnabled(true);-
1672 }-
1673}-
1674-
1675void QWizardPrivate::_q_emitCustomButtonClicked()-
1676{-
1677 Q_Q(QWizard);-
1678 QObject *button = q->sender();-
1679 for (int i = QWizard::NStandardButtons; i < QWizard::NButtons; ++i) {-
1680 if (btns[i] == button) {-
1681 emit q->customButtonClicked(QWizard::WizardButton(i));-
1682 break;-
1683 }-
1684 }-
1685}-
1686-
1687void QWizardPrivate::_q_updateButtonStates()-
1688{-
1689 Q_Q(QWizard);-
1690-
1691 disableUpdates();-
1692-
1693 const QWizardPage *page = q->currentPage();-
1694 bool complete = page && page->isComplete();-
1695-
1696 btn.back->setEnabled(history.count() > 1-
1697 && !q->page(history.at(history.count() - 2))->isCommitPage()-
1698 && (!canFinish || !(opts & QWizard::DisabledBackButtonOnLastPage)));-
1699 btn.next->setEnabled(canContinue && complete);-
1700 btn.commit->setEnabled(canContinue && complete);-
1701 btn.finish->setEnabled(canFinish && complete);-
1702-
1703 const bool backButtonVisible = buttonLayoutContains(QWizard::BackButton)-
1704 && (history.count() > 1 || !(opts & QWizard::NoBackButtonOnStartPage))-
1705 && (canContinue || !(opts & QWizard::NoBackButtonOnLastPage));-
1706 bool commitPage = page && page->isCommitPage();-
1707 btn.back->setVisible(backButtonVisible);-
1708 btn.next->setVisible(buttonLayoutContains(QWizard::NextButton) && !commitPage-
1709 && (canContinue || (opts & QWizard::HaveNextButtonOnLastPage)));-
1710 btn.commit->setVisible(buttonLayoutContains(QWizard::CommitButton) && commitPage-
1711 && canContinue);-
1712 btn.finish->setVisible(buttonLayoutContains(QWizard::FinishButton)-
1713 && (canFinish || (opts & QWizard::HaveFinishButtonOnEarlyPages)));-
1714-
1715 if (!(opts & QWizard::NoCancelButton))-
1716 btn.cancel->setVisible(buttonLayoutContains(QWizard::CancelButton)-
1717 && (canContinue || !(opts & QWizard::NoCancelButtonOnLastPage)));-
1718-
1719 bool useDefault = !(opts & QWizard::NoDefaultButton);-
1720 if (QPushButton *nextPush = qobject_cast<QPushButton *>(btn.next))-
1721 nextPush->setDefault(canContinue && useDefault && !commitPage);-
1722 if (QPushButton *commitPush = qobject_cast<QPushButton *>(btn.commit))-
1723 commitPush->setDefault(canContinue && useDefault && commitPage);-
1724 if (QPushButton *finishPush = qobject_cast<QPushButton *>(btn.finish))-
1725 finishPush->setDefault(!canContinue && useDefault);-
1726-
1727#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
1728 if (isVistaThemeEnabled()) {-
1729 vistaHelper->backButton()->setEnabled(btn.back->isEnabled());-
1730 vistaHelper->backButton()->setVisible(backButtonVisible);-
1731 btn.back->setVisible(false);-
1732 }-
1733#endif-
1734-
1735 enableUpdates();-
1736}-
1737-
1738void QWizardPrivate::_q_handleFieldObjectDestroyed(QObject *object)-
1739{-
1740 int destroyed_index = -1;-
1741 QVector<QWizardField>::iterator it = fields.begin();-
1742 while (it != fields.end()) {-
1743 const QWizardField &field = *it;-
1744 if (field.object == object) {-
1745 destroyed_index = fieldIndexMap.value(field.name, -1);-
1746 fieldIndexMap.remove(field.name);-
1747 it = fields.erase(it);-
1748 } else {-
1749 ++it;-
1750 }-
1751 }-
1752 if (destroyed_index != -1) {-
1753 QMap<QString, int>::iterator it2 = fieldIndexMap.begin();-
1754 while (it2 != fieldIndexMap.end()) {-
1755 int index = it2.value();-
1756 if (index > destroyed_index) {-
1757 QString field_name = it2.key();-
1758 fieldIndexMap.insert(field_name, index-1);-
1759 }-
1760 ++it2;-
1761 }-
1762 }-
1763}-
1764-
1765void QWizardPrivate::setStyle(QStyle *style)-
1766{-
1767 for (int i = 0; i < QWizard::NButtons; i++)-
1768 if (btns[i])-
1769 btns[i]->setStyle(style);-
1770 const PageMap::const_iterator pcend = pageMap.constEnd();-
1771 for (PageMap::const_iterator it = pageMap.constBegin(); it != pcend; ++it)-
1772 it.value()->setStyle(style);-
1773}-
1774-
1775#ifdef Q_OS_MACX-
1776-
1777QPixmap QWizardPrivate::findDefaultBackgroundPixmap()-
1778{-
1779 QGuiApplication *app = qobject_cast<QGuiApplication *>(QCoreApplication::instance());-
1780 if (!app)-
1781 return QPixmap();-
1782 QPlatformNativeInterface *platformNativeInterface = app->platformNativeInterface();-
1783 int at = platformNativeInterface->metaObject()->indexOfMethod("defaultBackgroundPixmapForQWizard()");-
1784 if (at == -1)-
1785 return QPixmap();-
1786 QMetaMethod defaultBackgroundPixmapForQWizard = platformNativeInterface->metaObject()->method(at);-
1787 QPixmap result;-
1788 if (!defaultBackgroundPixmapForQWizard.invoke(platformNativeInterface, Q_RETURN_ARG(QPixmap, result)))-
1789 return QPixmap();-
1790 return result;-
1791}-
1792-
1793#endif-
1794-
1795#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
1796void QWizardAntiFlickerWidget::paintEvent(QPaintEvent *)-
1797{-
1798 if (wizardPrivate->isVistaThemeEnabled()) {-
1799 int leftMargin, topMargin, rightMargin, bottomMargin;-
1800 wizardPrivate->buttonLayout->getContentsMargins(-
1801 &leftMargin, &topMargin, &rightMargin, &bottomMargin);-
1802 const int buttonLayoutTop = wizardPrivate->buttonLayout->contentsRect().top() - topMargin;-
1803 QPainter painter(this);-
1804 const QBrush brush(QColor(240, 240, 240)); // ### hardcoded for now-
1805 painter.fillRect(0, buttonLayoutTop, width(), height() - buttonLayoutTop, brush);-
1806 painter.setPen(QPen(QBrush(QColor(223, 223, 223)), 0)); // ### hardcoded for now-
1807 painter.drawLine(0, buttonLayoutTop, width(), buttonLayoutTop);-
1808 if (wizardPrivate->isVistaThemeEnabled(QVistaHelper::VistaBasic)) {-
1809 if (window()->isActiveWindow())-
1810 painter.setPen(QPen(QBrush(QColor(169, 191, 214)), 0)); // ### hardcoded for now-
1811 else-
1812 painter.setPen(QPen(QBrush(QColor(182, 193, 204)), 0)); // ### hardcoded for now-
1813 painter.drawLine(0, 0, width(), 0);-
1814 }-
1815 }-
1816}-
1817#endif-
1818-
1819/*!-
1820 \class QWizard-
1821 \since 4.3-
1822 \brief The QWizard class provides a framework for wizards.-
1823-
1824 \inmodule QtWidgets-
1825-
1826 A wizard (also called an assistant on \macos) is a special type-
1827 of input dialog that consists of a sequence of pages. A wizard's-
1828 purpose is to guide the user through a process step by step.-
1829 Wizards are useful for complex or infrequent tasks that users may-
1830 find difficult to learn.-
1831-
1832 QWizard inherits QDialog and represents a wizard. Each page is a-
1833 QWizardPage (a QWidget subclass). To create your own wizards, you-
1834 can use these classes directly, or you can subclass them for more-
1835 control.-
1836-
1837 Topics:-
1838-
1839 \tableofcontents-
1840-
1841 \section1 A Trivial Example-
1842-
1843 The following example illustrates how to create wizard pages and-
1844 add them to a wizard. For more advanced examples, see-
1845 \l{dialogs/classwizard}{Class Wizard} and \l{dialogs/licensewizard}{License-
1846 Wizard}.-
1847-
1848 \snippet dialogs/trivialwizard/trivialwizard.cpp 1-
1849 \snippet dialogs/trivialwizard/trivialwizard.cpp 3-
1850 \dots-
1851 \snippet dialogs/trivialwizard/trivialwizard.cpp 4-
1852 \codeline-
1853 \snippet dialogs/trivialwizard/trivialwizard.cpp 5-
1854 \snippet dialogs/trivialwizard/trivialwizard.cpp 7-
1855 \dots-
1856 \snippet dialogs/trivialwizard/trivialwizard.cpp 8-
1857 \codeline-
1858 \snippet dialogs/trivialwizard/trivialwizard.cpp 10-
1859-
1860 \section1 Wizard Look and Feel-
1861-
1862 QWizard supports four wizard looks:-
1863-
1864 \list-
1865 \li ClassicStyle-
1866 \li ModernStyle-
1867 \li MacStyle-
1868 \li AeroStyle-
1869 \endlist-
1870-
1871 You can explicitly set the look to use using setWizardStyle()-
1872 (e.g., if you want the same look on all platforms).-
1873-
1874 \table-
1875 \header \li ClassicStyle-
1876 \li ModernStyle-
1877 \li MacStyle-
1878 \li AeroStyle-
1879 \row \li \inlineimage qtwizard-classic1.png-
1880 \li \inlineimage qtwizard-modern1.png-
1881 \li \inlineimage qtwizard-mac1.png-
1882 \li \inlineimage qtwizard-aero1.png-
1883 \row \li \inlineimage qtwizard-classic2.png-
1884 \li \inlineimage qtwizard-modern2.png-
1885 \li \inlineimage qtwizard-mac2.png-
1886 \li \inlineimage qtwizard-aero2.png-
1887 \endtable-
1888-
1889 Note: AeroStyle has effect only on a Windows Vista system with alpha compositing enabled.-
1890 ModernStyle is used as a fallback when this condition is not met.-
1891-
1892 In addition to the wizard style, there are several options that-
1893 control the look and feel of the wizard. These can be set using-
1894 setOption() or setOptions(). For example, HaveHelpButton makes-
1895 QWizard show a \uicontrol Help button along with the other wizard-
1896 buttons.-
1897-
1898 You can even change the order of the wizard buttons to any-
1899 arbitrary order using setButtonLayout(), and you can add up to-
1900 three custom buttons (e.g., a \uicontrol Print button) to the button-
1901 row. This is achieved by calling setButton() or setButtonText()-
1902 with CustomButton1, CustomButton2, or CustomButton3 to set up the-
1903 button, and by enabling the HaveCustomButton1, HaveCustomButton2,-
1904 or HaveCustomButton3 options. Whenever the user clicks a custom-
1905 button, customButtonClicked() is emitted. For example:-
1906-
1907 \snippet dialogs/licensewizard/licensewizard.cpp 29-
1908-
1909 \section1 Elements of a Wizard Page-
1910-
1911 Wizards consist of a sequence of \l{QWizardPage}s. At any time,-
1912 only one page is shown. A page has the following attributes:-
1913-
1914 \list-
1915 \li A \l{QWizardPage::}{title}.-
1916 \li A \l{QWizardPage::}{subTitle}.-
1917 \li A set of pixmaps, which may or may not be honored, depending-
1918 on the wizard's style:-
1919 \list-
1920 \li WatermarkPixmap (used by ClassicStyle and ModernStyle)-
1921 \li BannerPixmap (used by ModernStyle)-
1922 \li LogoPixmap (used by ClassicStyle and ModernStyle)-
1923 \li BackgroundPixmap (used by MacStyle)-
1924 \endlist-
1925 \endlist-
1926-
1927 The diagram belows shows how QWizard renders these attributes,-
1928 assuming they are all present and ModernStyle is used:-
1929-
1930 \image qtwizard-nonmacpage.png-
1931-
1932 When a \l{QWizardPage::}{subTitle} is set, QWizard displays it-
1933 in a header, in which case it also uses the BannerPixmap and the-
1934 LogoPixmap to decorate the header. The WatermarkPixmap is-
1935 displayed on the left side, below the header. At the bottom,-
1936 there is a row of buttons allowing the user to navigate through-
1937 the pages.-
1938-
1939 The page itself (the \l{QWizardPage} widget) occupies the area-
1940 between the header, the watermark, and the button row. Typically,-
1941 the page is a QWizardPage on which a QGridLayout is installed,-
1942 with standard child widgets (\l{QLabel}s, \l{QLineEdit}s, etc.).-
1943-
1944 If the wizard's style is MacStyle, the page looks radically-
1945 different:-
1946-
1947 \image qtwizard-macpage.png-
1948-
1949 The watermark, banner, and logo pixmaps are ignored by the-
1950 MacStyle. If the BackgroundPixmap is set, it is used as the-
1951 background for the wizard; otherwise, a default "assistant" image-
1952 is used.-
1953-
1954 The title and subtitle are set by calling-
1955 QWizardPage::setTitle() and QWizardPage::setSubTitle() on the-
1956 individual pages. They may be plain text or HTML (see titleFormat-
1957 and subTitleFormat). The pixmaps can be set globally for the-
1958 entire wizard using setPixmap(), or on a per-page basis using-
1959 QWizardPage::setPixmap().-
1960-
1961 \target field mechanism-
1962 \section1 Registering and Using Fields-
1963-
1964 In many wizards, the contents of a page may affect the default-
1965 values of the fields of a later page. To make it easy to-
1966 communicate between pages, QWizard supports a "field" mechanism-
1967 that allows you to register a field (e.g., a QLineEdit) on a page-
1968 and to access its value from any page. It is also possible to-
1969 specify mandatory fields (i.e., fields that must be filled before-
1970 the user can advance to the next page).-
1971-
1972 To register a field, call QWizardPage::registerField() field.-
1973 For example:-
1974-
1975 \snippet dialogs/classwizard/classwizard.cpp 8-
1976 \dots-
1977 \snippet dialogs/classwizard/classwizard.cpp 10-
1978 \snippet dialogs/classwizard/classwizard.cpp 11-
1979 \dots-
1980 \snippet dialogs/classwizard/classwizard.cpp 13-
1981-
1982 The above code registers three fields, \c className, \c-
1983 baseClass, and \c qobjectMacro, which are associated with three-
1984 child widgets. The asterisk (\c *) next to \c className denotes a-
1985 mandatory field.-
1986-
1987 \target initialize page-
1988 The fields of any page are accessible from any other page. For-
1989 example:-
1990-
1991 \snippet dialogs/classwizard/classwizard.cpp 17-
1992-
1993 Here, we call QWizardPage::field() to access the contents of the-
1994 \c className field (which was defined in the \c ClassInfoPage)-
1995 and use it to initialize the \c OutputFilePage. The field's-
1996 contents is returned as a QVariant.-
1997-
1998 When we create a field using QWizardPage::registerField(), we-
1999 pass a unique field name and a widget. We can also provide a Qt-
2000 property name and a "changed" signal (a signal that is emitted-
2001 when the property changes) as third and fourth arguments;-
2002 however, this is not necessary for the most common Qt widgets,-
2003 such as QLineEdit, QCheckBox, and QComboBox, because QWizard-
2004 knows which properties to look for.-
2005-
2006 \target mandatory fields-
2007-
2008 If an asterisk (\c *) is appended to the name when the property-
2009 is registered, the field is a \e{mandatory field}. When a page has-
2010 mandatory fields, the \uicontrol Next and/or \uicontrol Finish buttons are-
2011 enabled only when all mandatory fields are filled.-
2012-
2013 To consider a field "filled", QWizard simply checks that the-
2014 field's current value doesn't equal the original value (the value-
2015 it had when initializePage() was called). For QLineEdit and-
2016 QAbstractSpinBox subclasses, QWizard also checks that-
2017 \l{QLineEdit::hasAcceptableInput()}{hasAcceptableInput()} returns-
2018 true, to honor any validator or mask.-
2019-
2020 QWizard's mandatory field mechanism is provided for convenience.-
2021 A more powerful (but also more cumbersome) alternative is to-
2022 reimplement QWizardPage::isComplete() and to emit the-
2023 QWizardPage::completeChanged() signal whenever the page becomes-
2024 complete or incomplete.-
2025-
2026 The enabled/disabled state of the \uicontrol Next and/or \uicontrol Finish-
2027 buttons is one way to perform validation on the user input.-
2028 Another way is to reimplement validateCurrentPage() (or-
2029 QWizardPage::validatePage()) to perform some last-minute-
2030 validation (and show an error message if the user has entered-
2031 incomplete or invalid information). If the function returns \c true,-
2032 the next page is shown (or the wizard finishes); otherwise, the-
2033 current page stays up.-
2034-
2035 \section1 Creating Linear Wizards-
2036-
2037 Most wizards have a linear structure, with page 1 followed by-
2038 page 2 and so on until the last page. The \l{dialogs/classwizard}{Class-
2039 Wizard} example is such a wizard. With QWizard, linear wizards-
2040 are created by instantiating the \l{QWizardPage}s and inserting-
2041 them using addPage(). By default, the pages are shown in the-
2042 order in which they were added. For example:-
2043-
2044 \snippet dialogs/classwizard/classwizard.cpp 0-
2045 \dots-
2046 \snippet dialogs/classwizard/classwizard.cpp 2-
2047-
2048 When a page is about to be shown, QWizard calls initializePage()-
2049 (which in turn calls QWizardPage::initializePage()) to fill the-
2050 page with default values. By default, this function does nothing,-
2051 but it can be reimplemented to initialize the page's contents-
2052 based on other pages' fields (see the \l{initialize page}{example-
2053 above}).-
2054-
2055 If the user presses \uicontrol Back, cleanupPage() is called (which in-
2056 turn calls QWizardPage::cleanupPage()). The default-
2057 implementation resets the page's fields to their original values-
2058 (the values they had before initializePage() was called). If you-
2059 want the \uicontrol Back button to be non-destructive and keep the-
2060 values entered by the user, simply enable the IndependentPages-
2061 option.-
2062-
2063 \section1 Creating Non-Linear Wizards-
2064-
2065 Some wizards are more complex in that they allow different-
2066 traversal paths based on the information provided by the user.-
2067 The \l{dialogs/licensewizard}{License Wizard} example illustrates this.-
2068 It provides five wizard pages; depending on which options are-
2069 selected, the user can reach different pages.-
2070-
2071 \image licensewizard-flow.png-
2072-
2073 In complex wizards, pages are identified by IDs. These IDs are-
2074 typically defined using an enum. For example:-
2075-
2076 \snippet dialogs/licensewizard/licensewizard.h 0-
2077 \dots-
2078 \snippet dialogs/licensewizard/licensewizard.h 2-
2079 \dots-
2080 \snippet dialogs/licensewizard/licensewizard.h 3-
2081-
2082 The pages are inserted using setPage(), which takes an ID and an-
2083 instance of QWizardPage (or of a subclass):-
2084-
2085 \snippet dialogs/licensewizard/licensewizard.cpp 1-
2086 \dots-
2087 \snippet dialogs/licensewizard/licensewizard.cpp 8-
2088-
2089 By default, the pages are shown in increasing ID order. To-
2090 provide a dynamic order that depends on the options chosen by the-
2091 user, we must reimplement QWizardPage::nextId(). For example:-
2092-
2093 \snippet dialogs/licensewizard/licensewizard.cpp 18-
2094 \codeline-
2095 \snippet dialogs/licensewizard/licensewizard.cpp 23-
2096 \codeline-
2097 \snippet dialogs/licensewizard/licensewizard.cpp 24-
2098 \codeline-
2099 \snippet dialogs/licensewizard/licensewizard.cpp 25-
2100 \codeline-
2101 \snippet dialogs/licensewizard/licensewizard.cpp 26-
2102-
2103 It would also be possible to put all the logic in one place, in a-
2104 QWizard::nextId() reimplementation. For example:-
2105-
2106 \snippet code/src_gui_dialogs_qwizard.cpp 0-
2107-
2108 To start at another page than the page with the lowest ID, call-
2109 setStartId().-
2110-
2111 To test whether a page has been visited or not, call-
2112 hasVisitedPage(). For example:-
2113-
2114 \snippet dialogs/licensewizard/licensewizard.cpp 27-
2115-
2116 \sa QWizardPage, {Class Wizard Example}, {License Wizard Example}-
2117*/-
2118-
2119/*!-
2120 \enum QWizard::WizardButton-
2121-
2122 This enum specifies the buttons in a wizard.-
2123-
2124 \value BackButton The \uicontrol Back button (\uicontrol {Go Back} on \macos)-
2125 \value NextButton The \uicontrol Next button (\uicontrol Continue on \macos)-
2126 \value CommitButton The \uicontrol Commit button-
2127 \value FinishButton The \uicontrol Finish button (\uicontrol Done on \macos)-
2128 \value CancelButton The \uicontrol Cancel button (see also NoCancelButton)-
2129 \value HelpButton The \uicontrol Help button (see also HaveHelpButton)-
2130 \value CustomButton1 The first user-defined button (see also HaveCustomButton1)-
2131 \value CustomButton2 The second user-defined button (see also HaveCustomButton2)-
2132 \value CustomButton3 The third user-defined button (see also HaveCustomButton3)-
2133-
2134 The following value is only useful when calling setButtonLayout():-
2135-
2136 \value Stretch A horizontal stretch in the button layout-
2137-
2138 \omitvalue NoButton-
2139 \omitvalue NStandardButtons-
2140 \omitvalue NButtons-
2141-
2142 \sa setButton(), setButtonText(), setButtonLayout(), customButtonClicked()-
2143*/-
2144-
2145/*!-
2146 \enum QWizard::WizardPixmap-
2147-
2148 This enum specifies the pixmaps that can be associated with a page.-
2149-
2150 \value WatermarkPixmap The tall pixmap on the left side of a ClassicStyle or ModernStyle page-
2151 \value LogoPixmap The small pixmap on the right side of a ClassicStyle or ModernStyle page header-
2152 \value BannerPixmap The pixmap that occupies the background of a ModernStyle page header-
2153 \value BackgroundPixmap The pixmap that occupies the background of a MacStyle wizard-
2154-
2155 \omitvalue NPixmaps-
2156-
2157 \sa setPixmap(), QWizardPage::setPixmap(), {Elements of a Wizard Page}-
2158*/-
2159-
2160/*!-
2161 \enum QWizard::WizardStyle-
2162-
2163 This enum specifies the different looks supported by QWizard.-
2164-
2165 \value ClassicStyle Classic Windows look-
2166 \value ModernStyle Modern Windows look-
2167 \value MacStyle \macos look-
2168 \value AeroStyle Windows Aero look-
2169-
2170 \omitvalue NStyles-
2171-
2172 \sa setWizardStyle(), WizardOption, {Wizard Look and Feel}-
2173*/-
2174-
2175/*!-
2176 \enum QWizard::WizardOption-
2177-
2178 This enum specifies various options that affect the look and feel-
2179 of a wizard.-
2180-
2181 \value IndependentPages The pages are independent of each other-
2182 (i.e., they don't derive values from each-
2183 other).-
2184 \value IgnoreSubTitles Don't show any subtitles, even if they are set.-
2185 \value ExtendedWatermarkPixmap Extend any WatermarkPixmap all the-
2186 way down to the window's edge.-
2187 \value NoDefaultButton Don't make the \uicontrol Next or \uicontrol Finish button the-
2188 dialog's \l{QPushButton::setDefault()}{default button}.-
2189 \value NoBackButtonOnStartPage Don't show the \uicontrol Back button on the start page.-
2190 \value NoBackButtonOnLastPage Don't show the \uicontrol Back button on the last page.-
2191 \value DisabledBackButtonOnLastPage Disable the \uicontrol Back button on the last page.-
2192 \value HaveNextButtonOnLastPage Show the (disabled) \uicontrol Next button on the last page.-
2193 \value HaveFinishButtonOnEarlyPages Show the (disabled) \uicontrol Finish button on non-final pages.-
2194 \value NoCancelButton Don't show the \uicontrol Cancel button.-
2195 \value CancelButtonOnLeft Put the \uicontrol Cancel button on the left of \uicontrol Back (rather than on-
2196 the right of \uicontrol Finish or \uicontrol Next).-
2197 \value HaveHelpButton Show the \uicontrol Help button.-
2198 \value HelpButtonOnRight Put the \uicontrol Help button on the far right of the button layout-
2199 (rather than on the far left).-
2200 \value HaveCustomButton1 Show the first user-defined button (CustomButton1).-
2201 \value HaveCustomButton2 Show the second user-defined button (CustomButton2).-
2202 \value HaveCustomButton3 Show the third user-defined button (CustomButton3).-
2203 \value NoCancelButtonOnLastPage Don't show the \uicontrol Cancel button on the last page.-
2204-
2205 \sa setOptions(), setOption(), testOption()-
2206*/-
2207-
2208/*!-
2209 Constructs a wizard with the given \a parent and window \a flags.-
2210-
2211 \sa parent(), windowFlags()-
2212*/-
2213QWizard::QWizard(QWidget *parent, Qt::WindowFlags flags)-
2214 : QDialog(*new QWizardPrivate, parent, flags)-
2215{-
2216 Q_D(QWizard);-
2217 d->init();-
2218#ifdef Q_OS_WINCE-
2219 if (!qt_wince_is_mobile())-
2220 setWindowFlags(windowFlags() & ~Qt::WindowOkButtonHint);-
2221#endif-
2222}-
2223-
2224/*!-
2225 Destroys the wizard and its pages, releasing any allocated resources.-
2226*/-
2227QWizard::~QWizard()-
2228{-
2229 Q_D(QWizard);-
2230 delete d->buttonLayout;-
2231}-
2232-
2233/*!-
2234 Adds the given \a page to the wizard, and returns the page's ID.-
2235-
2236 The ID is guaranteed to be larger than any other ID in the-
2237 QWizard so far.-
2238-
2239 \sa setPage(), page(), pageAdded()-
2240*/-
2241int QWizard::addPage(QWizardPage *page)-
2242{-
2243 Q_D(QWizard);-
2244 int theid = 0;-
2245 if (!d->pageMap.isEmpty())-
2246 theid = (d->pageMap.constEnd() - 1).key() + 1;-
2247 setPage(theid, page);-
2248 return theid;-
2249}-
2250-
2251/*!-
2252 \fn void QWizard::setPage(int id, QWizardPage *page)-
2253-
2254 Adds the given \a page to the wizard with the given \a id.-
2255-
2256 \note Adding a page may influence the value of the startId property-
2257 in case it was not set explicitly.-
2258-
2259 \sa addPage(), page(), pageAdded()-
2260*/-
2261void QWizard::setPage(int theid, QWizardPage *page)-
2262{-
2263 Q_D(QWizard);-
2264-
2265 if (Q_UNLIKELY(!page))) {
__builtin_expe...!page), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
2266 qWarning("QWizard::setPage: Cannot insert null page");-
2267 return;
never executed: return;
0
2268 }-
2269-
2270 if (Q_UNLIKELY(theid == -1))) {
__builtin_expe...== -1), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
2271 qWarning("QWizard::setPage: Cannot insert page with ID -1");-
2272 return;
never executed: return;
0
2273 }-
2274-
2275 if (Q_UNLIKELY(d->pageMap.contains(theid))))) {
__builtin_expe...heid)), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
2276 qWarning("QWizard::setPage: Page with duplicate ID %d ignored", theid);-
2277 return;
never executed: return;
0
2278 }-
2279-
2280 page->setParent(d->pageFrame);-
2281-
2282 QVector<QWizardField> &pendingFields = page->d_func()->pendingFields;-
2283 for (int i = 0; i < pendingFields.count(); ++i)
i < pendingFields.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
2284 d->addField(pendingFields.at(i));
never executed: d->addField(pendingFields.at(i));
0
2285 pendingFields.clear();-
2286-
2287 connect(page, SIGNAL(completeChanged()), this, SLOT(_q_updateButtonStates()));-
2288-
2289 d->pageMap.insert(theid, page);-
2290 page->d_func()->wizard = this;-
2291-
2292 int n = d->pageVBoxLayout->count();-
2293-
2294 // disable layout to prevent layout updates while adding-
2295 bool pageVBoxLayoutEnabled = d->pageVBoxLayout->isEnabled();-
2296 d->pageVBoxLayout->setEnabled(false);-
2297-
2298 d->pageVBoxLayout->insertWidget(n - 1, page);-
2299-
2300 // hide new page and reset layout to old status-
2301 page->hide();-
2302 d->pageVBoxLayout->setEnabled(pageVBoxLayoutEnabled);-
2303-
2304 if (!d->startSetByUser && d->pageMap.constBegin().key() == theid)
!d->startSetByUserDescription
TRUEnever evaluated
FALSEnever evaluated
d->pageMap.con...key() == theidDescription
TRUEnever evaluated
FALSEnever evaluated
0
2305 d->start = theid;
never executed: d->start = theid;
0
2306 emit pageAdded(theid);-
2307}
never executed: end of block
0
2308-
2309/*!-
2310 Removes the page with the given \a id. cleanupPage() will be called if necessary.-
2311-
2312 \note Removing a page may influence the value of the startId property.-
2313-
2314 \since 4.5-
2315 \sa addPage(), setPage(), pageRemoved(), startId()-
2316*/-
2317void QWizard::removePage(int id)-
2318{-
2319 Q_D(QWizard);-
2320-
2321 QWizardPage *removedPage = 0;-
2322-
2323 // update startItem accordingly-
2324 if (d->pageMap.count() > 0) { // only if we have any pages-
2325 if (d->start == id) {-
2326 const int firstId = d->pageMap.constBegin().key();-
2327 if (firstId == id) {-
2328 if (d->pageMap.count() > 1)-
2329 d->start = (++d->pageMap.constBegin()).key(); // secondId-
2330 else-
2331 d->start = -1; // removing the last page-
2332 } else { // startSetByUser has to be "true" here-
2333 d->start = firstId;-
2334 }-
2335 d->startSetByUser = false;-
2336 }-
2337 }-
2338-
2339 if (d->pageMap.contains(id))-
2340 emit pageRemoved(id);-
2341-
2342 if (!d->history.contains(id)) {-
2343 // Case 1: removing a page not in the history-
2344 removedPage = d->pageMap.take(id);-
2345 d->updateCurrentPage();-
2346 } else if (id != d->current) {-
2347 // Case 2: removing a page in the history before the current page-
2348 removedPage = d->pageMap.take(id);-
2349 d->history.removeOne(id);-
2350 d->_q_updateButtonStates();-
2351 } else if (d->history.count() == 1) {-
2352 // Case 3: removing the current page which is the first (and only) one in the history-
2353 d->reset();-
2354 removedPage = d->pageMap.take(id);-
2355 if (d->pageMap.isEmpty())-
2356 d->updateCurrentPage();-
2357 else-
2358 restart();-
2359 } else {-
2360 // Case 4: removing the current page which is not the first one in the history-
2361 back();-
2362 removedPage = d->pageMap.take(id);-
2363 d->updateCurrentPage();-
2364 }-
2365-
2366 if (removedPage) {-
2367 if (d->initialized.contains(id)) {-
2368 cleanupPage(id);-
2369 d->initialized.remove(id);-
2370 }-
2371-
2372 d->pageVBoxLayout->removeWidget(removedPage);-
2373-
2374 for (int i = d->fields.count() - 1; i >= 0; --i) {-
2375 if (d->fields.at(i).page == removedPage) {-
2376 removedPage->d_func()->pendingFields += d->fields.at(i);-
2377 d->removeFieldAt(i);-
2378 }-
2379 }-
2380 }-
2381}-
2382-
2383/*!-
2384 \fn QWizardPage *QWizard::page(int id) const-
2385-
2386 Returns the page with the given \a id, or 0 if there is no such-
2387 page.-
2388-
2389 \sa addPage(), setPage()-
2390*/-
2391QWizardPage *QWizard::page(int theid) const-
2392{-
2393 Q_D(const QWizard);-
2394 return d->pageMap.value(theid);-
2395}-
2396-
2397/*!-
2398 \fn bool QWizard::hasVisitedPage(int id) const-
2399-
2400 Returns \c true if the page history contains page \a id; otherwise,-
2401 returns \c false.-
2402-
2403 Pressing \uicontrol Back marks the current page as "unvisited" again.-
2404-
2405 \sa visitedPages()-
2406*/-
2407bool QWizard::hasVisitedPage(int theid) const-
2408{-
2409 Q_D(const QWizard);-
2410 return d->history.contains(theid);-
2411}-
2412-
2413/*!-
2414 Returns the list of IDs of visited pages, in the order in which the pages-
2415 were visited.-
2416-
2417 Pressing \uicontrol Back marks the current page as "unvisited" again.-
2418-
2419 \sa hasVisitedPage()-
2420*/-
2421QList<int> QWizard::visitedPages() const-
2422{-
2423 Q_D(const QWizard);-
2424 return d->history;-
2425}-
2426-
2427/*!-
2428 Returns the list of page IDs.-
2429 \since 4.5-
2430*/-
2431QList<int> QWizard::pageIds() const-
2432{-
2433 Q_D(const QWizard);-
2434 return d->pageMap.keys();-
2435}-
2436-
2437/*!-
2438 \property QWizard::startId-
2439 \brief the ID of the first page-
2440-
2441 If this property isn't explicitly set, this property defaults to-
2442 the lowest page ID in this wizard, or -1 if no page has been-
2443 inserted yet.-
2444-
2445 \sa restart(), nextId()-
2446*/-
2447void QWizard::setStartId(int theid)-
2448{-
2449 Q_D(QWizard);-
2450 int newStart = theid;-
2451 if (theid == -1)
theid == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2452 newStart = d->pageMap.count() ? d->pageMap.constBegin().key() : -1;
never executed: newStart = d->pageMap.count() ? d->pageMap.constBegin().key() : -1;
d->pageMap.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
2453-
2454 if (d->start == newStart) {
d->start == newStartDescription
TRUEnever evaluated
FALSEnever evaluated
0
2455 d->startSetByUser = theid != -1;-
2456 return;
never executed: return;
0
2457 }-
2458-
2459 if (Q_UNLIKELY(!d->pageMap.contains(newStart))))) {
__builtin_expe...tart)), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
2460 qWarning("QWizard::setStartId: Invalid page ID %d", newStart);-
2461 return;
never executed: return;
0
2462 }-
2463 d->start = newStart;-
2464 d->startSetByUser = theid != -1;-
2465}
never executed: end of block
0
2466-
2467int QWizard::startId() const-
2468{-
2469 Q_D(const QWizard);-
2470 return d->start;-
2471}-
2472-
2473/*!-
2474 Returns a pointer to the current page, or 0 if there is no current-
2475 page (e.g., before the wizard is shown).-
2476-
2477 This is equivalent to calling page(currentId()).-
2478-
2479 \sa page(), currentId(), restart()-
2480*/-
2481QWizardPage *QWizard::currentPage() const-
2482{-
2483 Q_D(const QWizard);-
2484 return page(d->current);-
2485}-
2486-
2487/*!-
2488 \property QWizard::currentId-
2489 \brief the ID of the current page-
2490-
2491 This property cannot be set directly. To change the current page,-
2492 call next(), back(), or restart().-
2493-
2494 By default, this property has a value of -1, indicating that no page is-
2495 currently shown.-
2496-
2497 \sa currentPage()-
2498*/-
2499int QWizard::currentId() const-
2500{-
2501 Q_D(const QWizard);-
2502 return d->current;-
2503}-
2504-
2505/*!-
2506 Sets the value of the field called \a name to \a value.-
2507-
2508 This function can be used to set fields on any page of the wizard.-
2509-
2510 \sa QWizardPage::registerField(), QWizardPage::setField(), field()-
2511*/-
2512void QWizard::setField(const QString &name, const QVariant &value)-
2513{-
2514 Q_D(QWizard);-
2515-
2516 int index = d->fieldIndexMap.value(name, -1);-
2517 if (Q_UNLIKELY(index !=== -1))) {
__builtin_expe...== -1), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
2518 qWarning("QWizard::setField: No such field '%ls'", qUtf16Printable(name));-
2519 return;
never executed: return;
0
2520 }-
2521-
2522 const QWizardField &field = d->fields.at(index);-
2523 if (Q_UNLIKELY(!field.object->setProperty(field.property, value)))))
__builtin_expe...alue)), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
2524 qWarning("QWizard::setField: Couldn't write to property '%s'",
never executed: QMessageLogger(__FILE__, 2524, __PRETTY_FUNCTION__).warning("QWizard::setField: Couldn't write to property '%s'", field.property.constData());
0
2525 field.property.constData());
never executed: QMessageLogger(__FILE__, 2524, __PRETTY_FUNCTION__).warning("QWizard::setField: Couldn't write to property '%s'", field.property.constData());
0
return;
never executed: end of block
}
never executed: end of block
qWarning("QWizard::setField: No such field '%s'", qPrintable(name));
never executed: end of block
}
never executed: end of block
2527-
2528/*!-
2529 Returns the value of the field called \a name.-
2530-
2531 This function can be used to access fields on any page of the wizard.-
2532-
2533 \sa QWizardPage::registerField(), QWizardPage::field(), setField()-
2534*/-
2535QVariant QWizard::field(const QString &name) const-
2536{-
2537 Q_D(const QWizard);-
2538-
2539 int index = d->fieldIndexMap.value(name, -1);-
2540 if (Q_UNLIKELY(index !=== -1))) {
__builtin_expe...== -1), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
2541 qWarning("QWizard::field: No such field '%ls'", qUtf16Printable(name));-
2542 return QVariant();
never executed: return QVariant();
0
2543 }-
2544-
2545 const QWizardField &field = d->fields.at(index);-
2546 return field.object->property(field.property);
never executed: return field.object->property(field.property);
0
}
qWarning("QWizard::field: No such field '%s'", qPrintable(name));
return QVariant();}
2548-
2549/*!-
2550 \property QWizard::wizardStyle-
2551 \brief the look and feel of the wizard-
2552-
2553 By default, QWizard uses the AeroStyle on a Windows Vista system with alpha compositing-
2554 enabled, regardless of the current widget style. If this is not the case, the default-
2555 wizard style depends on the current widget style as follows: MacStyle is the default if-
2556 the current widget style is QMacStyle, ModernStyle is the default if the current widget-
2557 style is QWindowsStyle, and ClassicStyle is the default in all other cases.-
2558-
2559 \sa {Wizard Look and Feel}, options-
2560*/-
2561void QWizard::setWizardStyle(WizardStyle style)-
2562{-
2563 Q_D(QWizard);-
2564-
2565 const bool styleChange = style != d->wizStyle;-
2566-
2567#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
2568 const bool aeroStyleChange =-
2569 d->vistaInitPending || d->vistaStateChanged || (styleChange && (style == AeroStyle || d->wizStyle == AeroStyle));-
2570 d->vistaStateChanged = false;-
2571 d->vistaInitPending = false;-
2572#endif-
2573-
2574 if (styleChange-
2575#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
2576 || aeroStyleChange-
2577#endif-
2578 ) {-
2579 d->disableUpdates();-
2580 d->wizStyle = style;-
2581 d->updateButtonTexts();-
2582#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
2583 if (aeroStyleChange) {-
2584 //Send a resizeevent since the antiflicker widget probably needs a new size-
2585 //because of the backbutton in the window title-
2586 QResizeEvent ev(geometry().size(), geometry().size());-
2587 QApplication::sendEvent(this, &ev);-
2588 }-
2589#endif-
2590 d->updateLayout();-
2591 updateGeometry();-
2592 d->enableUpdates();-
2593#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
2594 // Delay initialization when activating Aero style fails due to missing native window.-
2595 if (aeroStyleChange && !d->handleAeroStyleChange() && d->wizStyle == AeroStyle)-
2596 d->vistaInitPending = true;-
2597#endif-
2598 }-
2599}-
2600-
2601QWizard::WizardStyle QWizard::wizardStyle() const-
2602{-
2603 Q_D(const QWizard);-
2604 return d->wizStyle;-
2605}-
2606-
2607/*!-
2608 Sets the given \a option to be enabled if \a on is true;-
2609 otherwise, clears the given \a option.-
2610-
2611 \sa options, testOption(), setWizardStyle()-
2612*/-
2613void QWizard::setOption(WizardOption option, bool on)-
2614{-
2615 Q_D(QWizard);-
2616 if (!(d->opts & option) != !on)-
2617 setOptions(d->opts ^ option);-
2618}-
2619-
2620/*!-
2621 Returns \c true if the given \a option is enabled; otherwise, returns-
2622 false.-
2623-
2624 \sa options, setOption(), setWizardStyle()-
2625*/-
2626bool QWizard::testOption(WizardOption option) const-
2627{-
2628 Q_D(const QWizard);-
2629 return (d->opts & option) != 0;-
2630}-
2631-
2632/*!-
2633 \property QWizard::options-
2634 \brief the various options that affect the look and feel of the wizard-
2635-
2636 By default, the following options are set (depending on the platform):-
2637-
2638 \list-
2639 \li Windows: HelpButtonOnRight.-
2640 \li \macos: NoDefaultButton and NoCancelButton.-
2641 \li X11 and QWS (Qt for Embedded Linux): none.-
2642 \endlist-
2643-
2644 \sa wizardStyle-
2645*/-
2646void QWizard::setOptions(WizardOptions options)-
2647{-
2648 Q_D(QWizard);-
2649-
2650 WizardOptions changed = (options ^ d->opts);-
2651 if (!changed)-
2652 return;-
2653-
2654 d->disableUpdates();-
2655-
2656 d->opts = options;-
2657 if ((changed & IndependentPages) && !(d->opts & IndependentPages))-
2658 d->cleanupPagesNotInHistory();-
2659-
2660 if (changed & (NoDefaultButton | HaveHelpButton | HelpButtonOnRight | NoCancelButton-
2661 | CancelButtonOnLeft | HaveCustomButton1 | HaveCustomButton2-
2662 | HaveCustomButton3)) {-
2663 d->updateButtonLayout();-
2664 } else if (changed & (NoBackButtonOnStartPage | NoBackButtonOnLastPage-
2665 | HaveNextButtonOnLastPage | HaveFinishButtonOnEarlyPages-
2666 | DisabledBackButtonOnLastPage | NoCancelButtonOnLastPage)) {-
2667 d->_q_updateButtonStates();-
2668 }-
2669-
2670 d->enableUpdates();-
2671 d->updateLayout();-
2672}-
2673-
2674QWizard::WizardOptions QWizard::options() const-
2675{-
2676 Q_D(const QWizard);-
2677 return d->opts;-
2678}-
2679-
2680/*!-
2681 Sets the text on button \a which to be \a text.-
2682-
2683 By default, the text on buttons depends on the wizardStyle. For-
2684 example, on \macos, the \uicontrol Next button is called \uicontrol-
2685 Continue.-
2686-
2687 To add extra buttons to the wizard (e.g., a \uicontrol Print button),-
2688 one way is to call setButtonText() with CustomButton1,-
2689 CustomButton2, or CustomButton3 to set their text, and make the-
2690 buttons visible using the HaveCustomButton1, HaveCustomButton2,-
2691 and/or HaveCustomButton3 options.-
2692-
2693 Button texts may also be set on a per-page basis using QWizardPage::setButtonText().-
2694-
2695 \sa setButton(), button(), setButtonLayout(), setOptions(), QWizardPage::setButtonText()-
2696*/-
2697void QWizard::setButtonText(WizardButton which, const QString &text)-
2698{-
2699 Q_D(QWizard);-
2700-
2701 if (!d->ensureButton(which))-
2702 return;-
2703-
2704 d->buttonCustomTexts.insert(which, text);-
2705-
2706 if (!currentPage() || !currentPage()->d_func()->buttonCustomTexts.contains(which))-
2707 d->btns[which]->setText(text);-
2708}-
2709-
2710/*!-
2711 Returns the text on button \a which.-
2712-
2713 If a text has ben set using setButtonText(), this text is returned.-
2714-
2715 By default, the text on buttons depends on the wizardStyle. For-
2716 example, on \macos, the \uicontrol Next button is called \uicontrol-
2717 Continue.-
2718-
2719 \sa button(), setButton(), setButtonText(), QWizardPage::buttonText(),-
2720 QWizardPage::setButtonText()-
2721*/-
2722QString QWizard::buttonText(WizardButton which) const-
2723{-
2724 Q_D(const QWizard);-
2725-
2726 if (!d->ensureButton(which))-
2727 return QString();-
2728-
2729 if (d->buttonCustomTexts.contains(which))-
2730 return d->buttonCustomTexts.value(which);-
2731-
2732 const QString defText = buttonDefaultText(d->wizStyle, which, d);-
2733 if(!defText.isNull())-
2734 return defText;-
2735-
2736 return d->btns[which]->text();-
2737}-
2738-
2739/*!-
2740 Sets the order in which buttons are displayed to \a layout, where-
2741 \a layout is a list of \l{WizardButton}s.-
2742-
2743 The default layout depends on the options (e.g., whether-
2744 HelpButtonOnRight) that are set. You can call this function if-
2745 you need more control over the buttons' layout than what \l-
2746 options already provides.-
2747-
2748 You can specify horizontal stretches in the layout using \l-
2749 Stretch.-
2750-
2751 Example:-
2752-
2753 \snippet code/src_gui_dialogs_qwizard.cpp 1-
2754-
2755 \sa setButton(), setButtonText(), setOptions()-
2756*/-
2757void QWizard::setButtonLayout(const QList<WizardButton> &layout)-
2758{-
2759 Q_D(QWizard);-
2760-
2761 for (int i = 0; i < layout.count(); ++i) {
i < layout.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
2762 WizardButton button1 = layout.at(i);-
2763-
2764 if (button1 == NoButton || button1 == Stretch)
button1 == NoButtonDescription
TRUEnever evaluated
FALSEnever evaluated
button1 == StretchDescription
TRUEnever evaluated
FALSEnever evaluated
0
2765 continue;
never executed: continue;
0
2766 if (!d->ensureButton(button1))
!d->ensureButton(button1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2767 return;
never executed: return;
0
2768-
2769 // O(n^2), but n is very small-
2770 for (int j = 0; j < i; ++j) {
j < iDescription
TRUEnever evaluated
FALSEnever evaluated
0
2771 WizardButton button2 = layout.at(j);-
2772 if (Q_UNLIKELY(button2 == button1))) {
__builtin_expe...tton1), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
2773 qWarning("QWizard::setButtonLayout: Duplicate button in layout");-
2774 return;
never executed: return;
0
2775 }-
2776 }
never executed: end of block
0
2777 }
never executed: end of block
0
2778-
2779 d->buttonsHaveCustomLayout = true;-
2780 d->buttonsCustomLayout = layout;-
2781 d->updateButtonLayout();-
2782}
never executed: end of block
0
2783-
2784/*!-
2785 Sets the button corresponding to role \a which to \a button.-
2786-
2787 To add extra buttons to the wizard (e.g., a \uicontrol Print button),-
2788 one way is to call setButton() with CustomButton1 to-
2789 CustomButton3, and make the buttons visible using the-
2790 HaveCustomButton1 to HaveCustomButton3 options.-
2791-
2792 \sa setButtonText(), setButtonLayout(), options-
2793*/-
2794void QWizard::setButton(WizardButton which, QAbstractButton *button)-
2795{-
2796 Q_D(QWizard);-
2797-
2798 if (uint(which) >= NButtons || d->btns[which] == button)-
2799 return;-
2800-
2801 if (QAbstractButton *oldButton = d->btns[which]) {-
2802 d->buttonLayout->removeWidget(oldButton);-
2803 delete oldButton;-
2804 }-
2805-
2806 d->btns[which] = button;-
2807 if (button) {-
2808 button->setParent(d->antiFlickerWidget);-
2809 d->buttonCustomTexts.insert(which, button->text());-
2810 d->connectButton(which);-
2811 } else {-
2812 d->buttonCustomTexts.remove(which); // ### what about page-specific texts set for 'which'-
2813 d->ensureButton(which); // (QWizardPage::setButtonText())? Clear them as well?-
2814 }-
2815-
2816 d->updateButtonLayout();-
2817}-
2818-
2819/*!-
2820 Returns the button corresponding to role \a which.-
2821-
2822 \sa setButton(), setButtonText()-
2823*/-
2824QAbstractButton *QWizard::button(WizardButton which) const-
2825{-
2826 Q_D(const QWizard);-
2827#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
2828 if (d->wizStyle == AeroStyle && which == BackButton)-
2829 return d->vistaHelper->backButton();-
2830#endif-
2831 if (!d->ensureButton(which))-
2832 return 0;-
2833 return d->btns[which];-
2834}-
2835-
2836/*!-
2837 \property QWizard::titleFormat-
2838 \brief the text format used by page titles-
2839-
2840 The default format is Qt::AutoText.-
2841-
2842 \sa QWizardPage::title, subTitleFormat-
2843*/-
2844void QWizard::setTitleFormat(Qt::TextFormat format)-
2845{-
2846 Q_D(QWizard);-
2847 d->titleFmt = format;-
2848 d->updateLayout();-
2849}-
2850-
2851Qt::TextFormat QWizard::titleFormat() const-
2852{-
2853 Q_D(const QWizard);-
2854 return d->titleFmt;-
2855}-
2856-
2857/*!-
2858 \property QWizard::subTitleFormat-
2859 \brief the text format used by page subtitles-
2860-
2861 The default format is Qt::AutoText.-
2862-
2863 \sa QWizardPage::title, titleFormat-
2864*/-
2865void QWizard::setSubTitleFormat(Qt::TextFormat format)-
2866{-
2867 Q_D(QWizard);-
2868 d->subTitleFmt = format;-
2869 d->updateLayout();-
2870}-
2871-
2872Qt::TextFormat QWizard::subTitleFormat() const-
2873{-
2874 Q_D(const QWizard);-
2875 return d->subTitleFmt;-
2876}-
2877-
2878/*!-
2879 Sets the pixmap for role \a which to \a pixmap.-
2880-
2881 The pixmaps are used by QWizard when displaying a page. Which-
2882 pixmaps are actually used depend on the \l{Wizard Look and-
2883 Feel}{wizard style}.-
2884-
2885 Pixmaps can also be set for a specific page using-
2886 QWizardPage::setPixmap().-
2887-
2888 \sa QWizardPage::setPixmap(), {Elements of a Wizard Page}-
2889*/-
2890void QWizard::setPixmap(WizardPixmap which, const QPixmap &pixmap)-
2891{-
2892 Q_D(QWizard);-
2893 Q_ASSERT(uint(which) < NPixmaps);-
2894 d->defaultPixmaps[which] = pixmap;-
2895 d->updatePixmap(which);-
2896}-
2897-
2898/*!-
2899 Returns the pixmap set for role \a which.-
2900-
2901 By default, the only pixmap that is set is the BackgroundPixmap on-
2902 \macos.-
2903-
2904 \sa QWizardPage::pixmap(), {Elements of a Wizard Page}-
2905*/-
2906QPixmap QWizard::pixmap(WizardPixmap which) const-
2907{-
2908 Q_D(const QWizard);-
2909 Q_ASSERT(uint(which) < NPixmaps);-
2910#ifdef Q_OS_MACX-
2911 if (which == BackgroundPixmap && d->defaultPixmaps[BackgroundPixmap].isNull())-
2912 d->defaultPixmaps[BackgroundPixmap] = d->findDefaultBackgroundPixmap();-
2913#endif-
2914 return d->defaultPixmaps[which];-
2915}-
2916-
2917/*!-
2918 Sets the default property for \a className to be \a property,-
2919 and the associated change signal to be \a changedSignal.-
2920-
2921 The default property is used when an instance of \a className (or-
2922 of one of its subclasses) is passed to-
2923 QWizardPage::registerField() and no property is specified.-
2924-
2925 QWizard knows the most common Qt widgets. For these (or their-
2926 subclasses), you don't need to specify a \a property or a \a-
2927 changedSignal. The table below lists these widgets:-
2928-
2929 \table-
2930 \header \li Widget \li Property \li Change Notification Signal-
2931 \row \li QAbstractButton \li bool \l{QAbstractButton::}{checked} \li \l{QAbstractButton::}{toggled()}-
2932 \row \li QAbstractSlider \li int \l{QAbstractSlider::}{value} \li \l{QAbstractSlider::}{valueChanged()}-
2933 \row \li QComboBox \li int \l{QComboBox::}{currentIndex} \li \l{QComboBox::}{currentIndexChanged()}-
2934 \row \li QDateTimeEdit \li QDateTime \l{QDateTimeEdit::}{dateTime} \li \l{QDateTimeEdit::}{dateTimeChanged()}-
2935 \row \li QLineEdit \li QString \l{QLineEdit::}{text} \li \l{QLineEdit::}{textChanged()}-
2936 \row \li QListWidget \li int \l{QListWidget::}{currentRow} \li \l{QListWidget::}{currentRowChanged()}-
2937 \row \li QSpinBox \li int \l{QSpinBox::}{value} \li \l{QSpinBox::}{valueChanged()}-
2938 \endtable-
2939-
2940 \sa QWizardPage::registerField()-
2941*/-
2942void QWizard::setDefaultProperty(const char *className, const char *property,-
2943 const char *changedSignal)-
2944{-
2945 Q_D(QWizard);-
2946 for (int i = d->defaultPropertyTable.count() - 1; i >= 0; --i) {-
2947 if (qstrcmp(d->defaultPropertyTable.at(i).className, className) == 0) {-
2948 d->defaultPropertyTable.remove(i);-
2949 break;-
2950 }-
2951 }-
2952 d->defaultPropertyTable.append(QWizardDefaultProperty(className, property, changedSignal));-
2953}-
2954-
2955/*!-
2956 \since 4.7-
2957-
2958 Sets the given \a widget to be shown on the left side of the wizard.-
2959 For styles which use the WatermarkPixmap (ClassicStyle and ModernStyle)-
2960 the side widget is displayed on top of the watermark, for other styles-
2961 or when the watermark is not provided the side widget is displayed-
2962 on the left side of the wizard.-
2963-
2964 Passing 0 shows no side widget.-
2965-
2966 When the \a widget is not 0 the wizard reparents it.-
2967-
2968 Any previous side widget is hidden.-
2969-
2970 You may call setSideWidget() with the same widget at different-
2971 times.-
2972-
2973 All widgets set here will be deleted by the wizard when it is-
2974 destroyed unless you separately reparent the widget after setting-
2975 some other side widget (or 0).-
2976-
2977 By default, no side widget is present.-
2978*/-
2979void QWizard::setSideWidget(QWidget *widget)-
2980{-
2981 Q_D(QWizard);-
2982-
2983 d->sideWidget = widget;-
2984 if (d->watermarkLabel) {-
2985 d->watermarkLabel->setSideWidget(widget);-
2986 d->updateLayout();-
2987 }-
2988}-
2989-
2990/*!-
2991 \since 4.7-
2992-
2993 Returns the widget on the left side of the wizard or 0.-
2994-
2995 By default, no side widget is present.-
2996*/-
2997QWidget *QWizard::sideWidget() const-
2998{-
2999 Q_D(const QWizard);-
3000-
3001 return d->sideWidget;-
3002}-
3003-
3004/*!-
3005 \reimp-
3006*/-
3007void QWizard::setVisible(bool visible)-
3008{-
3009 Q_D(QWizard);-
3010 if (visible) {-
3011 if (d->current == -1)-
3012 restart();-
3013 }-
3014 QDialog::setVisible(visible);-
3015}-
3016-
3017/*!-
3018 \reimp-
3019*/-
3020QSize QWizard::sizeHint() const-
3021{-
3022 Q_D(const QWizard);-
3023 QSize result = d->mainLayout->totalSizeHint();-
3024 QSize extra(500, 360);-
3025 if (d->wizStyle == MacStyle && d->current != -1) {-
3026 QSize pixmap(currentPage()->pixmap(BackgroundPixmap).size());-
3027 extra.setWidth(616);-
3028 if (!pixmap.isNull()) {-
3029 extra.setHeight(pixmap.height());-
3030-
3031 /*-
3032 The width isn't always reliable as a size hint, as-
3033 some wizard backgrounds just cover the leftmost area.-
3034 Use a rule of thumb to determine if the width is-
3035 reliable or not.-
3036 */-
3037 if (pixmap.width() >= pixmap.height())-
3038 extra.setWidth(pixmap.width());-
3039 }-
3040 }-
3041 return result.expandedTo(extra);-
3042}-
3043-
3044/*!-
3045 \fn void QWizard::currentIdChanged(int id)-
3046-
3047 This signal is emitted when the current page changes, with the new-
3048 current \a id.-
3049-
3050 \sa currentId(), currentPage()-
3051*/-
3052-
3053/*!-
3054 \fn void QWizard::pageAdded(int id)-
3055-
3056 \since 4.7-
3057-
3058 This signal is emitted whenever a page is added to the-
3059 wizard. The page's \a id is passed as parameter.-
3060-
3061 \sa addPage(), setPage(), startId()-
3062*/-
3063-
3064/*!-
3065 \fn void QWizard::pageRemoved(int id)-
3066-
3067 \since 4.7-
3068-
3069 This signal is emitted whenever a page is removed from the-
3070 wizard. The page's \a id is passed as parameter.-
3071-
3072 \sa removePage(), startId()-
3073*/-
3074-
3075/*!-
3076 \fn void QWizard::helpRequested()-
3077-
3078 This signal is emitted when the user clicks the \uicontrol Help button.-
3079-
3080 By default, no \uicontrol Help button is shown. Call-
3081 setOption(HaveHelpButton, true) to have one.-
3082-
3083 Example:-
3084-
3085 \snippet dialogs/licensewizard/licensewizard.cpp 0-
3086 \dots-
3087 \snippet dialogs/licensewizard/licensewizard.cpp 5-
3088 \snippet dialogs/licensewizard/licensewizard.cpp 7-
3089 \dots-
3090 \snippet dialogs/licensewizard/licensewizard.cpp 8-
3091 \codeline-
3092 \snippet dialogs/licensewizard/licensewizard.cpp 10-
3093 \dots-
3094 \snippet dialogs/licensewizard/licensewizard.cpp 12-
3095 \codeline-
3096 \snippet dialogs/licensewizard/licensewizard.cpp 14-
3097 \codeline-
3098 \snippet dialogs/licensewizard/licensewizard.cpp 15-
3099-
3100 \sa customButtonClicked()-
3101*/-
3102-
3103/*!-
3104 \fn void QWizard::customButtonClicked(int which)-
3105-
3106 This signal is emitted when the user clicks a custom button. \a-
3107 which can be CustomButton1, CustomButton2, or CustomButton3.-
3108-
3109 By default, no custom button is shown. Call setOption() with-
3110 HaveCustomButton1, HaveCustomButton2, or HaveCustomButton3 to have-
3111 one, and use setButtonText() or setButton() to configure it.-
3112-
3113 \sa helpRequested()-
3114*/-
3115-
3116/*!-
3117 Goes back to the previous page.-
3118-
3119 This is equivalent to pressing the \uicontrol Back button.-
3120-
3121 \sa next(), accept(), reject(), restart()-
3122*/-
3123void QWizard::back()-
3124{-
3125 Q_D(QWizard);-
3126 int n = d->history.count() - 2;-
3127 if (n < 0)-
3128 return;-
3129 d->switchToPage(d->history.at(n), QWizardPrivate::Backward);-
3130}-
3131-
3132/*!-
3133 Advances to the next page.-
3134-
3135 This is equivalent to pressing the \uicontrol Next or \uicontrol Commit button.-
3136-
3137 \sa nextId(), back(), accept(), reject(), restart()-
3138*/-
3139void QWizard::next()-
3140{-
3141 Q_D(QWizard);-
3142-
3143 if (d->current == -1)
d->current == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
3144 return;
never executed: return;
0
3145-
3146 if (validateCurrentPage()) {
validateCurrentPage()Description
TRUEnever evaluated
FALSEnever evaluated
0
3147 int next = nextId();-
3148 if (next != -1) {
next != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
3149 if (Q_UNLIKELY(d->history.contains(next))))) {
__builtin_expe...next)), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
3150 qWarning("QWizard::next: Page %d already met", next);-
3151 return;
never executed: return;
0
3152 }-
3153 if (Q_UNLIKELY(!d->pageMap.contains(next))))) {
__builtin_expe...next)), false)Description
TRUEnever evaluated
FALSEnever evaluated
0
3154 qWarning("QWizard::next: No such page %d", next);-
3155 return;
never executed: return;
0
3156 }-
3157 d->switchToPage(next, QWizardPrivate::Forward);-
3158 }
never executed: end of block
0
3159 }
never executed: end of block
0
3160}
never executed: end of block
0
3161-
3162/*!-
3163 Restarts the wizard at the start page. This function is called automatically when the-
3164 wizard is shown.-
3165-
3166 \sa startId()-
3167*/-
3168void QWizard::restart()-
3169{-
3170 Q_D(QWizard);-
3171 d->disableUpdates();-
3172 d->reset();-
3173 d->switchToPage(startId(), QWizardPrivate::Forward);-
3174 d->enableUpdates();-
3175}-
3176-
3177/*!-
3178 \reimp-
3179*/-
3180bool QWizard::event(QEvent *event)-
3181{-
3182 Q_D(QWizard);-
3183 if (event->type() == QEvent::StyleChange) { // Propagate style-
3184 d->setStyle(style());-
3185 d->updateLayout();-
3186 }-
3187#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
3188 else if (event->type() == QEvent::Show && d->vistaInitPending) {-
3189 d->vistaInitPending = false;-
3190 // Do not force AeroStyle when in Classic theme.-
3191 // Note that d->handleAeroStyleChange() needs to be called in any case as it does some-
3192 // necessary initialization, like ensures that the Aero specific back button is hidden if-
3193 // Aero theme isn't active.-
3194 if (QVistaHelper::vistaState() != QVistaHelper::Classic)-
3195 d->wizStyle = AeroStyle;-
3196 d->handleAeroStyleChange();-
3197 }-
3198 else if (d->isVistaThemeEnabled()) {-
3199 if (event->type() == QEvent::Resize-
3200 || event->type() == QEvent::LayoutDirectionChange) {-
3201 const int buttonLeft = (layoutDirection() == Qt::RightToLeft-
3202 ? width() - d->vistaHelper->backButton()->sizeHint().width()-
3203 : 0);-
3204-
3205 d->vistaHelper->backButton()->move(buttonLeft,-
3206 d->vistaHelper->backButton()->y());-
3207 }-
3208-
3209 d->vistaHelper->mouseEvent(event);-
3210 }-
3211#endif-
3212 return QDialog::event(event);-
3213}-
3214-
3215/*!-
3216 \reimp-
3217*/-
3218void QWizard::resizeEvent(QResizeEvent *event)-
3219{-
3220 Q_D(QWizard);-
3221 int heightOffset = 0;-
3222#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
3223 if (d->isVistaThemeEnabled()) {-
3224 heightOffset = d->vistaHelper->topOffset();-
3225 if (d->isVistaThemeEnabled(QVistaHelper::VistaAero))-
3226 heightOffset += d->vistaHelper->titleBarSize();-
3227 }-
3228#endif-
3229 d->antiFlickerWidget->resize(event->size().width(), event->size().height() - heightOffset);-
3230#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
3231 if (d->isVistaThemeEnabled())-
3232 d->vistaHelper->resizeEvent(event);-
3233#endif-
3234 QDialog::resizeEvent(event);-
3235}-
3236-
3237/*!-
3238 \reimp-
3239*/-
3240void QWizard::paintEvent(QPaintEvent * event)-
3241{-
3242 Q_D(QWizard);-
3243 if (d->wizStyle == MacStyle && currentPage()) {-
3244 QPixmap backgroundPixmap = currentPage()->pixmap(BackgroundPixmap);-
3245 if (backgroundPixmap.isNull())-
3246 return;-
3247-
3248 QPainter painter(this);-
3249 painter.drawPixmap(0, (height() - backgroundPixmap.height()) / 2, backgroundPixmap);-
3250 }-
3251#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
3252 else if (d->isVistaThemeEnabled()) {-
3253 if (d->isVistaThemeEnabled(QVistaHelper::VistaBasic)) {-
3254 QPainter painter(this);-
3255 QColor color = d->vistaHelper->basicWindowFrameColor();-
3256 painter.fillRect(0, 0, width(), QVistaHelper::topOffset(), color);-
3257 }-
3258 d->vistaHelper->paintEvent(event);-
3259 }-
3260#else-
3261 Q_UNUSED(event);-
3262#endif-
3263}-
3264-
3265#if defined(Q_OS_WIN)-
3266/*!-
3267 \reimp-
3268*/-
3269bool QWizard::nativeEvent(const QByteArray &eventType, void *message, long *result)-
3270{-
3271#if !defined(QT_NO_STYLE_WINDOWSVISTA)-
3272 Q_D(QWizard);-
3273 if (d->isVistaThemeEnabled() && eventType == "windows_generic_MSG") {-
3274 MSG *windowsMessage = static_cast<MSG *>(message);-
3275 const bool winEventResult = d->vistaHelper->handleWinEvent(windowsMessage, result);-
3276 if (QVistaHelper::vistaState() != d->vistaState) {-
3277 d->vistaState = QVistaHelper::vistaState();-
3278 d->vistaStateChanged = true;-
3279 setWizardStyle(AeroStyle);-
3280 }-
3281 return winEventResult;-
3282 } else {-
3283 return QDialog::nativeEvent(eventType, message, result);-
3284 }-
3285#else-
3286 return QDialog::nativeEvent(eventType, message, result);-
3287#endif-
3288}-
3289#endif-
3290-
3291/*!-
3292 \reimp-
3293*/-
3294void QWizard::done(int result)-
3295{-
3296 Q_D(QWizard);-
3297 // canceling leaves the wizard in a known state-
3298 if (result == Rejected) {-
3299 d->reset();-
3300 } else {-
3301 if (!validateCurrentPage())-
3302 return;-
3303 }-
3304 QDialog::done(result);-
3305}-
3306-
3307/*!-
3308 \fn void QWizard::initializePage(int id)-
3309-
3310 This virtual function is called by QWizard to prepare page \a id-
3311 just before it is shown either as a result of QWizard::restart()-
3312 being called, or as a result of the user clicking \uicontrol Next. (However, if the \l-
3313 QWizard::IndependentPages option is set, this function is only-
3314 called the first time the page is shown.)-
3315-
3316 By reimplementing this function, you can ensure that the page's-
3317 fields are properly initialized based on fields from previous-
3318 pages.-
3319-
3320 The default implementation calls QWizardPage::initializePage() on-
3321 page(\a id).-
3322-
3323 \sa QWizardPage::initializePage(), cleanupPage()-
3324*/-
3325void QWizard::initializePage(int theid)-
3326{-
3327 QWizardPage *page = this->page(theid);-
3328 if (page)-
3329 page->initializePage();-
3330}-
3331-
3332/*!-
3333 \fn void QWizard::cleanupPage(int id)-
3334-
3335 This virtual function is called by QWizard to clean up page \a id just before the-
3336 user leaves it by clicking \uicontrol Back (unless the \l QWizard::IndependentPages option is set).-
3337-
3338 The default implementation calls QWizardPage::cleanupPage() on-
3339 page(\a id).-
3340-
3341 \sa QWizardPage::cleanupPage(), initializePage()-
3342*/-
3343void QWizard::cleanupPage(int theid)-
3344{-
3345 QWizardPage *page = this->page(theid);-
3346 if (page)-
3347 page->cleanupPage();-
3348}-
3349-
3350/*!-
3351 This virtual function is called by QWizard when the user clicks-
3352 \uicontrol Next or \uicontrol Finish to perform some last-minute validation.-
3353 If it returns \c true, the next page is shown (or the wizard-
3354 finishes); otherwise, the current page stays up.-
3355-
3356 The default implementation calls QWizardPage::validatePage() on-
3357 the currentPage().-
3358-
3359 When possible, it is usually better style to disable the \uicontrol-
3360 Next or \uicontrol Finish button (by specifying \l{mandatory fields} or-
3361 by reimplementing QWizardPage::isComplete()) than to reimplement-
3362 validateCurrentPage().-
3363-
3364 \sa QWizardPage::validatePage(), currentPage()-
3365*/-
3366bool QWizard::validateCurrentPage()-
3367{-
3368 QWizardPage *page = currentPage();-
3369 if (!page)-
3370 return true;-
3371-
3372 return page->validatePage();-
3373}-
3374-
3375/*!-
3376 This virtual function is called by QWizard to find out which page-
3377 to show when the user clicks the \uicontrol Next button.-
3378-
3379 The return value is the ID of the next page, or -1 if no page follows.-
3380-
3381 The default implementation calls QWizardPage::nextId() on the-
3382 currentPage().-
3383-
3384 By reimplementing this function, you can specify a dynamic page-
3385 order.-
3386-
3387 \sa QWizardPage::nextId(), currentPage()-
3388*/-
3389int QWizard::nextId() const-
3390{-
3391 const QWizardPage *page = currentPage();-
3392 if (!page)-
3393 return -1;-
3394-
3395 return page->nextId();-
3396}-
3397-
3398/*!-
3399 \class QWizardPage-
3400 \since 4.3-
3401 \brief The QWizardPage class is the base class for wizard pages.-
3402-
3403 \inmodule QtWidgets-
3404-
3405 QWizard represents a wizard. Each page is a QWizardPage. When-
3406 you create your own wizards, you can use QWizardPage directly,-
3407 or you can subclass it for more control.-
3408-
3409 A page has the following attributes, which are rendered by-
3410 QWizard: a \l title, a \l subTitle, and a \l{setPixmap()}{set of-
3411 pixmaps}. See \l{Elements of a Wizard Page} for details. Once a-
3412 page is added to the wizard (using QWizard::addPage() or-
3413 QWizard::setPage()), wizard() returns a pointer to the-
3414 associated QWizard object.-
3415-
3416 Page provides five virtual functions that can be reimplemented to-
3417 provide custom behavior:-
3418-
3419 \list-
3420 \li initializePage() is called to initialize the page's contents-
3421 when the user clicks the wizard's \uicontrol Next button. If you-
3422 want to derive the page's default from what the user entered-
3423 on previous pages, this is the function to reimplement.-
3424 \li cleanupPage() is called to reset the page's contents when the-
3425 user clicks the wizard's \uicontrol Back button.-
3426 \li validatePage() validates the page when the user clicks \uicontrol-
3427 Next or \uicontrol Finish. It is often used to show an error message-
3428 if the user has entered incomplete or invalid information.-
3429 \li nextId() returns the ID of the next page. It is useful when-
3430 \l{creating non-linear wizards}, which allow different-
3431 traversal paths based on the information provided by the user.-
3432 \li isComplete() is called to determine whether the \uicontrol Next-
3433 and/or \uicontrol Finish button should be enabled or disabled. If-
3434 you reimplement isComplete(), also make sure that-
3435 completeChanged() is emitted whenever the complete state-
3436 changes.-
3437 \endlist-
3438-
3439 Normally, the \uicontrol Next button and the \uicontrol Finish button of a-
3440 wizard are mutually exclusive. If isFinalPage() returns \c true, \uicontrol-
3441 Finish is available; otherwise, \uicontrol Next is available. By-
3442 default, isFinalPage() is true only when nextId() returns -1. If-
3443 you want to show \uicontrol Next and \uicontrol Final simultaneously for a-
3444 page (letting the user perform an "early finish"), call-
3445 setFinalPage(true) on that page. For wizards that support early-
3446 finishes, you might also want to set the-
3447 \l{QWizard::}{HaveNextButtonOnLastPage} and-
3448 \l{QWizard::}{HaveFinishButtonOnEarlyPages} options on the-
3449 wizard.-
3450-
3451 In many wizards, the contents of a page may affect the default-
3452 values of the fields of a later page. To make it easy to-
3453 communicate between pages, QWizard supports a \l{Registering and-
3454 Using Fields}{"field" mechanism} that allows you to register a-
3455 field (e.g., a QLineEdit) on a page and to access its value from-
3456 any page. Fields are global to the entire wizard and make it easy-
3457 for any single page to access information stored by another page,-
3458 without having to put all the logic in QWizard or having the-
3459 pages know explicitly about each other. Fields are registered-
3460 using registerField() and can be accessed at any time using-
3461 field() and setField().-
3462-
3463 \sa QWizard, {Class Wizard Example}, {License Wizard Example}-
3464*/-
3465-
3466/*!-
3467 Constructs a wizard page with the given \a parent.-
3468-
3469 When the page is inserted into a wizard using QWizard::addPage()-
3470 or QWizard::setPage(), the parent is automatically set to be the-
3471 wizard.-
3472-
3473 \sa wizard()-
3474*/-
3475QWizardPage::QWizardPage(QWidget *parent)-
3476 : QWidget(*new QWizardPagePrivate, parent, 0)-
3477{-
3478 connect(this, SIGNAL(completeChanged()), this, SLOT(_q_updateCachedCompleteState()));-
3479}-
3480-
3481/*!-
3482 Destructor.-
3483*/-
3484QWizardPage::~QWizardPage()-
3485{-
3486}-
3487-
3488/*!-
3489 \property QWizardPage::title-
3490 \brief the title of the page-
3491-
3492 The title is shown by the QWizard, above the actual page. All-
3493 pages should have a title.-
3494-
3495 The title may be plain text or HTML, depending on the value of the-
3496 \l{QWizard::titleFormat} property.-
3497-
3498 By default, this property contains an empty string.-
3499-
3500 \sa subTitle, {Elements of a Wizard Page}-
3501*/-
3502void QWizardPage::setTitle(const QString &title)-
3503{-
3504 Q_D(QWizardPage);-
3505 d->title = title;-
3506 if (d->wizard && d->wizard->currentPage() == this)-
3507 d->wizard->d_func()->updateLayout();-
3508}-
3509-
3510QString QWizardPage::title() const-
3511{-
3512 Q_D(const QWizardPage);-
3513 return d->title;-
3514}-
3515-
3516/*!-
3517 \property QWizardPage::subTitle-
3518 \brief the subtitle of the page-
3519-
3520 The subtitle is shown by the QWizard, between the title and the-
3521 actual page. Subtitles are optional. In-
3522 \l{QWizard::ClassicStyle}{ClassicStyle} and-
3523 \l{QWizard::ModernStyle}{ModernStyle}, using subtitles is-
3524 necessary to make the header appear. In-
3525 \l{QWizard::MacStyle}{MacStyle}, the subtitle is shown as a text-
3526 label just above the actual page.-
3527-
3528 The subtitle may be plain text or HTML, depending on the value of-
3529 the \l{QWizard::subTitleFormat} property.-
3530-
3531 By default, this property contains an empty string.-
3532-
3533 \sa title, QWizard::IgnoreSubTitles, {Elements of a Wizard Page}-
3534*/-
3535void QWizardPage::setSubTitle(const QString &subTitle)-
3536{-
3537 Q_D(QWizardPage);-
3538 d->subTitle = subTitle;-
3539 if (d->wizard && d->wizard->currentPage() == this)-
3540 d->wizard->d_func()->updateLayout();-
3541}-
3542-
3543QString QWizardPage::subTitle() const-
3544{-
3545 Q_D(const QWizardPage);-
3546 return d->subTitle;-
3547}-
3548-
3549/*!-
3550 Sets the pixmap for role \a which to \a pixmap.-
3551-
3552 The pixmaps are used by QWizard when displaying a page. Which-
3553 pixmaps are actually used depend on the \l{Wizard Look and-
3554 Feel}{wizard style}.-
3555-
3556 Pixmaps can also be set for the entire wizard using-
3557 QWizard::setPixmap(), in which case they apply for all pages that-
3558 don't specify a pixmap.-
3559-
3560 \sa QWizard::setPixmap(), {Elements of a Wizard Page}-
3561*/-
3562void QWizardPage::setPixmap(QWizard::WizardPixmap which, const QPixmap &pixmap)-
3563{-
3564 Q_D(QWizardPage);-
3565 Q_ASSERT(uint(which) < QWizard::NPixmaps);-
3566 d->pixmaps[which] = pixmap;-
3567 if (d->wizard && d->wizard->currentPage() == this)-
3568 d->wizard->d_func()->updatePixmap(which);-
3569}-
3570-
3571/*!-
3572 Returns the pixmap set for role \a which.-
3573-
3574 Pixmaps can also be set for the entire wizard using-
3575 QWizard::setPixmap(), in which case they apply for all pages that-
3576 don't specify a pixmap.-
3577-
3578 \sa QWizard::pixmap(), {Elements of a Wizard Page}-
3579*/-
3580QPixmap QWizardPage::pixmap(QWizard::WizardPixmap which) const-
3581{-
3582 Q_D(const QWizardPage);-
3583 Q_ASSERT(uint(which) < QWizard::NPixmaps);-
3584-
3585 const QPixmap &pixmap = d->pixmaps[which];-
3586 if (!pixmap.isNull())-
3587 return pixmap;-
3588-
3589 if (wizard())-
3590 return wizard()->pixmap(which);-
3591-
3592 return pixmap;-
3593}-
3594-
3595/*!-
3596 This virtual function is called by QWizard::initializePage() to-
3597 prepare the page just before it is shown either as a result of QWizard::restart()-
3598 being called, or as a result of the user clicking \uicontrol Next.-
3599 (However, if the \l QWizard::IndependentPages option is set, this function is only-
3600 called the first time the page is shown.)-
3601-
3602 By reimplementing this function, you can ensure that the page's-
3603 fields are properly initialized based on fields from previous-
3604 pages. For example:-
3605-
3606 \snippet dialogs/classwizard/classwizard.cpp 17-
3607-
3608 The default implementation does nothing.-
3609-
3610 \sa QWizard::initializePage(), cleanupPage(), QWizard::IndependentPages-
3611*/-
3612void QWizardPage::initializePage()-
3613{-
3614}-
3615-
3616/*!-
3617 This virtual function is called by QWizard::cleanupPage() when-
3618 the user leaves the page by clicking \uicontrol Back (unless the \l QWizard::IndependentPages-
3619 option is set).-
3620-
3621 The default implementation resets the page's fields to their-
3622 original values (the values they had before initializePage() was-
3623 called).-
3624-
3625 \sa QWizard::cleanupPage(), initializePage(), QWizard::IndependentPages-
3626*/-
3627void QWizardPage::cleanupPage()-
3628{-
3629 Q_D(QWizardPage);-
3630 if (d->wizard) {
d->wizardDescription
TRUEnever evaluated
FALSEnever evaluated
0
3631 const QVector<QWizardField> &fields = d->wizard->d_func()->fields;-
3632 for (int i = 0; i < fields.count(); ++i) {const QWizardFieldauto &field =: fields.at(i);) {-
3633 if (field.page == this)
field.page == thisDescription
TRUEnever evaluated
FALSEnever evaluated
0
3634 field.object->setProperty(field.property, field.initialValue);
never executed: field.object->setProperty(field.property, field.initialValue);
0
3635 }
never executed: end of block
0
3636 }
never executed: end of block
0
3637}
never executed: end of block
0
3638-
3639/*!-
3640 This virtual function is called by QWizard::validateCurrentPage()-
3641 when the user clicks \uicontrol Next or \uicontrol Finish to perform some-
3642 last-minute validation. If it returns \c true, the next page is shown-
3643 (or the wizard finishes); otherwise, the current page stays up.-
3644-
3645 The default implementation returns \c true.-
3646-
3647 When possible, it is usually better style to disable the \uicontrol-
3648 Next or \uicontrol Finish button (by specifying \l{mandatory fields} or-
3649 reimplementing isComplete()) than to reimplement validatePage().-
3650-
3651 \sa QWizard::validateCurrentPage(), isComplete()-
3652*/-
3653bool QWizardPage::validatePage()-
3654{-
3655 return true;-
3656}-
3657-
3658/*!-
3659 This virtual function is called by QWizard to determine whether-
3660 the \uicontrol Next or \uicontrol Finish button should be enabled or-
3661 disabled.-
3662-
3663 The default implementation returns \c true if all \l{mandatory-
3664 fields} are filled; otherwise, it returns \c false.-
3665-
3666 If you reimplement this function, make sure to emit completeChanged(),-
3667 from the rest of your implementation, whenever the value of isComplete()-
3668 changes. This ensures that QWizard updates the enabled or disabled state of-
3669 its buttons. An example of the reimplementation is-
3670 available \l{http://doc.qt.io/archives/qq/qq22-qwizard.html#validatebeforeitstoolate}-
3671 {here}.-
3672-
3673 \sa completeChanged(), isFinalPage()-
3674*/-
3675bool QWizardPage::isComplete() const-
3676{-
3677 Q_D(const QWizardPage);-
3678-
3679 if (!d->wizard)-
3680 return true;-
3681-
3682 const QVector<QWizardField> &wizardFields = d->wizard->d_func()->fields;-
3683 for (int i = wizardFields.count() - 1; i >= 0; --i) {-
3684 const QWizardField &field = wizardFields.at(i);-
3685 if (field.page == this && field.mandatory) {-
3686 QVariant value = field.object->property(field.property);-
3687 if (value == field.initialValue)-
3688 return false;-
3689-
3690#ifndef QT_NO_LINEEDIT-
3691 if (QLineEdit *lineEdit = qobject_cast<QLineEdit *>(field.object)) {-
3692 if (!lineEdit->hasAcceptableInput())-
3693 return false;-
3694 }-
3695#endif-
3696#ifndef QT_NO_SPINBOX-
3697 if (QAbstractSpinBox *spinBox = qobject_cast<QAbstractSpinBox *>(field.object)) {-
3698 if (!spinBox->hasAcceptableInput())-
3699 return false;-
3700 }-
3701#endif-
3702 }-
3703 }-
3704 return true;-
3705}-
3706-
3707/*!-
3708 Explicitly sets this page to be final if \a finalPage is true.-
3709-
3710 After calling setFinalPage(true), isFinalPage() returns \c true and the \uicontrol-
3711 Finish button is visible (and enabled if isComplete() returns-
3712 true).-
3713-
3714 After calling setFinalPage(false), isFinalPage() returns \c true if-
3715 nextId() returns -1; otherwise, it returns \c false.-
3716-
3717 \sa isComplete(), QWizard::HaveFinishButtonOnEarlyPages-
3718*/-
3719void QWizardPage::setFinalPage(bool finalPage)-
3720{-
3721 Q_D(QWizardPage);-
3722 d->explicitlyFinal = finalPage;-
3723 QWizard *wizard = this->wizard();-
3724 if (wizard && wizard->currentPage() == this)-
3725 wizard->d_func()->updateCurrentPage();-
3726}-
3727-
3728/*!-
3729 This function is called by QWizard to determine whether the \uicontrol-
3730 Finish button should be shown for this page or not.-
3731-
3732 By default, it returns \c true if there is no next page-
3733 (i.e., nextId() returns -1); otherwise, it returns \c false.-
3734-
3735 By explicitly calling setFinalPage(true), you can let the user perform an-
3736 "early finish".-
3737-
3738 \sa isComplete(), QWizard::HaveFinishButtonOnEarlyPages-
3739*/-
3740bool QWizardPage::isFinalPage() const-
3741{-
3742 Q_D(const QWizardPage);-
3743 if (d->explicitlyFinal)-
3744 return true;-
3745-
3746 QWizard *wizard = this->wizard();-
3747 if (wizard && wizard->currentPage() == this) {-
3748 // try to use the QWizard implementation if possible-
3749 return wizard->nextId() == -1;-
3750 } else {-
3751 return nextId() == -1;-
3752 }-
3753}-
3754-
3755/*!-
3756 Sets this page to be a commit page if \a commitPage is true; otherwise,-
3757 sets it to be a normal page.-
3758-
3759 A commit page is a page that represents an action which cannot be undone-
3760 by clicking \uicontrol Back or \uicontrol Cancel.-
3761-
3762 A \uicontrol Commit button replaces the \uicontrol Next button on a commit page. Clicking this-
3763 button simply calls QWizard::next() just like clicking \uicontrol Next does.-
3764-
3765 A page entered directly from a commit page has its \uicontrol Back button disabled.-
3766-
3767 \sa isCommitPage()-
3768*/-
3769void QWizardPage::setCommitPage(bool commitPage)-
3770{-
3771 Q_D(QWizardPage);-
3772 d->commit = commitPage;-
3773 QWizard *wizard = this->wizard();-
3774 if (wizard && wizard->currentPage() == this)-
3775 wizard->d_func()->updateCurrentPage();-
3776}-
3777-
3778/*!-
3779 Returns \c true if this page is a commit page; otherwise returns \c false.-
3780-
3781 \sa setCommitPage()-
3782*/-
3783bool QWizardPage::isCommitPage() const-
3784{-
3785 Q_D(const QWizardPage);-
3786 return d->commit;-
3787}-
3788-
3789/*!-
3790 Sets the text on button \a which to be \a text on this page.-
3791-
3792 By default, the text on buttons depends on the QWizard::wizardStyle,-
3793 but may be redefined for the wizard as a whole using QWizard::setButtonText().-
3794-
3795 \sa buttonText(), QWizard::setButtonText(), QWizard::buttonText()-
3796*/-
3797void QWizardPage::setButtonText(QWizard::WizardButton which, const QString &text)-
3798{-
3799 Q_D(QWizardPage);-
3800 d->buttonCustomTexts.insert(which, text);-
3801 if (wizard() && wizard()->currentPage() == this && wizard()->d_func()->btns[which])-
3802 wizard()->d_func()->btns[which]->setText(text);-
3803}-
3804-
3805/*!-
3806 Returns the text on button \a which on this page.-
3807-
3808 If a text has ben set using setButtonText(), this text is returned.-
3809 Otherwise, if a text has been set using QWizard::setButtonText(),-
3810 this text is returned.-
3811-
3812 By default, the text on buttons depends on the QWizard::wizardStyle.-
3813 For example, on \macos, the \uicontrol Next button is called \uicontrol-
3814 Continue.-
3815-
3816 \sa setButtonText(), QWizard::buttonText(), QWizard::setButtonText()-
3817*/-
3818QString QWizardPage::buttonText(QWizard::WizardButton which) const-
3819{-
3820 Q_D(const QWizardPage);-
3821-
3822 if (d->buttonCustomTexts.contains(which))-
3823 return d->buttonCustomTexts.value(which);-
3824-
3825 if (wizard())-
3826 return wizard()->buttonText(which);-
3827-
3828 return QString();-
3829}-
3830-
3831/*!-
3832 This virtual function is called by QWizard::nextId() to find-
3833 out which page to show when the user clicks the \uicontrol Next button.-
3834-
3835 The return value is the ID of the next page, or -1 if no page follows.-
3836-
3837 By default, this function returns the lowest ID greater than the ID-
3838 of the current page, or -1 if there is no such ID.-
3839-
3840 By reimplementing this function, you can specify a dynamic page-
3841 order. For example:-
3842-
3843 \snippet dialogs/licensewizard/licensewizard.cpp 18-
3844-
3845 \sa QWizard::nextId()-
3846*/-
3847int QWizardPage::nextId() const-
3848{-
3849 Q_D(const QWizardPage);-
3850-
3851 if (!d->wizard)-
3852 return -1;-
3853-
3854 bool foundCurrentPage = false;-
3855-
3856 const QWizardPrivate::PageMap &pageMap = d->wizard->d_func()->pageMap;-
3857 QWizardPrivate::PageMap::const_iterator i = pageMap.constBegin();-
3858 QWizardPrivate::PageMap::const_iterator end = pageMap.constEnd();-
3859-
3860 for (; i != end; ++i) {-
3861 if (i.value() == this) {-
3862 foundCurrentPage = true;-
3863 } else if (foundCurrentPage) {-
3864 return i.key();-
3865 }-
3866 }-
3867 return -1;-
3868}-
3869-
3870/*!-
3871 \fn void QWizardPage::completeChanged()-
3872-
3873 This signal is emitted whenever the complete state of the page-
3874 (i.e., the value of isComplete()) changes.-
3875-
3876 If you reimplement isComplete(), make sure to emit-
3877 completeChanged() whenever the value of isComplete() changes, to-
3878 ensure that QWizard updates the enabled or disabled state of its-
3879 buttons.-
3880-
3881 \sa isComplete()-
3882*/-
3883-
3884/*!-
3885 Sets the value of the field called \a name to \a value.-
3886-
3887 This function can be used to set fields on any page of the wizard.-
3888 It is equivalent to calling-
3889 wizard()->\l{QWizard::setField()}{setField(\a name, \a value)}.-
3890-
3891 \sa QWizard::setField(), field(), registerField()-
3892*/-
3893void QWizardPage::setField(const QString &name, const QVariant &value)-
3894{-
3895 Q_D(QWizardPage);-
3896 if (!d->wizard)-
3897 return;-
3898 d->wizard->setField(name, value);-
3899}-
3900-
3901/*!-
3902 Returns the value of the field called \a name.-
3903-
3904 This function can be used to access fields on any page of the-
3905 wizard. It is equivalent to calling-
3906 wizard()->\l{QWizard::field()}{field(\a name)}.-
3907-
3908 Example:-
3909-
3910 \snippet dialogs/classwizard/classwizard.cpp 17-
3911-
3912 \sa QWizard::field(), setField(), registerField()-
3913*/-
3914QVariant QWizardPage::field(const QString &name) const-
3915{-
3916 Q_D(const QWizardPage);-
3917 if (!d->wizard)-
3918 return QVariant();-
3919 return d->wizard->field(name);-
3920}-
3921-
3922/*!-
3923 Creates a field called \a name associated with the given \a-
3924 property of the given \a widget. From then on, that property-
3925 becomes accessible using field() and setField().-
3926-
3927 Fields are global to the entire wizard and make it easy for any-
3928 single page to access information stored by another page, without-
3929 having to put all the logic in QWizard or having the pages know-
3930 explicitly about each other.-
3931-
3932 If \a name ends with an asterisk (\c *), the field is a mandatory-
3933 field. When a page has mandatory fields, the \uicontrol Next and/or-
3934 \uicontrol Finish buttons are enabled only when all mandatory fields-
3935 are filled. This requires a \a changedSignal to be specified, to-
3936 tell QWizard to recheck the value stored by the mandatory field.-
3937-
3938 QWizard knows the most common Qt widgets. For these (or their-
3939 subclasses), you don't need to specify a \a property or a \a-
3940 changedSignal. The table below lists these widgets:-
3941-
3942 \table-
3943 \header \li Widget \li Property \li Change Notification Signal-
3944 \row \li QAbstractButton \li bool \l{QAbstractButton::}{checked} \li \l{QAbstractButton::}{toggled()}-
3945 \row \li QAbstractSlider \li int \l{QAbstractSlider::}{value} \li \l{QAbstractSlider::}{valueChanged()}-
3946 \row \li QComboBox \li int \l{QComboBox::}{currentIndex} \li \l{QComboBox::}{currentIndexChanged()}-
3947 \row \li QDateTimeEdit \li QDateTime \l{QDateTimeEdit::}{dateTime} \li \l{QDateTimeEdit::}{dateTimeChanged()}-
3948 \row \li QLineEdit \li QString \l{QLineEdit::}{text} \li \l{QLineEdit::}{textChanged()}-
3949 \row \li QListWidget \li int \l{QListWidget::}{currentRow} \li \l{QListWidget::}{currentRowChanged()}-
3950 \row \li QSpinBox \li int \l{QSpinBox::}{value} \li \l{QSpinBox::}{valueChanged()}-
3951 \endtable-
3952-
3953 You can use QWizard::setDefaultProperty() to add entries to this-
3954 table or to override existing entries.-
3955-
3956 To consider a field "filled", QWizard simply checks that their-
3957 current value doesn't equal their original value (the value they-
3958 had before initializePage() was called). For QLineEdit, it also-
3959 checks that-
3960 \l{QLineEdit::hasAcceptableInput()}{hasAcceptableInput()} returns-
3961 true, to honor any validator or mask.-
3962-
3963 QWizard's mandatory field mechanism is provided for convenience.-
3964 It can be bypassed by reimplementing QWizardPage::isComplete().-
3965-
3966 \sa field(), setField(), QWizard::setDefaultProperty()-
3967*/-
3968void QWizardPage::registerField(const QString &name, QWidget *widget, const char *property,-
3969 const char *changedSignal)-
3970{-
3971 Q_D(QWizardPage);-
3972 QWizardField field(this, name, widget, property, changedSignal);-
3973 if (d->wizard) {-
3974 d->wizard->d_func()->addField(field);-
3975 } else {-
3976 d->pendingFields += field;-
3977 }-
3978}-
3979-
3980/*!-
3981 Returns the wizard associated with this page, or 0 if this page-
3982 hasn't been inserted into a QWizard yet.-
3983-
3984 \sa QWizard::addPage(), QWizard::setPage()-
3985*/-
3986QWizard *QWizardPage::wizard() const-
3987{-
3988 Q_D(const QWizardPage);-
3989 return d->wizard;-
3990}-
3991-
3992QT_END_NAMESPACE-
3993-
3994#include "moc_qwizard.cpp"-
3995-
3996#endif // QT_NO_WIZARD-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9