qt5base-lts/tests/manual/dialogs/wizardpanel.cpp
Mikolaj Boc 701852e17b Add window-modal show option to dialogs manual test
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>
2022-09-13 18:13:00 +02:00

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"