From: Peter Penz Date: Fri, 16 Sep 2011 20:33:00 +0000 (+0200) Subject: Fix crash when expanding/closing a sub-tree X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/5070666ad2cd5fe3e559adca00a52aed5d137153?ds=sidebyside Fix crash when expanding/closing a sub-tree m_pendingItems and m_pendingInvisibleItems might contain already removed items. Take care to delete them before starting to resolve the roles. Thanks to Frank Reininghaus for finding out the root-cause. --- diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp index 4607cf6e4..1bde3484d 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.cpp +++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp @@ -285,9 +285,28 @@ void KFileItemModelRolesUpdater::slotItemsRemoved(const KItemRangeList& itemRang { Q_UNUSED(itemRanges); m_firstVisibleIndex = 0; - m_lastVisibleIndex = -1; - if (hasPendingRoles() && m_model->count() <= 0) { + m_lastVisibleIndex = -1; + if (!hasPendingRoles()) { + return; + } + + if (m_model->count() == 0) { + // Most probably a directory change is done. Clear all pending items + // and also kill all ongoing preview-jobs. resetPendingRoles(); + } else { + // Remove all items from m_pendingVisibleItems and m_pendingInvisibleItems + // that are not part of the model anymore. + for (int i = 0; i <= 1; ++i) { + QSet& pendingItems = (i == 0) ? m_pendingVisibleItems : m_pendingInvisibleItems; + QMutableSetIterator it(pendingItems); + while (it.hasNext()) { + const KFileItem item = it.next(); + if (m_model->index(item) < 0) { + pendingItems.remove(item); + } + } + } } } @@ -477,7 +496,7 @@ void KFileItemModelRolesUpdater::resolveNextPendingRoles() void KFileItemModelRolesUpdater::startPreviewJob(const KFileItemList& items) { - if (items.count() <= 0 || m_paused) { + if (items.isEmpty() || m_paused) { return; } @@ -541,7 +560,6 @@ void KFileItemModelRolesUpdater::resetPendingRoles() void KFileItemModelRolesUpdater::triggerPendingRolesResolving(int count) { - Q_ASSERT(count <= m_model->count()); if (count == m_model->count()) { // When initially loading a directory a synchronous resolving prevents a minor // flickering when opening directories. This is also fine from a performance point @@ -565,7 +583,7 @@ void KFileItemModelRolesUpdater::sortAndResolveAllRoles() Q_ASSERT(m_pendingVisibleItems.isEmpty()); Q_ASSERT(m_pendingInvisibleItems.isEmpty()); - if (m_model->count() <= 0) { + if (m_model->count() == 0) { return; } @@ -599,7 +617,7 @@ void KFileItemModelRolesUpdater::sortAndResolveAllRoles() void KFileItemModelRolesUpdater::sortAndResolvePendingRoles() { Q_ASSERT(!m_paused); - if (m_model->count() <= 0) { + if (m_model->count() == 0) { return; } @@ -638,6 +656,10 @@ void KFileItemModelRolesUpdater::sortAndResolvePendingRoles() bool KFileItemModelRolesUpdater::applyResolvedRoles(const KFileItem& item, ResolveHint hint) { + if (item.isNull()) { + return false; + } + const bool resolveAll = (hint == ResolveAll); bool mimeTypeChanged = false;