[Digikam-devel] extragear/graphics/digikam/digikam
Johannes Wienke
languitar at semipol.de
Sun Feb 14 16:39:33 GMT 2010
Hi Marcel,
this commit breaks restoring the state for searching. Tag a tree view
and collapse everything so that only the first hierarchy is visible.
Afterwards start a search maybe starting with the letter "w". After
removing the search string from the searchtextbar no everything is
collapsed that contains a w. The idea of my code was to completely
backup the state of the tree view before starting a search, collapse
everything as usual during a search, and after the search restore the
complete state + collapse to the now selected album. I would suspect,
that state saving is called now also after the first letter for the
search is entered.
Johannes
Am 14.02.2010 16:18 schrieb Marcel Wiesweg:
> SVN commit 1090062 by mwiesweg:
>
> restoreState was called very often. The problem is that queued signals
> will be delivered when sent even if the connection is removed.
> When the connection is removed from the slot of the queued signal, and
> albums are added in one event loop run, then signals will be received for each
> album even though the connection is removed after the first one.
>
> Now, the restoring code is modified to work in the rowsInserted() code directly
> and not for the full hierarchy each time. Expansion only works when children
> are available, so parents will get restored a second time.
>
> M +88 -106 albumtreeview.cpp
> M +9 -15 albumtreeview.h
>
>
> --- trunk/extragear/graphics/digikam/digikam/albumtreeview.cpp #1090061:1090062
> @@ -320,7 +320,7 @@
>
> kDebug() << "Searching finished, restoring tree view state";
>
> - restoreState(QModelIndex(), d->searchBackup);
> + restoreStateForHierarchy(QModelIndex(), d->searchBackup);
> d->searchBackup.clear();
>
> if (d->lastSelectedAlbum)
> @@ -519,12 +519,12 @@
>
> KConfigGroup configGroup = getConfigGroup();
>
> - //kDebug() << "Loading view state from " << configGroup.name();
> + //kDebug() << "Loading view state from " << this << configGroup.name() << objectName();
>
> // extract the selection from the config
> const QStringList selection = configGroup.readEntry(entryName(d->configSelectionEntry),
> QStringList());
> -// kDebug() << "selection: " << selection;
> + //kDebug() << "selection: " << selection;
> foreach(const QString &key, selection)
> {
> bool validId;
> @@ -551,7 +551,7 @@
>
> // extract current index from config
> const QString key = configGroup.readEntry(entryName(d->configCurrentIndexEntry), QString());
> -// kDebug() << "currentIndey: " << key;
> + //kDebug() << "currentIndex: " << key;
> bool validId;
> const int id = key.toInt(&validId);
> if (validId)
> @@ -559,33 +559,22 @@
> d->statesByAlbumId[id].currentIndex = true;
> }
>
> -// for (QMap<int, Digikam::State>::iterator it = d->statesByAlbumId.begin(); it
> -// != d->statesByAlbumId.end(); ++it)
> -// {
> -// kDebug() << "id = " << it.key() << ": recovered state (selected = "
> -// << it.value().selected << ", expanded = "
> -// << it.value().expanded << ", currentIndex = "
> -// << it.value().currentIndex << ")";
> -// }
> -
> -
> - // initial restore run, for everything already loaded
> -// kDebug() << "initial restore run with " << model()->rowCount() << " rows";
> - for (int i = 0; i < model()->rowCount(); ++i)
> + /*
> + for (QMap<int, Digikam::State>::iterator it = d->statesByAlbumId.begin(); it
> + != d->statesByAlbumId.end(); ++it)
> {
> - const QModelIndex index = model()->index(i, 0);
> - restoreState(index, d->statesByAlbumId);
> + kDebug() << "id = " << it.key() << ": recovered state (selected = "
> + << it.value().selected << ", expanded = "
> + << it.value().expanded << ", currentIndex = "
> + << it.value().currentIndex << ")";
> }
> + */
>
> - // if there are still untreated entries that need to be restored, used the
> - // model's signal to handle them
> - if (!d->statesByAlbumId.empty())
> - {
> - // and the watch the model for new items added
> - connect(model(), SIGNAL(rowsInserted(QModelIndex, int, int)),
> - SLOT(slotFixRowsInserted(QModelIndex, int, int)), Qt::QueuedConnection);
> - }
>
> + // initial restore run, for everything already loaded
> + //kDebug() << "initial restore run with " << model()->rowCount() << " rows";
> + restoreStateForHierarchy(QModelIndex(), d->statesByAlbumId);
> +
> // also restore the sorting order
> sortByColumn(configGroup.readEntry(entryName(d->configSortColumnEntry), 0),
> (Qt::SortOrder) configGroup.readEntry(entryName(d->configSortOrderEntry), (int) Qt::AscendingOrder));
> @@ -599,26 +588,36 @@
>
> }
>
> -void AbstractAlbumTreeView::restoreState(const QModelIndex &index, QMap<int, Digikam::State> &stateStore)
> +void AbstractAlbumTreeView::restoreStateForHierarchy(const QModelIndex &index, QMap<int, Digikam::State> &stateStore)
> {
> + restoreState(index, stateStore);
> + // do a recursive call of the state restoration
> + for (int i = 0; i < model()->rowCount(index); ++i)
> + {
> + const QModelIndex child = model()->index(i, 0, index);
> + restoreStateForHierarchy(child, stateStore);
> + }
> +}
>
> +void AbstractAlbumTreeView::restoreState(const QModelIndex &index, QMap<int, Digikam::State> &stateStore)
> +{
> Album *album = albumFilterModel()->albumForIndex(index);
> - if (album)
> + if (album && stateStore.contains(album->id()))
> {
>
> - Digikam::State state = stateStore[album->id()];
> + Digikam::State state = stateStore.value(album->id());
>
> -// kDebug() << "Trying to restore state of album " << album->title()
> -// << ": state(selected = " << state.selected
> -// << ", expanded = " << state.expanded
> -// << ", currentIndex = " << state.currentIndex << ")";
> -
> - // restore selection state
> + /*
> + kDebug() << "Trying to restore state of album " << album->title()
> + << ": state(selected = " << state.selected
> + << ", expanded = " << state.expanded
> + << ", currentIndex = " << state.currentIndex << ")" << this;
> + */
> if (state.selected)
> {
> -// kDebug() << "Selecting" << album->title();
> - selectionModel()->select(index, QItemSelectionModel::Select
> - | QItemSelectionModel::Rows);
> + //kDebug() << "Selecting" << album->title();
> + selectionModel()->select(index, QItemSelectionModel::SelectCurrent
> + | QItemSelectionModel::Rows);
> }
>
> // restore expansion state but ensure that the root album is always
> @@ -635,44 +634,48 @@
> // restore the current index
> if (state.currentIndex)
> {
> -// kDebug() << "Setting current index" << album->title();
> - setCurrentIndex(index);
> + //kDebug() << "Setting current index" << album->title();
> + selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent
> + | QItemSelectionModel::Rows);
> }
> -
> - // remove this state so that we don't get in trouble later in case the
> - // same album id is reused again
> - stateStore.remove(album->id());
> -
> }
> +}
>
> - // do a recursive call of the state restoration
> - for (int i = 0; i < model()->rowCount(index); ++i)
> +void AbstractAlbumTreeView::rowsInserted(const QModelIndex &parent, int start, int end)
> +{
> + QTreeView::rowsInserted(parent, start, end);
> +
> + if (!d->statesByAlbumId.isEmpty())
> {
> - const QModelIndex child = model()->index(i, 0, index);
> - restoreState(child, stateStore);
> - }
> + //kDebug() << "slot rowInserted called with index = " << index
> + // << ", start = " << start << ", end = " << end << "remaining ids" << d->statesByAlbumId.keys();
>
> + // Restore state for parent a second time - expansion can only be restored if there are children
> + restoreState(parent, d->statesByAlbumId);
> +
> + for (int i = start; i <= end; ++i)
> + {
> + const QModelIndex child = model()->index(i, 0, parent);
> + restoreState(child, d->statesByAlbumId);
> + }
> + }
> }
>
> -void AbstractAlbumTreeView::slotFixRowsInserted(const QModelIndex &index, int start, int end)
> +void AbstractAlbumTreeView::rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end)
> {
> + QTreeView::rowsAboutToBeRemoved(parent, start, end);
>
> -// kDebug() << "slot rowInserted called with index = " << index
> -// << ", start = " << start << ", end = " << end;
> -
> - for (int i = start; i <= end; ++i)
> + // Clean up map if album id is reused for a new album
> + if (!d->statesByAlbumId.isEmpty())
> {
> - const QModelIndex child = model()->index(i, 0, index);
> - restoreState(child, d->statesByAlbumId);
> + for (int i = start; i <= end; ++i)
> + {
> + const QModelIndex child = model()->index(i, 0, parent);
> + Album *album = albumModel()->albumForIndex(child);
> + if (album)
> + d->statesByAlbumId.remove(album->id());
> + }
> }
> -
> - if (d->statesByAlbumId.empty())
> - {
> - // disconnect if not needed anymore
> - disconnect(model(), SIGNAL(rowsInserted(QModelIndex, int, int)),
> - this, SLOT(slotFixRowsInserted(QModelIndex, int, int)));
> - }
> -
> }
>
> void AbstractAlbumTreeView::adaptColumnsToContent()
> @@ -883,9 +886,6 @@
> {
> AbstractAlbumTreeView::setAlbumFilterModel(filterModel);
>
> - connect(m_albumFilterModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
> - this, SLOT(slotRowsInserted(const QModelIndex &, int, int)));
> -
> // Initialize expanded/collapsed showCount state
> updateShowCountState(QModelIndex(), true);
> }
> @@ -920,8 +920,9 @@
> static_cast<AbstractCountingAlbumModel*>(m_albumModel)->setShowCount(AlbumSettings::instance()->getShowFolderTreeViewItemsCount());
> }
>
> -void AbstractCountingAlbumTreeView::slotRowsInserted(const QModelIndex& parent, int start, int end)
> +void AbstractCountingAlbumTreeView::rowsInserted(const QModelIndex& parent, int start, int end)
> {
> + AbstractAlbumTreeView::rowsInserted(parent, start, end);
> // initialize showCount state when items are added
> for (int i=start; i<=end; ++i)
> updateShowCountState(m_albumFilterModel->index(i, 0, parent), false);
> @@ -1030,25 +1031,26 @@
> }
>
> // initially sync with the albums that are already in the model
> - for (int i = 0; i < checkableModel()->rowCount(); ++i)
> - {
> - const QModelIndex index = checkableModel()->index(i, 0);
> - restoreCheckState(index);
> - }
> + restoreCheckStateForHierarchy(QModelIndex());
> +}
>
> - // wait for missing albums in the background
> - if (!d->checkedAlbumIds.empty())
> +void AbstractCheckableAlbumTreeView::rowsInserted(const QModelIndex& parent, int start, int end)
> +{
> + AbstractCountingAlbumTreeView::rowsInserted(parent, start, end);
> + if (!d->checkedAlbumIds.isEmpty())
> {
> - // and the watch the model for new items added
> - connect(checkableModel(), SIGNAL(rowsInserted(QModelIndex, int, int)),
> - this, SLOT(slotRowsAddedCheckState(QModelIndex, int, int)), Qt::QueuedConnection);
> + for (int i = start; i <= end; ++i)
> + {
> + const QModelIndex child = checkableModel()->index(i, 0, parent);
> + restoreCheckState(child);
> + }
> }
> -
> }
>
> -void AbstractCheckableAlbumTreeView::slotRowsAddedCheckState(QModelIndex index, int start, int end)
> +void AbstractCheckableAlbumTreeView::restoreCheckStateForHierarchy(const QModelIndex &index)
> {
> - for (int i = start; i <= end; ++i)
> + // recurse children
> + for (int i = 0; i < checkableModel()->rowCount(index); ++i)
> {
> const QModelIndex child = checkableModel()->index(i, 0, index);
> restoreCheckState(child);
> @@ -1057,32 +1059,12 @@
>
> void AbstractCheckableAlbumTreeView::restoreCheckState(const QModelIndex &index)
> {
> -
> Album *album = checkableModel()->albumForIndex(index);
> - if (album)
> + if (album && d->checkedAlbumIds.contains(album->id()))
> {
> -
> - if (d->checkedAlbumIds.contains(album->id()))
> - {
> - checkableModel()->setCheckState(album, Qt::Checked);
> - d->checkedAlbumIds.removeOne(album->id());
> - if (d->checkedAlbumIds.empty())
> - {
> - // disconnect if not needed anymore
> - disconnect(model(), SIGNAL(rowsInserted(QModelIndex, int, int)),
> - this, SLOT(slotRowsAddedCheckState(QModelIndex, int, int)));
> - }
> - }
> -
> + checkableModel()->setCheckState(album, Qt::Checked);
> + d->checkedAlbumIds.removeOne(album->id());
> }
> -
> - // recurse children
> - for (int i = 0; i < checkableModel()->rowCount(index); ++i)
> - {
> - const QModelIndex child = checkableModel()->index(i, 0, index);
> - restoreCheckState(child);
> - }
> -
> }
>
> void AbstractCheckableAlbumTreeView::doSaveState()
> --- trunk/extragear/graphics/digikam/digikam/albumtreeview.h #1090061:1090062
> @@ -233,6 +233,8 @@
> bool checkExpandedState(const QModelIndex& index);
> void mousePressEvent(QMouseEvent *e);
>
> + void rowsInserted(const QModelIndex &index, int start, int end);
> + void rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end);
> void startDrag(Qt::DropActions supportedActions);
> void dragEnterEvent(QDragEnterEvent *e);
> void dragMoveEvent(QDragMoveEvent *e);
> @@ -263,6 +265,10 @@
> * @param index index to start restoring
> * @param stateStore states indexed by album id
> */
> + void restoreStateForHierarchy(const QModelIndex &index, QMap<int, Digikam::State> &stateStore);
> + /**
> + * Restore the state for this index.
> + */
> void restoreState(const QModelIndex &index, QMap<int, Digikam::State> &stateStore);
>
> /**
> @@ -275,16 +281,6 @@
> private Q_SLOTS:
>
> /**
> - * Used for asynchronous restoring of the tree view state if the contents of
> - * the model are received after the view has been created.
> - *
> - * @param index parent index of the inserted data
> - * @param start start row of new data under the parent index
> - * @param end end row of new data under the parent index
> - */
> - void slotFixRowsInserted(const QModelIndex &index, int start, int end);
> -
> - /**
> * Adapts the columns in between the given model indices to the content
> * size. This can be connected to dataChanged.
> *
> @@ -333,13 +329,13 @@
> protected:
>
> void setAlbumFilterModel(AlbumFilterModel *filterModel);
> + virtual void rowsInserted(const QModelIndex& parent, int start, int end);
>
> private Q_SLOTS:
>
> void slotCollapsed(const QModelIndex& index);
> void slotExpanded(const QModelIndex& index);
> void slotSetShowCount();
> - void slotRowsInserted(const QModelIndex& parent, int start, int end);
> void updateShowCountState(const QModelIndex& index, bool recurse);
>
> private:
> @@ -391,13 +387,11 @@
> protected:
>
> virtual void middleButtonPressed(Album *a);
> + virtual void rowsInserted(const QModelIndex& parent, int start, int end);
>
> -private Q_SLOTS:
> -
> - void slotRowsAddedCheckState(QModelIndex index, int start, int end);
> -
> private:
>
> + void restoreCheckStateForHierarchy(const QModelIndex &index);
> void restoreCheckState(const QModelIndex &index);
>
> AbstractCheckableAlbumTreeViewPriv *d;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 262 bytes
Desc: OpenPGP digital signature
URL: <http://mail.kde.org/pipermail/digikam-devel/attachments/20100214/a3ab6dc9/attachment.sig>
More information about the Digikam-devel
mailing list