diff options
| author | Akseli Lahtinen <[email protected]> | 2025-03-13 12:26:40 +0000 |
|---|---|---|
| committer | Akseli Lahtinen <[email protected]> | 2025-03-13 12:26:40 +0000 |
| commit | dd2cc41fdeed515f8b7921caa9da823e3cba424c (patch) | |
| tree | 36c47fc63a0b2e2a32b43b2cf471c58123514347 /src/kitemviews/kfileitemmodelrolesupdater.cpp | |
| parent | 4f25090d0b5e6e69097e0f62db45eec0085b0c49 (diff) | |
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
Diffstat (limited to 'src/kitemviews/kfileitemmodelrolesupdater.cpp')
| -rw-r--r-- | src/kitemviews/kfileitemmodelrolesupdater.cpp | 65 |
1 files changed, 58 insertions, 7 deletions
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<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" |
