qt5base-lts/tests/auto/qmdisubwindow/tst_qmdisubwindow.cpp
Qt by Nokia 38be0d1383 Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you
want to look at revision history older than this, please refer to the
Qt Git wiki for how to use Git history grafting. At the time of
writing, this wiki is located here:

http://qt.gitorious.org/qt/pages/GitIntroductionWithQt

If you have already performed the grafting and you don't see any
history beyond this commit, try running "git log" with the "--follow"
argument.

Branched from the monolithic repo, Qt master branch, at commit
896db169ea224deb96c59ce8af800d019de63f12
2011-04-27 12:05:43 +02:00

2034 lines
70 KiB
C++

/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include "qmdisubwindow.h"
#include "qmdiarea.h"
#include <QLayout>
#include <QLineEdit>
#include <QMainWindow>
#include <QMenuBar>
#include <QMenu>
#include <QGroupBox>
#include <QTextEdit>
#include <QLayout>
#include <QHBoxLayout>
#include <QByteArray>
#include <QStyle>
#include <QStyleOptionTitleBar>
#include <QPushButton>
#include <QSizeGrip>
#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
#include <QMacStyle>
#endif
#include "../../shared/util.h"
QT_BEGIN_NAMESPACE
#if defined(Q_WS_X11)
extern void qt_x11_wait_for_window_manager(QWidget *w);
#endif
#if !defined(Q_WS_WIN)
extern bool qt_tab_all_widgets;
#endif
QT_END_NAMESPACE
static inline bool tabAllWidgets()
{
#if !defined(Q_WS_WIN)
if (qApp->style()->inherits("QMacStyle"))
return qt_tab_all_widgets;
#endif
return true;
}
static inline void triggerSignal(QMdiSubWindow *window, QMdiArea *workspace,
const QByteArray &signal)
{
if (signal == SIGNAL(windowMaximized())) {
window->showMaximized();
qApp->processEvents();
if (window->parent())
QVERIFY(window->isMaximized());
} else if (signal == SIGNAL(windowMinimized())) {
window->showMinimized();
qApp->processEvents();
if (window->parent())
QVERIFY(window->isMinimized());
} else if (signal == SIGNAL(windowRestored())) {
window->showMaximized();
qApp->processEvents();
window->showNormal();
qApp->processEvents();
QVERIFY(!window->isMinimized());
QVERIFY(!window->isMaximized());
QVERIFY(!window->isShaded());
} else if (signal == SIGNAL(aboutToActivate())) {
if (window->parent()) {
workspace->setActiveSubWindow(window);
qApp->processEvents();
}
} else if (signal == SIGNAL(windowActivated())) {
if (window->parent()) {
workspace->setActiveSubWindow(window);
qApp->processEvents();
}
} else if (signal == SIGNAL(windowDeactivated())) {
if (!window->parent())
return;
workspace->setActiveSubWindow(window);
qApp->processEvents();
workspace->setActiveSubWindow(0);
qApp->processEvents();
}
}
// --- from tst_qgraphicsview.cpp ---
static void sendMousePress(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::LeftButton)
{
QMouseEvent event(QEvent::MouseButtonPress, point, widget->mapToGlobal(point), button, 0, 0);
QApplication::sendEvent(widget, &event);
}
static void sendMouseMove(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::LeftButton)
{
QMouseEvent event(QEvent::MouseMove, point, widget->mapToGlobal(point), button, button, 0);
QApplication::sendEvent(widget, &event);
}
static void sendMouseRelease(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::LeftButton)
{
QMouseEvent event(QEvent::MouseButtonRelease, point, widget->mapToGlobal(point), button, 0, 0);
QApplication::sendEvent(widget, &event);
}
// ---
static void sendMouseDoubleClick(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::LeftButton)
{
sendMousePress(widget, point, button);
sendMouseRelease(widget, point, button);
QMouseEvent event(QEvent::MouseButtonDblClick, point, widget->mapToGlobal(point), button, 0, 0);
QApplication::sendEvent(widget, &event);
}
static const Qt::WindowFlags StandardWindowFlags
= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint;
static const Qt::WindowFlags DialogWindowFlags
= Qt::WindowTitleHint | Qt::WindowSystemMenuHint;
Q_DECLARE_METATYPE(Qt::WindowState);
Q_DECLARE_METATYPE(Qt::WindowStates);
Q_DECLARE_METATYPE(Qt::WindowType);
Q_DECLARE_METATYPE(Qt::WindowFlags);
//TESTED_CLASS=
//TESTED_FILES=
class tst_QMdiSubWindow : public QObject
{
Q_OBJECT
private slots:
void initTestCase();
void sizeHint();
void minimumSizeHint();
void minimumSize();
void setWidget();
void setWindowState_data();
void setWindowState();
void mainWindowSupport();
void emittingOfSignals_data();
void emittingOfSignals();
void showShaded();
void showNormal_data();
void showNormal();
void setOpaqueResizeAndMove_data();
void setOpaqueResizeAndMove();
void setWindowFlags_data();
void setWindowFlags();
void mouseDoubleClick();
void setSystemMenu();
void restoreFocus();
void changeFocusWithTab();
void closeEvent();
void setWindowTitle();
void resizeEvents_data();
void resizeEvents();
#if defined(Q_WS_MAC)
void defaultSizeGrip();
#endif
void hideAndShow();
void keepWindowMaximizedState();
void explicitlyHiddenWidget();
void resizeTimer();
void fixedMinMaxSize();
#if !defined (Q_WS_MAC) && !defined (Q_OS_WINCE)
void replaceMenuBarWhileMaximized();
void closeOnDoubleClick();
#endif
void setFont();
void task_188849();
void mdiArea();
void task_182852();
void task_233197();
void task_226929();
};
void tst_QMdiSubWindow::initTestCase()
{
qRegisterMetaType<Qt::WindowStates>("Qt::WindowStates");
}
void tst_QMdiSubWindow::sizeHint()
{
QMdiSubWindow *window = new QMdiSubWindow;
QCOMPARE(window->sizeHint(), window->minimumSizeHint());
window->show();
QCOMPARE(window->sizeHint(), window->minimumSizeHint());
QMdiArea workspace;
workspace.addSubWindow(window);
QCOMPARE(window->sizeHint(), window->minimumSizeHint());
}
void tst_QMdiSubWindow::minimumSizeHint()
{
QMdiSubWindow window;
window.show();
QCOMPARE(window.minimumSizeHint(), qApp->globalStrut());
window.setWidget(new QWidget);
QCOMPARE(window.minimumSizeHint(), window.layout()->minimumSize()
.expandedTo(qApp->globalStrut()));
delete window.widget();
delete window.layout();
window.setWidget(new QWidget);
QCOMPARE(window.minimumSizeHint(), qApp->globalStrut());
window.widget()->show();
QCOMPARE(window.minimumSizeHint(), window.widget()->minimumSizeHint()
.expandedTo(qApp->globalStrut()));
}
void tst_QMdiSubWindow::minimumSize()
{
QMdiArea mdiArea;
mdiArea.resize(200, 200);
// Check that we respect the minimum size set on the sub-window itself.
QMdiSubWindow *subWindow1 = mdiArea.addSubWindow(new QWidget);
subWindow1->setMinimumSize(1000, 1000);
mdiArea.show();
#if defined(Q_WS_X11)
qt_x11_wait_for_window_manager(&mdiArea);
#endif
QCOMPARE(subWindow1->size(), QSize(1000, 1000));
// Check that we respect the minimum size set on the internal widget.
QWidget *widget = new QWidget;
widget->setMinimumSize(1000, 1000);
QMdiSubWindow *subWindow2 = mdiArea.addSubWindow(widget);
QVERIFY(subWindow2->size() != mdiArea.viewport()->size());
QCOMPARE(subWindow2->size(), subWindow2->minimumSizeHint());
}
void tst_QMdiSubWindow::setWidget()
{
QMdiSubWindow window;
window.show();
QVERIFY(window.layout());
QVERIFY(!window.widget());
// QPointer so we can check if the widget is deleted
QPointer<QWidget> widget = new QWidget;
widget->setWindowTitle(QString::fromLatin1("DummyTitle"));
QCOMPARE(widget->windowTitle(), QString::fromLatin1("DummyTitle"));
window.setWidget(widget);
QCOMPARE(window.windowTitle(), window.widget()->windowTitle());
QCOMPARE(widget->parentWidget(), static_cast<QWidget *>(&window));
QVERIFY(!widget->isVisible());
QCOMPARE(window.layout()->count(), 1);
QTest::ignoreMessage(QtWarningMsg,"QMdiSubWindow::setWidget: widget is already set");
window.setWidget(widget);
QCOMPARE(window.widget(), static_cast<QWidget *>(widget));
QCOMPARE(widget->parentWidget(), static_cast<QWidget *>(&window));
window.setWidget(0);
QVERIFY(widget);
QVERIFY(!widget->parent());
QVERIFY(!window.widget());
QCOMPARE(window.layout()->count(), 0);
window.setWidget(widget);
delete window.layout();
QVERIFY(!window.layout());
QVERIFY(window.widget());
QCOMPARE(window.widget()->parentWidget(), static_cast<QWidget *>(&window));
delete window.widget();
QVERIFY(!widget);
QVERIFY(!window.widget());
}
void tst_QMdiSubWindow::setWindowState_data()
{
QTest::addColumn<Qt::WindowState>("windowState");
QTest::newRow("maximized") << Qt::WindowMaximized;
QTest::newRow("minimized") << Qt::WindowMinimized;
QTest::newRow("normalized") << Qt::WindowNoState;
}
void tst_QMdiSubWindow::setWindowState()
{
QFETCH(Qt::WindowState, windowState);
QMdiArea workspace;
QMdiSubWindow *window = qobject_cast<QMdiSubWindow *>(workspace.addSubWindow(new QLineEdit));
window->show();
workspace.show();
#if defined(Q_WS_X11)
qt_x11_wait_for_window_manager(&workspace);
#endif
QWidget *testWidget = 0;
for (int iteration = 0; iteration < 2; ++iteration) {
if (iteration == 0)
testWidget = window;
else
testWidget = window->widget();
testWidget->setWindowState(windowState);
Qt::WindowStates windowStateWindow = window->windowState();
windowStateWindow &= ~Qt::WindowActive;
Qt::WindowStates windowStateWidget = window->widget()->windowState();
windowStateWidget &= ~Qt::WindowActive;
QCOMPARE(windowStateWindow, windowStateWidget);
switch (windowState) {
case Qt::WindowNoState:
QVERIFY(!window->widget()->isMinimized());
QVERIFY(!window->widget()->isMaximized());
QVERIFY(!window->isMinimized());
QVERIFY(!window->isMaximized());
break;
case Qt::WindowMinimized:
QVERIFY(window->widget()->isMinimized());
QVERIFY(window->isMinimized());
break;
case Qt::WindowMaximized:
QVERIFY(window->widget()->isMaximized());
QVERIFY(window->isMaximized());
break;
default:
break;
}
}
}
void tst_QMdiSubWindow::mainWindowSupport()
{
QList<QMdiSubWindow *> windows;
QMdiArea *workspace = new QMdiArea;
QMainWindow mainWindow;
mainWindow.setCentralWidget(workspace);
mainWindow.show();
mainWindow.menuBar()->setVisible(true);
qApp->setActiveWindow(&mainWindow);
// QMainWindow's window title is empty
#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE)
{
QCOMPARE(mainWindow.windowTitle(), QString());
QMdiSubWindow *window = workspace->addSubWindow(new QPushButton(QLatin1String("Test")));
QString expectedTitle = QLatin1String("MainWindow's title is empty");
window->setWindowTitle(expectedTitle);
QCOMPARE(window->windowTitle(), expectedTitle);
window->showMaximized();
QVERIFY(window->isMaximized());
QCOMPARE(window->windowTitle(), expectedTitle);
QCOMPARE(mainWindow.windowTitle(), expectedTitle);
window->showNormal();
QCOMPARE(window->windowTitle(), expectedTitle);
QCOMPARE(mainWindow.windowTitle(), QString());
window->close();
}
#endif
QString originalWindowTitle = QString::fromLatin1("MainWindow");
mainWindow.setWindowTitle(originalWindowTitle);
for (int i = 0; i < 5; ++i) {
mainWindow.menuBar()->setVisible(false);
QMdiSubWindow *window = new QMdiSubWindow;
windows.append(window);
QVERIFY(!window->maximizedButtonsWidget());
QVERIFY(!window->maximizedSystemMenuIconWidget());
QMdiArea *nestedWorkspace = new QMdiArea; // :-)
window->setWidget(nestedWorkspace);
window->widget()->setWindowTitle(QString::fromLatin1("Window %1").arg(i));
workspace->addSubWindow(window);
QVERIFY(!window->maximizedButtonsWidget());
QVERIFY(!window->maximizedSystemMenuIconWidget());
window->show();
// mainWindow.menuBar() is not visible
window->showMaximized();
qApp->processEvents();
QVERIFY(window->isMaximized());
QVERIFY(!window->maximizedButtonsWidget());
QVERIFY(!window->maximizedSystemMenuIconWidget());
window->showNormal();
// Now it is
mainWindow.menuBar()->setVisible(true);
window->showMaximized();
qApp->processEvents();
QVERIFY(window->isMaximized());
#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE)
QVERIFY(window->maximizedButtonsWidget());
QCOMPARE(window->maximizedButtonsWidget(), mainWindow.menuBar()->cornerWidget(Qt::TopRightCorner));
QVERIFY(window->maximizedSystemMenuIconWidget());
QCOMPARE(window->maximizedSystemMenuIconWidget(), qobject_cast<QWidget *>(mainWindow.menuBar()
->cornerWidget(Qt::TopLeftCorner)));
QCOMPARE(mainWindow.windowTitle(), QString::fromLatin1("%1 - [%2]")
.arg(originalWindowTitle, window->widget()->windowTitle()));
#endif
// Check that nested child windows don't set window title
nestedWorkspace->show();
QMdiSubWindow *nestedWindow = new QMdiSubWindow;
nestedWindow->setWidget(new QWidget);
nestedWorkspace->addSubWindow(nestedWindow);
nestedWindow->widget()->setWindowTitle(QString::fromLatin1("NestedWindow %1").arg(i));
nestedWindow->showMaximized();
qApp->processEvents();
QVERIFY(nestedWindow->isMaximized());
QVERIFY(!nestedWindow->maximizedButtonsWidget());
QVERIFY(!nestedWindow->maximizedSystemMenuIconWidget());
#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE)
QCOMPARE(mainWindow.windowTitle(), QString::fromLatin1("%1 - [%2]")
.arg(originalWindowTitle, window->widget()->windowTitle()));
#endif
}
#if defined(Q_WS_MAC) || defined(Q_OS_WINCE)
return;
#endif
workspace->activateNextSubWindow();
qApp->processEvents();
foreach (QMdiSubWindow *window, windows) {
QCOMPARE(workspace->activeSubWindow(), window);
QVERIFY(window->isMaximized());
QVERIFY(window->maximizedButtonsWidget());
QCOMPARE(window->maximizedButtonsWidget(), mainWindow.menuBar()->cornerWidget(Qt::TopRightCorner));
QVERIFY(window->maximizedSystemMenuIconWidget());
QCOMPARE(window->maximizedSystemMenuIconWidget(), qobject_cast<QWidget *>(mainWindow.menuBar()
->cornerWidget(Qt::TopLeftCorner)));
QCOMPARE(mainWindow.windowTitle(), QString::fromLatin1("%1 - [%2]")
.arg(originalWindowTitle, window->widget()->windowTitle()));
workspace->activateNextSubWindow();
qApp->processEvents();
}
}
// This test was written when QMdiSubWindow emitted separate signals
void tst_QMdiSubWindow::emittingOfSignals_data()
{
QTest::addColumn<QByteArray>("signal");
QTest::addColumn<Qt::WindowState>("watchedState");
QTest::newRow("windowMaximized") << QByteArray(SIGNAL(windowMaximized())) << Qt::WindowMaximized;
QTest::newRow("windowMinimized") << QByteArray(SIGNAL(windowMinimized())) << Qt::WindowMinimized;
QTest::newRow("windowRestored") << QByteArray(SIGNAL(windowRestored())) << Qt::WindowNoState;
QTest::newRow("aboutToActivate") << QByteArray(SIGNAL(aboutToActivate())) << Qt::WindowNoState;
QTest::newRow("windowActivated") << QByteArray(SIGNAL(windowActivated())) << Qt::WindowActive;
QTest::newRow("windowDeactivated") << QByteArray(SIGNAL(windowDeactivated())) << Qt::WindowActive;
}
void tst_QMdiSubWindow::emittingOfSignals()
{
QFETCH(QByteArray, signal);
QFETCH(Qt::WindowState, watchedState);
QMdiArea workspace;
workspace.show();
qApp->processEvents();
qApp->setActiveWindow(&workspace);
QMdiSubWindow *window = qobject_cast<QMdiSubWindow *>(workspace.addSubWindow(new QWidget));
qApp->processEvents();
window->show();
if (signal != SIGNAL(windowRestored()))
workspace.setActiveSubWindow(0);
qApp->processEvents();
QSignalSpy spy(window, signal == SIGNAL(aboutToActivate())
? signal.data()
: SIGNAL(windowStateChanged(Qt::WindowStates, Qt::WindowStates)));
QVERIFY(spy.isEmpty());
triggerSignal(window, &workspace, signal);
// Unless the signal is windowRestored or windowDeactivated,
// we're already in correct state and nothing should happen.
if (signal != SIGNAL(windowRestored()) && signal != SIGNAL(windowDeactivated()))
triggerSignal(window, &workspace, signal);
int count = 0;
if (signal == SIGNAL(aboutToActivate())) {
count += spy.count();
} else {
for (int i = 0; i < spy.count(); ++i) {
Qt::WindowStates oldState = qvariant_cast<Qt::WindowStates>(spy.at(i).at(0));
Qt::WindowStates newState = qvariant_cast<Qt::WindowStates>(spy.at(i).at(1));
if (watchedState != Qt::WindowNoState) {
if (!(oldState & watchedState) && (newState & watchedState))
++count;
} else {
if ((oldState & (Qt::WindowMinimized | Qt::WindowMaximized))
&& (newState & (watchedState | Qt::WindowActive))) {
++count;
}
}
}
}
QCOMPARE(count, 1);
window->setParent(0);
window->showNormal();
#if defined(Q_WS_X11)
qt_x11_wait_for_window_manager(window);
#endif
qApp->processEvents();
spy.clear();
triggerSignal(window, &workspace, signal);
QCOMPARE(spy.count(), 0);
delete window;
window = 0;
}
void tst_QMdiSubWindow::showShaded()
{
QMdiArea workspace;
QMdiSubWindow *window = workspace.addSubWindow(new QLineEdit);
window->resize(300, 300);
qApp->processEvents();
workspace.show();
#ifdef Q_WS_X11
qt_x11_wait_for_window_manager(&workspace);
#endif
QVERIFY(!window->isShaded());
QVERIFY(!window->isMaximized());
QCOMPARE(window->size(), QSize(300, 300));
QRect restoreGeometry = window->geometry();
window->showShaded();
QVERIFY(window->isShaded());
QVERIFY(window->isMinimized());
window->showNormal();
QVERIFY(!window->isShaded());
QVERIFY(!window->isMinimized());
QCOMPARE(window->geometry(), restoreGeometry);
window->showShaded();
window->showNormal();
QVERIFY(!window->isShaded());
QVERIFY(!window->isMinimized());
QCOMPARE(window->geometry(), restoreGeometry);
window->showMinimized();
window->showMaximized();
window->showShaded();
QCOMPARE(window->width(), workspace.contentsRect().width());
window->showNormal();
QCOMPARE(window->geometry(), workspace.contentsRect());
window->resize(300, 300);
QCOMPARE(window->size(), QSize(300, 300));
window->showShaded();
window->showNormal();
QTest::qWait(250);
#ifdef Q_OS_WINCE
QSKIP("Until we have a QEvent::WindowFlagsChange event, this will skip", SkipAll);
#endif
const QSize minimumSizeHint = window->minimumSizeHint();
QVERIFY(minimumSizeHint.height() < 300);
const int maxHeightDiff = 300 - minimumSizeHint.height();
// Calculate mouse position for bottom right corner and simulate a
// vertical resize with the mouse.
int offset = window->style()->pixelMetric(QStyle::PM_MDIFrameWidth) / 2;
QPoint mousePosition(window->width() - qMax(offset, 2), window->height() - qMax(offset, 2));
QWidget *mouseReceiver = 0;
#ifdef Q_WS_MAC
if (qobject_cast<QMacStyle*>(window->style()))
mouseReceiver = qFindChild<QSizeGrip *>(window);
else
#endif
mouseReceiver = window;
QVERIFY(mouseReceiver);
sendMouseMove(mouseReceiver, mousePosition, Qt::NoButton);
sendMousePress(mouseReceiver, mousePosition);
for (int i = 0; i < maxHeightDiff + 20; ++i) {
--mousePosition.ry();
sendMouseMove(mouseReceiver, mousePosition);
}
sendMouseRelease(mouseReceiver, mousePosition);
// Make sure we respect the minimumSizeHint!
QCOMPARE(window->height(), minimumSizeHint.height());
window->showShaded();
window->setParent(0);
window->show();
QVERIFY(!window->isShaded());
delete window;
}
void tst_QMdiSubWindow::showNormal_data()
{
QTest::addColumn<QByteArray>("slot");
QTest::newRow("showMinimized") << QByteArray("showMinimized");
QTest::newRow("showMaximized") << QByteArray("showMaximized");
QTest::newRow("showShaded") << QByteArray("showShaded");
}
void tst_QMdiSubWindow::showNormal()
{
QFETCH(QByteArray, slot);
QMdiArea workspace;
QWidget *window = workspace.addSubWindow(new QWidget);
qApp->processEvents();
workspace.show();
window->show();
#if defined(Q_WS_X11)
qt_x11_wait_for_window_manager(&workspace);
#endif
QRect originalGeometry = window->geometry();
QVERIFY(QMetaObject::invokeMethod(window, slot.data()));
qApp->processEvents();
window->showNormal();
qApp->processEvents();
QCOMPARE(window->geometry(), originalGeometry);
}
class EventSpy : public QObject
{
public:
EventSpy(QObject *object, QEvent::Type event)
: eventToSpy(event), _count(0)
{
if (object)
object->installEventFilter(this);
}
int count() const { return _count; }
void clear() { _count = 0; }
protected:
bool eventFilter(QObject *object, QEvent *event)
{
if (event->type() == eventToSpy)
++_count;
return QObject::eventFilter(object, event);
}
private:
QEvent::Type eventToSpy;
int _count;
};
void tst_QMdiSubWindow::setOpaqueResizeAndMove_data()
{
QTest::addColumn<bool>("opaqueMode");
QTest::addColumn<int>("geometryCount");
QTest::addColumn<int>("expectedGeometryCount");
QTest::addColumn<QSize>("workspaceSize");
QTest::addColumn<QSize>("windowSize");
QTest::newRow("normal mode") << true<< 20 << 20 << QSize(400, 400) << QSize(200, 200);
QTest::newRow("rubberband mode") << false << 20 << 1 << QSize(400, 400) << QSize(200, 200);
}
void tst_QMdiSubWindow::setOpaqueResizeAndMove()
{
#if defined (QT_NO_CURSOR) || defined (Q_OS_WINCE_WM) //For Windows CE we will set QT_NO_CURSOR if there is no cursor support
QSKIP("No cursor available", SkipAll);
#endif
QFETCH(bool, opaqueMode);
QFETCH(int, geometryCount);
QFETCH(int, expectedGeometryCount);
QFETCH(QSize, workspaceSize);
QFETCH(QSize, windowSize);
QMdiArea workspace;
QMdiSubWindow *window = qobject_cast<QMdiSubWindow *>(workspace.addSubWindow(new QWidget));
qApp->processEvents();
workspace.resize(workspaceSize);
workspace.show();
#ifdef Q_WS_X11
qt_x11_wait_for_window_manager(&workspace);
#endif
QWidget *mouseReceiver = 0;
if (window->style()->inherits("QMacStyle"))
mouseReceiver = qFindChild<QSizeGrip *>(window);
else
mouseReceiver = window;
QVERIFY(mouseReceiver);
// ----------------------------- resize -----------------------------
{
// setOpaqueResize
window->setOption(QMdiSubWindow::RubberBandResize, !opaqueMode);
QCOMPARE(window->testOption(QMdiSubWindow::RubberBandResize), !opaqueMode);
// Check that the event spy actually works
EventSpy resizeSpy(window, QEvent::Resize);
QCOMPARE(resizeSpy.count(), 0);
window->resize(windowSize);
QCOMPARE(window->size(), windowSize);
QCOMPARE(resizeSpy.count(), 1);
resizeSpy.clear();
QCOMPARE(resizeSpy.count(), 0);
QTest::qWait(250); // delayed update of dirty regions
// Enter resize mode.
int offset = window->style()->pixelMetric(QStyle::PM_MDIFrameWidth) / 2;
QPoint mousePosition(mouseReceiver->width() - qMax(offset, 2), mouseReceiver->height() - qMax(offset, 2));
sendMouseMove(mouseReceiver, mousePosition, Qt::NoButton);
sendMousePress(mouseReceiver, mousePosition);
// The window itself is the grabber in rubberband mode
if (!opaqueMode) {
mouseReceiver = window;
mousePosition = QPoint(window->width() - qMax(offset, 2), window->height() - qMax(offset, 2));
}
// Trigger resize events
for (int i = 0; i < geometryCount; ++i) {
if (mouseReceiver == window) {
++mousePosition.rx();
++mousePosition.ry();
sendMouseMove(mouseReceiver, mousePosition);
} else {
sendMouseMove(mouseReceiver, mousePosition + QPoint(1, 1));
}
}
// Leave resize mode
sendMouseRelease(mouseReceiver, mousePosition);
QCOMPARE(resizeSpy.count(), expectedGeometryCount);
QCOMPARE(window->size(), windowSize + QSize(geometryCount, geometryCount));
}
// ------------------------------ move ------------------------------
{
// setOpaqueMove
window->setOption(QMdiSubWindow::RubberBandMove, !opaqueMode);
QCOMPARE(window->testOption(QMdiSubWindow::RubberBandMove), !opaqueMode);
EventSpy moveSpy(window, QEvent::Move);
QCOMPARE(moveSpy.count(), 0);
window->move(30, 30);
QCOMPARE(moveSpy.count(), 1);
moveSpy.clear();
// Enter move mode
QStyleOptionTitleBar options;
options.initFrom(window);
int height = window->style()->pixelMetric(QStyle::PM_TitleBarHeight, &options);
#if defined(Q_WS_MAC)
// ### Remove this after mac style has been fixed
height -= 4;
#endif
QPoint mousePosition(window->width() / 2, height - 1);
sendMouseMove(window, mousePosition, Qt::NoButton);
sendMousePress(window, mousePosition);
// Trigger move events
for (int i = 0; i < geometryCount; ++i) {
++mousePosition.rx();
++mousePosition.ry();
sendMouseMove(window, mousePosition);
}
// Leave move mode
sendMouseRelease(window, mousePosition);
QCOMPARE(moveSpy.count(), expectedGeometryCount);
QCOMPARE(window->size(), windowSize + QSize(geometryCount, geometryCount));
}
}
void tst_QMdiSubWindow::setWindowFlags_data()
{
QTest::addColumn<Qt::WindowType>("windowType");
QTest::addColumn<Qt::WindowType>("expectedWindowType");
QTest::addColumn<Qt::WindowFlags>("customFlags");
QTest::addColumn<Qt::WindowFlags>("expectedCustomFlags");
// NB! If 'expectedCustomFlags' is set to 'Qt::WindowFlags(0)'
// and nothing else, it means we're expecting the same as customFlags.
// Standard window types with no custom flags set.
QTest::newRow("Qt::Widget") << Qt::Widget << Qt::SubWindow
<< Qt::WindowFlags(0) << StandardWindowFlags;
QTest::newRow("Qt::Window") << Qt::Window << Qt::SubWindow
<< Qt::WindowFlags(0) << StandardWindowFlags;
QTest::newRow("Qt::Dialog") << Qt::Dialog << Qt::SubWindow
<< Qt::WindowFlags(0) << DialogWindowFlags;
QTest::newRow("Qt::Sheet") << Qt::Sheet << Qt::SubWindow
<< Qt::WindowFlags(0) << StandardWindowFlags;
QTest::newRow("Qt::Drawer") << Qt::Drawer << Qt::SubWindow
<< Qt::WindowFlags(0) << StandardWindowFlags;
QTest::newRow("Qt::Popup") << Qt::Popup << Qt::SubWindow
<< Qt::WindowFlags(0) << StandardWindowFlags;
QTest::newRow("Qt::Tool") << Qt::Tool << Qt::SubWindow
<< Qt::WindowFlags(0) << StandardWindowFlags;
QTest::newRow("Qt::ToolTip") << Qt::ToolTip << Qt::SubWindow
<< Qt::WindowFlags(0) << StandardWindowFlags;
QTest::newRow("Qt::SplashScreen") << Qt::SplashScreen << Qt::SubWindow
<< Qt::WindowFlags(0) << StandardWindowFlags;
QTest::newRow("Qt::Desktop") << Qt::Desktop << Qt::SubWindow
<< Qt::WindowFlags(0) << StandardWindowFlags;
QTest::newRow("Qt::SubWindow") << Qt::SubWindow << Qt::SubWindow
<< Qt::WindowFlags(0) << StandardWindowFlags;
// Custom flags
QTest::newRow("Title") << Qt::SubWindow << Qt::SubWindow
<< (Qt::WindowTitleHint | Qt::WindowFlags(0))
<< Qt::WindowFlags(0);
QTest::newRow("TitleAndMin") << Qt::SubWindow << Qt::SubWindow
<< (Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint)
<< Qt::WindowFlags(0);
QTest::newRow("TitleAndMax") << Qt::SubWindow << Qt::SubWindow
<< (Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint)
<< Qt::WindowFlags(0);
QTest::newRow("TitleAndMinMax") << Qt::SubWindow << Qt::SubWindow
<< (Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint)
<< Qt::WindowFlags(0);
QTest::newRow("Standard") << Qt::SubWindow << Qt::SubWindow
<< StandardWindowFlags
<< Qt::WindowFlags(0);
QTest::newRow("StandardAndShade") << Qt::SubWindow << Qt::SubWindow
<< (StandardWindowFlags | Qt::WindowShadeButtonHint)
<< Qt::WindowFlags(0);
QTest::newRow("StandardAndContext") << Qt::SubWindow << Qt::SubWindow
<< (StandardWindowFlags | Qt::WindowContextHelpButtonHint)
<< Qt::WindowFlags(0);
QTest::newRow("StandardAndStaysOnTop") << Qt::SubWindow << Qt::SubWindow
<< (StandardWindowFlags | Qt::WindowStaysOnTopHint)
<< Qt::WindowFlags(0);
QTest::newRow("StandardAndFrameless") << Qt::SubWindow << Qt::SubWindow
<< (StandardWindowFlags | Qt::FramelessWindowHint)
<< (Qt::FramelessWindowHint | Qt::WindowFlags(0));
QTest::newRow("StandardAndFramelessAndStaysOnTop") << Qt::SubWindow << Qt::SubWindow
<< (StandardWindowFlags | Qt::FramelessWindowHint
| Qt::WindowStaysOnTopHint)
<< (Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
QTest::newRow("Shade") << Qt::SubWindow << Qt::SubWindow
<< (Qt::WindowShadeButtonHint | Qt::WindowFlags(0))
<< (StandardWindowFlags | Qt::WindowShadeButtonHint);
QTest::newRow("ShadeAndCustomize") << Qt::SubWindow << Qt::SubWindow
<< (Qt::WindowShadeButtonHint | Qt::CustomizeWindowHint)
<< Qt::WindowFlags(0);
QTest::newRow("Context") << Qt::SubWindow << Qt::SubWindow
<< (Qt::WindowContextHelpButtonHint | Qt::WindowFlags(0))
<< (StandardWindowFlags | Qt::WindowContextHelpButtonHint);
QTest::newRow("ContextAndCustomize") << Qt::SubWindow << Qt::SubWindow
<< (Qt::WindowContextHelpButtonHint | Qt::CustomizeWindowHint)
<< Qt::WindowFlags(0);
QTest::newRow("ShadeAndContext") << Qt::SubWindow << Qt::SubWindow
<< (Qt::WindowShadeButtonHint | Qt::WindowContextHelpButtonHint)
<< (StandardWindowFlags | Qt::WindowShadeButtonHint | Qt::WindowContextHelpButtonHint);
QTest::newRow("ShadeAndContextAndCustomize") << Qt::SubWindow << Qt::SubWindow
<< (Qt::WindowShadeButtonHint | Qt::WindowContextHelpButtonHint | Qt::CustomizeWindowHint)
<< Qt::WindowFlags(0);
QTest::newRow("OnlyCustomize") << Qt::SubWindow << Qt::SubWindow
<< (Qt::CustomizeWindowHint | Qt::WindowFlags(0))
<< Qt::WindowFlags(0);
}
void tst_QMdiSubWindow::setWindowFlags()
{
QSKIP("Until we have a QEvent::WindowFlagsChange event, this will skip", SkipAll);
QFETCH(Qt::WindowType, windowType);
QFETCH(Qt::WindowType, expectedWindowType);
QFETCH(Qt::WindowFlags, customFlags);
QFETCH(Qt::WindowFlags, expectedCustomFlags);
QMdiArea workspace;
QMdiSubWindow *window = qobject_cast<QMdiSubWindow *>(workspace.addSubWindow(new QWidget));
qApp->processEvents();
workspace.show();
window->show();
#if defined(Q_WS_X11)
qt_x11_wait_for_window_manager(&workspace);
#endif
window->setWindowFlags(windowType | customFlags);
QCOMPARE(window->windowType(), expectedWindowType);
if (!expectedCustomFlags) // We expect the same as 'customFlags'
QCOMPARE(window->windowFlags() & ~expectedWindowType, customFlags);
else
QCOMPARE(window->windowFlags() & ~expectedWindowType, expectedCustomFlags);
}
void tst_QMdiSubWindow::mouseDoubleClick()
{
QMdiArea workspace;
QMdiSubWindow *window = qobject_cast<QMdiSubWindow *>(workspace.addSubWindow(new QWidget));
qApp->processEvents();
workspace.show();
window->show();
QVERIFY(!window->isMaximized());
QVERIFY(!window->isShaded());
QRect originalGeometry = window->geometry();
// Calculate mouse position
QStyleOptionTitleBar options;
options.initFrom(window);
int height = window->style()->pixelMetric(QStyle::PM_TitleBarHeight, &options);
// ### Remove this after mac style has been fixed
if (window->style()->inherits("QMacStyle"))
height -= 4;
// has border
if (!window->style()->styleHint(QStyle::SH_TitleBar_NoBorder, &options, window))
height += window->isMinimized() ? 8 : 4;
QPoint mousePosition(window->width() / 2, height - 1);
sendMouseMove(window, mousePosition, Qt::NoButton);
// Without Qt::WindowShadeButtonHint flag set
sendMouseDoubleClick(window, mousePosition);
qApp->processEvents();
QVERIFY(window->isMaximized());
sendMouseDoubleClick(window, mousePosition);
qApp->processEvents();
QVERIFY(!window->isMaximized());
QCOMPARE(window->geometry(), originalGeometry);
// With Qt::WindowShadeButtonHint flag set
QSKIP("Until we have a QEvent::WindowFlagsChange event, this will skip", SkipAll);
window->setWindowFlags(window->windowFlags() | Qt::WindowShadeButtonHint);
QVERIFY(window->windowFlags() & Qt::WindowShadeButtonHint);
originalGeometry = window->geometry();
sendMouseDoubleClick(window, mousePosition);
qApp->processEvents();
QVERIFY(window->isShaded());
sendMouseDoubleClick(window, mousePosition);
qApp->processEvents();
QVERIFY(!window->isShaded());
QCOMPARE(window->geometry(), originalGeometry);
window->showMinimized();
QVERIFY(window->isMinimized());
sendMouseDoubleClick(window, mousePosition);
QVERIFY(!window->isMinimized());
QCOMPARE(window->geometry(), originalGeometry);
}
void tst_QMdiSubWindow::setSystemMenu()
{
QMdiSubWindow *subWindow = new QMdiSubWindow;
subWindow->resize(200, 50);
QPointer<QMenu>systemMenu = subWindow->systemMenu();
QVERIFY(systemMenu);
QCOMPARE(subWindow->actions(), systemMenu->actions());
QMainWindow mainWindow;
QMdiArea *mdiArea = new QMdiArea;
mdiArea->addSubWindow(subWindow);
mainWindow.setCentralWidget(mdiArea);
mainWindow.menuBar();
mainWindow.show();
QTest::qWaitForWindowShown(&mainWindow);
QTest::qWait(60);
QTRY_VERIFY(subWindow->isVisible());
QPoint globalPopupPos;
// Show system menu
QVERIFY(!qApp->activePopupWidget());
subWindow->showSystemMenu();
QTest::qWait(25);
QTRY_COMPARE(qApp->activePopupWidget(), qobject_cast<QWidget *>(systemMenu));
QTRY_COMPARE(systemMenu->mapToGlobal(QPoint(0, 0)),
(globalPopupPos = subWindow->mapToGlobal(subWindow->contentsRect().topLeft())) );
systemMenu->hide();
QVERIFY(!qApp->activePopupWidget());
QTest::ignoreMessage(QtWarningMsg, "QMdiSubWindow::setSystemMenu: system menu is already set");
subWindow->setSystemMenu(systemMenu);
subWindow->setSystemMenu(0);
QVERIFY(!systemMenu); // systemMenu is QPointer
systemMenu = new QMenu(subWindow);
systemMenu->addAction(QIcon(subWindow->style()->standardIcon(QStyle::SP_TitleBarCloseButton)),
QObject::tr("&Close"), subWindow, SLOT(close()));
subWindow->setSystemMenu(systemMenu);
QCOMPARE(subWindow->systemMenu(), qobject_cast<QMenu *>(systemMenu));
QCOMPARE(subWindow->systemMenu()->parentWidget(), static_cast<QWidget *>(subWindow));
QCOMPARE(subWindow->systemMenu()->actions().count(), 1);
// Show the new system menu
QVERIFY(!qApp->activePopupWidget());
subWindow->showSystemMenu();
QTest::qWait(25);
QTRY_COMPARE(qApp->activePopupWidget(), qobject_cast<QWidget *>(systemMenu));
QTRY_COMPARE(systemMenu->mapToGlobal(QPoint(0, 0)), globalPopupPos);
systemMenu->hide();
QVERIFY(!qApp->activePopupWidget());
#if !defined (Q_WS_MAC) && !defined (Q_OS_WINCE)
// System menu in menu bar.
subWindow->showMaximized();
QVERIFY(subWindow->isMaximized());
QWidget *menuLabel = subWindow->maximizedSystemMenuIconWidget();
QVERIFY(menuLabel);
subWindow->showSystemMenu();
QTest::qWait(25);
QTRY_COMPARE(qApp->activePopupWidget(), qobject_cast<QWidget *>(systemMenu));
QCOMPARE(systemMenu->mapToGlobal(QPoint(0, 0)),
(globalPopupPos = menuLabel->mapToGlobal(QPoint(0, menuLabel->y() + menuLabel->height()))));
systemMenu->hide();
QTRY_VERIFY(!qApp->activePopupWidget());
subWindow->showNormal();
#endif
// Reverse
qApp->setLayoutDirection(Qt::RightToLeft);
qApp->processEvents();
mainWindow.updateGeometry();
QTest::qWait(150);
subWindow->showSystemMenu();
QTest::qWait(250);
QTRY_COMPARE(qApp->activePopupWidget(), qobject_cast<QWidget *>(systemMenu));
// + QPoint(1, 0) because topRight() == QPoint(left() + width() -1, top())
globalPopupPos = subWindow->mapToGlobal(subWindow->contentsRect().topRight()) + QPoint(1, 0);
globalPopupPos -= QPoint(systemMenu->sizeHint().width(), 0);
QTRY_COMPARE(systemMenu->mapToGlobal(QPoint(0, 0)), globalPopupPos);
systemMenu->hide();
QVERIFY(!qApp->activePopupWidget());
#if !defined (Q_WS_MAC) && !defined (Q_OS_WINCE)
// System menu in menu bar in reverse mode.
subWindow->showMaximized();
QVERIFY(subWindow->isMaximized());
menuLabel = subWindow->maximizedSystemMenuIconWidget();
QVERIFY(menuLabel);
subWindow->showSystemMenu();
QTest::qWait(250);
QTRY_COMPARE(qApp->activePopupWidget(), qobject_cast<QWidget *>(systemMenu));
globalPopupPos = menuLabel->mapToGlobal(QPoint(menuLabel->width(), menuLabel->y() + menuLabel->height()));
globalPopupPos -= QPoint(systemMenu->sizeHint().width(), 0);
QTRY_COMPARE(systemMenu->mapToGlobal(QPoint(0, 0)), globalPopupPos);
#endif
delete systemMenu;
QVERIFY(!qApp->activePopupWidget());
QVERIFY(!subWindow->systemMenu());
// Restore layout direction.
qApp->setLayoutDirection(Qt::LeftToRight);
}
void tst_QMdiSubWindow::restoreFocus()
{
// Create complex layout.
QGroupBox *box = new QGroupBox(tr("GroupBox"));
box->setCheckable(true);
QGroupBox *box1 = new QGroupBox(tr("&TopLeft"));
box1->setLayout(new QHBoxLayout);
box1->layout()->addWidget(new QTextEdit);
QGroupBox *box2 = new QGroupBox(tr("&TopRight"));
box2->setLayout(new QHBoxLayout);
box2->layout()->addWidget(new QTextEdit);
QGroupBox *box3 = new QGroupBox(tr("&BottomLeft"));
box3->setLayout(new QHBoxLayout);
box3->layout()->addWidget(new QTextEdit);
QGroupBox *box4 = new QGroupBox(tr("&BottomRight"));
box4->setLayout(new QHBoxLayout);
QMdiArea *nestedWorkspace = new QMdiArea;
for (int i = 0; i < 4; ++i)
nestedWorkspace->addSubWindow(new QTextEdit)->show();
qApp->processEvents();
nestedWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
nestedWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
box4->layout()->addWidget(nestedWorkspace);
QGridLayout *layout = new QGridLayout;
layout->addWidget(box1, 0, 0);
layout->addWidget(box2, 0, 1);
layout->addWidget(box3, 1, 0);
layout->addWidget(box4, 1, 1);
box->setLayout(layout);
// Add complex widget to workspace.
QMdiArea topArea;
QMdiSubWindow *complexWindow = topArea.addSubWindow(box);
topArea.show();
box->show();
qApp->setActiveWindow(&topArea);
QMdiSubWindow *expectedFocusWindow = nestedWorkspace->subWindowList().last();
QVERIFY(expectedFocusWindow);
QVERIFY(expectedFocusWindow->widget());
QCOMPARE(qApp->focusWidget(), expectedFocusWindow->widget());
// Normal -> minimized
expectedFocusWindow->showMinimized();
qApp->processEvents();
QVERIFY(expectedFocusWindow->isMinimized());
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(expectedFocusWindow));
// Minimized -> normal
expectedFocusWindow->showNormal();
qApp->processEvents();
QVERIFY(!expectedFocusWindow->isMinimized());
QCOMPARE(qApp->focusWidget(), expectedFocusWindow->widget());
// Normal -> maximized
expectedFocusWindow->showMaximized();
qApp->processEvents();
QVERIFY(expectedFocusWindow->isMaximized());
QCOMPARE(qApp->focusWidget(), expectedFocusWindow->widget());
// Maximized -> normal
expectedFocusWindow->showNormal();
qApp->processEvents();
QVERIFY(!expectedFocusWindow->isMaximized());
QCOMPARE(qApp->focusWidget(), expectedFocusWindow->widget());
// Minimized -> maximized
expectedFocusWindow->showMinimized();
qApp->processEvents();
QVERIFY(expectedFocusWindow->isMinimized());
expectedFocusWindow->showMaximized();
qApp->processEvents();
QVERIFY(expectedFocusWindow->isMaximized());
QCOMPARE(qApp->focusWidget(), expectedFocusWindow->widget());
// Maximized -> minimized
expectedFocusWindow->showNormal();
qApp->processEvents();
QVERIFY(!expectedFocusWindow->isMaximized());
expectedFocusWindow->showMaximized();
qApp->processEvents();
QVERIFY(expectedFocusWindow->isMaximized());
expectedFocusWindow->showMinimized();
qApp->processEvents();
QVERIFY(expectedFocusWindow->isMinimized());
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(expectedFocusWindow));
complexWindow->showMinimized();
qApp->processEvents();
QVERIFY(complexWindow->isMinimized());
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(complexWindow));
complexWindow->showNormal();
qApp->processEvents();
QVERIFY(!complexWindow->isMinimized());
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(expectedFocusWindow));
}
void tst_QMdiSubWindow::changeFocusWithTab()
{
QWidget *widget = new QWidget;
widget->setLayout(new QVBoxLayout);
QLineEdit *firstLineEdit = new QLineEdit;
widget->layout()->addWidget(firstLineEdit);
QLineEdit *secondLineEdit = new QLineEdit;
widget->layout()->addWidget(secondLineEdit);
QLineEdit *thirdLineEdit = new QLineEdit;
widget->layout()->addWidget(thirdLineEdit);
QMdiArea mdiArea;
mdiArea.addSubWindow(widget);
mdiArea.show();
QCOMPARE(mdiArea.subWindowList().count(), 1);
qApp->setActiveWindow(&mdiArea);
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(firstLineEdit));
// Next
QTest::keyPress(widget, Qt::Key_Tab);
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(secondLineEdit));
// Next
QTest::keyPress(widget, Qt::Key_Tab);
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(thirdLineEdit));
// Previous
QTest::keyPress(widget, Qt::Key_Backtab);
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(secondLineEdit));
// Previous
QTest::keyPress(widget, Qt::Key_Backtab);
QCOMPARE(qApp->focusWidget(), static_cast<QWidget *>(firstLineEdit));
QMdiSubWindow *window = mdiArea.addSubWindow(new QPushButton);
window->show();
QCOMPARE(mdiArea.activeSubWindow(), window);
// Check that we don't give away focus to another window by
// just hitting tab if the child widget does not accept
// focus (which is the case for a QPushButton).
QTest::keyPress(window, Qt::Key_Tab);
QCOMPARE(mdiArea.activeSubWindow(), window);
QCOMPARE(qApp->focusWidget(), tabAllWidgets() ? window->widget() : window);
QTest::keyPress(window, Qt::Key_Tab);
QCOMPARE(mdiArea.activeSubWindow(), window);
QCOMPARE(qApp->focusWidget(), tabAllWidgets() ? window->widget() : window);
}
class MyTextEdit : public QTextEdit
{
public:
MyTextEdit(QWidget *parent = 0) : QTextEdit(parent), acceptClose(false) {}
void setAcceptClose(bool enable = true) { acceptClose = enable; }
protected:
void closeEvent(QCloseEvent *closeEvent)
{
if (!acceptClose)
closeEvent->ignore();
}
private:
bool acceptClose;
};
void tst_QMdiSubWindow::closeEvent()
{
QMdiArea mdiArea;
mdiArea.show();
MyTextEdit *textEdit = new MyTextEdit;
textEdit->setAcceptClose(false);
QMdiSubWindow *window = mdiArea.addSubWindow(textEdit);
EventSpy closeSpy(window->widget(), QEvent::Close);
window->show();
QCOMPARE(closeSpy.count(), 0);
QVERIFY(window->isVisible());
QVERIFY(textEdit->isVisible());
QVERIFY(!window->close());
QCOMPARE(closeSpy.count(), 1);
QVERIFY(window->isVisible());
QVERIFY(textEdit->isVisible());
QVERIFY(!textEdit->close());
QCOMPARE(closeSpy.count(), 2);
QVERIFY(window->isVisible());
QVERIFY(textEdit->isVisible());
textEdit->setAcceptClose(true);
QVERIFY(window->close());
QCOMPARE(closeSpy.count(), 3);
QCOMPARE(mdiArea.subWindowList().count(), 0);
}
// There exists more tests in QMdiArea which covers window title support
// related to QMainWindow. This test is specific for QMdiSubWindow and its
// widget.
void tst_QMdiSubWindow::setWindowTitle()
{
QString expectedWindowTitle = QLatin1String("This is teh shit[*]");
QTextEdit *textEdit = new QTextEdit;
textEdit->setWindowTitle(expectedWindowTitle);
QCOMPARE(textEdit->windowTitle(), expectedWindowTitle);
textEdit->setWindowModified(true);
QCOMPARE(textEdit->isWindowModified(), true);
QMdiArea mdiArea;
QMdiSubWindow *window = new QMdiSubWindow;
mdiArea.addSubWindow(window);
QCOMPARE(window->windowTitle(), QString());
QVERIFY(!window->isWindowModified());
window->setWidget(textEdit);
QVERIFY(window->isWindowModified());
QCOMPARE(textEdit->windowTitle(), expectedWindowTitle);
QCOMPARE(window->windowTitle(), window->widget()->windowTitle());
textEdit->setWindowModified(false);
QVERIFY(!textEdit->isWindowModified());
QVERIFY(!window->isWindowModified());
// This will return the title including the astrix, but the
// actual window title does not contain the astrix. This behavior
// seems a bit odd, but is equal to e.g. QTextEdit (and probably all
// other widgets which are not real top-level widgets).
QCOMPARE(window->windowTitle(), expectedWindowTitle);
textEdit->setWindowModified(true);;
expectedWindowTitle = QLatin1String("Override child title");
window->setWindowTitle(expectedWindowTitle);
QVERIFY(window->isWindowModified());
QCOMPARE(window->windowTitle(), expectedWindowTitle);
textEdit->setWindowTitle(QLatin1String("My parent overrides me"));
QCOMPARE(window->windowTitle(), expectedWindowTitle);
textEdit->setWindowModified(false);
QVERIFY(window->isWindowModified());
QCOMPARE(window->windowTitle(), expectedWindowTitle);
window->setWindowModified(false);
QVERIFY(!window->isWindowModified());
window->setWindowTitle(QString());
QCOMPARE(window->windowTitle(), QString());
expectedWindowTitle = QLatin1String("My parent doesn't have any title so now I can set one[*]");
textEdit->setWindowTitle(expectedWindowTitle);
QCOMPARE(window->windowTitle(), expectedWindowTitle);
textEdit->setWindowModified(true);
QVERIFY(window->isWindowModified());
window->setWidget(0);
QCOMPARE(window->windowTitle(), QString());
QVERIFY(!window->isWindowModified());
delete textEdit;
}
void tst_QMdiSubWindow::resizeEvents_data()
{
QTest::addColumn<Qt::WindowState>("windowState");
QTest::addColumn<int>("expectedWindowResizeEvents");
QTest::addColumn<int>("expectedWidgetResizeEvents");
QTest::addColumn<bool>("isShadeMode");
QTest::newRow("minimized") << Qt::WindowMinimized << 1 << 0 << false;
QTest::newRow("maximized") << Qt::WindowMaximized << 1 << 1 << false;
QTest::newRow("shaded") << Qt::WindowMinimized << 1 << 0 << true;
}
void tst_QMdiSubWindow::resizeEvents()
{
QFETCH(Qt::WindowState, windowState);
QFETCH(int, expectedWindowResizeEvents);
QFETCH(int, expectedWidgetResizeEvents);
QFETCH(bool, isShadeMode);
QMainWindow mainWindow;
QMdiArea *mdiArea = new QMdiArea;
mainWindow.setCentralWidget(mdiArea);
mainWindow.show();
#if defined(Q_WS_X11)
qt_x11_wait_for_window_manager(&mainWindow);
#endif
QMdiSubWindow *window = mdiArea->addSubWindow(new QTextEdit);
window->show();
EventSpy windowResizeEventSpy(window, QEvent::Resize);
QCOMPARE(windowResizeEventSpy.count(), 0);
EventSpy widgetResizeEventSpy(window->widget(), QEvent::Resize);
QCOMPARE(widgetResizeEventSpy.count(), 0);
// Set the window state.
if (!isShadeMode)
window->setWindowState(windowState);
else
window->showShaded();
// Check that the window state is correct.
QCOMPARE(window->windowState(), windowState | Qt::WindowActive);
QCOMPARE(window->widget()->windowState(), windowState);
// Make sure we got as many resize events as expected.
QCOMPARE(windowResizeEventSpy.count(), expectedWindowResizeEvents);
QCOMPARE(widgetResizeEventSpy.count(), expectedWidgetResizeEvents);
windowResizeEventSpy.clear();
widgetResizeEventSpy.clear();
// Normalize.
window->showNormal();
// Check that the window state is correct.
QCOMPARE(window->windowState(), Qt::WindowNoState | Qt::WindowActive);
QCOMPARE(window->widget()->windowState(), Qt::WindowNoState);
// Make sure we got as many resize events as expected.
QCOMPARE(windowResizeEventSpy.count(), expectedWindowResizeEvents);
QCOMPARE(widgetResizeEventSpy.count(), expectedWidgetResizeEvents);
}
#if defined(Q_WS_MAC)
void tst_QMdiSubWindow::defaultSizeGrip()
{
if (!qApp->style()->inherits("QMacStyle"))
return;
QMdiArea mdiArea;
mdiArea.show();
// QSizeGrip on windows with decoration.
QMdiSubWindow *windowWithDecoration = mdiArea.addSubWindow(new QWidget);
windowWithDecoration->show();
QVERIFY(qFindChild<QSizeGrip *>(windowWithDecoration));
// ...but not on windows without decoration (Qt::FramelessWindowHint).
QMdiSubWindow *windowWithoutDecoration = mdiArea.addSubWindow(new QWidget, Qt::FramelessWindowHint);
windowWithoutDecoration->show();
QVERIFY(!qFindChild<QSizeGrip *>(windowWithoutDecoration));
}
#endif
void tst_QMdiSubWindow::hideAndShow()
{
// Create a QTabWidget with two tabs; QMdiArea and QTextEdit.
QTabWidget *tabWidget = new QTabWidget;
QMdiArea *mdiArea = new QMdiArea;
tabWidget->addTab(mdiArea, QLatin1String("QMdiArea"));
tabWidget->addTab(new QTextEdit, QLatin1String("Dummy"));
// Set the tab widget as the central widget in QMainWindow.
QMainWindow mainWindow;
mainWindow.setGeometry(0, 0, 640, 480);
QMenuBar *menuBar = mainWindow.menuBar();
mainWindow.setCentralWidget(tabWidget);
mainWindow.show();
#ifdef Q_WS_X11
qt_x11_wait_for_window_manager(&mainWindow);
#endif
QVERIFY(!menuBar->cornerWidget(Qt::TopRightCorner));
QMdiSubWindow *subWindow = mdiArea->addSubWindow(new QTextEdit);
subWindow->showMaximized();
#if !defined (Q_WS_MAC) && !defined (Q_OS_WINCE)
QVERIFY(menuBar->cornerWidget(Qt::TopRightCorner));
QCOMPARE(menuBar->cornerWidget(Qt::TopRightCorner), subWindow->maximizedButtonsWidget());
#endif
// Hide QMdiArea.
tabWidget->setCurrentIndex(1);
QVERIFY(!menuBar->cornerWidget(Qt::TopRightCorner));
QVERIFY(!subWindow->maximizedButtonsWidget());
QVERIFY(!subWindow->maximizedSystemMenuIconWidget());
// Show QMdiArea.
tabWidget->setCurrentIndex(0);
#if !defined (Q_WS_MAC) && !defined (Q_OS_WINCE)
QVERIFY(menuBar->cornerWidget(Qt::TopRightCorner));
QVERIFY(subWindow->maximizedButtonsWidget());
QVERIFY(subWindow->maximizedSystemMenuIconWidget());
QCOMPARE(menuBar->cornerWidget(Qt::TopRightCorner), subWindow->maximizedButtonsWidget());
#endif
// Hide QMdiArea.
tabWidget->setCurrentIndex(1);
// Add few more windows.
for (int i = 0; i < 5; ++i)
mdiArea->addSubWindow(new QTextEdit);
// Show QMdiArea.
tabWidget->setCurrentIndex(0);
qApp->processEvents();
subWindow = mdiArea->subWindowList().back();
QVERIFY(subWindow);
QCOMPARE(mdiArea->activeSubWindow(), subWindow);
#if !defined (Q_WS_MAC) && !defined (Q_OS_WINCE)
QVERIFY(menuBar->cornerWidget(Qt::TopRightCorner));
QVERIFY(subWindow->maximizedButtonsWidget());
QVERIFY(subWindow->maximizedSystemMenuIconWidget());
QCOMPARE(menuBar->cornerWidget(Qt::TopRightCorner), subWindow->maximizedButtonsWidget());
#endif
subWindow->showNormal();
QVERIFY(!menuBar->cornerWidget(Qt::TopRightCorner));
// Check that newly added windows got right sizes.
foreach (QMdiSubWindow *window, mdiArea->subWindowList())
QCOMPARE(window->size(), window->sizeHint());
subWindow->showMaximized();
#ifndef Q_WS_MAC
QCOMPARE(menuBar->cornerWidget(Qt::TopRightCorner), subWindow->maximizedButtonsWidget());
#endif
subWindow->hide();
QVERIFY(!subWindow->maximizedButtonsWidget());
QVERIFY(!subWindow->maximizedSystemMenuIconWidget());
QVERIFY(!menuBar->cornerWidget(Qt::TopRightCorner));
subWindow->show();
#if !defined (Q_WS_MAC) && !defined (Q_OS_WINCE)
QVERIFY(subWindow->maximizedButtonsWidget());
QVERIFY(subWindow->maximizedSystemMenuIconWidget());
QCOMPARE(menuBar->cornerWidget(Qt::TopRightCorner), subWindow->maximizedButtonsWidget());
#endif
// Hide QMainWindow.
mainWindow.hide();
QVERIFY(!subWindow->maximizedButtonsWidget());
QVERIFY(!subWindow->maximizedSystemMenuIconWidget());
QVERIFY(!menuBar->cornerWidget(Qt::TopRightCorner));
// Show QMainWindow.
mainWindow.show();
#if !defined (Q_WS_MAC) && !defined (Q_OS_WINCE)
QVERIFY(subWindow->maximizedButtonsWidget());
QVERIFY(subWindow->maximizedSystemMenuIconWidget());
QCOMPARE(menuBar->cornerWidget(Qt::TopRightCorner), subWindow->maximizedButtonsWidget());
#endif
}
void tst_QMdiSubWindow::keepWindowMaximizedState()
{
QMdiArea mdiArea;
QMdiSubWindow *subWindow = mdiArea.addSubWindow(new QTextEdit);
mdiArea.show();
#ifdef Q_WS_X11
qt_x11_wait_for_window_manager(&mdiArea);
#endif
subWindow->showMaximized();
QVERIFY(subWindow->isMaximized());
// move
const QPoint newPosition = subWindow->pos() + QPoint(10, 10);
subWindow->move(newPosition);
QCOMPARE(subWindow->pos(), newPosition);
QVERIFY(subWindow->isMaximized());
// resize
const QSize newSize = subWindow->size() - QSize(10, 10);
subWindow->resize(newSize);
QCOMPARE(subWindow->size(), newSize);
QVERIFY(subWindow->isMaximized());
// setGeometry
const QRect newGeometry = QRect(newPosition - QPoint(10, 10), newSize + QSize(10, 10));
subWindow->setGeometry(newGeometry);
QCOMPARE(subWindow->geometry(), newGeometry);
QVERIFY(subWindow->isMaximized());
subWindow->showNormal();
// Verify that we don't force Qt::WindowMaximized.
QVERIFY(!subWindow->isMaximized());
subWindow->setGeometry(QRect(newPosition, newSize));
QCOMPARE(subWindow->geometry(), QRect(newPosition, newSize));
QVERIFY(!subWindow->isMaximized());
}
void tst_QMdiSubWindow::explicitlyHiddenWidget()
{
QMdiArea mdiArea;
QTextEdit *textEdit = new QTextEdit;
textEdit->hide();
QMdiSubWindow *subWindow = mdiArea.addSubWindow(textEdit);
mdiArea.show();
#ifdef Q_WS_X11
qt_x11_wait_for_window_manager(&mdiArea);
#endif
QVERIFY(subWindow->isVisible());
QVERIFY(!textEdit->isVisible());
textEdit->show();
QVERIFY(textEdit->isVisible());
// normal -> minimized
subWindow->showMinimized();
QVERIFY(subWindow->isVisible());
QVERIFY(!textEdit->isVisible());
// minimized -> normal
subWindow->showNormal();
QVERIFY(subWindow->isVisible());
QVERIFY(textEdit->isVisible());
// minimized -> maximized
subWindow->showMinimized();
subWindow->showMaximized();
QVERIFY(subWindow->isVisible());
QVERIFY(textEdit->isVisible());
textEdit->hide();
// maximized -> normal
subWindow->showNormal();
QVERIFY(subWindow->isVisible());
QVERIFY(!textEdit->isVisible());
textEdit->show();
subWindow->showMinimized();
subWindow->setWidget(0);
delete textEdit;
textEdit = new QTextEdit;
textEdit->hide();
subWindow->setWidget(textEdit);
subWindow->showNormal();
QVERIFY(subWindow->isVisible());
QVERIFY(!textEdit->isVisible());
}
void tst_QMdiSubWindow::resizeTimer()
{
QMdiArea mdiArea;
QMdiSubWindow *subWindow = mdiArea.addSubWindow(new QWidget);
mdiArea.show();
QTest::qWaitForWindowShown(&mdiArea);
QTest::qWait(300);
EventSpy timerEventSpy(subWindow, QEvent::Timer);
QCOMPARE(timerEventSpy.count(), 0);
for (int i = 0; i < 20; ++i) {
subWindow->resize(subWindow->size() + QSize(2, 2));
qApp->processEvents();
}
QTest::qWait(500); // Wait for timer events to occur.
QTRY_VERIFY(timerEventSpy.count() > 0);
}
void tst_QMdiSubWindow::fixedMinMaxSize()
{
QMdiArea mdiArea;
mdiArea.setGeometry(0, 0, 640, 480);
mdiArea.show();
#ifdef Q_WS_X11
qt_x11_wait_for_window_manager(&mdiArea);
#endif
const QSize minimumSize = QSize(250, 150);
const QSize maximumSize = QSize(300, 200);
// Add the sub window to QMdiArea and set min/max size.
QMdiSubWindow *subWindow = new QMdiSubWindow;
subWindow->setMinimumSize(minimumSize);
QCOMPARE(subWindow->minimumSize(), minimumSize);
subWindow->setMaximumSize(maximumSize);
QCOMPARE(subWindow->maximumSize(), maximumSize);
mdiArea.addSubWindow(subWindow);
subWindow->show();
QCOMPARE(subWindow->size(), minimumSize);
// Calculate the size of a minimized sub window.
QStyleOptionTitleBar options;
options.initFrom(subWindow);
int minimizedHeight = subWindow->style()->pixelMetric(QStyle::PM_TitleBarHeight, &options);
#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
// ### Remove this after mac style has been fixed
if (qobject_cast<QMacStyle *>(subWindow->style()))
minimizedHeight -= 4;
#endif
if (!subWindow->style()->styleHint(QStyle::SH_TitleBar_NoBorder, &options, subWindow))
minimizedHeight += 8;
int minimizedWidth = subWindow->style()->pixelMetric(QStyle::PM_MDIMinimizedWidth, &options);
const QSize minimizedSize = QSize(minimizedWidth, minimizedHeight);
// Even though the sub window has a minimum size set, it should be possible
// to minimize the window.
subWindow->showMinimized();
QVERIFY(subWindow->isMinimized());
QCOMPARE(subWindow->size(), minimizedSize);
QCOMPARE(subWindow->minimumSize(), minimizedSize);
// Restore minimum size.
subWindow->showNormal();
QVERIFY(!subWindow->isMinimized());
QCOMPARE(subWindow->size(), minimumSize);
QCOMPARE(subWindow->minimumSize(), minimumSize);
// Well, the logic here is of course broken (calling showMaximized on a window with
// maximum size set), but we should handle it :)
subWindow->showMaximized();
QVERIFY(subWindow->isMaximized());
QCOMPARE(subWindow->size(), maximumSize);
subWindow->showNormal();
QVERIFY(!subWindow->isMaximized());
QCOMPARE(subWindow->size(), minimumSize);
}
#if !defined( Q_WS_MAC) && !defined( Q_OS_WINCE)
void tst_QMdiSubWindow::replaceMenuBarWhileMaximized()
{
QMainWindow mainWindow;
QMdiArea *mdiArea = new QMdiArea;
QMdiSubWindow *subWindow = mdiArea->addSubWindow(new QTextEdit);
subWindow->showMaximized();
mainWindow.setCentralWidget(mdiArea);
QMenuBar *menuBar = mainWindow.menuBar();
mainWindow.show();
#ifdef Q_WS_X11
qt_x11_wait_for_window_manager(&mainWindow);
#endif
qApp->processEvents();
QVERIFY(subWindow->maximizedButtonsWidget());
QVERIFY(subWindow->maximizedSystemMenuIconWidget());
QCOMPARE(menuBar->cornerWidget(Qt::TopLeftCorner), subWindow->maximizedSystemMenuIconWidget());
QCOMPARE(menuBar->cornerWidget(Qt::TopRightCorner), subWindow->maximizedButtonsWidget());
// Replace.
mainWindow.setMenuBar(new QMenuBar);
menuBar = mainWindow.menuBar();
qApp->processEvents();
QVERIFY(subWindow->maximizedButtonsWidget());
QVERIFY(subWindow->maximizedSystemMenuIconWidget());
QCOMPARE(menuBar->cornerWidget(Qt::TopLeftCorner), subWindow->maximizedSystemMenuIconWidget());
QCOMPARE(menuBar->cornerWidget(Qt::TopRightCorner), subWindow->maximizedButtonsWidget());
subWindow->showNormal();
QVERIFY(!subWindow->maximizedButtonsWidget());
QVERIFY(!subWindow->maximizedSystemMenuIconWidget());
QVERIFY(!menuBar->cornerWidget(Qt::TopLeftCorner));
QVERIFY(!menuBar->cornerWidget(Qt::TopRightCorner));
// Delete and replace.
subWindow->showMaximized();
delete menuBar;
mainWindow.setMenuBar(new QMenuBar);
qApp->processEvents();
QVERIFY(!subWindow->maximizedButtonsWidget());
QVERIFY(!subWindow->maximizedSystemMenuIconWidget());
subWindow->showNormal();
QVERIFY(!subWindow->maximizedButtonsWidget());
QVERIFY(!subWindow->maximizedSystemMenuIconWidget());
// Delete.
subWindow->showMaximized();
mainWindow.setMenuBar(0);
qApp->processEvents();
QVERIFY(!mainWindow.menuWidget());
QVERIFY(!subWindow->maximizedButtonsWidget());
QVERIFY(!subWindow->maximizedSystemMenuIconWidget());
subWindow->showNormal();
QVERIFY(!subWindow->maximizedButtonsWidget());
QVERIFY(!subWindow->maximizedSystemMenuIconWidget());
}
void tst_QMdiSubWindow::closeOnDoubleClick()
{
QMdiArea mdiArea;
QPointer<QMdiSubWindow> subWindow = mdiArea.addSubWindow(new QWidget);
mdiArea.show();
#ifdef Q_WS_X11
qt_x11_wait_for_window_manager(&mdiArea);
#endif
subWindow->showSystemMenu();
QTest::qWait(200);
QPointer<QMenu> systemMenu = subWindow->systemMenu();
QVERIFY(systemMenu);
QVERIFY(systemMenu->isVisible());
sendMouseDoubleClick(systemMenu, QPoint(10, 10));
if (qApp->activePopupWidget() == static_cast<QWidget *>(systemMenu))
systemMenu->hide();
qApp->processEvents();
QVERIFY(!subWindow || !subWindow->isVisible());
QVERIFY(!systemMenu || !systemMenu->isVisible());
}
#endif
void tst_QMdiSubWindow::setFont()
{
QMdiArea mdiArea;
QMdiSubWindow *subWindow = mdiArea.addSubWindow(new QPushButton(QLatin1String("test")));
subWindow->resize(300, 100);
subWindow->setWindowTitle(QLatin1String("Window title"));
mdiArea.show();
#ifdef Q_WS_X11
qt_x11_wait_for_window_manager(&mdiArea);
#endif
const QFont originalFont = QApplication::font("QWorkspaceTitleBar");
QStyleOptionTitleBar opt;
opt.initFrom(subWindow);
const int titleBarHeight = subWindow->style()->pixelMetric(QStyle::PM_TitleBarHeight, &opt);
const QRect titleBarRect = QRect(0, 0, subWindow->width(), titleBarHeight);
const QImage originalTitleBar = QPixmap::grabWidget(subWindow, titleBarRect).toImage();
QFont newFont(QLatin1String("Helvetica"), 16);
newFont.setBold(true);
subWindow->setFont(newFont);
qApp->processEvents();
const QFont &swFont = subWindow->font();
QCOMPARE(swFont.family(), newFont.family());
QCOMPARE(swFont.pointSize(), newFont.pointSize());
QCOMPARE(swFont.weight(), newFont.weight());
QImage newTitleBar = QPixmap::grabWidget(subWindow, titleBarRect).toImage();
QVERIFY(newTitleBar != originalTitleBar);
subWindow->setFont(originalFont);
qApp->processEvents();
QCOMPARE(subWindow->font(), originalFont);
newTitleBar = QPixmap::grabWidget(subWindow, titleBarRect).toImage();
QCOMPARE(newTitleBar, originalTitleBar);
}
void tst_QMdiSubWindow::task_188849()
{
QMainWindow mainWindow;
// Sets a regular QWidget (and NOT a QMenuBar) as the menu bar.
mainWindow.setMenuWidget(new QWidget);
QMdiArea *mdiArea = new QMdiArea;
QMdiSubWindow *subWindow = mdiArea->addSubWindow(new QWidget);
mainWindow.setCentralWidget(mdiArea);
mainWindow.show();
#if defined(Q_WS_X11)
qt_x11_wait_for_window_manager(&mainWindow);
#endif
// QMdiSubWindow will now try to show its buttons in the menu bar.
// Without checking that the menu bar is actually a QMenuBar
// and not a regular QWidget, this will crash.
subWindow->showMaximized();
}
void tst_QMdiSubWindow::mdiArea()
{
QMdiArea mdiArea;
QMdiSubWindow *subWindow = mdiArea.addSubWindow(new QWidget);
QCOMPARE(subWindow->mdiArea(), &mdiArea);
subWindow->setParent(0);
QVERIFY(!subWindow->mdiArea());
// Child of the area's corner widget.
mdiArea.setCornerWidget(new QWidget);
subWindow->setParent(mdiArea.cornerWidget());
QVERIFY(!subWindow->mdiArea());
// Nested mdi area.
QMdiArea *nestedArea = new QMdiArea;
mdiArea.addSubWindow(nestedArea);
nestedArea->addSubWindow(subWindow);
QCOMPARE(subWindow->mdiArea(), nestedArea);
nestedArea->setViewport(new QWidget);
QCOMPARE(subWindow->mdiArea(), nestedArea);
}
void tst_QMdiSubWindow::task_182852()
{
#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE)
QMdiArea *workspace = new QMdiArea;
QMainWindow mainWindow;
mainWindow.setCentralWidget(workspace);
mainWindow.show();
mainWindow.menuBar()->setVisible(true);
qApp->setActiveWindow(&mainWindow);
QString originalWindowTitle = QString::fromLatin1("MainWindow - [foo]");
mainWindow.setWindowTitle(originalWindowTitle);
QMdiSubWindow *window = new QMdiSubWindow;
QMdiArea *nestedWorkspace = new QMdiArea; // :-)
window->setWidget(nestedWorkspace);
window->widget()->setWindowTitle(QString::fromLatin1("Window"));
workspace->addSubWindow(window);
window->showMaximized();
qApp->processEvents();
QVERIFY(window->isMaximized());
QCOMPARE(mainWindow.windowTitle(), QString::fromLatin1("%1 - [%2]")
.arg(originalWindowTitle, window->widget()->windowTitle()));
window->showNormal();
QCOMPARE(mainWindow.windowTitle(), originalWindowTitle);
window->widget()->setWindowTitle(QString::fromLatin1("foo"));
window->showMaximized();
QCOMPARE(mainWindow.windowTitle(), originalWindowTitle);
window->showNormal();
QCOMPARE(mainWindow.windowTitle(), originalWindowTitle);
window->widget()->setWindowTitle(QString::fromLatin1("bar"));
window->showMaximized();
QCOMPARE(mainWindow.windowTitle(), QString::fromLatin1("%1 - [%2]")
.arg(originalWindowTitle, window->widget()->windowTitle()));
#endif
}
void tst_QMdiSubWindow::task_233197()
{
QMainWindow *mainWindow = new QMainWindow;
mainWindow->setAttribute(Qt::WA_DeleteOnClose);
mainWindow->resize(500, 200);
mainWindow->show();
QMdiArea *mdiArea = new QMdiArea(mainWindow);
mdiArea->setOption(QMdiArea::DontMaximizeSubWindowOnActivation, true);
mainWindow->setCentralWidget(mdiArea);
QMdiSubWindow *subWindow1 = new QMdiSubWindow();
mdiArea->addSubWindow(subWindow1);
subWindow1->showMaximized();
QMdiSubWindow *subWindow2 = new QMdiSubWindow();
mdiArea->addSubWindow(subWindow2);
subWindow2->showMaximized();
QMdiSubWindow *subWindow3 = new QMdiSubWindow();
mdiArea->addSubWindow(subWindow3);
subWindow3->showMaximized();
QMenuBar *menuBar = mainWindow->menuBar(); // force creation of a menubar
Q_UNUSED(menuBar);
QPushButton *focus1 = new QPushButton(QLatin1String("Focus 1"), mainWindow);
QObject::connect(focus1, SIGNAL(clicked()), subWindow1, SLOT(setFocus()));
focus1->move(5, 30);
focus1->show();
QPushButton *focus2 = new QPushButton(QLatin1String("Focus 2"), mainWindow);
QObject::connect(focus2, SIGNAL(clicked()), subWindow2, SLOT(setFocus()));
focus2->move(5, 60);
focus2->show();
QPushButton *close = new QPushButton(QLatin1String("Close"), mainWindow);
QObject::connect(close, SIGNAL(clicked()), mainWindow, SLOT(close()));
close->move(5, 90);
close->show();
QTest::qWait(200);
sendMousePress(focus2, QPoint());
sendMouseRelease(focus2, QPoint());
sendMousePress(focus1, QPoint());
sendMouseRelease(focus1, QPoint());
sendMousePress(focus2, QPoint());
sendMouseRelease(focus2, QPoint());
sendMousePress(close, QPoint());
sendMouseRelease(close, QPoint());
QTest::qWait(200);
}
void tst_QMdiSubWindow::task_226929()
{
QMdiArea mdiArea;
mdiArea.show();
#ifdef Q_WS_X11
qt_x11_wait_for_window_manager(&mdiArea);
#endif
QMdiSubWindow *sub1 = mdiArea.addSubWindow(new QTextEdit);
sub1->showMinimized();
QMdiSubWindow *sub2 = mdiArea.addSubWindow(new QTextEdit);
sub2->showMaximized();
QTest::qWait(100);
// Do not assert.
// This window will now be activated and automatically maximized
// (if not QMdiArea::DontMaximizeSubWindowOnActionvation is set).
sub1->showNormal();
QVERIFY(sub1->isMaximized());
}
QTEST_MAIN(tst_QMdiSubWindow)
#include "tst_qmdisubwindow.moc"