X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/59723fca41a44e4d1ee753e93589027cbdf8d20d..6bfa0ccfc701df5af5f043fce3168b3840858212:/src/kitemviews/kfileitemmodel.cpp diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index c0dedff39..eb7b16461 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -192,8 +192,30 @@ bool KFileItemModel::setData(int index, const QHash& value emit itemsChanged(KItemRangeList() << KItemRange(index, 1), changedRoles); - if (changedRoles.contains(sortRole())) { - m_resortAllItemsTimer->start(); + // Trigger a resorting if the item's correct position has changed. Note + // that this can happen even if the sort role has not changed at all + // because the file name can be used as a fallback. + if (changedRoles.contains(sortRole()) || changedRoles.contains(roleForType(NameRole))) { + // Compare the changed item with its neighbors to see + // if an expensive resorting is needed at all. + const ItemData* changedItem = m_itemData.at(index); + const ItemData* previousItem = (index == 0) ? 0 : m_itemData.at(index - 1); + const ItemData* nextItem = (index == m_itemData.count() - 1) ? 0 : m_itemData.at(index + 1); + + if ((previousItem && lessThan(changedItem, previousItem)) + || (nextItem && lessThan(nextItem, changedItem))) { + m_resortAllItemsTimer->start(); + } else if (groupedSorting() && changedRoles.contains(sortRole())) { + // The position is still correct, but the groups might have changed + // if the changed item is either the first or the last item in a + // group. + // In principle, we could try to find out if the item really is the + // first or last one in its group and then update the groups + // (possibly with a delayed timer to make sure that we don't + // re-calculate the groups very often if items are updated one by + // one), but starting m_resortAllItemsTimer is easier. + m_resortAllItemsTimer->start(); + } } return true; @@ -689,7 +711,6 @@ void KFileItemModel::resortAllItems() oldUrls.append(itemData->item.url()); } - m_groups.clear(); m_items.clear(); // Resort the items @@ -698,20 +719,45 @@ void KFileItemModel::resortAllItems() m_items.insert(m_itemData.at(i)->item.url(), i); } - // Determine the indexes that have been moved - QList movedToIndexes; - movedToIndexes.reserve(itemCount); - for (int i = 0; i < itemCount; i++) { - const int newIndex = m_items.value(oldUrls.at(i)); - movedToIndexes.append(newIndex); + // Determine the first index that has been moved. + int firstMovedIndex = 0; + while (firstMovedIndex < itemCount + && firstMovedIndex == m_items.value(oldUrls.at(firstMovedIndex))) { + ++firstMovedIndex; } - // Don't check whether items have really been moved and always emit a - // itemsMoved() signal after resorting: In case of grouped items - // the groups might change even if the items themselves don't change their - // position. Let the receiver of the signal decide whether a check for moved - // items makes sense. - emit itemsMoved(KItemRange(0, itemCount), movedToIndexes); + const bool itemsHaveMoved = firstMovedIndex < itemCount; + if (itemsHaveMoved) { + m_groups.clear(); + + int lastMovedIndex = itemCount - 1; + while (lastMovedIndex > firstMovedIndex + && lastMovedIndex == m_items.value(oldUrls.at(lastMovedIndex))) { + --lastMovedIndex; + } + + Q_ASSERT(firstMovedIndex <= lastMovedIndex); + + // Create a list movedToIndexes, which has the property that + // movedToIndexes[i] is the new index of the item with the old index + // firstMovedIndex + i. + const int movedItemsCount = lastMovedIndex - firstMovedIndex + 1; + QList movedToIndexes; + movedToIndexes.reserve(movedItemsCount); + for (int i = firstMovedIndex; i <= lastMovedIndex; ++i) { + const int newIndex = m_items.value(oldUrls.at(i)); + movedToIndexes.append(newIndex); + } + + emit itemsMoved(KItemRange(firstMovedIndex, movedItemsCount), movedToIndexes); + } else if (groupedSorting()) { + // The groups might have changed even if the order of the items has not. + const QList > oldGroups = m_groups; + m_groups.clear(); + if (groups() != oldGroups) { + emit groupsChanged(); + } + } #ifdef KFILEITEMMODEL_DEBUG kDebug() << "[TIME] Resorting of" << itemCount << "items:" << timer.elapsed();