701852e17b
This provides an easy way to test window modality using a ready available test. Change-Id: Ia23736c61fd56dda8f72ae19f5f102163951271b Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
340 lines
12 KiB
C++
340 lines
12 KiB
C++
// Copyright (C) 2016 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
|
|
#include "wizardpanel.h"
|
|
|
|
#include <QWizard>
|
|
#include <QWizardPage>
|
|
#include <QVBoxLayout>
|
|
#include <QGridLayout>
|
|
#include <QRadioButton>
|
|
#include <QPushButton>
|
|
#include <QCheckBox>
|
|
#include <QButtonGroup>
|
|
#include <QSpacerItem>
|
|
#include <QGroupBox>
|
|
#include <QLabel>
|
|
#include <QStyle>
|
|
#include <QIcon>
|
|
#include <QImage>
|
|
#include <QPainter>
|
|
#include <QFont>
|
|
#include <QFontMetrics>
|
|
#include <QHash>
|
|
|
|
static QIcon coloredIcon(const Qt::GlobalColor color)
|
|
{
|
|
QImage image(QSize(24, 24), QImage::Format_RGB32);
|
|
image.fill(color);
|
|
return QIcon(QPixmap::fromImage(image));
|
|
}
|
|
|
|
static QPixmap pixmapWithText(const QString &text, const QColor color)
|
|
{
|
|
QFont font;
|
|
QFontMetrics metric(font);
|
|
QRect rectangle = metric.boundingRect(text);
|
|
rectangle.setBottomRight(rectangle.bottomRight() + QPoint(20, 20));
|
|
QImage image(rectangle.size(), QImage::Format_RGB32);
|
|
image.fill(color);
|
|
QPainter painter(&image);
|
|
painter.setFont(font);
|
|
painter.drawText(rectangle, Qt::AlignHCenter | Qt::AlignVCenter, text);
|
|
return QPixmap::fromImage(image);
|
|
}
|
|
|
|
// A radio-group control for QWizard::WizardStyle.
|
|
class WizardStyleControl : public QGroupBox
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
WizardStyleControl(QWidget *parent = nullptr);
|
|
|
|
void setWizardStyle(int style);
|
|
QWizard::WizardStyle wizardStyle() const;
|
|
|
|
signals:
|
|
void wizardStyleChanged(int);
|
|
|
|
private:
|
|
QButtonGroup *m_group;
|
|
};
|
|
|
|
WizardStyleControl::WizardStyleControl(QWidget *parent)
|
|
: QGroupBox(tr("Style"), parent)
|
|
, m_group(new QButtonGroup(this))
|
|
{
|
|
m_group->setExclusive(true);
|
|
connect(m_group, &QButtonGroup::idClicked, this, &WizardStyleControl::wizardStyleChanged);
|
|
QVBoxLayout *vLayout = new QVBoxLayout(this);
|
|
QRadioButton *radioButton = new QRadioButton(tr("None/OS Default"), this);
|
|
m_group->addButton(radioButton, QWizard::NStyles);
|
|
vLayout->addWidget(radioButton);
|
|
radioButton = new QRadioButton(tr("ClassicStyle"), this);
|
|
m_group->addButton(radioButton, QWizard::ClassicStyle);
|
|
vLayout->addWidget(radioButton);
|
|
radioButton = new QRadioButton(tr("ModernStyle"), this);
|
|
m_group->addButton(radioButton, QWizard::ModernStyle);
|
|
vLayout->addWidget(radioButton);
|
|
radioButton = new QRadioButton(tr("MacStyle"), this);
|
|
m_group->addButton(radioButton, QWizard::MacStyle);
|
|
vLayout->addWidget(radioButton);
|
|
radioButton = new QRadioButton(tr("AeroStyle"), this);
|
|
m_group->addButton(radioButton, QWizard::AeroStyle);
|
|
vLayout->addWidget(radioButton);
|
|
vLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
|
|
|
|
setWizardStyle(style()->styleHint(QStyle::SH_WizardStyle));
|
|
}
|
|
|
|
QWizard::WizardStyle WizardStyleControl::wizardStyle() const
|
|
{
|
|
return static_cast<QWizard::WizardStyle>(m_group->checkedId());
|
|
}
|
|
|
|
void WizardStyleControl::setWizardStyle(int wizardStyle)
|
|
{
|
|
if (wizardStyle < 0 || wizardStyle > QWizard::NStyles)
|
|
wizardStyle = QWizard::NStyles;
|
|
QAbstractButton *button = m_group->button(wizardStyle);
|
|
Q_ASSERT(button);
|
|
const bool blocked = m_group->blockSignals(true);
|
|
button->setChecked(true);
|
|
m_group->blockSignals(blocked);
|
|
}
|
|
|
|
// A control with checkboxes for QWizard::WizardOption.
|
|
class WizardOptionsControl : public QGroupBox
|
|
{
|
|
public:
|
|
explicit WizardOptionsControl(QWidget *parent = nullptr);
|
|
|
|
QWizard::WizardOption wizardOptions() const;
|
|
void setWizardOptions(int options);
|
|
|
|
private:
|
|
typedef QHash<int, QCheckBox *> CheckBoxHash;
|
|
|
|
void addCheckBox(QVBoxLayout *layout, int flag, const QString &title);
|
|
|
|
CheckBoxHash m_checkBoxes;
|
|
};
|
|
|
|
WizardOptionsControl::WizardOptionsControl(QWidget *parent)
|
|
: QGroupBox(tr("Options"), parent)
|
|
{
|
|
QVBoxLayout *vLayout = new QVBoxLayout(this);
|
|
addCheckBox(vLayout, QWizard::IndependentPages, QLatin1String("IndependentPages"));
|
|
addCheckBox(vLayout, QWizard::IgnoreSubTitles, QLatin1String("IgnoreSubTitles"));
|
|
addCheckBox(vLayout, QWizard::ExtendedWatermarkPixmap, QLatin1String("ExtendedWatermarkPixmap"));
|
|
addCheckBox(vLayout, QWizard::NoDefaultButton, QLatin1String("NoDefaultButton"));
|
|
addCheckBox(vLayout, QWizard::NoBackButtonOnStartPage, QLatin1String("NoBackButtonOnStartPage"));
|
|
addCheckBox(vLayout, QWizard::NoBackButtonOnLastPage, QLatin1String("NoBackButtonOnLastPage"));
|
|
addCheckBox(vLayout, QWizard::DisabledBackButtonOnLastPage, QLatin1String("DisabledBackButtonOnLastPage"));
|
|
addCheckBox(vLayout, QWizard::HaveNextButtonOnLastPage, QLatin1String("HaveNextButtonOnLastPage"));
|
|
addCheckBox(vLayout, QWizard::HaveFinishButtonOnEarlyPages, QLatin1String("HaveFinishButtonOnEarlyPages"));
|
|
addCheckBox(vLayout, QWizard::NoCancelButton, QLatin1String("NoCancelButton"));
|
|
addCheckBox(vLayout, QWizard::CancelButtonOnLeft, QLatin1String("CancelButtonOnLeft"));
|
|
addCheckBox(vLayout, QWizard::HaveHelpButton, QLatin1String("HaveHelpButton"));
|
|
addCheckBox(vLayout, QWizard::HelpButtonOnRight, QLatin1String("HelpButtonOnRight"));
|
|
addCheckBox(vLayout, QWizard::HaveCustomButton1, QLatin1String("HaveCustomButton1"));
|
|
addCheckBox(vLayout, QWizard::HaveCustomButton2, QLatin1String("HaveCustomButton2"));
|
|
addCheckBox(vLayout, QWizard::HaveCustomButton3, QLatin1String("HaveCustomButton3"));
|
|
vLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
|
|
}
|
|
|
|
void WizardOptionsControl::addCheckBox(QVBoxLayout *layout, int flag, const QString &title)
|
|
{
|
|
QCheckBox *checkBox = new QCheckBox(title, this);
|
|
layout->addWidget(checkBox);
|
|
m_checkBoxes.insert(flag, checkBox);
|
|
}
|
|
|
|
QWizard::WizardOption WizardOptionsControl::wizardOptions() const
|
|
{
|
|
int result = 0;
|
|
typedef CheckBoxHash::const_iterator ConstIterator;
|
|
const ConstIterator cend = m_checkBoxes.constEnd();
|
|
for (ConstIterator it = m_checkBoxes.constBegin(); it != cend; ++it)
|
|
if (it.value()->isChecked())
|
|
result |= it.key();
|
|
return static_cast<QWizard::WizardOption>(result);
|
|
}
|
|
|
|
void WizardOptionsControl::setWizardOptions(int options)
|
|
{
|
|
typedef CheckBoxHash::iterator Iterator;
|
|
const Iterator end = m_checkBoxes.end();
|
|
for (Iterator it = m_checkBoxes.begin(); it != end; ++it)
|
|
it.value()->setChecked(options & it.key());
|
|
}
|
|
|
|
// A test wizard with a slot to change its style.
|
|
class Wizard : public QWizard {
|
|
Q_OBJECT
|
|
public:
|
|
explicit Wizard(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
|
|
|
|
public slots:
|
|
void changeWizardStyle(int newStyle);
|
|
};
|
|
|
|
void Wizard::changeWizardStyle(int newStyle)
|
|
{
|
|
if (newStyle >= 0 && newStyle < int(QWizard::NStyles))
|
|
setWizardStyle(static_cast<QWizard::WizardStyle>(newStyle));
|
|
}
|
|
|
|
// A test wizard page with a WizardStyleControl.
|
|
class WizardPage : public QWizardPage
|
|
{
|
|
public:
|
|
explicit WizardPage(const QString &title, QWidget *parent = nullptr);
|
|
|
|
void initializePage();
|
|
|
|
private:
|
|
WizardStyleControl *m_styleControl;
|
|
bool m_firstTimeShown;
|
|
};
|
|
|
|
WizardPage::WizardPage(const QString &title, QWidget *parent)
|
|
: QWizardPage(parent)
|
|
, m_styleControl(new WizardStyleControl(this))
|
|
, m_firstTimeShown(true)
|
|
{
|
|
setTitle(title);
|
|
setSubTitle(title + QLatin1String(" SubTitle"));
|
|
QVBoxLayout *vLayout = new QVBoxLayout(this);
|
|
vLayout->addWidget(m_styleControl);
|
|
}
|
|
|
|
void WizardPage::initializePage()
|
|
{
|
|
m_styleControl->setWizardStyle(wizard()->wizardStyle());
|
|
if (m_firstTimeShown) {
|
|
m_firstTimeShown = false;
|
|
connect(m_styleControl, SIGNAL(wizardStyleChanged(int)),
|
|
wizard(), SLOT(changeWizardStyle(int)));
|
|
}
|
|
}
|
|
|
|
Wizard::Wizard(QWidget *parent, Qt::WindowFlags flags)
|
|
: QWizard(parent, flags)
|
|
{
|
|
setWindowIcon(coloredIcon(Qt::red));
|
|
setWindowTitle(QLatin1String("Wizard ") + QLatin1String(QT_VERSION_STR));
|
|
addPage(new WizardPage(tr("Page 1"), this));
|
|
addPage(new WizardPage(tr("Page 2"), this));
|
|
addPage(new WizardPage(tr("Page 3"), this));
|
|
}
|
|
|
|
// A dialog using a Wizard as child widget (emulating Qt Designer).
|
|
class WizardEmbeddingDialog : public QDialog {
|
|
public:
|
|
explicit WizardEmbeddingDialog(QWidget *parent = nullptr);
|
|
|
|
Wizard *wizard() const { return m_wizard; }
|
|
|
|
private:
|
|
Wizard *m_wizard;
|
|
};
|
|
|
|
WizardEmbeddingDialog::WizardEmbeddingDialog(QWidget *parent)
|
|
: QDialog(parent)
|
|
, m_wizard(new Wizard)
|
|
{
|
|
setWindowTitle(QString::fromLatin1("Dialog Embedding QWizard %1").arg(QT_VERSION_STR));
|
|
QGridLayout *gridLayout = new QGridLayout(this);
|
|
gridLayout->addWidget(new QLabel(tr("Above wizard")), 0, 0, 1, 3);
|
|
gridLayout->addWidget(new QLabel(tr("Left of wizard")), 1, 0);
|
|
m_wizard->setObjectName(QLatin1String("EmbeddedWizard"));
|
|
m_wizard->setParent(this, Qt::Widget);
|
|
gridLayout->addWidget(m_wizard, 1, 1);
|
|
gridLayout->addWidget(new QLabel(tr("Right of wizard")), 1, 2);
|
|
gridLayout->addWidget(new QLabel(tr("Below wizard")), 2, 0, 1, 3);
|
|
}
|
|
|
|
WizardPanel::WizardPanel(QWidget *parent)
|
|
: QWidget(parent)
|
|
, m_styleControl(new WizardStyleControl(this))
|
|
, m_optionsControl(new WizardOptionsControl(this))
|
|
{
|
|
{
|
|
QWizard wizard;
|
|
m_optionsControl->setWizardOptions(wizard.options());
|
|
m_styleControl->setWizardStyle(wizard.wizardStyle());
|
|
}
|
|
|
|
QGridLayout *gridLayout = new QGridLayout(this);
|
|
gridLayout->addWidget(m_optionsControl, 0, 0, 2, 1);
|
|
gridLayout->addWidget(m_styleControl, 0, 1);
|
|
QGroupBox *buttonGroupBox = new QGroupBox(this);
|
|
QVBoxLayout *vLayout = new QVBoxLayout(buttonGroupBox);
|
|
QPushButton *button = new QPushButton(tr("Exec modal"), this);
|
|
connect(button, SIGNAL(clicked()), this, SLOT(execModal()));
|
|
vLayout->addWidget(button);
|
|
button = new QPushButton(tr("Show application modal"), this);
|
|
connect(button, &QPushButton::clicked, [this]() { showModal(Qt::ApplicationModal); });
|
|
vLayout->addWidget(button);
|
|
button = new QPushButton(tr("Show window modal"), this);
|
|
connect(button, &QPushButton::clicked, [this]() { showModal(Qt::WindowModal); });
|
|
vLayout->addWidget(button);
|
|
button = new QPushButton(tr("Show non-modal"), this);
|
|
connect(button, SIGNAL(clicked()), this, SLOT(showNonModal()));
|
|
vLayout->addWidget(button);
|
|
button = new QPushButton(tr("Show embedded"), this);
|
|
button->setToolTip(tr("Test QWizard's behavior when used as a widget child."));
|
|
connect(button, SIGNAL(clicked()), this, SLOT(showEmbedded()));
|
|
vLayout->addWidget(button);
|
|
vLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
|
|
gridLayout->addWidget(buttonGroupBox, 1, 1);
|
|
}
|
|
|
|
void WizardPanel::execModal()
|
|
{
|
|
Wizard wizard(this);
|
|
applyParameters(&wizard);
|
|
wizard.exec();
|
|
}
|
|
|
|
void WizardPanel::showModal(Qt::WindowModality modality)
|
|
{
|
|
Wizard *wizard = new Wizard(this);
|
|
applyParameters(wizard);
|
|
wizard->setModal(true);
|
|
wizard->setAttribute(Qt::WA_DeleteOnClose);
|
|
wizard->setWindowModality(modality);
|
|
wizard->show();
|
|
}
|
|
|
|
void WizardPanel::showNonModal()
|
|
{
|
|
Wizard *wizard = new Wizard(this);
|
|
applyParameters(wizard);
|
|
wizard->setModal(false);
|
|
wizard->setAttribute(Qt::WA_DeleteOnClose);
|
|
wizard->show();
|
|
}
|
|
|
|
void WizardPanel::showEmbedded()
|
|
{
|
|
WizardEmbeddingDialog *dialog = new WizardEmbeddingDialog(this);
|
|
applyParameters(dialog->wizard());
|
|
dialog->setModal(false);
|
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
|
dialog->show();
|
|
}
|
|
|
|
void WizardPanel::applyParameters(QWizard *wizard) const
|
|
{
|
|
wizard->setWizardStyle(m_styleControl->wizardStyle());
|
|
wizard->setOptions(m_optionsControl->wizardOptions());
|
|
wizard->setPixmap(QWizard::WatermarkPixmap, pixmapWithText(QLatin1String("Watermark"), QColor(Qt::blue).lighter()));
|
|
wizard->setPixmap(QWizard::LogoPixmap, pixmapWithText(QLatin1String("Logo"), Qt::green));
|
|
wizard->setPixmap(QWizard::BannerPixmap, pixmapWithText(QLatin1String("Banner"), Qt::green));
|
|
wizard->setPixmap(QWizard::BackgroundPixmap, pixmapWithText(QLatin1String("Background"), QColor(Qt::red).lighter()));
|
|
}
|
|
|
|
#include "wizardpanel.moc"
|