20#include "entitytreeviewstatesaver.h"
22#include <akonadi/collection.h>
23#include <akonadi/entitytreemodel.h>
24#include <akonadi/item.h>
26#include <KConfigGroup>
48class EntityTreeViewStateSaverPrivate
51 explicit EntityTreeViewStateSaverPrivate(EntityTreeViewStateSaver *parent)
54 , horizontalScrollBarValue(-1)
55 , verticalScrollBarValue(-1)
59 inline bool hasChanges()
const
61 return !pendingCollectionChanges.isEmpty() || !pendingItemChanges.isEmpty();
64 static inline QString key(
const QModelIndex &index)
66 if (!index.isValid()) {
67 return QLatin1String(
"x-1");
71 return QString::fromLatin1(
"c%1").arg(c.id());
76 void saveState(
const QModelIndex &index, QStringList &selection, QStringList &expansion)
78 const QString cfgKey = key(index);
79 if (view->selectionModel()->isSelected(index)) {
80 selection.append(cfgKey);
82 if (view->isExpanded(index)) {
83 expansion.append(cfgKey);
85 for (
int i = 0; i < view->model()->rowCount(index); ++i) {
86 const QModelIndex child = view->model()->index(i, 0, index);
87 saveState(child, selection, expansion);
91 inline void restoreState(
const QModelIndex &index,
const State &state)
94 view->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);
97 view->setExpanded(index,
true);
99 if (state.currentIndex) {
100 view->setCurrentIndex(index);
102 QTimer::singleShot(0, q, SLOT(restoreScrollBarState()));
105 void restoreState(
const QModelIndex &index)
109 if (pendingCollectionChanges.contains(c.id())) {
110 restoreState(index, pendingCollectionChanges.value(c.id()));
111 pendingCollectionChanges.remove(c.id());
115 if (pendingItemChanges.contains(itemId)) {
116 restoreState(index, pendingItemChanges.value(itemId));
117 pendingItemChanges.remove(itemId);
120 for (
int i = 0; i < view->model()->rowCount(index) && hasChanges(); ++i) {
121 const QModelIndex child = view->model()->index(i, 0, index);
126 inline void restoreScrollBarState()
128 if (horizontalScrollBarValue >= 0 && horizontalScrollBarValue <= view->horizontalScrollBar()->maximum()) {
129 view->horizontalScrollBar()->setValue(horizontalScrollBarValue);
130 horizontalScrollBarValue = -1;
132 if (verticalScrollBarValue >= 0 && verticalScrollBarValue <= view->verticalScrollBar()->maximum()) {
133 view->verticalScrollBar()->setValue(verticalScrollBarValue);
134 verticalScrollBarValue = -1;
138 void rowsInserted(
const QModelIndex &index,
int start,
int end)
141 QObject::disconnect(view->model(), SIGNAL(rowsInserted(QModelIndex,
int,
int)),
142 q, SLOT(rowsInserted(QModelIndex,
int,
int)));
146 for (
int i = start; i <= end && hasChanges(); ++i) {
147 const QModelIndex child = view->model()->index(i, 0, index);;
152 EntityTreeViewStateSaver *q;
154 QHash<Entity::Id, State> pendingCollectionChanges, pendingItemChanges;
155 int horizontalScrollBarValue, verticalScrollBarValue;
160 , d(new EntityTreeViewStateSaverPrivate(this))
172 if (!d->view->model()) {
176 configGroup.deleteGroup();
177 QStringList selection, expansion;
178 const int rowCount = d->view->model()->rowCount();
179 for (
int i = 0; i < rowCount; ++i) {
180 const QModelIndex index = d->view->model()->index(i, 0);
181 d->saveState(index, selection, expansion);
184 const QString currentIndex = d->key(d->view->selectionModel()->currentIndex());
186 configGroup.writeEntry(
"Selection", selection);
187 configGroup.writeEntry(
"Expansion", expansion);
188 configGroup.writeEntry(
"CurrentIndex", currentIndex);
189 configGroup.writeEntry(
"ScrollBarHorizontal", d->view->horizontalScrollBar()->value());
190 configGroup.writeEntry(
"ScrollBarVertical", d->view->verticalScrollBar()->value());
195 if (!d->view->model()) {
199 const QStringList selection = configGroup.readEntry(
"Selection", QStringList());
200 foreach (
const QString &key, selection) {
205 if (key.startsWith(QLatin1Char(
'c'))) {
206 d->pendingCollectionChanges[id].selected =
true;
207 }
else if (key.startsWith(QLatin1Char(
'i'))) {
208 d->pendingItemChanges[id].selected =
true;
212 const QStringList expansion = configGroup.readEntry(
"Expansion", QStringList());
213 foreach (
const QString &key, expansion) {
218 if (key.startsWith(QLatin1Char(
'c'))) {
219 d->pendingCollectionChanges[id].expanded =
true;
220 }
else if (key.startsWith(QLatin1Char(
'i'))) {
221 d->pendingItemChanges[id].expanded =
true;
225 const QString key = configGroup.readEntry(
"CurrentIndex", QString());
226 const Entity::Id id = key.mid(1).toLongLong();
228 if (key.startsWith(QLatin1Char(
'c'))) {
229 d->pendingCollectionChanges[id].currentIndex =
true;
230 }
else if (key.startsWith(QLatin1Char(
'i'))) {
231 d->pendingItemChanges[id].currentIndex =
true;
235 d->horizontalScrollBarValue = configGroup.readEntry(
"ScrollBarHorizontal", -1);
236 d->verticalScrollBarValue = configGroup.readEntry(
"ScrollBarVertical", -1);
239 for (
int i = 0; i < d->view->model()->rowCount() && d->hasChanges(); ++i) {
240 const QModelIndex index = d->view->model()->index(i, 0);
241 d->restoreState(index);
243 d->restoreScrollBarState();
246 if (d->hasChanges()) {
247 connect(d->view->model(), SIGNAL(rowsInserted(QModelIndex,
int,
int)),
248 SLOT(rowsInserted(QModelIndex,
int,
int)));
254#include "moc_entitytreeviewstatesaver.cpp"
@ CollectionRole
The collection.
EntityTreeViewStateSaver(QTreeView *view)
Creates a new state saver, for saving or restoring.
void saveState(KConfigGroup &configGroup) const
Stores the current state in the given config group.
~EntityTreeViewStateSaver()
Destroys this state saver.
void restoreState(const KConfigGroup &configGroup) const
Restore the state stored in configGroup as soon as the corresponding entities become available in the...
qint64 Id
Describes the unique id type.
FreeBusyManager::Singleton.