From c45327aafdfa19f065bc83f6f6e750233ecb2e60 Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Wed, 26 Jun 2019 14:57:14 +0200 Subject: [PATCH 1/2] Removed enum eXmlMode and added XmlAutoFormatting flag anc XmlCompressionEnabled flag to eConfigFlags. Added support for XML compression for the XML generated by the store function. If enabled then XML the generated XML is not human readable anymore but it needs less space when storing into settings file --- src/DockManager.cpp | 9 +++++---- src/DockManager.h | 16 +++++++--------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/DockManager.cpp b/src/DockManager.cpp index c3b3ace..9de76eb 100644 --- a/src/DockManager.cpp +++ b/src/DockManager.cpp @@ -336,8 +336,9 @@ void DockManagerPrivate::emitTopLevelEvents() //============================================================================ -bool DockManagerPrivate::restoreState(const QByteArray &state, int version) +bool DockManagerPrivate::restoreState(const QByteArray& State, int version) { + QByteArray state = State.startsWith("ConfigFlags.testFlag(XmlAutoFormattingEnabled)); s.writeStartDocument(); s.writeStartElement("QtAdvancedDockingSystem"); s.writeAttribute("Version", QString::number(version)); @@ -506,7 +507,7 @@ QByteArray CDockManager::saveState(eXmlMode XmlMode, int version) const s.writeEndElement(); s.writeEndDocument(); - return xmldata; + return d->ConfigFlags.testFlag(XmlCompressionEnabled) ? qCompress(xmldata, 9) : xmldata; } diff --git a/src/DockManager.h b/src/DockManager.h index 72ab026..4a6dfdc 100644 --- a/src/DockManager.h +++ b/src/DockManager.h @@ -51,7 +51,9 @@ struct DockWidgetTabPrivate; struct DockAreaWidgetPrivate; /** - * The central dock manager that maintains the complete docking system + * The central dock manager that maintains the complete docking system. + * With the configuration flags you can globally control the functionality + * of the docking system. **/ class ADS_EXPORT CDockManager : public CDockContainerWidget { @@ -108,12 +110,6 @@ public: MenuAlphabeticallySorted }; - enum eXmlMode - { - XmlAutoFormattingDisabled, - XmlAutoFormattingEnabled - }; - /** * These global configuration flags configure some global dock manager * settings. @@ -124,7 +120,9 @@ public: DockAreaHasCloseButton = 0x02, //!< If the flag is set each dock area has a close button DockAreaCloseButtonClosesTab = 0x04,//!< If the flag is set, the dock area close button closes the active tab, if not set, it closes the complete cock area OpaqueSplitterResize = 0x08, //!< See QSplitter::setOpaqueResize() documentation - DefaultConfig = ActiveTabHasCloseButton | DockAreaHasCloseButton | OpaqueSplitterResize, ///< the default configuration + XmlAutoFormattingEnabled = 0x10,//!< If enabled, the XML writer automatically adds line-breaks and indentation to empty sections between elements (ignorable whitespace). + XmlCompressionEnabled = 0x20,//!< If enabled, the XML output will be compressed and is not human readable anymore + DefaultConfig = ActiveTabHasCloseButton | DockAreaHasCloseButton | OpaqueSplitterResize | XmlCompressionEnabled, ///< the default configuration }; Q_DECLARE_FLAGS(ConfigFlags, eConfigFlag) @@ -228,7 +226,7 @@ public: * The XmlMode XmlAutoFormattingDisabled is better if you would like to have * a more compact XML output - i.e. for storage in ini files. */ - QByteArray saveState(eXmlMode XmlMode = XmlAutoFormattingDisabled, int version = 0) const; + QByteArray saveState(int version = 0) const; /** * Restores the state of this dockmanagers dockwidgets. From 0de1a9ccae2234fff7ec9cc2a0af8b29e9adfe1e Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Thu, 11 Jul 2019 15:12:39 +0200 Subject: [PATCH 2/2] Properly implemented support for DockWidgetFloatable feature - now detaching a DockWidget or a DockAre that is not floatable is not possible (support for DockWidgetMovable feature is not implemented yet) --- demo/MainWindow.cpp | 31 ++++++++++++++++++++++++++++++- src/DockAreaTabBar.cpp | 12 ++++++++++++ src/DockAreaTitleBar.cpp | 10 +++++++--- src/DockAreaWidget.cpp | 22 ++++++++++++---------- src/DockWidget.h | 2 +- src/DockWidgetTab.cpp | 16 ++++++++++------ 6 files changed, 72 insertions(+), 21 deletions(-) diff --git a/demo/MainWindow.cpp b/demo/MainWindow.cpp index 50aa1d7..5e10d98 100644 --- a/demo/MainWindow.cpp +++ b/demo/MainWindow.cpp @@ -88,6 +88,32 @@ static ads::CDockWidget* createLongTextLabelDockWidget(QMenu* ViewMenu) } +/** + * Function returns a features string with closable (c), movable (m) and floatable (f) + * features. i.e. The following string is for a not closable but movable and floatable + * widget: c- m+ f+ + */ +static QString featuresString(ads::CDockWidget* DockWidget) +{ + auto f = DockWidget->features(); + return QString("c%1 m%2 f%3") + .arg(f.testFlag(ads::CDockWidget::DockWidgetClosable) ? "+" : "-") + .arg(f.testFlag(ads::CDockWidget::DockWidgetMovable) ? "+" : "-") + .arg(f.testFlag(ads::CDockWidget::DockWidgetFloatable) ? "+" : "-"); +} + + +/** + * Appends the string returned by featuresString() to the window title of + * the given DockWidget + */ +static void appendFeaturStringToWindowTitle(ads::CDockWidget* DockWidget) +{ + DockWidget->setWindowTitle(DockWidget->windowTitle() + + QString(" (%1)").arg(featuresString(DockWidget))); +} + + //============================================================================ static ads::CDockWidget* createCalendarDockWidget(QMenu* ViewMenu) { @@ -110,7 +136,8 @@ static ads::CDockWidget* createFileSystemTreeDockWidget(QMenu* ViewMenu) QFileSystemModel* m = new QFileSystemModel(w); m->setRootPath(QDir::currentPath()); w->setModel(m); - ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Filesystem %1").arg(FileSystemCount++)); + ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Filesystem %1") + .arg(FileSystemCount++)); DockWidget->setWidget(w); ViewMenu->addAction(DockWidget->toggleViewAction()); return DockWidget; @@ -185,6 +212,8 @@ void MainWindowPrivate::createContent() ToolBar->addAction(ui.actionSaveState); ToolBar->addAction(ui.actionRestoreState); FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false); + FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false); + appendFeaturStringToWindowTitle(FileSystemWidget); auto TopDockArea = DockManager->addDockWidget(ads::TopDockWidgetArea, FileSystemWidget); DockWidget = createCalendarDockWidget(ViewMenu); DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false); diff --git a/src/DockAreaTabBar.cpp b/src/DockAreaTabBar.cpp index a579a6c..7f9ab97 100644 --- a/src/DockAreaTabBar.cpp +++ b/src/DockAreaTabBar.cpp @@ -205,6 +205,13 @@ void CDockAreaTabBar::mouseMoveEvent(QMouseEvent* ev) return; } + // If one single dock widget in this area is not floatable then the whole + // area is not floatable + if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable)) + { + return; + } + int DragDistance = (d->DragStartMousePos - ev->pos()).manhattanLength(); if (DragDistance >= CDockManager::startDragDistance()) { @@ -228,6 +235,11 @@ void CDockAreaTabBar::mouseDoubleClickEvent(QMouseEvent *event) { return; } + + if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable)) + { + return; + } makeAreaFloating(event->pos(), DraggingInactive); } diff --git a/src/DockAreaTitleBar.cpp b/src/DockAreaTitleBar.cpp index 5802760..ace9a21 100644 --- a/src/DockAreaTitleBar.cpp +++ b/src/DockAreaTitleBar.cpp @@ -288,7 +288,10 @@ void CDockAreaTitleBar::onCloseButtonClicked() //============================================================================ void CDockAreaTitleBar::onUndockButtonClicked() { - d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive); + if (d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable)) + { + d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive); + } } @@ -343,9 +346,10 @@ void CDockAreaTitleBar::setVisible(bool Visible) void CDockAreaTitleBar::showContextMenu(const QPoint& pos) { QMenu Menu(this); - Menu.addAction(tr("Detach Area"), this, SLOT(onUndockButtonClicked())); + auto Action = Menu.addAction(tr("Detach Area"), this, SLOT(onUndockButtonClicked())); + Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable)); Menu.addSeparator(); - auto Action = Menu.addAction(tr("Close Area"), this, SLOT(onCloseButtonClicked())); + Action = Menu.addAction(tr("Close Area"), this, SLOT(onCloseButtonClicked())); Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable)); Menu.addAction(tr("Close Other Areas"), d->DockArea, SLOT(closeOtherAreas())); Menu.exec(mapToGlobal(pos)); diff --git a/src/DockAreaWidget.cpp b/src/DockAreaWidget.cpp index 292d54b..c2d6e6c 100644 --- a/src/DockAreaWidget.cpp +++ b/src/DockAreaWidget.cpp @@ -241,7 +241,7 @@ struct DockAreaWidgetPrivate DockAreaLayout* ContentsLayout = nullptr; CDockAreaTitleBar* TitleBar = nullptr; CDockManager* DockManager = nullptr; - bool UpdateCloseButton = false; + bool UpdateTitleBarButtons = false; /** * Private data constructor @@ -295,9 +295,9 @@ struct DockAreaWidgetPrivate } /** - * Udpates the enable state of the close button + * Udpates the enable state of the close and detach button */ - void updateCloseButtonState(); + void updateTitleBarButtonStates(); }; // struct DockAreaWidgetPrivate @@ -322,17 +322,19 @@ void DockAreaWidgetPrivate::createTitleBar() //============================================================================ -void DockAreaWidgetPrivate::updateCloseButtonState() +void DockAreaWidgetPrivate::updateTitleBarButtonStates() { if (_this->isHidden()) { - UpdateCloseButton = true; + UpdateTitleBarButtons = true; return; } TitleBar->button(TitleBarButtonClose)->setEnabled( _this->features().testFlag(CDockWidget::DockWidgetClosable)); - UpdateCloseButton = false; + TitleBar->button(TitleBarButtonUndock)->setEnabled( + _this->features().testFlag(CDockWidget::DockWidgetFloatable)); + UpdateTitleBarButtons = false; } @@ -400,7 +402,7 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget, setCurrentIndex(index); } DockWidget->setDockArea(this); - d->updateCloseButtonState(); + d->updateTitleBarButtonStates(); } @@ -433,7 +435,7 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget) hideAreaWithNoVisibleContent(); } - d->updateCloseButtonState(); + d->updateTitleBarButtonStates(); updateTitleBarVisibility(); auto TopLevelDockWidget = DockContainer->topLevelDockWidget(); if (TopLevelDockWidget) @@ -765,9 +767,9 @@ void CDockAreaWidget::toggleView(bool Open) void CDockAreaWidget::setVisible(bool Visible) { Super::setVisible(Visible); - if (d->UpdateCloseButton) + if (d->UpdateTitleBarButtons) { - d->updateCloseButtonState(); + d->updateTitleBarButtonStates(); } } diff --git a/src/DockWidget.h b/src/DockWidget.h index 658372f..32152db 100644 --- a/src/DockWidget.h +++ b/src/DockWidget.h @@ -141,7 +141,7 @@ public: enum DockWidgetFeature { DockWidgetClosable = 0x01, - DockWidgetMovable = 0x02, + DockWidgetMovable = 0x02,///< this feature is not properly implemented yet and is ignored DockWidgetFloatable = 0x04, AllDockWidgetFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable, NoDockWidgetFeatures = 0x00 diff --git a/src/DockWidgetTab.cpp b/src/DockWidgetTab.cpp index 496a5f8..d2f5c3a 100644 --- a/src/DockWidgetTab.cpp +++ b/src/DockWidgetTab.cpp @@ -327,7 +327,7 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev) } // Floating is only allowed for widgets that are movable - if (d->DockWidget->features().testFlag(CDockWidget::DockWidgetMovable)) + if (d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable)) { d->startFloating(); } @@ -351,9 +351,10 @@ void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev) d->DragStartMousePosition = ev->pos(); QMenu Menu(this); - Menu.addAction(tr("Detach"), this, SLOT(onDetachActionTriggered())); + auto Action = Menu.addAction(tr("Detach"), this, SLOT(onDetachActionTriggered())); + Action->setEnabled(d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable)); Menu.addSeparator(); - auto Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested())); + Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested())); Action->setEnabled(isClosable()); Menu.addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested())); Menu.exec(mapToGlobal(ev->pos())); @@ -468,7 +469,8 @@ void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event) // If this is the last dock area in a dock container it does not make // sense to move it to a new floating widget and leave this one // empty - if (!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1) + if ((!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1) + && d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable)) { d->DragStartMousePosition = event->pos(); d->startFloating(DraggingInactive); @@ -504,13 +506,15 @@ bool CDockWidgetTab::isClosable() const //=========================================================================== void CDockWidgetTab::onDetachActionTriggered() { + if (!d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable)) + { + return; + } d->DragStartMousePosition = mapFromGlobal(QCursor::pos()); d->startFloating(DraggingInactive); } - - //============================================================================ bool CDockWidgetTab::event(QEvent *e) {