From 641946bff5783a30881d1464e150fde5aadfbf6f Mon Sep 17 00:00:00 2001 From: Tibo Clausen Date: Wed, 15 May 2019 13:47:58 +0100 Subject: [PATCH 1/6] Add CDockManager::removeDockWidget() --- src/DockAreaWidget.cpp | 8 ++++---- src/DockContainerWidget.cpp | 9 +++++++++ src/DockContainerWidget.h | 5 +++++ src/DockManager.cpp | 6 ++++++ src/DockManager.h | 5 +++++ 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/DockAreaWidget.cpp b/src/DockAreaWidget.cpp index b681ede..292d54b 100644 --- a/src/DockAreaWidget.cpp +++ b/src/DockAreaWidget.cpp @@ -414,14 +414,15 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget) auto TabWidget = DockWidget->tabWidget(); TabWidget->hide(); d->tabBar()->removeTab(TabWidget); + CDockContainerWidget* DockContainer = dockContainer(); if (NextOpenDockWidget) { setCurrentDockWidget(NextOpenDockWidget); } - else if (d->ContentsLayout->isEmpty()) + else if (d->ContentsLayout->isEmpty() && DockContainer->dockAreaCount() > 1) { qDebug() << "Dock Area empty"; - dockContainer()->removeDockArea(this); + DockContainer->removeDockArea(this); this->deleteLater(); } else @@ -434,14 +435,13 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget) d->updateCloseButtonState(); updateTitleBarVisibility(); - auto TopLevelDockWidget = dockContainer()->topLevelDockWidget(); + auto TopLevelDockWidget = DockContainer->topLevelDockWidget(); if (TopLevelDockWidget) { TopLevelDockWidget->emitTopLevelChanged(true); } #if (ADS_DEBUG_LEVEL > 0) - CDockContainerWidget* DockContainer = dockContainer(); DockContainer->dumpLayout(); #endif } diff --git a/src/DockContainerWidget.cpp b/src/DockContainerWidget.cpp index 6cc3a13..4985fc3 100644 --- a/src/DockContainerWidget.cpp +++ b/src/DockContainerWidget.cpp @@ -998,6 +998,15 @@ CDockAreaWidget* CDockContainerWidget::addDockWidget(DockWidgetArea area, CDockW } } +//============================================================================ +void CDockContainerWidget::removeDockWidget(CDockWidget* Dockwidget) +{ + CDockAreaWidget* Area = Dockwidget->dockAreaWidget(); + if (Area) + { + Area->removeDockWidget(Dockwidget); + } +} //============================================================================ unsigned int CDockContainerWidget::zOrderIndex() const diff --git a/src/DockContainerWidget.h b/src/DockContainerWidget.h index 0483137..c923ecc 100644 --- a/src/DockContainerWidget.h +++ b/src/DockContainerWidget.h @@ -166,6 +166,11 @@ public: CDockAreaWidget* addDockWidget(DockWidgetArea area, CDockWidget* Dockwidget, CDockAreaWidget* DockAreaWidget = nullptr); + /** + * Removes dockwidget + */ + void removeDockWidget(CDockWidget* Dockwidget); + /** * Returns the current zOrderIndex */ diff --git a/src/DockManager.cpp b/src/DockManager.cpp index 44a0a2b..1ce3d22 100644 --- a/src/DockManager.cpp +++ b/src/DockManager.cpp @@ -586,6 +586,12 @@ CDockWidget* CDockManager::findDockWidget(const QString& ObjectName) const return d->DockWidgetsMap.value(ObjectName, nullptr); } +//============================================================================ +void CDockManager::removeDockWidget(CDockWidget* Dockwidget) +{ + d->DockWidgetsMap.remove(Dockwidget->objectName()); + CDockContainerWidget::removeDockWidget(Dockwidget); +} //============================================================================ QMap CDockManager::dockWidgetsMap() const diff --git a/src/DockManager.h b/src/DockManager.h index a7c088c..72ab026 100644 --- a/src/DockManager.h +++ b/src/DockManager.h @@ -192,6 +192,11 @@ public: */ CDockWidget* findDockWidget(const QString& ObjectName) const; + /** + * Remove the given Dock from the dock manager + */ + void removeDockWidget(CDockWidget* Dockwidget); + /** * This function returns a readable reference to the internal dock * widgets map so that it is possible to iterate over all dock widgets From 69894f3f88e7a2e2ac2e97e2a2be89479d96d4b5 Mon Sep 17 00:00:00 2001 From: Tibo Clausen Date: Wed, 15 May 2019 14:20:08 +0100 Subject: [PATCH 2/6] Remove area from LastAddedAreaCache --- src/DockContainerWidget.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/DockContainerWidget.cpp b/src/DockContainerWidget.cpp index 4985fc3..15b246d 100644 --- a/src/DockContainerWidget.cpp +++ b/src/DockContainerWidget.cpp @@ -1066,6 +1066,12 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area) area->setParent(nullptr); internal::hideEmptyParentSplitters(Splitter); + // Remove this area from cached areas + const auto& cache = d->LastAddedAreaCache; + if (auto p = std::find(cache, cache+sizeof(cache)/sizeof(cache[0]), area)) { + d->LastAddedAreaCache[std::distance(cache, p)] = nullptr; + } + // If splitter has more than 1 widgets, we are finished and can leave if (Splitter->count() > 1) { From 5ee94d760264b8789dba6f5ae679f44d0c368b4b Mon Sep 17 00:00:00 2001 From: Tibo Clausen Date: Wed, 15 May 2019 14:30:32 +0100 Subject: [PATCH 3/6] Improve CDockManager::addDockWidgetTab() for dynamically added widgets --- src/DockManager.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/DockManager.cpp b/src/DockManager.cpp index 1ce3d22..c3b3ace 100644 --- a/src/DockManager.cpp +++ b/src/DockManager.cpp @@ -565,9 +565,13 @@ CDockAreaWidget* CDockManager::addDockWidgetTab(DockWidgetArea area, { return addDockWidget(ads::CenterDockWidgetArea, Dockwidget, AreaWidget); } + else if (!openedDockAreas().isEmpty()) + { + return addDockWidget(area, Dockwidget, openedDockAreas().last()); + } else { - return addDockWidget(area, Dockwidget, AreaWidget); + return addDockWidget(area, Dockwidget, nullptr); } } From e2c5204d00f9003cdca46ef4bb9148f4beafd9b7 Mon Sep 17 00:00:00 2001 From: Tibo Clausen Date: Wed, 15 May 2019 16:13:55 +0100 Subject: [PATCH 4/6] Clear LastAddedAreaCache when restoring --- src/DockContainerWidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/DockContainerWidget.cpp b/src/DockContainerWidget.cpp index 15b246d..3539406 100644 --- a/src/DockContainerWidget.cpp +++ b/src/DockContainerWidget.cpp @@ -1289,6 +1289,7 @@ bool CDockContainerWidget::restoreState(QXmlStreamReader& s, bool Testing) { d->VisibleDockAreaCount = -1;// invalidate the dock area count d->DockAreas.clear(); + std::fill(std::begin(d->LastAddedAreaCache),std::end(d->LastAddedAreaCache), nullptr); } if (IsFloating) From b9b8ff9c76aaa606e372f2ac258314390ac3bfe0 Mon Sep 17 00:00:00 2001 From: Tibo Clausen Date: Thu, 16 May 2019 11:53:31 +0100 Subject: [PATCH 5/6] Add CDockWidget::releaseWidget() --- src/DockWidget.cpp | 9 +++++++++ src/DockWidget.h | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/src/DockWidget.cpp b/src/DockWidget.cpp index c8ca3bb..e901808 100644 --- a/src/DockWidget.cpp +++ b/src/DockWidget.cpp @@ -262,6 +262,15 @@ void CDockWidget::setWidget(QWidget* widget, eInsertMode InsertMode) } +//============================================================================ +void CDockWidget::releaseWidget() +{ + d->ScrollArea->takeWidget(); + d->Layout->removeWidget(d->Widget); + d->Widget->setParent(nullptr); +} + + //============================================================================ QWidget* CDockWidget::widget() const { diff --git a/src/DockWidget.h b/src/DockWidget.h index e083137..3decfc6 100644 --- a/src/DockWidget.h +++ b/src/DockWidget.h @@ -238,6 +238,11 @@ public: */ void setWidget(QWidget* widget, eInsertMode InsertMode = AutoScrollArea); + /** + * Remove the widget from the dock and give ownership back to the caller + */ + void releaseWidget(); + /** * Returns the widget for the dock widget. This function returns zero if * the widget has not been set. From c630a59afe9d7566b81ee1b09e3e865f58edbf66 Mon Sep 17 00:00:00 2001 From: Tibo Clausen Date: Thu, 16 May 2019 13:08:48 +0100 Subject: [PATCH 6/6] Replace CDockWidget::releaseWidget() with CDockWidget::takeWidget() --- src/DockWidget.cpp | 3 ++- src/DockWidget.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/DockWidget.cpp b/src/DockWidget.cpp index e901808..08c47e4 100644 --- a/src/DockWidget.cpp +++ b/src/DockWidget.cpp @@ -263,11 +263,12 @@ void CDockWidget::setWidget(QWidget* widget, eInsertMode InsertMode) //============================================================================ -void CDockWidget::releaseWidget() +QWidget* CDockWidget::takeWidget() { d->ScrollArea->takeWidget(); d->Layout->removeWidget(d->Widget); d->Widget->setParent(nullptr); + return d->Widget; } diff --git a/src/DockWidget.h b/src/DockWidget.h index 3decfc6..658372f 100644 --- a/src/DockWidget.h +++ b/src/DockWidget.h @@ -241,7 +241,7 @@ public: /** * Remove the widget from the dock and give ownership back to the caller */ - void releaseWidget(); + QWidget* takeWidget(); /** * Returns the widget for the dock widget. This function returns zero if