/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "controllerwindow.h" #include "controls.h" #include #include #include #include #include #include #include #include #include #include #include #include #if QT_VERSION >= 0x050000 # include # include # include #endif #include ControllerWidget::ControllerWidget(QWidget *parent) : QWidget(parent) , previewWidget(0) { parentWindow = new QMainWindow; parentWindow->setWindowTitle(tr("Preview parent window")); QLabel *label = new QLabel(tr("Parent window")); parentWindow->setCentralWidget(label); previewWindow = new PreviewWindow; previewWindow->installEventFilter(this); previewWidget = new PreviewWidget; previewWidget->installEventFilter(this); previewDialog = new PreviewDialog; previewDialog->installEventFilter(this); createTypeGroupBox(); hintsControl = new HintControl; hintsControl->setHints(previewWidget->windowFlags()); connect(hintsControl, SIGNAL(changed(Qt::WindowFlags)), this, SLOT(updatePreview())); statesControl = new WindowStatesControl; statesControl->setStates(previewWidget->windowState()); statesControl->setVisibleValue(true); connect(statesControl, SIGNAL(changed()), this, SLOT(updatePreview())); typeControl = new TypeControl; typeControl->setType(previewWidget->windowFlags()); connect(typeControl, SIGNAL(changed(Qt::WindowFlags)), this, SLOT(updatePreview())); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->addWidget(widgetTypeGroupBox); mainLayout->addWidget(additionalOptionsGroupBox); mainLayout->addWidget(typeControl); mainLayout->addWidget(hintsControl); mainLayout->addWidget(statesControl); updatePreview(); } bool ControllerWidget::eventFilter(QObject *, QEvent *e) { if (e->type() == QEvent::WindowStateChange) updateStateControl(); return false; } void ControllerWidget::updateStateControl() { if (activePreview) statesControl->setStates(activePreview->windowStates()); } void ControllerWidget::updatePreview(QWindow *preview) { activePreview = preview; const Qt::WindowFlags flags = typeControl->type() | hintsControl->hints(); if (modalWindowCheckBox->isChecked()) { parentWindow->show(); preview->setModality(Qt::WindowModal); preview->setParent(parentWindow->windowHandle()); } else { preview->setModality(Qt::NonModal); preview->setParent(0); parentWindow->hide(); } preview->setFlags(flags); if (fixedSizeWindowCheckBox->isChecked()) { preview->setMinimumSize(preview->size()); preview->setMaximumSize(preview->size()); } else { preview->setMinimumSize(QSize(0, 0)); preview->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); } preview->setWindowStates(statesControl->states()); preview->setVisible(statesControl->visibleValue()); } void ControllerWidget::updatePreview(QWidget *preview) { activePreview = preview->windowHandle(); const Qt::WindowFlags flags = typeControl->type() | hintsControl->hints(); if (modalWindowCheckBox->isChecked()) { parentWindow->show(); preview->setWindowModality(Qt::WindowModal); preview->setParent(parentWindow); } else { preview->setWindowModality(Qt::NonModal); preview->setParent(0); parentWindow->hide(); } preview->setWindowFlags(flags); QSize fixedSize = fixedSizeWindowCheckBox->isChecked() ? preview->size() : QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); preview->setFixedSize(fixedSize); QPoint pos = preview->pos(); if (pos.x() < 0) pos.setX(0); if (pos.y() < 0) pos.setY(0); preview->move(pos); preview->setWindowState(statesControl->states()); preview->setVisible(statesControl->visibleValue()); } void ControllerWidget::updatePreview() { if (previewWindowButton->isChecked()) { previewDialog->hide(); previewWidget->close(); updatePreview(previewWindow); } else if (previewWidgetButton->isChecked()) { previewWindow->hide(); previewDialog->hide(); updatePreview(previewWidget); } else { previewWindow->hide(); previewWidget->close(); updatePreview(previewDialog); } } void ControllerWidget::createTypeGroupBox() { widgetTypeGroupBox = new QGroupBox(tr("Window Type")); previewWindowButton = createRadioButton(tr("QWindow")); previewWidgetButton = createRadioButton(tr("QWidget")); previewDialogButton = createRadioButton(tr("QDialog")); previewWindowButton->setChecked(true); QHBoxLayout *l = new QHBoxLayout; l->addWidget(previewWindowButton); l->addWidget(previewWidgetButton); l->addWidget(previewDialogButton); widgetTypeGroupBox->setLayout(l); additionalOptionsGroupBox = new QGroupBox(tr("Additional options")); l = new QHBoxLayout; modalWindowCheckBox = createCheckBox(tr("Modal window")); fixedSizeWindowCheckBox = createCheckBox(tr("Fixed size window")); l->addWidget(modalWindowCheckBox); l->addWidget(fixedSizeWindowCheckBox); additionalOptionsGroupBox->setLayout(l); } QCheckBox *ControllerWidget::createCheckBox(const QString &text) { QCheckBox *checkBox = new QCheckBox(text); connect(checkBox, SIGNAL(clicked()), this, SLOT(updatePreview())); return checkBox; } QRadioButton *ControllerWidget::createRadioButton(const QString &text) { QRadioButton *button = new QRadioButton(text); connect(button, SIGNAL(clicked()), this, SLOT(updatePreview())); return button; } static bool isTopLevel(const QObject *o) { if (o->isWidgetType()) return static_cast(o)->isWindow(); #if QT_VERSION >= 0x050000 if (o->isWindowType()) return static_cast(o)->isTopLevel(); #endif return false; } static Qt::WindowStates windowState(const QObject *o) { if (o->isWidgetType()) { Qt::WindowStates states = static_cast(o)->windowState(); states &= ~Qt::WindowActive; return states; } #if QT_VERSION >= 0x050000 if (o->isWindowType()) return static_cast(o)->windowState(); #endif return Qt::WindowNoState; } class EventFilter : public QObject { public: explicit EventFilter(QObject *parent = 0) : QObject(parent) {} bool eventFilter(QObject *o, QEvent *e) { switch (e->type()) { case QEvent::Move: case QEvent::Resize: case QEvent::WindowStateChange: case QEvent::ApplicationActivate: case QEvent::ApplicationDeactivate: #if QT_VERSION >= 0x050000 case QEvent::ApplicationStateChange: #endif if (isTopLevel(o)) formatEvent(o, e); break; default: break; } return QObject::eventFilter(o ,e); } private: void formatEvent(QObject *o, QEvent *e) { static int n = 0; QDebug debug = qDebug().nospace(); #if QT_VERSION >= 0x050000 debug.noquote(); #endif debug << '#' << n++ << ' ' << o->metaObject()->className(); const QString name = o->objectName(); if (!name.isEmpty()) debug << "/\"" << name << '"'; debug << ' ' << e; if (e->type() == QEvent::WindowStateChange) debug << ' ' << windowState(o); } }; LogWidget *LogWidget::m_instance = 0; #if QT_VERSION >= 0x050000 static void qt5MessageHandler(QtMsgType, const QMessageLogContext &, const QString &text) { if (LogWidget *lw = LogWidget::instance()) lw->appendText(text); } #else // Qt 5 static void qt4MessageHandler(QtMsgType, const char *text) { if (LogWidget *lw = LogWidget::instance()) lw->appendText(QString::fromLocal8Bit(text)); } #endif // Qt 4 LogWidget::LogWidget(QWidget *parent) : QPlainTextEdit(parent) { LogWidget::m_instance = this; setReadOnly(true); appendText(startupMessage()); } LogWidget::~LogWidget() { LogWidget::m_instance = 0; } void LogWidget::install() { #if QT_VERSION >= 0x050000 qInstallMessageHandler(qt5MessageHandler); #else qInstallMsgHandler(qt4MessageHandler); #endif } QString LogWidget::startupMessage() { QString result; #if QT_VERSION >= 0x050300 result += QLatin1String(QLibraryInfo::build()); #else result += QLatin1String("Qt ") + QLatin1String(QT_VERSION_STR); #endif #if QT_VERSION >= 0x050000 result += QLatin1Char(' '); result += QGuiApplication::platformName(); #endif return result; } void LogWidget::appendText(const QString &message) { appendPlainText(message); ensureCursorVisible(); } ControllerWindow::ControllerWindow() { setWindowTitle(tr("Window Flags (Qt version %1, %2)") .arg(QLatin1String(qVersion()), #if QT_VERSION >= 0x050000 qApp->platformName())); #else QLatin1String(""))); #endif QVBoxLayout *layout = new QVBoxLayout(this); QTabWidget *tabWidget = new QTabWidget(this); ControllerWidget *controllerWidget = new ControllerWidget(tabWidget); tabWidget->addTab(controllerWidget, tr("Control")); LogWidget *logWidget = new LogWidget(tabWidget); tabWidget->addTab(logWidget, tr("Event log")); layout->addWidget(tabWidget); QHBoxLayout *bottomLayout = new QHBoxLayout; layout->addLayout(bottomLayout); bottomLayout->addStretch(); QPushButton *updateControlsButton = new QPushButton(tr("&Update")); connect(updateControlsButton, SIGNAL(clicked()), controllerWidget, SLOT(updateStateControl())); bottomLayout->addWidget(updateControlsButton); QPushButton *clearLogButton = new QPushButton(tr("Clear &Log")); connect(clearLogButton, SIGNAL(clicked()), logWidget, SLOT(clear())); bottomLayout->addWidget(clearLogButton); QPushButton *quitButton = new QPushButton(tr("&Quit")); connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit())); quitButton->setShortcut(Qt::CTRL + Qt::Key_Q); bottomLayout->addWidget(quitButton); } void ControllerWindow::registerEventFilter() { qApp->installEventFilter(new EventFilter(qApp)); }