X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/d472cb2a25cef38dbebbd0ec9073e4ec05d65272..8b4d3624ad1be3de678cc5fcaa5a6baa43767914:/src/kitemviews/kfileitemmodel.cpp diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index b3080d933..776466d68 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -1084,32 +1084,46 @@ void KFileItemModel::slotRefreshItems(const QList >& QSet changedRoles; KFileItemList changedFiles; + // Contains the indexes of the currently visible items + // that should get hidden and hence moved to m_filteredItems. + QVector newFilteredIndexes; + + // Contains currently hidden items that should + // get visible and hence removed from m_filteredItems + QList newVisibleItems; + QListIterator > it(items); while (it.hasNext()) { const QPair& itemPair = it.next(); const KFileItem& oldItem = itemPair.first; const KFileItem& newItem = itemPair.second; const int indexForItem = index(oldItem); + const bool newItemMatchesFilter = m_filter.matches(newItem); if (indexForItem >= 0) { m_itemData[indexForItem]->item = newItem; // Keep old values as long as possible if they could not retrieved synchronously yet. // The update of the values will be done asynchronously by KFileItemModelRolesUpdater. - QHashIterator it(retrieveData(newItem, m_itemData.at(indexForItem)->parent)); - QHash& values = m_itemData[indexForItem]->values; + ItemData * const itemData = m_itemData.at(indexForItem); + QHashIterator it(retrieveData(newItem, itemData->parent)); while (it.hasNext()) { it.next(); const QByteArray& role = it.key(); - if (values.value(role) != it.value()) { - values.insert(role, it.value()); + if (itemData->values.value(role) != it.value()) { + itemData->values.insert(role, it.value()); changedRoles.insert(role); } } m_items.remove(oldItem.url()); - m_items.insert(newItem.url(), indexForItem); - changedFiles.append(newItem); - indexes.append(indexForItem); + if (newItemMatchesFilter) { + m_items.insert(newItem.url(), indexForItem); + changedFiles.append(newItem); + indexes.append(indexForItem); + } else { + newFilteredIndexes.append(indexForItem); + m_filteredItems.insert(newItem, itemData); + } } else { // Check if 'oldItem' is one of the filtered items. QHash::iterator it = m_filteredItems.find(oldItem); @@ -1122,11 +1136,22 @@ void KFileItemModel::slotRefreshItems(const QList >& itemData->values.clear(); m_filteredItems.erase(it); - m_filteredItems.insert(newItem, itemData); + if (newItemMatchesFilter) { + newVisibleItems.append(itemData); + } else { + m_filteredItems.insert(newItem, itemData); + } } } } + // Hide items, previously visible that should get hidden + const KItemRangeList removedRanges = KItemRangeList::fromSortedContainer(newFilteredIndexes); + removeItems(removedRanges, KeepItemData); + + // Show previously hidden items that should get visible + insertItems(newVisibleItems); + // If the changed items have been created recently, they might not be in m_items yet. // In that case, the list 'indexes' might be empty. if (indexes.isEmpty()) { @@ -1728,15 +1753,6 @@ bool KFileItemModel::lessThan(const ItemData* a, const ItemData* b, const QColla } } - // Show hidden files and folders last - const bool isHiddenA = a->item.isHidden(); - const bool isHiddenB = b->item.isHidden(); - if (isHiddenA && !isHiddenB) { - return false; - } else if (!isHiddenA && isHiddenB) { - return true; - } - if (m_sortDirsFirst || (DetailsModeSettings::directorySizeCount() && m_sortRole == SizeRole)) { const bool isDirA = a->item.isDir(); const bool isDirB = b->item.isDir(); @@ -1775,6 +1791,11 @@ void KFileItemModel::sort(const QList::iterator &begi int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const QCollator& collator) const { + // This function must never return 0, because that would break stable + // sorting, which leads to all kinds of bugs. + // See: https://bugs.kde.org/show_bug.cgi?id=433247 + // If two items have equal sort values, let the fallbacks at the bottom of + // the function handle it. const KFileItem& itemA = a->item; const KFileItem& itemB = b->item; @@ -1792,29 +1813,21 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const auto valueA = a->values.value("count"); auto valueB = b->values.value("count"); if (valueA.isNull()) { - if (valueB.isNull()) { - result = 0; - break; - } else { - result = -1; - break; + if (!valueB.isNull()) { + return -1; } } else if (valueB.isNull()) { - result = +1; - break; + return +1; } else { if (valueA.toLongLong() < valueB.toLongLong()) { - result = -1; - break; + return -1; } else if (valueA.toLongLong() > valueB.toLongLong()) { - result = +1; - break; - } else { - result = 0; - break; + return +1; } } + break; } + KIO::filesize_t sizeA = 0; if (itemA.isDir()) { sizeA = a->values.value("size").toULongLong(); @@ -1827,12 +1840,10 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const } else { sizeB = itemB.size(); } - if (sizeA > sizeB) { - result = +1; - } else if (sizeA < sizeB) { - result = -1; - } else { - result = 0; + if (sizeA < sizeB) { + return -1; + } else if (sizeA > sizeB) { + return +1; } break; } @@ -1841,9 +1852,9 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const const long long dateTimeA = itemA.entry().numberValue(KIO::UDSEntry::UDS_MODIFICATION_TIME, -1); const long long dateTimeB = itemB.entry().numberValue(KIO::UDSEntry::UDS_MODIFICATION_TIME, -1); if (dateTimeA < dateTimeB) { - result = -1; + return -1; } else if (dateTimeA > dateTimeB) { - result = +1; + return +1; } break; } @@ -1852,9 +1863,9 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const const long long dateTimeA = itemA.entry().numberValue(KIO::UDSEntry::UDS_CREATION_TIME, -1); const long long dateTimeB = itemB.entry().numberValue(KIO::UDSEntry::UDS_CREATION_TIME, -1); if (dateTimeA < dateTimeB) { - result = -1; + return -1; } else if (dateTimeA > dateTimeB) { - result = +1; + return +1; } break; } @@ -1863,9 +1874,9 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const const QDateTime dateTimeA = a->values.value("deletiontime").toDateTime(); const QDateTime dateTimeB = b->values.value("deletiontime").toDateTime(); if (dateTimeA < dateTimeB) { - result = -1; + return -1; } else if (dateTimeA > dateTimeB) { - result = +1; + return +1; } break; } @@ -1886,9 +1897,9 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const const QString roleValueA = a->values.value(role).toString(); const QString roleValueB = b->values.value(role).toString(); if (!roleValueA.isEmpty() && roleValueB.isEmpty()) { - result = -1; + return -1; } else if (roleValueA.isEmpty() && !roleValueB.isEmpty()) { - result = +1; + return +1; } else if (isRoleValueNatural(m_sortRole)) { result = stringCompare(roleValueA, roleValueB, collator); } else {