📄 qwizard.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qwizard.h"#ifndef QT_NO_WIZARD#include "qalgorithms.h"#include "qapplication.h"#include "qboxlayout.h"#include "qdesktopwidget.h"#include "qevent.h"#include "qframe.h"#include "qlabel.h"#include "qlineedit.h"#include "qpainter.h"#include "qpushbutton.h"#include "qset.h"#include "qstyle.h"#include "qvarlengtharray.h"#if defined(Q_WS_MAC)#include "qmacstyle_mac.h"#include "private/qt_mac_p.h"#include "qlibrary.h"#elif !defined(QT_NO_STYLE_WINDOWSVISTA)#include "qwizard_win_p.h"#include "qtimer.h"#endif#include "private/qdialog_p.h"#include <qdebug.h>#include <string.h> // for memset()// These fudge terms were needed a few places to obtain pixel-perfect resultsconst int GapBetweenLogoAndRightEdge = 5;const int ModernHeaderTopMargin = 2;const int ClassicHMargin = 4;const int MacButtonTopMargin = 13;const int MacLayoutLeftMargin = 20;const int MacLayoutTopMargin = 14;const int MacLayoutRightMargin = 20;const int MacLayoutBottomMargin = 17;static void changeSpacerSize(QLayout *layout, int index, int width, int height){ QSpacerItem *spacer = layout->itemAt(index)->spacerItem(); Q_ASSERT(spacer); spacer->changeSize(width, height);}static QWidget *iWantTheFocus(QWidget *ancestor){ const int MaxIterations = 100; QWidget *candidate = ancestor; for (int i = 0; i < MaxIterations; ++i) { candidate = candidate->nextInFocusChain(); if (!candidate) break; if (candidate->focusPolicy() & Qt::TabFocus) { if (candidate != ancestor && ancestor->isAncestorOf(candidate)) return candidate; } } return 0;}static bool objectInheritsXAndXIsCloserThanY(const QObject *object, const QByteArray &classX, const QByteArray &classY){ const QMetaObject *metaObject = object->metaObject(); while (metaObject) { if (metaObject->className() == classX) return true; if (metaObject->className() == classY) return false; metaObject = metaObject->superClass(); } return false;}const int NFallbackDefaultProperties = 7;const struct { const char *className; const char *property; const char *changedSignal;} fallbackProperties[NFallbackDefaultProperties] = { // If you modify this list, make sure to update the documentation (and the auto test) { "QAbstractButton", "checked", SIGNAL(toggled(bool)) }, { "QAbstractSlider", "value", SIGNAL(valueChanged(int)) }, { "QComboBox", "currentIndex", SIGNAL(currentIndexChanged(int)) }, { "QDateTimeEdit", "dateTime", SIGNAL(dateTimeChanged(QDateTime)) }, { "QLineEdit", "text", SIGNAL(textChanged(QString)) }, { "QListWidget", "currentRow", SIGNAL(currentRowChanged(int)) }, { "QSpinBox", "value", SIGNAL(valueChanged(int)) }};class QWizardDefaultProperty{public: QByteArray className; QByteArray property; QByteArray changedSignal; inline QWizardDefaultProperty() {} inline QWizardDefaultProperty(const char *className, const char *property, const char *changedSignal) : className(className), property(property), changedSignal(changedSignal) {}};class QWizardField{public: inline QWizardField() {} QWizardField(QWizardPage *page, const QString &spec, QObject *object, const char *property, const char *changedSignal); void resolve(const QVector<QWizardDefaultProperty> &defaultPropertyTable); void findProperty(const QWizardDefaultProperty *properties, int propertyCount); QWizardPage *page; QString name; bool mandatory; QObject *object; QByteArray property; QByteArray changedSignal; QVariant initialValue;};QWizardField::QWizardField(QWizardPage *page, const QString &spec, QObject *object, const char *property, const char *changedSignal) : page(page), name(spec), mandatory(false), object(object), property(property), changedSignal(changedSignal){ if (name.endsWith(QLatin1Char('*'))) { name.chop(1); mandatory = true; }}void QWizardField::resolve(const QVector<QWizardDefaultProperty> &defaultPropertyTable){ if (property.isEmpty()) findProperty(defaultPropertyTable.constData(), defaultPropertyTable.count()); initialValue = object->property(property);}void QWizardField::findProperty(const QWizardDefaultProperty *properties, int propertyCount){ QByteArray className; for (int i = 0; i < propertyCount; ++i) { if (objectInheritsXAndXIsCloserThanY(object, properties[i].className, className)) { className = properties[i].className; property = properties[i].property; changedSignal = properties[i].changedSignal; } }}class QWizardLayoutInfo{public: inline QWizardLayoutInfo() : topLevelMargin(-1), childMargin(-1), hspacing(-1), vspacing(-1), wizStyle(QWizard::ClassicStyle), header(false), watermark(false), title(false), subTitle(false), extension(false) {} int topLevelMargin; int childMargin; int hspacing; int vspacing; int buttonSpacing; QWizard::WizardStyle wizStyle; bool header; bool watermark; bool title; bool subTitle; bool extension; bool operator==(const QWizardLayoutInfo &other); inline bool operator!=(const QWizardLayoutInfo &other) { return !operator==(other); }};bool QWizardLayoutInfo::operator==(const QWizardLayoutInfo &other){ return topLevelMargin == other.topLevelMargin && childMargin == other.childMargin && hspacing == other.hspacing && vspacing == other.vspacing && buttonSpacing == other.buttonSpacing && wizStyle == other.wizStyle && header == other.header && watermark == other.watermark && title == other.title && subTitle == other.subTitle && extension == other.extension;}class QWizardHeader : public QWidget{public: enum RulerType { Ruler }; inline QWizardHeader(RulerType /* ruler */, QWidget *parent = 0) : QWidget(parent) { setFixedHeight(2); } QWizardHeader(QWidget *parent = 0); void setup(const QWizardLayoutInfo &info, const QString &title, const QString &subTitle, const QPixmap &logo, const QPixmap &banner, Qt::TextFormat titleFormat, Qt::TextFormat subTitleFormat);protected: void paintEvent(QPaintEvent *event);private: QLabel *titleLabel; QLabel *subTitleLabel; QLabel *logoLabel; QGridLayout *layout; QPixmap bannerPixmap;};QWizardHeader::QWizardHeader(QWidget *parent) : QWidget(parent){ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); setBackgroundRole(QPalette::Base); titleLabel = new QLabel(this); titleLabel->setBackgroundRole(QPalette::Base); subTitleLabel = new QLabel(this); subTitleLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft); subTitleLabel->setWordWrap(true); logoLabel = new QLabel(this); QFont font = titleLabel->font(); font.setBold(true); titleLabel->setFont(font); layout = new QGridLayout(this); layout->setMargin(0); layout->setSpacing(0); layout->setRowMinimumHeight(3, 1); layout->setRowStretch(4, 1); layout->setColumnStretch(2, 1); layout->setColumnMinimumWidth(4, 2 * GapBetweenLogoAndRightEdge); layout->setColumnMinimumWidth(6, GapBetweenLogoAndRightEdge); layout->addWidget(titleLabel, 2, 1, 1, 2); layout->addWidget(subTitleLabel, 4, 2); layout->addWidget(logoLabel, 1, 5, 5, 1);}void QWizardHeader::setup(const QWizardLayoutInfo &info, const QString &title, const QString &subTitle, const QPixmap &logo, const QPixmap &banner, Qt::TextFormat titleFormat, Qt::TextFormat subTitleFormat){ bool modern = (info.wizStyle == QWizard::ModernStyle); layout->setRowMinimumHeight(0, modern ? ModernHeaderTopMargin : 0); layout->setRowMinimumHeight(1, modern ? info.topLevelMargin - ModernHeaderTopMargin - 1 : 0); layout->setRowMinimumHeight(6, (modern ? 3 : GapBetweenLogoAndRightEdge) + 2); int minColumnWidth0 = modern ? 2 * info.topLevelMargin : 0; int minColumnWidth1 = modern ? 2 * info.topLevelMargin + 1 : info.topLevelMargin + ClassicHMargin; layout->setColumnMinimumWidth(0, minColumnWidth0); layout->setColumnMinimumWidth(1, minColumnWidth1); titleLabel->setTextFormat(titleFormat); titleLabel->setText(title); logoLabel->setPixmap(logo); subTitleLabel->setTextFormat(subTitleFormat); subTitleLabel->setText(QLatin1String("Pq\nPq")); int desiredSubTitleHeight = subTitleLabel->sizeHint().height(); subTitleLabel->setText(subTitle); if (modern) { bannerPixmap = banner; } else { bannerPixmap = QPixmap(); } if (bannerPixmap.isNull()) { /* There is no widthForHeight() function, so we simulate it with a loop. */ int candidateSubTitleWidth = qMin(512, 2 * qApp->desktop()->width() / 3); int delta = candidateSubTitleWidth >> 1; while (delta > 0) { if (subTitleLabel->heightForWidth(candidateSubTitleWidth - delta) <= desiredSubTitleHeight) candidateSubTitleWidth -= delta; delta >>= 1; } subTitleLabel->setMinimumSize(candidateSubTitleWidth, desiredSubTitleHeight); QSize size = layout->totalMinimumSize(); setMinimumSize(size); setMaximumSize(QWIDGETSIZE_MAX, size.height()); } else { subTitleLabel->setMinimumSize(0, 0); setFixedSize(banner.size() + QSize(0, 2)); } updateGeometry();}void QWizardHeader::paintEvent(QPaintEvent * /* event */){ QPainter painter(this); painter.drawPixmap(0, 0, bannerPixmap); int x = width() - 2; int y = height() - 2; const QPalette &pal = palette(); painter.setPen(pal.mid().color()); painter.drawLine(0, y, x, y); painter.setPen(pal.base().color()); painter.drawPoint(x + 1, y); painter.drawLine(0, y + 1, x + 1, y + 1);}// We save one vtable by basing QWizardRuler on QWizardHeaderclass QWizardRuler : public QWizardHeader{public: inline QWizardRuler(QWidget *parent = 0) : QWizardHeader(Ruler, parent) {}};class QWizardPagePrivate : public QWidgetPrivate{ Q_DECLARE_PUBLIC(QWizardPage)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -