]> cloud.milkyroute.net Git - dolphin.git/commitdiff
KFileItemModelRolesUpdater: reset size and count before updating folders
authorAkseli Lahtinen <akselmo@akselmo.dev>
Thu, 13 Mar 2025 12:26:40 +0000 (12:26 +0000)
committerAkseli Lahtinen <akselmo@akselmo.dev>
Thu, 13 Mar 2025 12:26:40 +0000 (12:26 +0000)
Folder count would not update properly when user would delete file from
a folder, or add a new file to it.

Previously when size value is set to -2 after update, the update will
never be called again unless user presses F5. This change will instead
reset that -2 to 0 whenever we are requesting for calculating
directory sizes.

We never updated the count when a file was deleted, so that has been added as well.

This change also calculates the item counts from the processedAmount, which is the total amount of items we're processing. From there we remove the unwanted items and get the final count.

For remote files, we set the count to -1 since we don't calculate them.

BUG: 500502

src/kitemviews/kfileitemmodelrolesupdater.cpp
src/kitemviews/kfileitemmodelrolesupdater.h

index 97b51ae84e14357c135abd5a9203bd24a3fbb8f3..f9a50b9de67b9bf318c38d06e8b60d582a6bee87 100644 (file)
@@ -370,19 +370,28 @@ void KFileItemModelRolesUpdater::slotItemsInserted(const KItemRangeList &itemRan
 
     // Determine the sort role synchronously for as many items as possible.
     if (m_resolvableRoles.contains(m_model->sortRole())) {
+        QList<QUrl> dirsWithAddedItems;
+
         int insertedCount = 0;
         for (const KItemRange &range : itemRanges) {
             const int lastIndex = insertedCount + range.index + range.count - 1;
             for (int i = insertedCount + range.index; i <= lastIndex; ++i) {
+                const auto fileItem = m_model->fileItem(i);
+                const auto fileItemParentFolderUrl = fileItem.url().adjusted(QUrl::RemoveFilename);
+                if (!dirsWithAddedItems.contains(fileItemParentFolderUrl)) {
+                    dirsWithAddedItems.append(fileItemParentFolderUrl);
+                }
                 if (timer.elapsed() < MaxBlockTimeout) {
                     applySortRole(i);
                 } else {
-                    m_pendingSortRoleItems.insert(m_model->fileItem(i));
+                    m_pendingSortRoleItems.insert(fileItem);
                 }
             }
             insertedCount += range.count;
         }
 
+        recountDirectoryItems(dirsWithAddedItems);
+
         applySortProgressToModel();
 
         // If there are still items whose sort role is unknown, check if the
@@ -439,17 +448,25 @@ void KFileItemModelRolesUpdater::slotItemsRemoved(const KItemRangeList &itemRang
             m_directoryContentsCounter->stopWorker();
         }
     } else {
+        QList<QUrl> dirsWithDeletedItems;
         // Only remove the items from m_finishedItems. They will be removed
         // from the other sets later on.
         QSet<KFileItem>::iterator it = m_finishedItems.begin();
         while (it != m_finishedItems.end()) {
             if (m_model->index(*it) < 0) {
+                // Get the folder path of the file.
+                const auto folderUrl = it->url().adjusted(QUrl::RemoveFilename);
+                if (!dirsWithDeletedItems.contains(folderUrl)) {
+                    dirsWithDeletedItems.append(folderUrl);
+                }
                 it = m_finishedItems.erase(it);
             } else {
                 ++it;
             }
         }
 
+        recountDirectoryItems(dirsWithDeletedItems);
+
         // Removed items won't have hover previews loaded anymore.
         for (const KItemRange &itemRange : itemRanges) {
             int index = itemRange.index;
@@ -1270,13 +1287,20 @@ bool KFileItemModelRolesUpdater::applyResolvedRoles(int index, ResolveHint hint)
 
 void KFileItemModelRolesUpdater::startDirectorySizeCounting(const KFileItem &item, int index)
 {
-    if (ContentDisplaySettings::directorySizeMode() == ContentDisplaySettings::EnumDirectorySizeMode::None || !item.isLocalFile()) {
+    if (ContentDisplaySettings::directorySizeMode() == ContentDisplaySettings::EnumDirectorySizeMode::None) {
         return;
     }
 
+    // Set any remote files to unknown size (-1).
+    if (!item.isLocalFile()) {
+        resetSizeData(index, -1);
+        return;
+    } else {
+        resetSizeData(index);
+    }
+
     if (ContentDisplaySettings::directorySizeMode() == ContentDisplaySettings::EnumDirectorySizeMode::ContentCount || item.isSlow()) {
         // fastpath no recursion necessary
-
         auto data = m_model->data(index);
         if (data.value("size") == -2) {
             // means job already started
@@ -1296,28 +1320,33 @@ void KFileItemModelRolesUpdater::startDirectorySizeCounting(const KFileItem &ite
         connect(m_model, &KFileItemModel::itemsChanged, this, &KFileItemModelRolesUpdater::slotItemsChanged);
 
         auto listJob = KIO::listDir(url, KIO::HideProgressInfo);
-        QObject::connect(listJob, &KIO::ListJob::entries, this, [this, item](const KJob * /*job*/, const KIO::UDSEntryList &list) {
+
+        QObject::connect(listJob, &KIO::ListJob::entries, this, [this, item](const KJob *job, const KIO::UDSEntryList &list) {
             int index = m_model->index(item);
             if (index < 0) {
                 return;
             }
             auto data = m_model->data(index);
             int origCount = data.value("count").toInt();
-            int entryCount = origCount;
+            // Get the amount of processed items...
+            int entryCount = job->processedAmount(KJob::Bytes);
 
+            // ...and then remove the unwanted items from the amount.
             for (const KIO::UDSEntry &entry : list) {
                 const auto name = entry.stringValue(KIO::UDSEntry::UDS_NAME);
 
                 if (name == QStringLiteral("..") || name == QStringLiteral(".")) {
+                    --entryCount;
                     continue;
                 }
                 if (!m_model->showHiddenFiles() && name.startsWith(QLatin1Char('.'))) {
+                    --entryCount;
                     continue;
                 }
                 if (m_model->showDirectoriesOnly() && !entry.isDir()) {
+                    --entryCount;
                     continue;
                 }
-                ++entryCount;
             }
 
             QHash<QByteArray, QVariant> newData;
@@ -1328,7 +1357,6 @@ void KFileItemModelRolesUpdater::startDirectorySizeCounting(const KFileItem &ite
             }
 
             if (origCount != entryCount) {
-                // count has changed
                 newData.insert("count", entryCount);
             }
 
@@ -1511,4 +1539,27 @@ void KFileItemModelRolesUpdater::trimHoverSequenceLoadedItems()
     }
 }
 
+void KFileItemModelRolesUpdater::resetSizeData(const int index, const int size)
+{
+    disconnect(m_model, &KFileItemModel::itemsChanged, this, &KFileItemModelRolesUpdater::slotItemsChanged);
+    auto data = m_model->data(index);
+    data.insert("size", size);
+    m_model->setData(index, data);
+    connect(m_model, &KFileItemModel::itemsChanged, this, &KFileItemModelRolesUpdater::slotItemsChanged);
+}
+
+void KFileItemModelRolesUpdater::recountDirectoryItems(const QList<QUrl> directories)
+{
+    for (const auto &dir : directories) {
+        auto index = m_model->index(dir);
+        if (index < 0) {
+            continue;
+        }
+        auto item = m_model->fileItem(index);
+        if (item.isDir()) {
+            startDirectorySizeCounting(item, index);
+        }
+    }
+}
+
 #include "moc_kfileitemmodelrolesupdater.cpp"
index 3480713eef0c661da3d8fd745358f99e4aaf0ef7..56e28ce72587dbdae53096c1b7cbc3da57df9079 100644 (file)
@@ -340,6 +340,10 @@ private:
 
     void trimHoverSequenceLoadedItems();
 
+    void resetSizeData(const int index, const int size = 0);
+
+    void recountDirectoryItems(const QList<QUrl> directories);
+
 private:
     QSize cacheSize();
     /**