From: Akseli Lahtinen Date: Thu, 13 Mar 2025 12:26:40 +0000 (+0000) Subject: KFileItemModelRolesUpdater: reset size and count before updating folders X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/dd2cc41fdeed515f8b7921caa9da823e3cba424c?hp=4f25090d0b5e6e69097e0f62db45eec0085b0c49 KFileItemModelRolesUpdater: reset size and count before updating folders 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 --- diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp index 97b51ae84..f9a50b9de 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.cpp +++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp @@ -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 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 dirsWithDeletedItems; // Only remove the items from m_finishedItems. They will be removed // from the other sets later on. QSet::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 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 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" diff --git a/src/kitemviews/kfileitemmodelrolesupdater.h b/src/kitemviews/kfileitemmodelrolesupdater.h index 3480713ee..56e28ce72 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.h +++ b/src/kitemviews/kfileitemmodelrolesupdater.h @@ -340,6 +340,10 @@ private: void trimHoverSequenceLoadedItems(); + void resetSizeData(const int index, const int size = 0); + + void recountDirectoryItems(const QList directories); + private: QSize cacheSize(); /**