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->setMinimumSize(200,150);
const auto autoHideContainer = DockManager->addAutoHideDockWidget(SideBarLocation::Left, TableDockWidget, CDockWidget::Last);
autoHideContainer->setSize(480, 100);
autoHideContainer->setSize(480);
ui->menuView->addAction(TableDockWidget->toggleViewAction());
table = new QTableWidget();

View File

@ -167,7 +167,14 @@ AutoHideDockContainerPrivate::AutoHideDockContainerPrivate(
//============================================================================
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),
d(new AutoHideDockContainerPrivate(this))
{
hide(); // auto hide dock container is initially always hidden
d->SideTabBarArea = area;
d->SideTab = componentsFactory()->createDockWidgetSideTab(nullptr);
connect(d->SideTab, &CDockWidgetSideTab::pressed, this, &CAutoHideDockContainer::toggleCollapseState);
@ -363,40 +371,11 @@ void CAutoHideDockContainer::cleanupAndDelete()
//============================================================================
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()));
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;
s.writeEndElement();
}
@ -438,6 +417,11 @@ void CAutoHideDockContainer::collapseView(bool Enable)
show();
d->DockWidget->dockManager()->setDockWidgetFocused(d->DockWidget);
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);
@ -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();
}

View File

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

View File

@ -870,13 +870,6 @@ void CDockAreaWidget::saveState(QXmlStreamWriter& s) const
QString Name = CurrentDockWidget ? CurrentDockWidget->objectName() : "";
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)
{
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 Ok;

View File

@ -301,8 +301,8 @@ public:
* Restores a dock area.
* \see restoreChildNodes() for details
*/
static bool restoreDockArea(CDockingStateReader& Stream, CDockAreaWidget*& CreatedWidget,
bool Testing, CDockContainerWidget* Container);
static bool restoreState(CDockingStateReader& Stream, CDockAreaWidget*& CreatedWidget,
bool Testing, CDockContainerWidget* ParentContainer);
/**
* 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 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
*/
@ -1030,98 +1023,13 @@ bool DockContainerWidgetPrivate::restoreSplitter(CDockingStateReader& s,
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,
QWidget*& CreatedWidget, bool Testing)
{
CDockAreaWidget* DockArea = nullptr;
auto Result = CDockAreaWidget::restoreDockArea(s, DockArea, Testing, _this);
auto Result = CDockAreaWidget::restoreState(s, DockArea, Testing, _this);
if (Result && DockArea)
{
appendDockAreas({DockArea});
@ -1136,14 +1044,14 @@ bool DockContainerWidgetPrivate::restoreSideBar(CDockingStateReader& s,
QWidget*& CreatedWidget, bool Testing)
{
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))
{
return true;
}
bool Ok;
//int Tabs = s.attributes().value("Tabs").toInt(&Ok);
auto Area = (ads::SideBarLocation)s.attributes().value("Area").toInt(&Ok);
if (!Ok)
{
@ -1152,15 +1060,42 @@ bool DockContainerWidgetPrivate::restoreSideBar(CDockingStateReader& s,
while (s.readNextStartElement())
{
if (s.name() != QLatin1String("Area"))
if (s.name() != QLatin1String("Widget"))
{
continue;
}
if (!restoreAutoHideDockArea(s, Area, Testing))
{
return false;
}
auto Name = s.attributes().value("Name");
if (Name.isEmpty())
{
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;
@ -1453,14 +1388,6 @@ CAutoHideDockContainer* CDockContainerWidget::createAndSetupAutoHideContainer(
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);
}

View File

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

View File

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

View File

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

View File

@ -42,6 +42,7 @@
#include "DockFocusController.h"
#include "AutoHideDockContainer.h"
#include "DockAreaWidget.h"
#include "DockingStateReader.h"
namespace ads
{
@ -141,15 +142,6 @@ void CSideTabBar::insertSideTab(int Index, CDockWidgetSideTab* SideTab)
//============================================================================
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);
DockWidget->dockManager()->dockFocusController()->clearDockWidgetFocus(DockWidget);
auto Tab = AutoHideContainer->sideTab();
@ -297,10 +289,11 @@ void CSideTabBar::saveState(QXmlStreamWriter& s) const
continue;
}
auto DockArea = Tab->dockWidget()->dockAreaWidget();
DockArea->saveState(s);
Tab->dockWidget()->autoHideDockContainer()->saveState(s);
}
s.writeEndElement();
}
}
} // namespace ads

View File

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