Properly implemented restore functionality for auto hide container

This commit is contained in:
Uwe Kindler 2022-11-01 11:02:01 +01:00
parent d1d801cf16
commit 44790307d8
11 changed files with 95 additions and 186 deletions

View File

@ -47,7 +47,7 @@ CMainWindow::CMainWindow(QWidget *parent)
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget); TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->setMinimumSize(200,150); TableDockWidget->setMinimumSize(200,150);
const auto autoHideContainer = DockManager->addAutoHideDockWidget(SideBarLocation::Left, TableDockWidget, CDockWidget::Last); const auto autoHideContainer = DockManager->addAutoHideDockWidget(SideBarLocation::Left, TableDockWidget, CDockWidget::Last);
autoHideContainer->setSize(480, 100); autoHideContainer->setSize(480);
ui->menuView->addAction(TableDockWidget->toggleViewAction()); ui->menuView->addAction(TableDockWidget->toggleViewAction());
table = new QTableWidget(); table = new QTableWidget();

View File

@ -167,7 +167,14 @@ AutoHideDockContainerPrivate::AutoHideDockContainerPrivate(
//============================================================================ //============================================================================
CDockContainerWidget* CAutoHideDockContainer::parentContainer() const CDockContainerWidget* CAutoHideDockContainer::parentContainer() const
{ {
return internal::findParent<CDockContainerWidget*>(this); if (d->DockArea)
{
return d->DockArea->dockContainer();
}
else
{
return internal::findParent<CDockContainerWidget*>(this);
}
} }
@ -176,6 +183,7 @@ CAutoHideDockContainer::CAutoHideDockContainer(CDockManager* DockManager, SideBa
Super(parent), Super(parent),
d(new AutoHideDockContainerPrivate(this)) d(new AutoHideDockContainerPrivate(this))
{ {
hide(); // auto hide dock container is initially always hidden
d->SideTabBarArea = area; d->SideTabBarArea = area;
d->SideTab = componentsFactory()->createDockWidgetSideTab(nullptr); d->SideTab = componentsFactory()->createDockWidgetSideTab(nullptr);
connect(d->SideTab, &CDockWidgetSideTab::pressed, this, &CAutoHideDockContainer::toggleCollapseState); connect(d->SideTab, &CDockWidgetSideTab::pressed, this, &CAutoHideDockContainer::toggleCollapseState);
@ -363,40 +371,11 @@ void CAutoHideDockContainer::cleanupAndDelete()
//============================================================================ //============================================================================
void CAutoHideDockContainer::saveState(QXmlStreamWriter& s) void CAutoHideDockContainer::saveState(QXmlStreamWriter& s)
{ {
s.writeStartElement("Widget");
s.writeAttribute("Name", d->DockWidget->objectName());
s.writeAttribute("Closed", QString::number(d->DockWidget->isClosed() ? 1 : 0));
s.writeAttribute("Size", QString::number(d->isHorizontal() ? d->Size.height() : d->Size.width())); s.writeAttribute("Size", QString::number(d->isHorizontal() ? d->Size.height() : d->Size.width()));
s.writeEndElement();
qDebug() << ": saveState Size: " << d->Size;
qDebug() << ": saveState Size " << QString::number(d->isHorizontal() ? d->Size.height() : d->Size.width());
}
//============================================================================
bool CAutoHideDockContainer::restoreState(CDockingStateReader& s, bool Testing)
{
bool ok;
int Size = s.attributes().value("Size").toInt(&ok);
if (!ok)
{
return false;
}
if (Testing)
{
return true;
}
if (d->isHorizontal())
{
d->Size.setHeight(Size);
}
else
{
d->Size.setWidth(Size);
qDebug() << ": restoreState Width " << Size;
}
qDebug() << ": restoreState Size: " << d->Size;
return true;
} }
@ -438,6 +417,11 @@ void CAutoHideDockContainer::collapseView(bool Enable)
show(); show();
d->DockWidget->dockManager()->setDockWidgetFocused(d->DockWidget); d->DockWidget->dockManager()->setDockWidgetFocused(d->DockWidget);
qApp->installEventFilter(this); qApp->installEventFilter(this);
qDebug() << "CAutoHideDockContainer.hidden " << this->isHidden();
qDebug() << "d->DockArea->isHidden() " << d->DockArea->isHidden();
qDebug() << "d->DockWidget->isHidden() " << d->DockWidget->isHidden();
qDebug() << "CAutoHideDockContainer.geometry() " << this->geometry();
} }
ADS_PRINT("CAutoHideDockContainer::collapseView " << Enable); ADS_PRINT("CAutoHideDockContainer::collapseView " << Enable);
@ -453,9 +437,17 @@ void CAutoHideDockContainer::toggleCollapseState()
//============================================================================ //============================================================================
void CAutoHideDockContainer::setSize(int width, int height) void CAutoHideDockContainer::setSize(int Size)
{ {
d->Size = QSize(width, height); if (d->isHorizontal())
{
d->Size.setHeight(Size);
}
else
{
d->Size.setWidth(Size);
}
updateSize(); updateSize();
} }

View File

@ -46,6 +46,7 @@ class CDockContainerWidget;
class CSideTabBar; class CSideTabBar;
class CDockAreaWidget; class CDockAreaWidget;
class CDockingStateReader; class CDockingStateReader;
struct SideTabBarPrivate;
/** /**
* Auto hide container for hosting an auto hide dock widget * Auto hide container for hosting an auto hide dock widget
@ -57,13 +58,18 @@ class ADS_EXPORT CAutoHideDockContainer : public QFrame
private: private:
AutoHideDockContainerPrivate* d; ///< private data (pimpl) AutoHideDockContainerPrivate* d; ///< private data (pimpl)
friend struct AutoHideDockContainerPrivate; friend struct AutoHideDockContainerPrivate;
friend CSideTabBar;
friend SideTabBarPrivate;
protected: protected:
bool eventFilter(QObject* watched, QEvent* event) override; bool eventFilter(QObject* watched, QEvent* event) override;
void resizeEvent(QResizeEvent* event) override; void resizeEvent(QResizeEvent* event) override;
void updateSize(); void updateSize();
CDockContainerWidget* parentContainer() const; /*
* Saves the state and size
*/
void saveState(QXmlStreamWriter& Stream);
public: public:
using Super = QFrame; using Super = QFrame;
@ -114,6 +120,11 @@ public:
*/ */
CDockAreaWidget* dockAreaWidget() const; CDockAreaWidget* dockAreaWidget() const;
/**
* Returns the parent container that hosts this auto hide container
*/
CDockContainerWidget* parentContainer() const;
/** /**
* Moves the contents to the parent container widget * Moves the contents to the parent container widget
* Used before removing this Auto Hide dock container * Used before removing this Auto Hide dock container
@ -125,16 +136,6 @@ public:
*/ */
void cleanupAndDelete(); void cleanupAndDelete();
/*
* Saves the state and size
*/
void saveState(QXmlStreamWriter& Stream);
/*
* Restores the size of the splitter
*/
bool restoreState(CDockingStateReader& Stream, bool Testing);
/* /*
* Toggles the auto Hide dock container widget * Toggles the auto Hide dock container widget
* This will also hide the side tab widget * This will also hide the side tab widget
@ -153,13 +154,13 @@ public:
void toggleCollapseState(); void toggleCollapseState();
/** /**
* Use this instead of resize. This will ensure the size is consistent internally. * Use this instead of resize.
* E.g. If you set a height less than the parent height when it's vertical * Depending on the sidebar location this will set the width or heigth
* It will simply be rescaled to the parent height while the width will be resized * of this auto hide container.
*/ */
void setSize(int width, int height); void setSize(int Size);
}; };
} } // namespace ads
//-----------------------------------------------------------------------------
#endif #endif

View File

@ -870,13 +870,6 @@ void CDockAreaWidget::saveState(QXmlStreamWriter& s) const
QString Name = CurrentDockWidget ? CurrentDockWidget->objectName() : ""; QString Name = CurrentDockWidget ? CurrentDockWidget->objectName() : "";
s.writeAttribute("Current", Name); s.writeAttribute("Current", Name);
// To keep the saved XML data small, we only save the allowed areas and the
// dock area flags if the values are different from the default values
if (isAutoHide())
{
autoHideDockContainer()->saveState(s);
}
if (d->AllowedAreas != DefaultAllowedAreas) if (d->AllowedAreas != DefaultAllowedAreas)
{ {
s.writeAttribute("AllowedAreas", QString::number(d->AllowedAreas, 16)); s.writeAttribute("AllowedAreas", QString::number(d->AllowedAreas, 16));
@ -897,7 +890,7 @@ void CDockAreaWidget::saveState(QXmlStreamWriter& s) const
//============================================================================ //============================================================================
bool CDockAreaWidget::restoreDockArea(CDockingStateReader& s, CDockAreaWidget*& CreatedWidget, bool CDockAreaWidget::restoreState(CDockingStateReader& s, CDockAreaWidget*& CreatedWidget,
bool Testing, CDockContainerWidget* Container) bool Testing, CDockContainerWidget* Container)
{ {
bool Ok; bool Ok;

View File

@ -301,8 +301,8 @@ public:
* Restores a dock area. * Restores a dock area.
* \see restoreChildNodes() for details * \see restoreChildNodes() for details
*/ */
static bool restoreDockArea(CDockingStateReader& Stream, CDockAreaWidget*& CreatedWidget, static bool restoreState(CDockingStateReader& Stream, CDockAreaWidget*& CreatedWidget,
bool Testing, CDockContainerWidget* Container); bool Testing, CDockContainerWidget* ParentContainer);
/** /**
* This functions returns the dock widget features of all dock widget in * This functions returns the dock widget features of all dock widget in

View File

@ -250,13 +250,6 @@ public:
bool restoreDockArea(CDockingStateReader& Stream, QWidget*& CreatedWidget, bool restoreDockArea(CDockingStateReader& Stream, QWidget*& CreatedWidget,
bool Testing); bool Testing);
/**
* Restores the auto hide dock area.
* Assumes that there are no auto hidden dock areas, and then restores all the dock areas that
* exist in the XML
*/
bool restoreAutoHideDockArea(CDockingStateReader& s, SideBarLocation area, bool Testing);
/** /**
* Restores a auto hide side bar * Restores a auto hide side bar
*/ */
@ -1030,98 +1023,13 @@ bool DockContainerWidgetPrivate::restoreSplitter(CDockingStateReader& s,
return true; return true;
} }
//============================================================================
bool DockContainerWidgetPrivate::restoreAutoHideDockArea(CDockingStateReader& s, SideBarLocation area, bool Testing)
{
if (!CDockManager::testConfigFlag(CDockManager::AutoHideFeatureEnabled))
{
return false;
}
bool Ok;
#ifdef ADS_DEBUG_PRINT
int Tabs = s.attributes().value("Tabs").toInt(&Ok);
if (!Ok)
{
return false;
}
#endif
QString CurrentDockWidget = s.attributes().value("Current").toString();
ADS_PRINT("Restore NodeDockArea Tabs: " << Tabs << " Current: "
<< CurrentDockWidget);
CDockAreaWidget* DockArea = nullptr;
CAutoHideDockContainer* AutoHideContainer = nullptr;
if (!Testing)
{
AutoHideContainer = new CAutoHideDockContainer(DockManager, area, _this);
if (!AutoHideContainer->restoreState(s, Testing))
{
return false;
}
AutoHideContainer->hide();
DockArea = AutoHideContainer->dockAreaWidget();
DockArea->updateAutoHideButtonCheckState();
DockArea->updateTitleBarButtonToolTip();
}
while (s.readNextStartElement())
{
if (s.name() != QLatin1String("Widget"))
{
continue;
}
auto ObjectName = s.attributes().value("Name");
if (ObjectName.isEmpty())
{
return false;
}
bool Closed = s.attributes().value("Closed").toInt(&Ok);
if (!Ok)
{
return false;
}
s.skipCurrentElement();
CDockWidget* DockWidget = DockManager->findDockWidget(ObjectName.toString());
if (!DockWidget || Testing)
{
continue;
}
ADS_PRINT("Dock Widget found - parent " << DockWidget->parent());
// We hide the DockArea here to prevent the short display (the flashing)
// of the dock areas during application startup
DockArea->hide();
DockWidget->setToggleViewActionChecked(!Closed);
DockWidget->setClosedState(Closed);
DockWidget->setProperty(internal::ClosedProperty, Closed);
DockWidget->setProperty(internal::DirtyProperty, false);
_this->sideTabBar(area)->insertSideTab(-1, DockWidget->sideTabWidget());
DockArea->autoHideDockContainer()->addDockWidget(DockWidget);
DockWidget->sideTabWidget()->updateStyle(); // Needed as the side tab widget get it's left/right property from the overlay dock container which was just added
DockArea->autoHideDockContainer()->toggleView(!Closed);
}
if (AutoHideContainer && !AutoHideContainer->dockWidget())
{
AutoHideContainer->cleanupAndDelete();
}
return true;
}
//============================================================================ //============================================================================
bool DockContainerWidgetPrivate::restoreDockArea(CDockingStateReader& s, bool DockContainerWidgetPrivate::restoreDockArea(CDockingStateReader& s,
QWidget*& CreatedWidget, bool Testing) QWidget*& CreatedWidget, bool Testing)
{ {
CDockAreaWidget* DockArea = nullptr; CDockAreaWidget* DockArea = nullptr;
auto Result = CDockAreaWidget::restoreDockArea(s, DockArea, Testing, _this); auto Result = CDockAreaWidget::restoreState(s, DockArea, Testing, _this);
if (Result && DockArea) if (Result && DockArea)
{ {
appendDockAreas({DockArea}); appendDockAreas({DockArea});
@ -1136,14 +1044,14 @@ bool DockContainerWidgetPrivate::restoreSideBar(CDockingStateReader& s,
QWidget*& CreatedWidget, bool Testing) QWidget*& CreatedWidget, bool Testing)
{ {
Q_UNUSED(CreatedWidget) Q_UNUSED(CreatedWidget)
// Simply ignore side bar auto hide widgets // Simply ignore side bar auto hide widgets from saved state if
// auto hide support is disabled
if (!CDockManager::testConfigFlag(CDockManager::AutoHideFeatureEnabled)) if (!CDockManager::testConfigFlag(CDockManager::AutoHideFeatureEnabled))
{ {
return true; return true;
} }
bool Ok; bool Ok;
//int Tabs = s.attributes().value("Tabs").toInt(&Ok);
auto Area = (ads::SideBarLocation)s.attributes().value("Area").toInt(&Ok); auto Area = (ads::SideBarLocation)s.attributes().value("Area").toInt(&Ok);
if (!Ok) if (!Ok)
{ {
@ -1152,15 +1060,42 @@ bool DockContainerWidgetPrivate::restoreSideBar(CDockingStateReader& s,
while (s.readNextStartElement()) while (s.readNextStartElement())
{ {
if (s.name() != QLatin1String("Area")) if (s.name() != QLatin1String("Widget"))
{ {
continue; continue;
} }
if (!restoreAutoHideDockArea(s, Area, Testing)) auto Name = s.attributes().value("Name");
{ if (Name.isEmpty())
return false; {
} return false;
}
bool Ok;
bool Closed = s.attributes().value("Closed").toInt(&Ok);
if (!Ok)
{
return false;
}
int Size = s.attributes().value("Size").toInt(&Ok);
if (!Ok)
{
return false;
}
s.skipCurrentElement();
CDockWidget* DockWidget = DockManager->findDockWidget(Name.toString());
if (!DockWidget || Testing)
{
continue;
}
auto SideBar = _this->sideTabBar(Area);
auto AutoHideContainer = SideBar->insertDockWidget(-1, DockWidget);
AutoHideContainer->setSize(Size);
DockWidget->setProperty(internal::ClosedProperty, Closed);
DockWidget->setProperty(internal::DirtyProperty, false);
} }
return true; return true;
@ -1453,14 +1388,6 @@ CAutoHideDockContainer* CDockContainerWidget::createAndSetupAutoHideContainer(
DockWidget->setDockManager(d->DockManager); // Auto hide Dock Container needs a valid dock manager DockWidget->setDockManager(d->DockManager); // Auto hide Dock Container needs a valid dock manager
} }
/*sideTabBar(area)->insertSideTab(insertOrder == CDockWidget::First ? 0 : -1, DockWidget->sideTabWidget());
DockWidget->sideTabWidget()->show();
const auto AutoHideContainer = new CAutoHideDockContainer(DockWidget, area, this);
AutoHideContainer->hide();
d->DockManager->dockFocusController()->clearDockWidgetFocus(DockWidget);
return AutoHideContainer;*/
return sideTabBar(area)->insertDockWidget(insertOrder == CDockWidget::First ? 0 : -1, DockWidget); return sideTabBar(area)->insertDockWidget(insertOrder == CDockWidget::First ? 0 : -1, DockWidget);
} }

View File

@ -700,7 +700,8 @@ QByteArray CDockManager::saveState(int version) const
QByteArray xmldata; QByteArray xmldata;
QXmlStreamWriter s(&xmldata); QXmlStreamWriter s(&xmldata);
auto ConfigFlags = CDockManager::configFlags(); auto ConfigFlags = CDockManager::configFlags();
s.setAutoFormatting(ConfigFlags.testFlag(XmlAutoFormattingEnabled)); //s.setAutoFormatting(ConfigFlags.testFlag(XmlAutoFormattingEnabled));
s.setAutoFormatting(true);
s.writeStartDocument(); s.writeStartDocument();
s.writeStartElement("QtAdvancedDockingSystem"); s.writeStartElement("QtAdvancedDockingSystem");
s.writeAttribute("Version", QString::number(CurrentVersion)); s.writeAttribute("Version", QString::number(CurrentVersion));

View File

@ -48,6 +48,7 @@ class DockContainerWidgetPrivate;
class CFloatingDockContainer; class CFloatingDockContainer;
class CDockWidgetSideTab; class CDockWidgetSideTab;
class CAutoHideDockContainer; class CAutoHideDockContainer;
class CSideTabBar;
/** /**
* The QDockWidget class provides a widget that can be docked inside a * The QDockWidget class provides a widget that can be docked inside a
@ -78,6 +79,7 @@ protected:
friend struct DockWidgetTabPrivate; friend struct DockWidgetTabPrivate;
friend struct DockAreaTitleBarPrivate; friend struct DockAreaTitleBarPrivate;
friend class CAutoHideDockContainer; friend class CAutoHideDockContainer;
friend CSideTabBar;
/** /**
* Assigns the dock manager that manages this dock widget * Assigns the dock manager that manages this dock widget

View File

@ -114,7 +114,6 @@ SideBarLocation CDockWidgetSideTab::sideTabBarArea() const
{ {
if (d->SideTabBar) if (d->SideTabBar)
{ {
qDebug() << "CDockWidgetSideTab::sideTabBarArea() " << d->SideTabBar->sideTabBarArea();
return d->SideTabBar->sideTabBarArea(); return d->SideTabBar->sideTabBarArea();
} }

View File

@ -42,6 +42,7 @@
#include "DockFocusController.h" #include "DockFocusController.h"
#include "AutoHideDockContainer.h" #include "AutoHideDockContainer.h"
#include "DockAreaWidget.h" #include "DockAreaWidget.h"
#include "DockingStateReader.h"
namespace ads namespace ads
{ {
@ -141,15 +142,6 @@ void CSideTabBar::insertSideTab(int Index, CDockWidgetSideTab* SideTab)
//============================================================================ //============================================================================
CAutoHideDockContainer* CSideTabBar::insertDockWidget(int Index, CDockWidget* DockWidget) CAutoHideDockContainer* CSideTabBar::insertDockWidget(int Index, CDockWidget* DockWidget)
{ {
/*
* sideTabBar(area)->insertSideTab(insertOrder == CDockWidget::First ? 0 : -1, DockWidget->sideTabWidget());
DockWidget->sideTabWidget()->show();
const auto AutoHideContainer = new CAutoHideDockContainer(DockWidget, area, this);
AutoHideContainer->hide();
d->DockManager->dockFocusController()->clearDockWidgetFocus(DockWidget);
return AutoHideContainer;*/
auto AutoHideContainer = new CAutoHideDockContainer(DockWidget, d->SideTabArea, d->ContainerWidget); auto AutoHideContainer = new CAutoHideDockContainer(DockWidget, d->SideTabArea, d->ContainerWidget);
DockWidget->dockManager()->dockFocusController()->clearDockWidgetFocus(DockWidget); DockWidget->dockManager()->dockFocusController()->clearDockWidgetFocus(DockWidget);
auto Tab = AutoHideContainer->sideTab(); auto Tab = AutoHideContainer->sideTab();
@ -297,10 +289,11 @@ void CSideTabBar::saveState(QXmlStreamWriter& s) const
continue; continue;
} }
auto DockArea = Tab->dockWidget()->dockAreaWidget(); Tab->dockWidget()->autoHideDockContainer()->saveState(s);
DockArea->saveState(s);
} }
s.writeEndElement(); s.writeEndElement();
} }
}
} // namespace ads

View File

@ -42,6 +42,7 @@ class DockContainerWidgetPrivate;
class CDockContainerWidget; class CDockContainerWidget;
class CDockWidgetSideTab; class CDockWidgetSideTab;
class CAutoHideDockContainer; class CAutoHideDockContainer;
class CDockingStateReader;
/** /**
* Side tab bar widget that is shown at the edges of a dock container. * Side tab bar widget that is shown at the edges of a dock container.