38be0d1383
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
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$
|
|
** 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"
|
|
|