Fixed bug with FloatingWidget deletion, fixed handling of unassigned DockWidgets after restoreState() call

This commit is contained in:
Uwe Kindler 2017-03-28 10:57:03 +02:00
parent 9adc524a42
commit aa8a52b845
6 changed files with 134 additions and 21 deletions

View File

@ -34,6 +34,7 @@
#include <QList>
#include <QGridLayout>
#include <QPointer>
#include <QVariant>
#include "DockManager.h"
#include "DockAreaWidget.h"
@ -432,6 +433,7 @@ bool DockContainerWidgetPrivate::restoreDockArea(QDataStream& stream,
<< std::endl;
DockArea->addDockWidget(DockWidget);
DockWidget->toggleView(!Closed);
DockWidget->setProperty("dirty", false);
}
if (Testing)
@ -528,6 +530,7 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
//============================================================================
void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
{
#if defined(QT_DEBUG)
QSplitter* Splitter = dynamic_cast<QSplitter*>(widget);
QByteArray buf;
buf.fill(' ', level * 4);
@ -549,6 +552,7 @@ void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
}
std::cout << buf.toStdString() << "DockArea" << std::endl;
}
#endif
}

View File

@ -33,6 +33,7 @@
#include <QMainWindow>
#include <QList>
#include <QMap>
#include <QVariant>
#include <iostream>
@ -41,6 +42,7 @@
#include "DockWidget.h"
#include "ads_globals.h"
#include "DockStateSerialization.h"
#include "DockWidgetTitleBar.h"
namespace ads
{
@ -77,6 +79,11 @@ struct DockManagerPrivate
* Restores the state
*/
bool restoreState(const QByteArray &state, int version);
/**
* Restores the container with the given index
*/
bool restoreContainer(int Index, QDataStream& stream, bool Testing);
};
// struct DockManagerPrivate
@ -135,6 +142,22 @@ bool DockManagerPrivate::checkFormat(const QByteArray &state, int version)
}
//============================================================================
bool DockManagerPrivate::restoreContainer(int Index, QDataStream& stream, bool Testing)
{
if (Index >= Containers.count())
{
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(_this);
return FloatingWidget->restoreState(stream, internal::Restore);
}
else
{
std::cout << "d->Containers[i]->restoreState " << Index << std::endl;
return Containers[Index]->restoreState(stream, internal::Restore);
}
}
//============================================================================
bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
{
@ -162,15 +185,9 @@ bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
int i;
for (i = 0; i < ContainerCount; ++i)
{
if (i >= Containers.count())
Result = restoreContainer(i, stream, internal::Restore);
if (!Result)
{
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(_this);
}
std::cout << "d->Containers[i]->restoreState " << i << std::endl;
if (!Containers[i]->restoreState(stream, internal::Restore))
{
Result = false;
break;
}
}
@ -180,7 +197,7 @@ bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
int DeleteCount = FloatingWidgets.count() - FloatingWidgetIndex;
for (int i = 0; i < DeleteCount; ++i)
{
delete FloatingWidgets[FloatingWidgetIndex];
FloatingWidgets[FloatingWidgetIndex]->deleteLater();
}
return Result;
@ -309,12 +326,29 @@ bool CDockManager::restoreState(const QByteArray &state, int version)
return false;
}
for (auto DockWidget : d->DockWidgetsMap)
{
DockWidget->setProperty("dirty", true);
}
if (!d->restoreState(state, version))
{
std::cout << "restoreState: Error restoring state!!!!!!!" << std::endl;
return false;
}
// 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
// The do not belong to any dock container, until the user toggles the
// toggle view action the next time
for (auto DockWidget : d->DockWidgetsMap)
{
if (DockWidget->property("dirty").toBool())
{
DockWidget->flagAsUnassigned();
}
}
return true;
}

View File

@ -36,6 +36,7 @@
#include <QStack>
#include <QTextStream>
#include <QPointer>
#include <QEvent>
#include <iostream>
@ -108,21 +109,30 @@ DockWidgetPrivate::DockWidgetPrivate(CDockWidget* _public) :
//============================================================================
void DockWidgetPrivate::showDockWidget()
{
DockArea->show();
DockArea->setCurrentIndex(DockArea->tabIndex(_this));
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
if (Splitter)
if (!DockArea)
{
Splitter->show();
}
CDockContainerWidget* Container = DockArea->dockContainer();
if (Container->isFloating())
{
CFloatingDockContainer* FloatingWidget = internal::findParent<
CFloatingDockContainer*>(Container);
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(_this);
FloatingWidget->resize(_this->size());
FloatingWidget->show();
}
else
{
DockArea->show();
DockArea->setCurrentIndex(DockArea->tabIndex(_this));
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
if (Splitter)
{
Splitter->show();
}
CDockContainerWidget* Container = DockArea->dockContainer();
if (Container->isFloating())
{
CFloatingDockContainer* FloatingWidget = internal::findParent<
CFloatingDockContainer*>(Container);
FloatingWidget->show();
}
}
}
@ -363,6 +373,27 @@ void CDockWidget::saveState(QDataStream& stream) const
}
//============================================================================
void CDockWidget::flagAsUnassigned()
{
setParent(d->DockManager);
setDockArea(nullptr);
titleBar()->setParent(this);
}
//============================================================================
bool CDockWidget::event(QEvent *e)
{
if (e->type() == QEvent::WindowTitleChange)
{
emit titleChanged(windowTitle());
}
return QFrame::event(e);
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@ -55,6 +55,7 @@ protected:
friend class CDockContainerWidget;
friend class CDockAreaWidget;
friend class CFloatingDockContainer;
friend class CDockManager;
/**
* Assigns the dock manager that manages this dock widget
@ -80,6 +81,17 @@ protected:
*/
void saveState(QDataStream& Stream) const;
/**
* This is a helper function for the dock manager to flag this widget
* as unassigned.
* When calling the restore function, it may happen, that the saved state
* contains less dock widgets then currently available. All widgets whose
* data is not contained in the saved state, are flagged as unassigned
* after the restore process. If the user shows an unassigned dock widget,
* a floating widget will be created to take up the dock widget.
*/
void flagAsUnassigned();
public:
enum DockWidgetFeature
{
@ -172,6 +184,11 @@ public:
*/
QAction* toggleViewAction() const;
/**
* Emits titleChanged signal if title change event occures
*/
virtual bool event(QEvent *e) override;
public slots:
/**
* This property controls whether the dock widget is open or closed.
@ -189,6 +206,12 @@ signals:
* This signal is emitted if the dock widget is closed
*/
void closed();
/**
* This signal is emitted if the window title of this dock widget
* changed
*/
void titleChanged(const QString& Title);
}; // class DockWidget
}
// namespace ads

View File

@ -367,6 +367,7 @@ void CFloatingDockContainer::moveFloating()
//============================================================================
void CFloatingDockContainer::onDockAreasAddedOrRemoved()
{
std::cout << "CFloatingDockContainer::onDockAreasAddedOrRemoved()" << std::endl;
if (d->DockContainer->dockAreaCount() == 1)
{
d->SingleDockArea = d->DockContainer->dockArea(0);
@ -394,6 +395,18 @@ void CFloatingDockContainer::onDockAreaCurrentChanged(int Index)
}
//============================================================================
bool CFloatingDockContainer::restoreState(QDataStream& Stream, bool Testing)
{
if (!d->DockContainer->restoreState(Stream, Testing))
{
return false;
}
onDockAreasAddedOrRemoved();
return true;
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@ -103,6 +103,14 @@ public:
* startFloating() was called
*/
void moveFloating();
/**
* Restores the state from given stream.
* If Testing is true, the function only parses the data from the given
* stream but does not restore anything. You can use this check for
* faulty files before you start restoring the state
*/
bool restoreState(QDataStream& Stream, bool Testing);
}; // class FloatingDockContainer
}
// namespace ads