Skip to content

Commit aa8a52b

Browse files
author
Uwe Kindler
committed
Fixed bug with FloatingWidget deletion, fixed handling of unassigned DockWidgets after restoreState() call
1 parent 9adc524 commit aa8a52b

File tree

6 files changed

+133
-20
lines changed

6 files changed

+133
-20
lines changed

src/DockContainerWidget.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <QList>
3535
#include <QGridLayout>
3636
#include <QPointer>
37+
#include <QVariant>
3738

3839
#include "DockManager.h"
3940
#include "DockAreaWidget.h"
@@ -432,6 +433,7 @@ bool DockContainerWidgetPrivate::restoreDockArea(QDataStream& stream,
432433
<< std::endl;
433434
DockArea->addDockWidget(DockWidget);
434435
DockWidget->toggleView(!Closed);
436+
DockWidget->setProperty("dirty", false);
435437
}
436438

437439
if (Testing)
@@ -528,6 +530,7 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
528530
//============================================================================
529531
void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
530532
{
533+
#if defined(QT_DEBUG)
531534
QSplitter* Splitter = dynamic_cast<QSplitter*>(widget);
532535
QByteArray buf;
533536
buf.fill(' ', level * 4);
@@ -549,6 +552,7 @@ void DockContainerWidgetPrivate::dumpRecursive(int level, QWidget* widget)
549552
}
550553
std::cout << buf.toStdString() << "DockArea" << std::endl;
551554
}
555+
#endif
552556
}
553557

554558

src/DockManager.cpp

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <QMainWindow>
3434
#include <QList>
3535
#include <QMap>
36+
#include <QVariant>
3637

3738
#include <iostream>
3839

@@ -41,6 +42,7 @@
4142
#include "DockWidget.h"
4243
#include "ads_globals.h"
4344
#include "DockStateSerialization.h"
45+
#include "DockWidgetTitleBar.h"
4446

4547
namespace ads
4648
{
@@ -77,6 +79,11 @@ struct DockManagerPrivate
7779
* Restores the state
7880
*/
7981
bool restoreState(const QByteArray &state, int version);
82+
83+
/**
84+
* Restores the container with the given index
85+
*/
86+
bool restoreContainer(int Index, QDataStream& stream, bool Testing);
8087
};
8188
// struct DockManagerPrivate
8289

@@ -135,6 +142,22 @@ bool DockManagerPrivate::checkFormat(const QByteArray &state, int version)
135142
}
136143

137144

145+
//============================================================================
146+
bool DockManagerPrivate::restoreContainer(int Index, QDataStream& stream, bool Testing)
147+
{
148+
if (Index >= Containers.count())
149+
{
150+
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(_this);
151+
return FloatingWidget->restoreState(stream, internal::Restore);
152+
}
153+
else
154+
{
155+
std::cout << "d->Containers[i]->restoreState " << Index << std::endl;
156+
return Containers[Index]->restoreState(stream, internal::Restore);
157+
}
158+
}
159+
160+
138161
//============================================================================
139162
bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
140163
{
@@ -162,15 +185,9 @@ bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
162185
int i;
163186
for (i = 0; i < ContainerCount; ++i)
164187
{
165-
if (i >= Containers.count())
188+
Result = restoreContainer(i, stream, internal::Restore);
189+
if (!Result)
166190
{
167-
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(_this);
168-
}
169-
170-
std::cout << "d->Containers[i]->restoreState " << i << std::endl;
171-
if (!Containers[i]->restoreState(stream, internal::Restore))
172-
{
173-
Result = false;
174191
break;
175192
}
176193
}
@@ -180,7 +197,7 @@ bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
180197
int DeleteCount = FloatingWidgets.count() - FloatingWidgetIndex;
181198
for (int i = 0; i < DeleteCount; ++i)
182199
{
183-
delete FloatingWidgets[FloatingWidgetIndex];
200+
FloatingWidgets[FloatingWidgetIndex]->deleteLater();
184201
}
185202

186203
return Result;
@@ -309,12 +326,29 @@ bool CDockManager::restoreState(const QByteArray &state, int version)
309326
return false;
310327
}
311328

329+
for (auto DockWidget : d->DockWidgetsMap)
330+
{
331+
DockWidget->setProperty("dirty", true);
332+
}
333+
312334
if (!d->restoreState(state, version))
313335
{
314336
std::cout << "restoreState: Error restoring state!!!!!!!" << std::endl;
315337
return false;
316338
}
317339

340+
// All dock widgets, that have not been processed in the restore state
341+
// function are invisible to the user now and have no assigned dock area
342+
// The do not belong to any dock container, until the user toggles the
343+
// toggle view action the next time
344+
for (auto DockWidget : d->DockWidgetsMap)
345+
{
346+
if (DockWidget->property("dirty").toBool())
347+
{
348+
DockWidget->flagAsUnassigned();
349+
}
350+
}
351+
318352
return true;
319353
}
320354

src/DockWidget.cpp

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <QStack>
3737
#include <QTextStream>
3838
#include <QPointer>
39+
#include <QEvent>
3940

4041
#include <iostream>
4142

@@ -108,20 +109,29 @@ DockWidgetPrivate::DockWidgetPrivate(CDockWidget* _public) :
108109
//============================================================================
109110
void DockWidgetPrivate::showDockWidget()
110111
{
111-
DockArea->show();
112-
DockArea->setCurrentIndex(DockArea->tabIndex(_this));
113-
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
114-
if (Splitter)
112+
if (!DockArea)
115113
{
116-
Splitter->show();
114+
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(_this);
115+
FloatingWidget->resize(_this->size());
116+
FloatingWidget->show();
117117
}
118-
119-
CDockContainerWidget* Container = DockArea->dockContainer();
120-
if (Container->isFloating())
118+
else
121119
{
122-
CFloatingDockContainer* FloatingWidget = internal::findParent<
123-
CFloatingDockContainer*>(Container);
124-
FloatingWidget->show();
120+
DockArea->show();
121+
DockArea->setCurrentIndex(DockArea->tabIndex(_this));
122+
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
123+
if (Splitter)
124+
{
125+
Splitter->show();
126+
}
127+
128+
CDockContainerWidget* Container = DockArea->dockContainer();
129+
if (Container->isFloating())
130+
{
131+
CFloatingDockContainer* FloatingWidget = internal::findParent<
132+
CFloatingDockContainer*>(Container);
133+
FloatingWidget->show();
134+
}
125135
}
126136
}
127137

@@ -363,6 +373,27 @@ void CDockWidget::saveState(QDataStream& stream) const
363373
}
364374

365375

376+
//============================================================================
377+
void CDockWidget::flagAsUnassigned()
378+
{
379+
setParent(d->DockManager);
380+
setDockArea(nullptr);
381+
titleBar()->setParent(this);
382+
}
383+
384+
385+
//============================================================================
386+
bool CDockWidget::event(QEvent *e)
387+
{
388+
if (e->type() == QEvent::WindowTitleChange)
389+
{
390+
emit titleChanged(windowTitle());
391+
}
392+
return QFrame::event(e);
393+
}
394+
395+
396+
366397
} // namespace ads
367398

368399
//---------------------------------------------------------------------------

src/DockWidget.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class CDockWidget : public QFrame
5555
friend class CDockContainerWidget;
5656
friend class CDockAreaWidget;
5757
friend class CFloatingDockContainer;
58+
friend class CDockManager;
5859

5960
/**
6061
* Assigns the dock manager that manages this dock widget
@@ -80,6 +81,17 @@ class CDockWidget : public QFrame
8081
*/
8182
void saveState(QDataStream& Stream) const;
8283

84+
/**
85+
* This is a helper function for the dock manager to flag this widget
86+
* as unassigned.
87+
* When calling the restore function, it may happen, that the saved state
88+
* contains less dock widgets then currently available. All widgets whose
89+
* data is not contained in the saved state, are flagged as unassigned
90+
* after the restore process. If the user shows an unassigned dock widget,
91+
* a floating widget will be created to take up the dock widget.
92+
*/
93+
void flagAsUnassigned();
94+
8395
public:
8496
enum DockWidgetFeature
8597
{
@@ -172,6 +184,11 @@ class CDockWidget : public QFrame
172184
*/
173185
QAction* toggleViewAction() const;
174186

187+
/**
188+
* Emits titleChanged signal if title change event occures
189+
*/
190+
virtual bool event(QEvent *e) override;
191+
175192
public slots:
176193
/**
177194
* This property controls whether the dock widget is open or closed.
@@ -189,6 +206,12 @@ public slots:
189206
* This signal is emitted if the dock widget is closed
190207
*/
191208
void closed();
209+
210+
/**
211+
* This signal is emitted if the window title of this dock widget
212+
* changed
213+
*/
214+
void titleChanged(const QString& Title);
192215
}; // class DockWidget
193216
}
194217
// namespace ads

src/FloatingDockContainer.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ void CFloatingDockContainer::moveFloating()
367367
//============================================================================
368368
void CFloatingDockContainer::onDockAreasAddedOrRemoved()
369369
{
370+
std::cout << "CFloatingDockContainer::onDockAreasAddedOrRemoved()" << std::endl;
370371
if (d->DockContainer->dockAreaCount() == 1)
371372
{
372373
d->SingleDockArea = d->DockContainer->dockArea(0);
@@ -394,6 +395,18 @@ void CFloatingDockContainer::onDockAreaCurrentChanged(int Index)
394395
}
395396

396397

398+
//============================================================================
399+
bool CFloatingDockContainer::restoreState(QDataStream& Stream, bool Testing)
400+
{
401+
if (!d->DockContainer->restoreState(Stream, Testing))
402+
{
403+
return false;
404+
}
405+
onDockAreasAddedOrRemoved();
406+
return true;
407+
}
408+
409+
397410
} // namespace ads
398411

399412
//---------------------------------------------------------------------------

src/FloatingDockContainer.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ private slots:
103103
* startFloating() was called
104104
*/
105105
void moveFloating();
106+
107+
/**
108+
* Restores the state from given stream.
109+
* If Testing is true, the function only parses the data from the given
110+
* stream but does not restore anything. You can use this check for
111+
* faulty files before you start restoring the state
112+
*/
113+
bool restoreState(QDataStream& Stream, bool Testing);
106114
}; // class FloatingDockContainer
107115
}
108116
// namespace ads

0 commit comments

Comments
 (0)