KWidgetsAddons

kviewstateserializer.h
1/*
2 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
3 SPDX-FileContributor: Stephen Kelly <stephen@kdab.com>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#ifndef KVIEWSTATESERIALIZER_H
9#define KVIEWSTATESERIALIZER_H
10
11#include <QObject>
12#include <QPair>
13#include <QStringList>
14#include <memory>
15
16#include "kwidgetsaddons_export.h"
17
22class QModelIndex;
23
24class KViewStateSerializerPrivate;
25
26/**
27 @class KViewStateSerializer kviewstateserializer.h KViewStateSerializer
28
29 @brief Object for saving and restoring state in QTreeViews and QItemSelectionModels
30
31 Implement the indexFromConfigString and indexToConfigString methods to handle
32 the model in the view whose state is being saved. These implementations can be
33 quite trivial:
34
35 @code
36 QModelIndex DynamicTreeStateSaver::indexFromConfigString(const QAbstractItemModel* model,
37 const QString& key) const
38 {
39 QModelIndexList list = model->match(model->index(0, 0),
40 DynamicTreeModel::DynamicTreeModelId,
41 key.toInt(), 1, Qt::MatchRecursive);
42 if (list.isEmpty()) {
43 return QModelIndex();
44 }
45 return list.first();
46 }
47
48 QString DynamicTreeStateSaver::indexToConfigString(const QModelIndex& index) const
49 {
50 return index.data(DynamicTreeModel::DynamicTreeModelId).toString();
51 }
52 @endcode
53
54 It is possible to restore the state of a QTreeView (that is, the expanded state and
55 selected state of all indexes as well as the horizontal and vertical scroll state) by
56 using setTreeView.
57
58 If there is no tree view state to restore (for example if using QML), the selection
59 state of a QItemSelectionModel can be saved or restored instead.
60
61 The state of any QAbstractScrollArea can also be saved and restored.
62
63 A KViewStateSerializer should be created on the stack when saving and on the heap
64 when restoring. The model may be populated dynamically between several event loops,
65 so it may not be immediate for the indexes that should be selected to be in the model.
66 The saver should *not* be persisted as a member. The saver will destroy itself when it
67 has completed the restoration specified in the config group, or a small amount of time
68 has elapsed.
69
70 @code
71 MyWidget::MyWidget(Qobject *parent)
72 : QWidget(parent)
73 {
74 ...
75
76 m_view = new QTreeView(splitter);
77 m_view->setModel(model);
78
79 connect(model, &QAbstractItemModel::modelAboutToBeReset, this, [this]() { saveState(); });
80 connect(model, &QAbstractItemModel::modelReset, [this]() { restoreState(); });
81 connect(qApp, &QApplication::aboutToQuit, this, [this]() { saveState(); });
82
83 restoreState();
84 }
85
86 void StateSaverWidget::saveState()
87 {
88 ConcreteStateSaver saver;
89 saver.setTreeView(m_view);
90
91 KConfigGroup cfg(KSharedConfig::openConfig(), "ExampleViewState");
92 saver.saveState(cfg);
93 cfg.sync();
94 }
95
96 void StateSaverWidget::restoreState()
97 {
98 // Will delete itself.
99 ConcreteTreeStateSaver *saver = new ConcreteStateSaver();
100 saver->setTreeView(m_view);
101 KConfigGroup cfg(KSharedConfig::openConfig(), "ExampleViewState");
102 saver->restoreState(cfg);
103 }
104 @endcode
105
106 After creating a saver, the state can be saved using a KConfigGroup.
107
108 It is also possible to save and restore state directly by using the restoreSelection,
109 restoreExpanded etc methods. Note that the implementation of these methods should return
110 strings that the indexFromConfigString implementation can handle.
111
112 @code
113 class DynamicTreeStateSaver : public KViewStateSerializer
114 {
115 Q_OBJECT
116 public:
117 // ...
118
119 void selectItems(const QList<qint64> &items)
120 {
121 QStringList itemStrings;
122 for (qint64 item : items) {
123 itemStrings << QString::number(item);
124 }
125 restoreSelection(itemStrings);
126 }
127
128 void expandItems(const QList<qint64> &items)
129 {
130 QStringList itemStrings;
131 for (qint64 item : items) {
132 itemStrings << QString::number(item);
133 }
134 restoreSelection(itemStrings);
135 }
136 };
137 @endcode
138
139 Note that a single instance of this class should be used with only one widget.
140 That is don't do this:
141
142 @code
143 saver->setTreeView(treeView1);
144 saver->setSelectionModel(treeView2->selectionModel());
145 saver->setScrollArea(treeView3);
146 @endcode
147
148 To save the state of 3 different widgets, use three savers, even if they operate
149 on the same root model.
150
151 @code
152 saver1->setTreeView(treeView1);
153 saver2->setSelectionModel(treeView2->selectionModel());
154 saver3->setScrollArea(treeView3);
155 @endcode
156
157 @note The KViewStateSerializer does not take ownership of any widgets set on it.
158
159 It is recommended to restore the state on application startup and after the
160 model has been reset, and to save the state on application close and before
161 the model has been reset.
162
163 @see QAbstractItemModel::modelAboutToBeReset QAbstractItemModel::modelReset
164
165 @author Stephen Kelly <stephen@kdab.com>
166 @since 4.5
167*/
168class KWIDGETSADDONS_EXPORT KViewStateSerializer : public QObject
169{
170 Q_OBJECT
171public:
172 /**
173 * Constructor
174 */
175 explicit KViewStateSerializer(QObject *parent = nullptr);
176
177 /**
178 * Destructor
179 */
181
182 /**
183 * The view whose state is persisted.
184 */
185 QAbstractItemView *view() const;
186
187 /**
188 * Sets the view whose state is persisted.
189 */
190 void setView(QAbstractItemView *view);
191
192 /**
193 * The QItemSelectionModel whose state is persisted.
194 */
195 QItemSelectionModel *selectionModel() const;
196
197 /**
198 * Sets the QItemSelectionModel whose state is persisted.
199 */
200 void setSelectionModel(QItemSelectionModel *selectionModel);
201
202 /**
203 * Returns a QStringList describing the selection in the selectionModel.
204 */
205 QStringList selectionKeys() const;
206
207 /**
208 * Returns a QStringList representing the expanded indexes in the QTreeView.
209 */
210 QStringList expansionKeys() const;
211
212 /**
213 * Returns a QString describing the current index in the selection model.
214 */
215 QString currentIndexKey() const;
216
217 /**
218 * Returns the vertical and horizontal scroll of the QAbstractScrollArea.
219 */
220 QPair<int, int> scrollState() const;
221
222 /**
223 * Select the indexes described by @p indexStrings
224 */
225 void restoreSelection(const QStringList &indexStrings);
226
227 /**
228 * Make the index described by @p indexString the currentIndex in the selectionModel.
229 */
230 void restoreCurrentItem(const QString &indexString);
231
232 /**
233 * Expand the indexes described by @p indexStrings in the QTreeView.
234 */
235 void restoreExpanded(const QStringList &indexStrings);
236
237 /**
238 * Restores the scroll state of the QAbstractScrollArea to the @p verticalScoll
239 * and @p horizontalScroll
240 */
241 void restoreScrollState(int verticalScoll, int horizontalScroll);
242
243protected:
244 /**
245 * Reimplement to return an index in the @p model described by the unique key @p key
246 */
247 virtual QModelIndex indexFromConfigString(const QAbstractItemModel *model, const QString &key) const = 0;
248
249 /**
250 * Reimplement to return a unique string for the @p index.
251 */
252 virtual QString indexToConfigString(const QModelIndex &index) const = 0;
253
254 void restoreState();
255
256private:
257 //@cond PRIVATE
259 std::unique_ptr<KViewStateSerializerPrivate> const d_ptr;
260 //@endcond
261};
262
263#endif
Object for saving and restoring state in QTreeViews and QItemSelectionModels.
virtual QString indexToConfigString(const QModelIndex &index) const =0
Reimplement to return a unique string for the index.
~KViewStateSerializer() override
Destructor.
virtual QModelIndex indexFromConfigString(const QAbstractItemModel *model, const QString &key) const =0
Reimplement to return an index in the model described by the unique key key.
T qobject_cast(QObject *object)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:14:43 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.