KWidgetsAddons

kviewstateserializer.h
1 /*
2  SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
3  SPDX-FileContributor: Stephen Kelly <[email protected]>
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 
18 class QAbstractItemView;
20 class QAbstractItemModel;
22 class QModelIndex;
23 
24 class 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 <[email protected]>
166  @since 4.5
167 */
168 class KWIDGETSADDONS_EXPORT KViewStateSerializer : public QObject
169 {
170  Q_OBJECT
171 public:
172  /**
173  * Constructor
174  */
175  explicit KViewStateSerializer(QObject *parent = nullptr);
176 
177  /**
178  * Destructor
179  */
180  ~KViewStateSerializer() override;
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 
243 protected:
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 
256 private:
257  //@cond PRIVATE
258  Q_DECLARE_PRIVATE(KViewStateSerializer)
259  std::unique_ptr<KViewStateSerializerPrivate> const d_ptr;
260  //@endcond
261 };
262 
263 #endif
Object for saving and restoring state in QTreeViews and QItemSelectionModels.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Sep 21 2023 04:03:41 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.