From 91b178316dcb8a3fd845fc6075aeb7a9e7b5004b Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Fri, 25 Feb 2022 20:27:25 +0200 Subject: [PATCH] add QDockWidget test Signed-off-by: Ivailo Monev --- tests/auto/qdockwidget/CMakeLists.txt | 3 + tests/auto/qdockwidget/tst_qdockwidget.cpp | 910 +++++++++++++++++++++ 2 files changed, 913 insertions(+) create mode 100644 tests/auto/qdockwidget/CMakeLists.txt create mode 100644 tests/auto/qdockwidget/tst_qdockwidget.cpp diff --git a/tests/auto/qdockwidget/CMakeLists.txt b/tests/auto/qdockwidget/CMakeLists.txt new file mode 100644 index 000000000..28d71c38d --- /dev/null +++ b/tests/auto/qdockwidget/CMakeLists.txt @@ -0,0 +1,3 @@ +katie_gui_test(tst_qdockwidget + ${CMAKE_CURRENT_SOURCE_DIR}/tst_qdockwidget.cpp +) diff --git a/tests/auto/qdockwidget/tst_qdockwidget.cpp b/tests/auto/qdockwidget/tst_qdockwidget.cpp new file mode 100644 index 000000000..8e7f10ce2 --- /dev/null +++ b/tests/auto/qdockwidget/tst_qdockwidget.cpp @@ -0,0 +1,910 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 Ivailo Monev +** +** This file is part of the test suite of the Katie 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. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + + +#include +#include +#include +#include +#include +#include +#include +#include "qdockwidget_p.h" + +bool hasFeature(QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature) +{ + return (dockwidget->features() & feature) == feature; +} + +void setFeature(QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature, bool on = true) +{ + const QDockWidget::DockWidgetFeatures features = dockwidget->features(); + dockwidget->setFeatures(on ? features | feature : features & ~feature); +} + +// TESTED_FILES= + +class tst_QDockWidget : public QObject +{ + Q_OBJECT + +public: + tst_QDockWidget(); + +private slots: + void getSetCheck(); + void widget(); + void setWidget(); + void setFeatures(); + void features(); + void setFloating(); + void setAllowedAreas(); + void allowedAreas(); + void isAreaAllowed(); + void toggleViewAction(); + void featuresChanged(); + void topLevelChanged(); + void allowedAreasChanged(); + void visibilityChanged(); + void dockLocationChanged(); + void setTitleBarWidget(); + void restoreStateOfFloating(); + // task specific tests: + void task165177_deleteFocusWidget(); + void task169808_setFloating(); + void task237438_setFloatingCrash(); + void task248604_infiniteResize(); + void task258459_visibilityChanged(); + void taskQTBUG_1665_closableChanged(); + void taskQTBUG_9758_undockedGeometry(); + void taskQTBUG_2940_resizeAfterUndocking(); +}; + +// Testing get/set functions +void tst_QDockWidget::getSetCheck() +{ + QDockWidget obj1; + // QWidget * QDockWidget::widget() + // void QDockWidget::setWidget(QWidget *) + QWidget *var1 = new QWidget(); + obj1.setWidget(var1); + QCOMPARE(var1, obj1.widget()); + obj1.setWidget((QWidget *)0); + QCOMPARE((QWidget *)0, obj1.widget()); + delete var1; + + // DockWidgetFeatures QDockWidget::features() + // void QDockWidget::setFeatures(DockWidgetFeatures) + obj1.setFeatures(QDockWidget::DockWidgetFeatures(QDockWidget::DockWidgetClosable)); + QCOMPARE(QDockWidget::DockWidgetFeatures(QDockWidget::DockWidgetClosable), obj1.features()); + obj1.setFeatures(QDockWidget::DockWidgetFeatures(QDockWidget::DockWidgetMovable)); + QCOMPARE(QDockWidget::DockWidgetFeatures(QDockWidget::DockWidgetMovable), obj1.features()); + obj1.setFeatures(QDockWidget::DockWidgetFeatures(QDockWidget::DockWidgetFloatable)); + QCOMPARE(QDockWidget::DockWidgetFeatures(QDockWidget::DockWidgetFloatable), obj1.features()); + obj1.setFeatures(QDockWidget::DockWidgetFeatures(QDockWidget::AllDockWidgetFeatures)); + QCOMPARE(QDockWidget::DockWidgetFeatures(QDockWidget::AllDockWidgetFeatures), obj1.features()); + obj1.setFeatures(QDockWidget::DockWidgetFeatures(QDockWidget::NoDockWidgetFeatures)); + QCOMPARE(QDockWidget::DockWidgetFeatures(QDockWidget::NoDockWidgetFeatures), obj1.features()); +} + +tst_QDockWidget::tst_QDockWidget() +{ + qRegisterMetaType("QDockWidget::DockWidgetFeatures"); + qRegisterMetaType("Qt::DockWidgetAreas"); +} + +void tst_QDockWidget::widget() +{ + { + QDockWidget dw; + QVERIFY(dw.widget() == 0); + } + + { + QDockWidget dw; + QWidget *w1 = new QWidget; + QWidget *w2 = new QWidget; + + dw.setWidget(w1); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w1); + QCOMPARE(w1->parentWidget(), (QWidget*)&dw); + + dw.setWidget(0); + QVERIFY(dw.widget() == 0); + + dw.setWidget(w2); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w2); + QCOMPARE(w2->parentWidget(), (QWidget*)&dw); + + dw.setWidget(0); + QVERIFY(dw.widget() == 0); + + dw.setWidget(w1); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w1); + QCOMPARE(w1->parentWidget(), (QWidget*)&dw); + + dw.setWidget(w2); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w2); + QCOMPARE(w2->parentWidget(), (QWidget*)&dw); + + dw.setWidget(0); + QVERIFY(dw.widget() == 0); + } + + { + QDockWidget dw; + QWidget *w1 = new QWidget; + QWidget *w2 = new QWidget; + + dw.setWidget(w1); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w1); + QCOMPARE(w1->parentWidget(), (QWidget*)&dw); + + w1->setParent(0); + QVERIFY(dw.widget() == 0); + + dw.setWidget(w2); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w2); + QCOMPARE(w2->parentWidget(), (QWidget*)&dw); + + w2->setParent(0); + QVERIFY(dw.widget() == 0); + + dw.setWidget(w1); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w1); + QCOMPARE(w1->parentWidget(), (QWidget*)&dw); + + dw.setWidget(w2); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w2); + QCOMPARE(w2->parentWidget(), (QWidget*)&dw); + + w1->setParent(0); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w2); + QCOMPARE(w2->parentWidget(), (QWidget*)&dw); + + w2->setParent(0); + QVERIFY(dw.widget() == 0); + delete w1; + delete w2; + } +} + +void tst_QDockWidget::setWidget() +{ + DEPENDS_ON("setWidget()"); +} + +void tst_QDockWidget::setFeatures() +{ + DEPENDS_ON("features()"); +} + +void tst_QDockWidget::features() +{ + QDockWidget dw; + + QSignalSpy spy(&dw, SIGNAL(featuresChanged(QDockWidget::DockWidgetFeatures))); + + // default features for dock widgets + int allDockWidgetFeatures = QDockWidget::DockWidgetClosable | + QDockWidget::DockWidgetMovable | + QDockWidget::DockWidgetFloatable; + + // defaults + QCOMPARE(dw.features(), allDockWidgetFeatures); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + + // test individual setting + setFeature(&dw, QDockWidget::DockWidgetClosable, false); + QCOMPARE(dw.features(), QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); + QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*(static_cast(spy.at(0).value(0).constData())), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + setFeature(&dw, QDockWidget::DockWidgetClosable); + QCOMPARE(dw.features(), allDockWidgetFeatures); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + setFeature(&dw, QDockWidget::DockWidgetMovable, false); + QCOMPARE(dw.features(), QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + setFeature(&dw, QDockWidget::DockWidgetMovable); + QCOMPARE(dw.features(), allDockWidgetFeatures); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + setFeature(&dw, QDockWidget::DockWidgetFloatable, false); + QCOMPARE(dw.features(), QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + setFeature(&dw, QDockWidget::DockWidgetFloatable); + QCOMPARE(dw.features(), allDockWidgetFeatures); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + // set all at once + dw.setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); + QCOMPARE(dw.features(), QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + dw.setFeatures(QDockWidget::DockWidgetClosable); + QCOMPARE(dw.features(), QDockWidget::DockWidgetClosable); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + dw.setFeatures(QDockWidget::AllDockWidgetFeatures); + QCOMPARE(dw.features(), QDockWidget::AllDockWidgetFeatures); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); +} + +void tst_QDockWidget::setFloating() +{ + const QRect deskRect = QApplication::desktop()->availableGeometry(); + QMainWindow mw; + mw.move(deskRect.left() + deskRect.width() * 2 / 3, deskRect.top() + deskRect.height() / 3); + QDockWidget dw; + mw.addDockWidget(Qt::LeftDockWidgetArea, &dw); + + mw.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&mw); +#endif + + QVERIFY(!dw.isFloating()); + const QPoint dockedPosition = dw.mapToGlobal(dw.pos()); + + QSignalSpy spy(&dw, SIGNAL(topLevelChanged(bool))); + + dw.setFloating(true); + const QPoint floatingPosition = dw.pos(); + + // QTBUG-31044, show approximately at old position, give or take window frame. + QVERIFY((dockedPosition - floatingPosition).manhattanLength() < 50); + + QVERIFY(dw.isFloating()); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).value(0).toBool(), dw.isFloating()); + spy.clear(); + dw.setFloating(dw.isFloating()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + dw.setFloating(false); + QVERIFY(!dw.isFloating()); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).value(0).toBool(), dw.isFloating()); + spy.clear(); + dw.setFloating(dw.isFloating()); + QCOMPARE(spy.count(), 0); + spy.clear(); +} + +void tst_QDockWidget::setAllowedAreas() +{ + DEPENDS_ON("allowedAreas()"); +} + +void tst_QDockWidget::allowedAreas() +{ + QDockWidget dw; + + QSignalSpy spy(&dw, SIGNAL(allowedAreasChanged(Qt::DockWidgetAreas))); + + // default + QCOMPARE(dw.allowedAreas(), Qt::AllDockWidgetAreas); + QVERIFY(dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + + // a single dock window area + dw.setAllowedAreas(Qt::LeftDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::LeftDockWidgetArea); + QVERIFY(dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + dw.setAllowedAreas(Qt::RightDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::RightDockWidgetArea); + QVERIFY(!dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + dw.setAllowedAreas(Qt::TopDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::TopDockWidgetArea); + QVERIFY(!dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + dw.setAllowedAreas(Qt::BottomDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::BottomDockWidgetArea); + QVERIFY(!dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + // multiple dock window areas + dw.setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); + QVERIFY(!dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + dw.setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + QVERIFY(dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + dw.setAllowedAreas(Qt::TopDockWidgetArea | Qt::LeftDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::TopDockWidgetArea | Qt::LeftDockWidgetArea); + QVERIFY(dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + dw.setAllowedAreas(Qt::BottomDockWidgetArea | Qt::RightDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::BottomDockWidgetArea | Qt::RightDockWidgetArea); + QVERIFY(!dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); +} + +void tst_QDockWidget::isAreaAllowed() +{ + DEPENDS_ON("allowedAreas()"); +} + +void tst_QDockWidget::toggleViewAction() +{ + QMainWindow mw; + QDockWidget dw(&mw); + mw.addDockWidget(Qt::LeftDockWidgetArea, &dw); + mw.show(); + QAction *toggleViewAction = dw.toggleViewAction(); + QVERIFY(!dw.isHidden()); + toggleViewAction->trigger(); + QVERIFY(dw.isHidden()); + toggleViewAction->trigger(); + QVERIFY(!dw.isHidden()); + toggleViewAction->trigger(); + QVERIFY(dw.isHidden()); +} + +void tst_QDockWidget::visibilityChanged() +{ + QMainWindow mw; + QDockWidget dw; + QSignalSpy spy(&dw, SIGNAL(visibilityChanged(bool))); + + mw.addDockWidget(Qt::LeftDockWidgetArea, &dw); + mw.show(); + + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), true); + spy.clear(); + + dw.hide(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), false); + spy.clear(); + + dw.hide(); + QCOMPARE(spy.count(), 0); + + dw.show(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), true); + spy.clear(); + + dw.show(); + QCOMPARE(spy.count(), 0); + + QDockWidget dw2; + mw.tabifyDockWidget(&dw, &dw2); + dw2.show(); + dw2.raise(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), false); + spy.clear(); + + dw2.hide(); + qApp->processEvents(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), true); + spy.clear(); + + dw2.show(); + dw2.raise(); + qApp->processEvents(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), false); + spy.clear(); + + dw.raise(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), true); + spy.clear(); + + dw.raise(); + QCOMPARE(spy.count(), 0); + + dw2.raise(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), false); + spy.clear(); + + dw2.raise(); + QCOMPARE(spy.count(), 0); + + mw.addDockWidget(Qt::RightDockWidgetArea, &dw2); + QTest::qWait(200); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), true); +} + +Q_DECLARE_METATYPE(Qt::DockWidgetArea) + +void tst_QDockWidget::dockLocationChanged() +{ + qRegisterMetaType("Qt::DockWidgetArea"); + + QMainWindow mw; + QDockWidget dw; + dw.setObjectName("dock1"); + QSignalSpy spy(&dw, SIGNAL(dockLocationChanged(Qt::DockWidgetArea))); + + mw.addDockWidget(Qt::LeftDockWidgetArea, &dw); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast(spy.at(0).at(0)), + Qt::LeftDockWidgetArea); + spy.clear(); + + mw.addDockWidget(Qt::LeftDockWidgetArea, &dw); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast(spy.at(0).at(0)), + Qt::LeftDockWidgetArea); + spy.clear(); + + mw.addDockWidget(Qt::RightDockWidgetArea, &dw); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast(spy.at(0).at(0)), + Qt::RightDockWidgetArea); + spy.clear(); + + mw.removeDockWidget(&dw); + QCOMPARE(spy.count(), 0); + + QDockWidget dw2; + dw2.setObjectName("dock2"); + mw.addDockWidget(Qt::TopDockWidgetArea, &dw2); + mw.tabifyDockWidget(&dw2, &dw); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast(spy.at(0).at(0)), + Qt::TopDockWidgetArea); + spy.clear(); + + mw.splitDockWidget(&dw2, &dw, Qt::Horizontal); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast(spy.at(0).at(0)), + Qt::TopDockWidgetArea); + spy.clear(); + + dw.setFloating(true); + QTest::qWait(100); + dw.setFloating(false); + QTest::qWait(100); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast(spy.at(0).at(0)), + Qt::TopDockWidgetArea); + spy.clear(); + + QByteArray ba = mw.saveState(); + mw.restoreState(ba); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast(spy.at(0).at(0)), + Qt::TopDockWidgetArea); +} + +void tst_QDockWidget::featuresChanged() +{ + DEPENDS_ON("features()"); +} + +void tst_QDockWidget::topLevelChanged() +{ + DEPENDS_ON("setFloating()"); +} + +void tst_QDockWidget::allowedAreasChanged() +{ + DEPENDS_ON("allowedAreas()"); +} + +void tst_QDockWidget::setTitleBarWidget() +{ + // test the successive usage of setTitleBarWidget + + QDockWidget dock; + QWidget w, w2; + + dock.show(); + qApp->processEvents(); + + dock.setTitleBarWidget(&w); + qApp->processEvents(); + QCOMPARE(w.isVisible(), true); + + // set another widget as the titlebar widget + dock.setTitleBarWidget(&w2); // this used to crash (task 184668) + qApp->processEvents(); + QCOMPARE(w.isVisible(), false); + QCOMPARE(w2.isVisible(), true); + + // tries to reset the titlebarwidget to none + dock.setTitleBarWidget(0); + qApp->processEvents(); + QCOMPARE(w.isVisible(), false); + QCOMPARE(w2.isVisible(), false); +} + +void tst_QDockWidget::restoreStateOfFloating() +{ + QMainWindow mw; + QDockWidget dock; + dock.setObjectName("dock1"); + mw.addDockWidget(Qt::TopDockWidgetArea, &dock); + QVERIFY(!dock.isFloating()); + QByteArray ba = mw.saveState(); + dock.setFloating(true); + QVERIFY(dock.isFloating()); + QVERIFY(mw.restoreState(ba)); + QVERIFY(!dock.isFloating()); +} + +void tst_QDockWidget::task165177_deleteFocusWidget() +{ + QMainWindow mw; + QDockWidget *dw = new QDockWidget(&mw); + mw.addDockWidget(Qt::LeftDockWidgetArea, dw); + QLineEdit *ledit = new QLineEdit; + dw->setWidget(ledit); + mw.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&mw); +#endif + qApp->processEvents(); + dw->setFloating(true); + delete ledit; + QCOMPARE(mw.focusWidget(), (QWidget *)0); + QCOMPARE(dw->focusWidget(), (QWidget *)0); +} + +void tst_QDockWidget::task169808_setFloating() +{ + // we try to test if the sizeHint of the dock widget widget is taken into account + + class MyWidget : public QWidget + { + public: + QSize sizeHint() const + { + const QRect& deskRect = qApp->desktop()->availableGeometry(); + return QSize(qMin(300, deskRect.width() / 2), qMin(300, deskRect.height() / 2)); + } + + QSize minimumSizeHint() const + { + return QSize(20,20); + } + + void paintEvent(QPaintEvent *) + { + QPainter p(this); + p.fillRect(rect(), Qt::red); + } + }; + QMainWindow mw; + mw.setCentralWidget(new MyWidget); + QDockWidget *dw = new QDockWidget("my dock"); + dw->setWidget(new MyWidget); + mw.addDockWidget(Qt::LeftDockWidgetArea, dw); + dw->setFloating(true); + mw.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&mw); +#endif + + QCOMPARE(dw->widget()->size(), dw->widget()->sizeHint()); + + // and now we try to test if the contents margin is taken into account + dw->widget()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + dw->setFloating(false); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&mw); +#endif + QTest::qWait(100); // leave time processing events + + + const QSize oldSize = dw->size(); + const int margin = 20; + + dw->setContentsMargins(margin, margin, margin, margin); + +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&mw); +#endif + QTest::qWait(100); // leave time processing events + + // widget size shouldn't have changed + QCOMPARE(dw->widget()->size(), dw->widget()->sizeHint()); + // dockwidget should be bigger + QCOMPARE(dw->size(), oldSize + QSize(margin * 2, margin * 2)); +} + +void tst_QDockWidget::task237438_setFloatingCrash() +{ + // should not crash + QDockWidget pqdwDock; + pqdwDock.setFloating(false); + pqdwDock.show(); +} + +void tst_QDockWidget::task248604_infiniteResize() +{ + QDockWidget d; + QTabWidget *t = new QTabWidget; + t->addTab(new QWidget, "Foo"); + d.setWidget(t); + d.setContentsMargins(2, 2, 2, 2); + d.setMinimumSize(320, 240); + d.show(); + QTest::qWait(400); + QCOMPARE(d.size(), QSize(320, 240)); +} + +void tst_QDockWidget::task258459_visibilityChanged() +{ + QMainWindow win; + QDockWidget dock1, dock2; + win.addDockWidget(Qt::RightDockWidgetArea, &dock1); + win.tabifyDockWidget(&dock1, &dock2); + QSignalSpy spy1(&dock1, SIGNAL(visibilityChanged(bool))); + QSignalSpy spy2(&dock2, SIGNAL(visibilityChanged(bool))); + win.show(); + QTest::qWait(200); + QCOMPARE(spy1.count(), 1); + QCOMPARE(spy1.first().first().toBool(), false); // dock1 is invisible + QCOMPARE(spy2.count(), 1); + QCOMPARE(spy2.first().first().toBool(), true); // dock1 is visible +} + +void tst_QDockWidget::taskQTBUG_1665_closableChanged() +{ + QDockWidget dock; + dock.show(); + QTest::qWaitForWindowShown(&dock); + + QDockWidgetLayout *l = qobject_cast(dock.layout()); + + if (l && !l->nativeWindowDeco()) + QSKIP("this machine doesn't support native dock widget", SkipAll); + + QVERIFY(dock.windowFlags() & Qt::WindowCloseButtonHint); + + // now let's remove the closable attribute + dock.setFeatures(dock.features() ^ QDockWidget::DockWidgetClosable); + QVERIFY(!(dock.windowFlags() & Qt::WindowCloseButtonHint)); +} + +void tst_QDockWidget::taskQTBUG_9758_undockedGeometry() +{ + QMainWindow window; + QDockWidget dock1(&window); + QDockWidget dock2(&window); + window.addDockWidget(Qt::RightDockWidgetArea, &dock1); + window.addDockWidget(Qt::RightDockWidgetArea, &dock2); + window.tabifyDockWidget(&dock1, &dock2); + dock1.hide(); + dock2.hide(); + window.show(); + QTest::qWaitForWindowShown(&window); + dock1.setFloating(true); + dock1.show(); + QTest::qWaitForWindowShown(&dock1); + + QVERIFY(dock1.x() >= 0); + QVERIFY(dock1.y() >= 0); +} + +void tst_QDockWidget::taskQTBUG_2940_resizeAfterUndocking() +{ + QMainWindow window; + QDockWidget dw("dw", &window); + window.setGeometry(window.x(), window.y(), 400, 400); + window.addDockWidget(Qt::TopDockWidgetArea, &dw); + window.show(); + dw.setFloating(true); + dw.setGeometry(dw.x(), dw.y(), 100, 100); + + // When docked, width should be the same than window's width + dw.setFloating(false); + QCOMPARE(dw.width(), window.width()); + + // Drag the dock widget out of the window + qApp->postEvent(&dw, new QMouseEvent(QEvent::MouseButtonPress, + QPoint(10, 10), Qt::LeftButton, 0, 0)); + qApp->postEvent(&dw, new QMouseEvent(QEvent::MouseMove, + QPoint(100, 100), Qt::LeftButton,Qt::LeftButton, 0)); + qApp->postEvent(&dw, new QMouseEvent(QEvent::MouseButtonRelease, + QPoint(100, 100), Qt::LeftButton, 0, 0)); + qApp->processEvents(); + + // When undocked, size should be the restored + QCOMPARE(dw.size(), QSize(100, 100)); +} + +QTEST_MAIN(tst_QDockWidget) + +#include "moc_tst_qdockwidget.cpp"