diff --git a/src/DockWidgetBase.cpp b/src/DockWidgetBase.cpp index cc942371..7641428f 100644 --- a/src/DockWidgetBase.cpp +++ b/src/DockWidgetBase.cpp @@ -110,7 +110,7 @@ public: void onDockWidgetHidden(); void show(); void close(); - void restoreToPreviousPosition(); + bool restoreToPreviousPosition(); void maybeRestoreToPreviousPosition(); int currentTabIndex() const; @@ -267,15 +267,12 @@ bool DockWidgetBase::isFloating() const return fw && fw->hasSingleDockWidget(); } -void DockWidgetBase::setFloating(bool floats) +bool DockWidgetBase::setFloating(bool floats) { const bool alreadyFloating = isFloating(); - qCDebug(docking) << Q_FUNC_INFO << "yes=" << floats - << "; already floating=" << alreadyFloating; - if ((floats && alreadyFloating) || (!floats && !alreadyFloating)) - return; // Nothing to do + return true; // Nothing to do if (floats) { d->saveTabIndex(); @@ -285,6 +282,7 @@ void DockWidgetBase::setFloating(bool floats) qWarning() << "DockWidget::setFloating: Tabbed but no frame exists" << this; Q_ASSERT(false); + return false; } frame->detachTab(this); @@ -297,9 +295,10 @@ void DockWidgetBase::setFloating(bool floats) if (auto fw = floatingWindow()) fw->setSuggestedGeometry(lastGeo, /*preserveCenter=*/true); } + return true; } else { saveLastFloatingGeometry(); - d->restoreToPreviousPosition(); + return d->restoreToPreviousPosition(); } } @@ -511,6 +510,11 @@ SideBarLocation DockWidgetBase::sideBarLocation() const return DockRegistry::self()->sideBarLocationForDockWidget(this); } +bool DockWidgetBase::hasPreviousDockedLocation() const +{ + return d->m_lastPositions.isValid(); +} + FloatingWindow *DockWidgetBase::morphIntoFloatingWindow() { qCDebug(creation) << "DockWidget::morphIntoFloatingWindow() this=" << this @@ -680,16 +684,17 @@ void DockWidgetBase::Private::close() } } -void DockWidgetBase::Private::restoreToPreviousPosition() +bool DockWidgetBase::Private::restoreToPreviousPosition() { if (!m_lastPositions.isValid()) - return; + return false; Layouting::Item *item = m_lastPositions.lastItem(); MultiSplitter *layout = DockRegistry::self()->layoutForItem(item); Q_ASSERT(layout); layout->restorePlaceholder(q, item, m_lastPositions.lastTabIndex()); + return true; } void DockWidgetBase::Private::maybeRestoreToPreviousPosition() diff --git a/src/DockWidgetBase.h b/src/DockWidgetBase.h index fe7a8c9f..b3959c16 100644 --- a/src/DockWidgetBase.h +++ b/src/DockWidgetBase.h @@ -158,8 +158,10 @@ public: /** * @brief setter to make the dock widget float or dock. * @param floats If true makes the dock widget float, otherwise docks it. + * + * Returns true if the request was accomplished */ - void setFloating(bool floats); + bool setFloating(bool floats); /** * @brief Returns the QAction that allows to hide/show the dock widget @@ -360,6 +362,12 @@ public: /// This is only relevant when using the auto-hide and side-bar feature. SideBarLocation sideBarLocation() const; + /// @brief Returns whether this floating dock widget knows its previous docked location + /// Result only makes sense if it's floating. + /// + /// When you call dockWidget->setFloating(false) it will only dock if it knows where to. + bool hasPreviousDockedLocation() const; + Q_SIGNALS: ///@brief signal emitted when the parent changed void parentChanged(); diff --git a/tests/tst_common.cpp b/tests/tst_common.cpp index 69a44e2d..281cc512 100644 --- a/tests/tst_common.cpp +++ b/tests/tst_common.cpp @@ -61,6 +61,7 @@ private Q_SLOTS: void tst_simple1(); void tst_doesntHaveNativeTitleBar(); void tst_resizeWindow2(); + void tst_hasLastDockedLocation(); }; void TestCommon::tst_simple1() @@ -117,6 +118,30 @@ void TestCommon::tst_resizeWindow2() delete fw2; } +void TestCommon::tst_hasLastDockedLocation() +{ + // Tests DockWidgetBase::hasPreviousDockedLocation() + + EnsureTopLevelsDeleted e; + auto m = createMainWindow(QSize(501, 500), MainWindowOption_None); + auto dock1 = createDockWidget("1"); + auto window1 = dock1->window(); + QVERIFY(dock1->isFloating()); + QVERIFY(!dock1->hasPreviousDockedLocation()); + QVERIFY(dock1->setFloating(true)); + QVERIFY(!dock1->setFloating(false)); // No docking location, so it's not docked + QVERIFY(dock1->isFloating()); + QVERIFY(!dock1->hasPreviousDockedLocation()); + + m->addDockWidget(dock1, Location_OnBottom); + QVERIFY(!dock1->isFloating()); + QVERIFY(dock1->setFloating(true)); + QVERIFY(dock1->hasPreviousDockedLocation()); + QVERIFY(dock1->setFloating(false)); + + delete window1; +} + int main(int argc, char *argv[]) { if (!qpaPassedAsArgument(argc, argv)) {