c5ea7fd39a
Basically breakage by <windows.h> being included from the OpenGL parts of <QtGui/QtGui> included from <QtTest/QtTest>. Change-Id: Id285fb89c64bf77e2408faac5688acd085579351 Reviewed-on: http://codereview.qt.nokia.com/3952 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
2034 lines
70 KiB
C++
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$
|
|
** GNU Lesser General Public License Usage
|
|
** 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.
|
|
**
|
|
** GNU General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU General
|
|
** Public License version 3.0 as published by the Free Software Foundation
|
|
** and appearing in the file LICENSE.GPL included in the packaging of this
|
|
** file. Please review the following information to ensure the GNU General
|
|
** Public License version 3.0 requirements will be met:
|
|
** http://www.gnu.org/copyleft/gpl.html.
|
|
**
|
|
** Other Usage
|
|
** Alternatively, this file may be used in accordance with the terms and
|
|
** conditions contained in a signed written agreement between you and Nokia.
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
** $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_OS_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"
|
|
|