20 #include "entitytreeviewstatesaver.h"
22 #include <akonadi/collection.h>
23 #include <akonadi/entitytreemodel.h>
24 #include <akonadi/item.h>
26 #include <KConfigGroup>
37 State() : selected( false ), expanded( false ), currentIndex( false ) {}
43 class EntityTreeViewStateSaverPrivate
46 explicit EntityTreeViewStateSaverPrivate( EntityTreeViewStateSaver *parent ) :
49 horizontalScrollBarValue( -1 ),
50 verticalScrollBarValue( -1 )
54 inline bool hasChanges()
const
56 return !pendingCollectionChanges.isEmpty() || !pendingItemChanges.isEmpty();
59 static inline QString key(
const QModelIndex &index )
61 if ( !index.isValid() )
62 return QLatin1String(
"x-1" );
65 return QString::fromLatin1(
"c%1" ).arg( c.id() );
69 void saveState(
const QModelIndex &index, QStringList &selection, QStringList &expansion )
71 const QString cfgKey = key( index );
72 if ( view->selectionModel()->isSelected( index ) )
73 selection.append( cfgKey );
74 if ( view->isExpanded( index ) )
75 expansion.append( cfgKey );
76 for (
int i = 0; i < view->model()->rowCount( index ); ++i ) {
77 const QModelIndex child = view->model()->index( i, 0, index );
78 saveState( child, selection, expansion );
82 inline void restoreState(
const QModelIndex &index,
const State &state )
85 view->selectionModel()->select( index, QItemSelectionModel::Select | QItemSelectionModel::Rows );
87 view->setExpanded( index,
true );
88 if ( state.currentIndex )
89 view->setCurrentIndex( index );
90 QTimer::singleShot( 0, q, SLOT(restoreScrollBarState()) );
93 void restoreState(
const QModelIndex &index )
97 if ( pendingCollectionChanges.contains( c.id() ) ) {
98 restoreState( index, pendingCollectionChanges.value( c.id() ) );
99 pendingCollectionChanges.remove( c.id() );
103 if ( pendingItemChanges.contains( itemId ) ) {
104 restoreState( index, pendingItemChanges.value( itemId ) );
105 pendingItemChanges.remove( itemId );
108 for (
int i = 0; i < view->model()->rowCount( index ) && hasChanges(); ++i ) {
109 const QModelIndex child = view->model()->index( i, 0, index );
110 restoreState( child );
114 inline void restoreScrollBarState()
116 if ( horizontalScrollBarValue >= 0 && horizontalScrollBarValue <= view->horizontalScrollBar()->maximum() ) {
117 view->horizontalScrollBar()->setValue( horizontalScrollBarValue );
118 horizontalScrollBarValue = -1;
120 if ( verticalScrollBarValue >= 0 && verticalScrollBarValue <= view->verticalScrollBar()->maximum() ) {
121 view->verticalScrollBar()->setValue( verticalScrollBarValue );
122 verticalScrollBarValue = -1;
126 void rowsInserted(
const QModelIndex &index,
int start,
int end )
128 if ( !hasChanges() ) {
129 QObject::disconnect( view->model(), SIGNAL(rowsInserted(QModelIndex,
int,
int)),
130 q, SLOT(rowsInserted(QModelIndex,
int,
int)) );
134 for (
int i = start; i <= end && hasChanges(); ++i ) {
135 const QModelIndex child = view->model()->index( i, 0, index);;
136 restoreState( child );
140 EntityTreeViewStateSaver *q;
142 QHash<Entity::Id, State> pendingCollectionChanges, pendingItemChanges;
143 int horizontalScrollBarValue, verticalScrollBarValue;
148 d( new EntityTreeViewStateSaverPrivate( this ) )
160 if ( !d->view->model() )
163 configGroup.deleteGroup();
164 QStringList selection, expansion;
165 const int rowCount = d->view->model()->rowCount();
166 for (
int i = 0; i < rowCount; ++i ) {
167 const QModelIndex index = d->view->model()->index( i, 0 );
168 d->saveState( index, selection, expansion );
171 const QString currentIndex = d->key( d->view->selectionModel()->currentIndex() );
173 configGroup.writeEntry(
"Selection", selection );
174 configGroup.writeEntry(
"Expansion", expansion );
175 configGroup.writeEntry(
"CurrentIndex", currentIndex );
176 configGroup.writeEntry(
"ScrollBarHorizontal", d->view->horizontalScrollBar()->value() );
177 configGroup.writeEntry(
"ScrollBarVertical", d->view->verticalScrollBar()->value() );
182 if ( !d->view->model() )
185 const QStringList selection = configGroup.readEntry(
"Selection", QStringList() );
186 foreach (
const QString &key, selection ) {
190 if ( key.startsWith( QLatin1Char(
'c' ) ) )
191 d->pendingCollectionChanges[
id].selected =
true;
192 else if ( key.startsWith( QLatin1Char(
'i' ) ) )
193 d->pendingItemChanges[
id].selected =
true;
196 const QStringList expansion = configGroup.readEntry(
"Expansion", QStringList() );
197 foreach (
const QString &key, expansion ) {
201 if ( key.startsWith( QLatin1Char(
'c' ) ) )
202 d->pendingCollectionChanges[
id].expanded =
true;
203 else if ( key.startsWith( QLatin1Char(
'i' ) ) )
204 d->pendingItemChanges[
id].expanded =
true;
207 const QString key = configGroup.readEntry(
"CurrentIndex", QString() );
208 const Entity::Id id = key.mid( 1 ).toLongLong();
210 if ( key.startsWith( QLatin1Char(
'c' ) ) )
211 d->pendingCollectionChanges[
id].currentIndex =
true;
212 else if ( key.startsWith( QLatin1Char(
'i' ) ) )
213 d->pendingItemChanges[
id].currentIndex =
true;
216 d->horizontalScrollBarValue = configGroup.readEntry(
"ScrollBarHorizontal", -1 );
217 d->verticalScrollBarValue = configGroup.readEntry(
"ScrollBarVertical", -1 );
220 for (
int i = 0; i < d->view->model()->rowCount() && d->hasChanges(); ++i ) {
221 const QModelIndex index = d->view->model()->index( i, 0 );
222 d->restoreState( index );
224 d->restoreScrollBarState();
227 if ( d->hasChanges() )
228 connect( d->view->model(), SIGNAL(rowsInserted(QModelIndex,
int,
int)),
229 SLOT(rowsInserted(QModelIndex,
int,
int)) );
234 #include "moc_entitytreeviewstatesaver.cpp"
~EntityTreeViewStateSaver()
Destroys this state saver.
qint64 Id
Describes the unique id type.
EntityTreeViewStateSaver(QTreeView *view)
Creates a new state saver, for saving or restoring.
void restoreState(const KConfigGroup &configGroup) const
Restore the state stored in configGroup as soon as the corresponding entities become available in the...
void saveState(KConfigGroup &configGroup) const
Stores the current state in the given config group.