From 6843703484c997de3c0747db468abd84b7ca781a Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Wed, 7 Nov 2018 13:50:43 +0100 Subject: [PATCH] Fixed title bar button minimum size to enable stylesheet styling, fixed restore functionality --- src/DockAreaTitleBar.cpp | 5 +- src/DockAreaWidget.cpp | 15 +++++ src/DockAreaWidget.h | 11 ++++ src/DockContainerWidget.cpp | 34 ---------- src/DockManager.cpp | 127 +++++++++++++++++++++++++++++------- 5 files changed, 132 insertions(+), 60 deletions(-) diff --git a/src/DockAreaTitleBar.cpp b/src/DockAreaTitleBar.cpp index fc5b70a..88b2143 100644 --- a/src/DockAreaTitleBar.cpp +++ b/src/DockAreaTitleBar.cpp @@ -115,13 +115,12 @@ void DockAreaTitleBarPrivate::createButtons() TabsMenuButton->setAutoRaise(true); TabsMenuButton->setPopupMode(QToolButton::InstantPopup); TabsMenuButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarUnshadeButton)); - TabsMenuButton->setMaximumWidth(TabsMenuButton->iconSize().width()); QMenu* TabsMenu = new QMenu(TabsMenuButton); _this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow())); TabsMenuButton->setMenu(TabsMenu); - TopLayout->addWidget(TabsMenuButton, 0); TabsMenuButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + TopLayout->addWidget(TabsMenuButton, 0); _this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)), SLOT(onTabsMenuActionTriggered(QAction*))); @@ -130,7 +129,7 @@ void DockAreaTitleBarPrivate::createButtons() UndockButton->setObjectName("undockButton"); UndockButton->setAutoRaise(true); UndockButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarNormalButton)); - UndockButton->setMaximumWidth(UndockButton->iconSize().width()); + UndockButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); TopLayout->addWidget(UndockButton, 0); _this->connect(UndockButton, SIGNAL(clicked()), SLOT(onUndockButtonClicked())); diff --git a/src/DockAreaWidget.cpp b/src/DockAreaWidget.cpp index 14c40e7..4b6a563 100644 --- a/src/DockAreaWidget.cpp +++ b/src/DockAreaWidget.cpp @@ -600,6 +600,21 @@ QList CDockAreaWidget::openedDockWidgets() const } +//============================================================================ +int CDockAreaWidget::indexOfFirstOpenDockWidget() const +{ + for (int i = 0; i < d->ContentsLayout->count(); ++i) + { + if (!dockWidget(i)->isClosed()) + { + return i; + } + } + + return -1; +} + + //============================================================================ int CDockAreaWidget::dockWidgetsCount() const { diff --git a/src/DockAreaWidget.h b/src/DockAreaWidget.h index f66e1fd..f7e0097 100644 --- a/src/DockAreaWidget.h +++ b/src/DockAreaWidget.h @@ -196,6 +196,17 @@ public: */ int currentIndex() const; + /** + * Returns the index of the first open dock widgets in the list of + * dock widgets. + * This function is here for performance reasons. Normally it would + * be possible to take the first dock widget from the list returned by + * openedDockWidgets() function. But that function enumerates all + * dock widgets while this functions stops after the first open dock widget. + * If there are no open dock widgets, the function returns -1. + */ + int indexOfFirstOpenDockWidget() const; + /** * Returns the current active dock widget or a nullptr if there is no * active dock widget (i.e. if all dock widgets are closed) diff --git a/src/DockContainerWidget.cpp b/src/DockContainerWidget.cpp index 004d963..a6638c9 100644 --- a/src/DockContainerWidget.cpp +++ b/src/DockContainerWidget.cpp @@ -1185,40 +1185,6 @@ bool CDockContainerWidget::restoreState(QXmlStreamReader& s, bool Testing) d->RootSplitter = dynamic_cast(NewRootSplitter); OldRoot->deleteLater(); - // All dock widgets, that have not been processed in the restore state - // function are invisible to the user now and have no assigned dock area - // They do not belong to any dock container, until the user toggles the - // toggle view action the next time - for (auto DockWidget : dockWidgets()) - { - if (DockWidget->property("dirty").toBool()) - { - DockWidget->flagAsUnassigned(); - } - else - { - DockWidget->toggleViewInternal(!DockWidget->property("closed").toBool()); - } - } - - // Finally we need to send the topLevelChanged() signals for all dock - // widgets if top level changed - CDockWidget* TopLevelDockWidget = topLevelDockWidget(); - if (TopLevelDockWidget) - { - TopLevelDockWidget->emitTopLevelChanged(true); - } - else - { - for (auto DockArea : d->DockAreas) - { - for (auto DockWidget : DockArea->dockWidgets()) - { - DockWidget->emitTopLevelChanged(false); - } - } - } - return true; } diff --git a/src/DockManager.cpp b/src/DockManager.cpp index eb668b5..609d71e 100644 --- a/src/DockManager.cpp +++ b/src/DockManager.cpp @@ -96,6 +96,27 @@ struct DockManagerPrivate */ bool restoreState(const QByteArray &state, int version); + void restoreDockWidgetsOpenState(); + void restoreDockAreasIndices(); + void emitTopLevelEvents(); + + void hideFloatingWidgets() + { + // Hide updates of floating widgets from use + for (auto FloatingWidget : FloatingWidgets) + { + FloatingWidget->hide(); + } + } + + void markDockWidgetsDirty() + { + for (auto DockWidget : DockWidgetsMap) + { + DockWidget->setProperty("dirty", true); + } + } + /** * Restores the container with the given index */ @@ -229,31 +250,29 @@ bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int versi //============================================================================ -bool DockManagerPrivate::restoreState(const QByteArray &state, int version) +void DockManagerPrivate::restoreDockWidgetsOpenState() { - if (!checkFormat(state, version)) - { - qDebug() << "checkFormat: Error checking format!!!!!!!"; - return false; - } - - // Hide updates of floatingf widgets from use - for (auto FloatingWidget : FloatingWidgets) - { - FloatingWidget->hide(); - } - + // All dock widgets, that have not been processed in the restore state + // function are invisible to the user now and have no assigned dock area + // They do not belong to any dock container, until the user toggles the + // toggle view action the next time for (auto DockWidget : DockWidgetsMap) { - DockWidget->setProperty("dirty", true); + if (DockWidget->property("dirty").toBool()) + { + DockWidget->flagAsUnassigned(); + } + else + { + DockWidget->toggleViewInternal(!DockWidget->property("closed").toBool()); + } } +} - if (!restoreStateFromXml(state, version)) - { - qDebug() << "restoreState: Error restoring state!!!!!!!"; - return false; - } +//============================================================================ +void DockManagerPrivate::restoreDockAreasIndices() +{ // Now all dock areas are properly restored and we setup the index of // The dock areas because the previous toggleView() action has changed // the dock area index @@ -265,18 +284,80 @@ bool DockManagerPrivate::restoreState(const QByteArray &state, int version) { CDockAreaWidget* DockArea = DockContainer->dockArea(i); QString DockWidgetName = DockArea->property("currentDockWidget").toString(); - if (DockWidgetName.isEmpty()) + CDockWidget* DockWidget = nullptr; + if (!DockWidgetName.isEmpty()) { - continue; + DockWidget = _this->findDockWidget(DockWidgetName); } - CDockWidget* DockWidget = _this->findDockWidget(DockWidgetName); - if (!DockWidget->isClosed()) + if (!DockWidget || DockWidget->isClosed()) + { + int Index = DockArea->indexOfFirstOpenDockWidget(); + if (Index < 0) + { + continue; + } + DockArea->setCurrentIndex(Index); + } + else { DockArea->internalSetCurrentDockWidget(DockWidget); } } } +} + + + +//============================================================================ +void DockManagerPrivate::emitTopLevelEvents() +{ + // Finally we need to send the topLevelChanged() signals for all dock + // widgets if top level changed + for (auto DockContainer : Containers) + { + CDockWidget* TopLevelDockWidget = DockContainer->topLevelDockWidget(); + if (TopLevelDockWidget) + { + TopLevelDockWidget->emitTopLevelChanged(true); + } + else + { + for (int i = 0; i < DockContainer->dockAreaCount(); ++i) + { + auto DockArea = DockContainer->dockArea(i); + for (auto DockWidget : DockArea->dockWidgets()) + { + DockWidget->emitTopLevelChanged(false); + } + } + } + } +} + + +//============================================================================ +bool DockManagerPrivate::restoreState(const QByteArray &state, int version) +{ + if (!checkFormat(state, version)) + { + qDebug() << "checkFormat: Error checking format!!!!!!!"; + return false; + } + + // Hide updates of floating widgets from use + hideFloatingWidgets(); + markDockWidgetsDirty(); + + if (!restoreStateFromXml(state, version)) + { + qDebug() << "restoreState: Error restoring state!!!!!!!"; + return false; + } + + restoreDockWidgetsOpenState(); + restoreDockAreasIndices(); + emitTopLevelEvents(); return true; }