diff --git a/README.md b/README.md index 7e24607..9b3d5dc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Advanced Docking System for Qt [![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System) [![Build status](https://ci.appveyor.com/api/projects/status/qcfb3cy932jw9mpy/branch/master?svg=true)](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master) +[![License: LGPL v2.1](https://img.shields.io/badge/License-LGPL%20v2.1-blue.svg)](gnu-lgpl-v2.1.md) @@ -60,9 +61,22 @@ main window layout. ![Perspective](doc/perspectives_dark.png) ## Tested Compatible Environments -- Windows 10 [![Build status](https://ci.appveyor.com/api/projects/status/qcfb3cy932jw9mpy/branch/master?svg=true)](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master) -- Ubuntu [![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System) -- macOS [![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System) +### Windows +Windows 10 [![Build status](https://ci.appveyor.com/api/projects/status/qcfb3cy932jw9mpy/branch/master?svg=true)](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master) + +The library was developed on and for Windows. It is used in a commercial Windows application and is therefore constantly tested. + +### macOS +macOS [![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System) + +The application can be compiled for macOS. A user reported, that the library works on macOS. If have not tested it. + +### Linux +Ubuntu [![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System) + +The application can be compiled for Linux but the master branch doesn't work under Linux because some required features are not supported by Linux. But there is the branch **linux_experimental** which was developed and tested with **Kubuntu 18.04**. and which should also work on other Linux distributions. The branch needs more testing and maybe some imrpovements before it can be merged into master. + +![Advanced Docking on Linux](doc/linux_kubuntu_1804.png) ## Build Open the `ads.pro` with QtCreator and start the build, that's it. @@ -144,5 +158,6 @@ MainWindow::~MainWindow() - Manuel Freiholz ## License information +[![License: LGPL v2.1](https://img.shields.io/badge/License-LGPL%20v2.1-blue.svg)](gnu-lgpl-v2.1.md) This project uses the [LGPLv2.1 license](gnu-lgpl-v2.1.md) diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt index 7580503..553bd18 100644 --- a/demo/CMakeLists.txt +++ b/demo/CMakeLists.txt @@ -23,7 +23,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(ads_demo_SRCS main.cpp MainWindow.cpp - MainWindow.ui + mainwindow.ui main.qrc ) add_executable(AdvancedDockingSystemDemo WIN32 ${ads_demo_SRCS}) diff --git a/doc/linux_kubuntu_1804.png b/doc/linux_kubuntu_1804.png new file mode 100644 index 0000000..1eb1424 Binary files /dev/null and b/doc/linux_kubuntu_1804.png differ 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..3539406 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 @@ -1057,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) { @@ -1274,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) 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 dfe5d6d..7a66686 100644 --- a/src/DockManager.cpp +++ b/src/DockManager.cpp @@ -569,9 +569,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); } } @@ -590,6 +594,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 diff --git a/src/DockWidget.cpp b/src/DockWidget.cpp index c8ca3bb..08c47e4 100644 --- a/src/DockWidget.cpp +++ b/src/DockWidget.cpp @@ -262,6 +262,16 @@ void CDockWidget::setWidget(QWidget* widget, eInsertMode InsertMode) } +//============================================================================ +QWidget* CDockWidget::takeWidget() +{ + d->ScrollArea->takeWidget(); + d->Layout->removeWidget(d->Widget); + d->Widget->setParent(nullptr); + return d->Widget; +} + + //============================================================================ QWidget* CDockWidget::widget() const { diff --git a/src/DockWidget.h b/src/DockWidget.h index e083137..658372f 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 + */ + QWidget* takeWidget(); + /** * Returns the widget for the dock widget. This function returns zero if * the widget has not been set.