Added support for file version handling for dock state files, added support for reading version 0 state file with wrong orientation character

This commit is contained in:
Uwe Kindler 2019-11-29 15:56:57 +01:00
parent 2ee7deb6d5
commit d3ad17d2c6
11 changed files with 124 additions and 31 deletions

View File

@ -37,6 +37,7 @@ set(ads_SRCS
src/DockSplitter.cpp src/DockSplitter.cpp
src/DockWidget.cpp src/DockWidget.cpp
src/DockWidgetTab.cpp src/DockWidgetTab.cpp
src/DockingStateReader.cpp
src/ElidingLabel.cpp src/ElidingLabel.cpp
src/FloatingDockContainer.cpp src/FloatingDockContainer.cpp
src/FloatingOverlay.cpp src/FloatingOverlay.cpp
@ -55,6 +56,7 @@ set(ads_INSTALL_INCLUDE
src/DockSplitter.h src/DockSplitter.h
src/DockWidget.h src/DockWidget.h
src/DockWidgetTab.h src/DockWidgetTab.h
src/DockingStateReader.h
src/ElidingLabel.h src/ElidingLabel.h
src/FloatingDockContainer.h src/FloatingDockContainer.h
src/FloatingOverlay.h src/FloatingOverlay.h

View File

@ -42,6 +42,7 @@
#include "DockManager.h" #include "DockManager.h"
#include "DockAreaWidget.h" #include "DockAreaWidget.h"
#include "DockWidget.h" #include "DockWidget.h"
#include "DockingStateReader.h"
#include "FloatingDockContainer.h" #include "FloatingDockContainer.h"
#include "DockOverlay.h" #include "DockOverlay.h"
#include "ads_globals.h" #include "ads_globals.h"
@ -218,21 +219,21 @@ public:
* \param[in] Testing If Testing is true, only the stream data is * \param[in] Testing If Testing is true, only the stream data is
* parsed without modifiying anything. * parsed without modifiying anything.
*/ */
bool restoreChildNodes(QXmlStreamReader& Stream, QWidget*& CreatedWidget, bool restoreChildNodes(CDockingStateReader& Stream, QWidget*& CreatedWidget,
bool Testing); bool Testing);
/** /**
* Restores a splitter. * Restores a splitter.
* \see restoreChildNodes() for details * \see restoreChildNodes() for details
*/ */
bool restoreSplitter(QXmlStreamReader& Stream, QWidget*& CreatedWidget, bool restoreSplitter(CDockingStateReader& Stream, QWidget*& CreatedWidget,
bool Testing); bool Testing);
/** /**
* Restores a dock area. * Restores a dock area.
* \see restoreChildNodes() for details * \see restoreChildNodes() for details
*/ */
bool restoreDockArea(QXmlStreamReader& Stream, QWidget*& CreatedWidget, bool restoreDockArea(CDockingStateReader& Stream, QWidget*& CreatedWidget,
bool Testing); bool Testing);
/** /**
@ -771,25 +772,30 @@ void DockContainerWidgetPrivate::saveChildNodesState(QXmlStreamWriter& s, QWidge
//============================================================================ //============================================================================
bool DockContainerWidgetPrivate::restoreSplitter(QXmlStreamReader& s, bool DockContainerWidgetPrivate::restoreSplitter(CDockingStateReader& s,
QWidget*& CreatedWidget, bool Testing) QWidget*& CreatedWidget, bool Testing)
{ {
bool Ok; bool Ok;
QString OrientationStr = s.attributes().value("Orientation").toString(); QString OrientationStr = s.attributes().value("Orientation").toString();
int Orientation;
if (OrientationStr.startsWith("|")) // Check if the orientation string is right
{ if (!OrientationStr.startsWith("|") && !OrientationStr.startsWith("-"))
Orientation = Qt::Horizontal;
}
else if (OrientationStr.startsWith("-"))
{
Orientation = Qt::Vertical;
}
else
{ {
return false; return false;
} }
// The "|" shall indicate a vertical splitter handle which in turn means
// a Horizontal orientation of the splitter layout.
bool HorizontalSplitter = OrientationStr.startsWith("|");
// In version 0 we had a small bug. The "|" indicated a vertical orientation,
// but this is wrong, because only the splitter handle is vertical, the
// layout of the splitter is a horizontal layout. We fix this here
if (s.fileVersion() == 0)
{
HorizontalSplitter = !HorizontalSplitter;
}
int Orientation = HorizontalSplitter ? Qt::Horizontal : Qt::Vertical;
int WidgetCount = s.attributes().value("Count").toInt(&Ok); int WidgetCount = s.attributes().value("Count").toInt(&Ok);
if (!Ok) if (!Ok)
{ {
@ -878,7 +884,7 @@ bool DockContainerWidgetPrivate::restoreSplitter(QXmlStreamReader& s,
//============================================================================ //============================================================================
bool DockContainerWidgetPrivate::restoreDockArea(QXmlStreamReader& s, bool DockContainerWidgetPrivate::restoreDockArea(CDockingStateReader& s,
QWidget*& CreatedWidget, bool Testing) QWidget*& CreatedWidget, bool Testing)
{ {
bool Ok; bool Ok;
@ -959,7 +965,7 @@ bool DockContainerWidgetPrivate::restoreDockArea(QXmlStreamReader& s,
//============================================================================ //============================================================================
bool DockContainerWidgetPrivate::restoreChildNodes(QXmlStreamReader& s, bool DockContainerWidgetPrivate::restoreChildNodes(CDockingStateReader& s,
QWidget*& CreatedWidget, bool Testing) QWidget*& CreatedWidget, bool Testing)
{ {
bool Result = true; bool Result = true;
@ -1508,7 +1514,7 @@ void CDockContainerWidget::saveState(QXmlStreamWriter& s) const
//============================================================================ //============================================================================
bool CDockContainerWidget::restoreState(QXmlStreamReader& s, bool Testing) bool CDockContainerWidget::restoreState(CDockingStateReader& s, bool Testing)
{ {
bool IsFloating = s.attributes().value("Floating").toInt(); bool IsFloating = s.attributes().value("Floating").toInt();
ADS_PRINT("Restore CDockContainerWidget Floating" << IsFloating); ADS_PRINT("Restore CDockContainerWidget Floating" << IsFloating);
@ -1529,7 +1535,7 @@ bool CDockContainerWidget::restoreState(QXmlStreamReader& s, bool Testing)
return false; return false;
} }
QByteArray GeometryString = s.readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).toLocal8Bit(); QByteArray GeometryString = s.readElementText(CDockingStateReader::ErrorOnUnexpectedElement).toLocal8Bit();
QByteArray Geometry = QByteArray::fromHex(GeometryString); QByteArray Geometry = QByteArray::fromHex(GeometryString);
if (Geometry.isEmpty()) if (Geometry.isEmpty())
{ {

View File

@ -36,7 +36,7 @@
#include "DockWidget.h" #include "DockWidget.h"
class QXmlStreamWriter; class QXmlStreamWriter;
class QXmlStreamReader;
namespace ads namespace ads
{ {
@ -49,6 +49,7 @@ class CFloatingDockContainer;
struct FloatingDockContainerPrivate; struct FloatingDockContainerPrivate;
class CFloatingOverlay; class CFloatingOverlay;
struct FloatingOverlayPrivate; struct FloatingOverlayPrivate;
class CDockingStateReader;
/** /**
* Container that manages a number of dock areas with single dock widgets * Container that manages a number of dock areas with single dock widgets
@ -120,7 +121,7 @@ protected:
* stream but does not restore anything. You can use this check for * stream but does not restore anything. You can use this check for
* faulty files before you start restoring the state * faulty files before you start restoring the state
*/ */
bool restoreState(QXmlStreamReader& Stream, bool Testing); bool restoreState(CDockingStateReader& Stream, bool Testing);
/** /**
* This function returns the last added dock area widget for the given * This function returns the last added dock area widget for the given

View File

@ -42,7 +42,6 @@
#include <QFile> #include <QFile>
#include <QAction> #include <QAction>
#include <QXmlStreamWriter> #include <QXmlStreamWriter>
#include <QXmlStreamReader>
#include <QSettings> #include <QSettings>
#include <QMenu> #include <QMenu>
#include <QApplication> #include <QApplication>
@ -53,6 +52,7 @@
#include "ads_globals.h" #include "ads_globals.h"
#include "DockAreaWidget.h" #include "DockAreaWidget.h"
#include "IconProvider.h" #include "IconProvider.h"
#include "DockingStateReader.h"
@ -123,7 +123,7 @@ struct DockManagerPrivate
/** /**
* Restores the container with the given index * Restores the container with the given index
*/ */
bool restoreContainer(int Index, QXmlStreamReader& stream, bool Testing); bool restoreContainer(int Index, CDockingStateReader& stream, bool Testing);
/** /**
* Loads the stylesheet * Loads the stylesheet
@ -163,7 +163,7 @@ void DockManagerPrivate::loadStylesheet()
//============================================================================ //============================================================================
bool DockManagerPrivate::restoreContainer(int Index, QXmlStreamReader& stream, bool Testing) bool DockManagerPrivate::restoreContainer(int Index, CDockingStateReader& stream, bool Testing)
{ {
if (Testing) if (Testing)
{ {
@ -209,7 +209,7 @@ bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int versi
{ {
return false; return false;
} }
QXmlStreamReader s(state); CDockingStateReader s(state);
s.readNextStartElement(); s.readNextStartElement();
if (s.name() != "QtAdvancedDockingSystem") if (s.name() != "QtAdvancedDockingSystem")
{ {
@ -218,11 +218,12 @@ bool DockManagerPrivate::restoreStateFromXml(const QByteArray &state, int versi
ADS_PRINT(s.attributes().value("Version")); ADS_PRINT(s.attributes().value("Version"));
bool ok; bool ok;
int v = s.attributes().value("Version").toInt(&ok); int v = s.attributes().value("Version").toInt(&ok);
if (!ok || v != version) if (!ok || v > CurrentVersion)
{ {
return false; return false;
} }
s.setFileVersion(v);
bool Result = true; bool Result = true;
#ifdef ADS_DEBUG_PRINT #ifdef ADS_DEBUG_PRINT
int DockContainers = s.attributes().value("Containers").toInt(); int DockContainers = s.attributes().value("Containers").toInt();

View File

@ -291,7 +291,7 @@ public:
* The XmlMode XmlAutoFormattingDisabled is better if you would like to have * The XmlMode XmlAutoFormattingDisabled is better if you would like to have
* a more compact XML output - i.e. for storage in ini files. * a more compact XML output - i.e. for storage in ini files.
*/ */
QByteArray saveState(int version = 0) const; QByteArray saveState(int version = Version1) const;
/** /**
* Restores the state of this dockmanagers dockwidgets. * Restores the state of this dockmanagers dockwidgets.
@ -300,7 +300,7 @@ public:
* returns false; otherwise, the state is restored, and this function * returns false; otherwise, the state is restored, and this function
* returns true. * returns true.
*/ */
bool restoreState(const QByteArray &state, int version = 0); bool restoreState(const QByteArray &state, int version = Version1);
/** /**
* Saves the current perspective to the internal list of perspectives. * Saves the current perspective to the internal list of perspectives.

View File

@ -0,0 +1,30 @@
//============================================================================
/// \file DockingStateReader.cpp
/// \author Uwe Kindler
/// \date 29.11.2019
/// \brief Implementation of CDockingStateReader
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include "DockingStateReader.h"
namespace ads
{
//============================================================================
void CDockingStateReader::setFileVersion(int FileVersion)
{
m_FileVersion = FileVersion;
}
//============================================================================
int CDockingStateReader::fileVersion() const
{
return m_FileVersion;
}
} // namespace ads
//---------------------------------------------------------------------------
// EOF DockingStateReader.cpp

43
src/DockingStateReader.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef DockingStateReaderH
#define DockingStateReaderH
//============================================================================
/// \file DockingStateReader.h
/// \author Uwe Kindler
/// \date 29.11.2019
/// \brief Declaration of CDockingStateReader
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include <QXmlStreamReader>
namespace ads
{
/**
* Extends QXmlStreamReader with file version information
*/
class CDockingStateReader : public QXmlStreamReader
{
private:
int m_FileVersion;
public:
using QXmlStreamReader::QXmlStreamReader;
/**
* Set the file version for this state reader
*/
void setFileVersion(int FileVersion);
/**
* Returns the file version set via setFileVersion
*/
int fileVersion() const;
};
} // namespace ads
//---------------------------------------------------------------------------
#endif // DockingStateReaderH

View File

@ -589,7 +589,7 @@ void CFloatingDockContainer::onDockAreaCurrentChanged(int Index)
} }
//============================================================================ //============================================================================
bool CFloatingDockContainer::restoreState(QXmlStreamReader &Stream, bool CFloatingDockContainer::restoreState(CDockingStateReader &Stream,
bool Testing) bool Testing)
{ {
if (!d->DockContainer->restoreState(Stream, Testing)) if (!d->DockContainer->restoreState(Stream, Testing))

View File

@ -41,7 +41,7 @@
#define tFloatingWidgetBase QWidget #define tFloatingWidgetBase QWidget
#endif #endif
class QXmlStreamReader; class CDockingStateReader;
namespace ads namespace ads
{ {
@ -58,6 +58,7 @@ struct DockWidgetTabPrivate;
class CDockAreaTitleBar; class CDockAreaTitleBar;
struct DockAreaTitleBarPrivate; struct DockAreaTitleBarPrivate;
class CFloatingWidgetTitleBar; class CFloatingWidgetTitleBar;
class CDockingStateReader;
/** /**
* Pure virtual interface for floating widgets * Pure virtual interface for floating widgets
@ -148,7 +149,7 @@ protected:
* stream but does not restore anything. You can use this check for * stream but does not restore anything. You can use this check for
* faulty files before you start restoring the state * faulty files before you start restoring the state
*/ */
bool restoreState(QXmlStreamReader& Stream, bool Testing); bool restoreState(CDockingStateReader& Stream, bool Testing);
/** /**
* Call this function to update the window title * Call this function to update the window title

View File

@ -61,6 +61,13 @@ class QSplitter;
namespace ads namespace ads
{ {
enum eStateFileVersion
{
InitialVerison = 0,
Version1 = 1,
CurrentVersion = Version1
};
class CDockSplitter; class CDockSplitter;
enum DockWidgetArea enum DockWidgetArea

View File

@ -36,6 +36,7 @@ HEADERS += \
DockManager.h \ DockManager.h \
DockWidget.h \ DockWidget.h \
DockWidgetTab.h \ DockWidgetTab.h \
DockingStateReader.h \
FloatingDockContainer.h \ FloatingDockContainer.h \
FloatingOverlay.h \ FloatingOverlay.h \
DockOverlay.h \ DockOverlay.h \
@ -52,6 +53,7 @@ SOURCES += \
DockContainerWidget.cpp \ DockContainerWidget.cpp \
DockManager.cpp \ DockManager.cpp \
DockWidget.cpp \ DockWidget.cpp \
DockingStateReader.cpp \
DockWidgetTab.cpp \ DockWidgetTab.cpp \
FloatingDockContainer.cpp \ FloatingDockContainer.cpp \
FloatingOverlay.cpp \ FloatingOverlay.cpp \