Skip to content

Commit a088578

Browse files
Rodrigo OlivaRodrigo Oliva
authored andcommitted
Add new flag that will delete the contained widget and recreate it from a factory when closing and opening the dock widget.
1 parent dbca6d7 commit a088578

File tree

3 files changed

+108
-13
lines changed

3 files changed

+108
-13
lines changed

examples/deleteonclose/main.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ int main(int argc, char *argv[])
4141
now->widget()->setFocus();
4242
});
4343

44-
QAction *action = new QAction("New Delete On Close", &w);
44+
QAction *action = new QAction("New Delete Dock Widget On Close", &w);
4545
w.menuBar()->addAction(action);
4646

4747
int i = 0;
@@ -53,7 +53,26 @@ int main(int argc, char *argv[])
5353
auto area = dockManager->addDockWidgetTab(ads::CenterDockWidgetArea, dw);
5454
qDebug() << "doc dock widget created!" << dw << area;
5555
});
56-
56+
57+
auto dw = new ads::CDockWidget(QStringLiteral("test doc %1").arg(i++), &w);
58+
auto editor = new QTextEdit(QStringLiteral("recreated lorem ipsum......"), dw);
59+
dw->setWidget(editor);
60+
dw->setFeature(ads::CDockWidget::RecreateContentsWidgetOnCloseAndOpen, true);
61+
dw->setWidgetFactory([](QWidget* dw){
62+
static int timesRecreated = 0;
63+
return new QTextEdit(QStringLiteral("recreated lorem ipsum... times %1").arg(++timesRecreated), dw);
64+
});
65+
auto area = dockManager->addDockWidgetTab(ads::CenterDockWidgetArea, dw);
66+
qDebug() << "RecreateContentsWidgetOnCloseAndOpen dock widget created!" << dw << area;
67+
68+
action = new QAction("Toggle Recreate Contents Widget On Close and Open", &w);
69+
w.menuBar()->addAction(action);
70+
71+
QObject::connect(action, &QAction::triggered, [dw]() {
72+
dw->toggleView(dw->isClosed());
73+
qDebug() << QString("dock widget %1! contents widget %2!").arg(dw->isClosed() ? "closed" : "open", dw->widget() ? "created" : "deleted");
74+
});
75+
5776
action = new QAction("New", &w);
5877
w.menuBar()->addAction(action);
5978
QObject::connect(action, &QAction::triggered, [&]() {

src/DockWidget.cpp

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ namespace ads
6666
*/
6767
struct DockWidgetPrivate
6868
{
69+
struct WidgetFactory
70+
{
71+
CDockWidget::FactoryFunc createWidget;
72+
CDockWidget::eInsertMode insertMode;
73+
};
74+
6975
CDockWidget* _this = nullptr;
7076
QBoxLayout* Layout = nullptr;
7177
QWidget* Widget = nullptr;
@@ -84,7 +90,8 @@ struct DockWidgetPrivate
8490
bool IsFloatingTopLevel = false;
8591
QList<QAction*> TitleBarActions;
8692
CDockWidget::eMinimumSizeHintMode MinimumSizeHintMode = CDockWidget::MinimumSizeHintFromDockWidget;
87-
93+
WidgetFactory* Factory = nullptr;
94+
8895
/**
8996
* Private data constructor
9097
*/
@@ -116,6 +123,12 @@ struct DockWidgetPrivate
116123
* Setup the main scroll area
117124
*/
118125
void setupScrollArea();
126+
127+
/**
128+
* Sets the widget factory that will be used to recreate and set the contents widget.
129+
*/
130+
void setWidgetFactory(CDockWidget::FactoryFunc createWidget, CDockWidget::eInsertMode insertMode);
131+
bool createWidgetFromFactory();
119132
};
120133
// struct DockWidgetPrivate
121134

@@ -130,6 +143,14 @@ DockWidgetPrivate::DockWidgetPrivate(CDockWidget* _public) :
130143
//============================================================================
131144
void DockWidgetPrivate::showDockWidget()
132145
{
146+
if (!Widget) {
147+
if(!createWidgetFromFactory()) {
148+
Q_ASSERT(!Features.testFlag(CDockWidget::RecreateContentsWidgetOnCloseAndOpen)
149+
&& "RecreateContentsWidgetOnCloseAndOpen flag was set, but the widget factory is missing or it doesn't return a valid QWidget.");
150+
return;
151+
}
152+
}
153+
133154
if (!DockArea)
134155
{
135156
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(_this);
@@ -167,6 +188,12 @@ void DockWidgetPrivate::hideDockWidget()
167188
{
168189
TabWidget->hide();
169190
updateParentDockArea();
191+
192+
if (Features.testFlag(CDockWidget::RecreateContentsWidgetOnCloseAndOpen))
193+
{
194+
Widget->deleteLater();
195+
Widget = nullptr;
196+
}
170197
}
171198

172199

@@ -219,6 +246,38 @@ void DockWidgetPrivate::setupScrollArea()
219246
Layout->addWidget(ScrollArea);
220247
}
221248

249+
void DockWidgetPrivate::setWidgetFactory(CDockWidget::FactoryFunc createWidget, CDockWidget::eInsertMode insertMode)
250+
{
251+
if (Factory)
252+
{
253+
delete Factory;
254+
}
255+
256+
Factory = new WidgetFactory { createWidget, insertMode };
257+
}
258+
259+
bool DockWidgetPrivate::createWidgetFromFactory()
260+
{
261+
if (!Features.testFlag(CDockWidget::RecreateContentsWidgetOnCloseAndOpen))
262+
{
263+
return false;
264+
}
265+
266+
if (!Factory)
267+
{
268+
return false;
269+
}
270+
271+
QWidget* w = Factory->createWidget(_this);
272+
if (!w)
273+
{
274+
return false;
275+
}
276+
277+
_this->setWidget(w, Factory->insertMode);
278+
return true;
279+
}
280+
222281

223282
//============================================================================
224283
CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
@@ -290,6 +349,11 @@ void CDockWidget::setWidget(QWidget* widget, eInsertMode InsertMode)
290349
d->Widget->setProperty("dockWidgetContent", true);
291350
}
292351

352+
//============================================================================
353+
void CDockWidget::setWidgetFactory(FactoryFunc createWidget, eInsertMode insertMode) {
354+
d->setWidgetFactory(createWidget, insertMode);
355+
}
356+
293357

294358
//============================================================================
295359
QWidget* CDockWidget::takeWidget()

src/DockWidget.h

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -147,18 +147,19 @@ private Q_SLOTS:
147147

148148
enum DockWidgetFeature
149149
{
150-
DockWidgetClosable = 0x01,///< dock widget has a close button
151-
DockWidgetMovable = 0x02,///< dock widget is movable and can be moved to a new position in the current dock container
152-
DockWidgetFloatable = 0x04,///< dock widget can be dragged into a floating window
153-
DockWidgetDeleteOnClose = 0x08, ///< deletes the dock widget when it is closed
154-
CustomCloseHandling = 0x10, ///< clicking the close button will not close the dock widget but emits the closeRequested() signal instead
155-
DockWidgetFocusable = 0x20, ///< if this is enabled, a dock widget can get focus highlighting
156-
DockWidgetForceCloseWithArea = 0x40, ///< dock widget will be closed when the dock area hosting it is closed
157-
NoTab = 0x80, ///< dock widget tab will never be shown if this flag is set
150+
DockWidgetClosable = 0x001,///< dock widget has a close button
151+
DockWidgetMovable = 0x002,///< dock widget is movable and can be moved to a new position in the current dock container
152+
DockWidgetFloatable = 0x004,///< dock widget can be dragged into a floating window
153+
DockWidgetDeleteOnClose = 0x008, ///< deletes the dock widget when it is closed
154+
CustomCloseHandling = 0x010, ///< clicking the close button will not close the dock widget but emits the closeRequested() signal instead
155+
DockWidgetFocusable = 0x020, ///< if this is enabled, a dock widget can get focus highlighting
156+
DockWidgetForceCloseWithArea = 0x040, ///< dock widget will be closed when the dock area hosting it is closed
157+
NoTab = 0x080, ///< dock widget tab will never be shown if this flag is set
158+
RecreateContentsWidgetOnCloseAndOpen = 0x100, ///< deletes only the contained widget on close, keeping the dock widget intact and in place. Attempts to rebuild the contents widget on show if there is a widget factory set.
158159
DefaultDockWidgetFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable | DockWidgetFocusable,
159160
AllDockWidgetFeatures = DefaultDockWidgetFeatures | DockWidgetDeleteOnClose | CustomCloseHandling,
160161
DockWidgetAlwaysCloseAndDelete = DockWidgetForceCloseWithArea | DockWidgetDeleteOnClose,
161-
NoDockWidgetFeatures = 0x00
162+
NoDockWidgetFeatures = 0x000
162163
};
163164
Q_DECLARE_FLAGS(DockWidgetFeatures, DockWidgetFeature)
164165

@@ -269,7 +270,18 @@ private Q_SLOTS:
269270
* provide the InsertMode ForceNoScrollArea
270271
*/
271272
void setWidget(QWidget* widget, eInsertMode InsertMode = AutoScrollArea);
272-
273+
274+
/**
275+
* Only used when the flag RecreateContentsWidgetOnCloseAndOpen is set.
276+
* Using the flag and setting a widget factory allows to free the resources of
277+
* the widget of your application while retaining the position the next time you want to
278+
* show your widget, unlike the flag DockWidgetDeleteOnClose which deletes the dock widget itself.
279+
* Since we keep the dock widget, all regular features of ADS should work as normal, including
280+
* saving and restoring the state of the docking system and using perspectives.
281+
*/
282+
using FactoryFunc = std::function<QWidget*(QWidget*)>;
283+
void setWidgetFactory(FactoryFunc createWidget, eInsertMode InsertMode = AutoScrollArea);
284+
273285
/**
274286
* Remove the widget from the dock and give ownership back to the caller
275287
*/

0 commit comments

Comments
 (0)