┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/kitemviews/kfileitemmodelrolesupdater.cpp
diff options
context:
space:
mode:
authorPan Zhang <[email protected]>2026-05-13 18:40:25 +0800
committerMéven Car <[email protected]>2026-05-13 10:40:25 +0000
commit914cd9010b52125a01e607c0b0f08401be225106 (patch)
treece3406a5c132b7745742cda6ac58b04dc7704089 /src/kitemviews/kfileitemmodelrolesupdater.cpp
parent66e66b7c2881cfb182ec4bf0b18a959371748300 (diff)
kfileitemmodelrolesupdater: fix directory item count for large folders
Dolphin reported an incorrect item count in the "Size" column for directories containing 200 or more entries. Use KIO::ListJob::ListFlag::ExcludeDotAndDotDot and ExcludeHidden to filter entries at the source. Use a local counter (totalCount) captured via std::shared_ptr in the lambda to ensure each scan job starts from zero and maintains its own state. Add a fast path using list.size() when showDirectoriesOnly is false to improve performance. BUG: 509150
Diffstat (limited to 'src/kitemviews/kfileitemmodelrolesupdater.cpp')
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.cpp46
1 files changed, 25 insertions, 21 deletions
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp
index 0f4816424..38fa58436 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -1288,36 +1288,40 @@ void KFileItemModelRolesUpdater::startDirectorySizeCounting(const KFileItem &ite
m_model->setData(index, data);
connect(m_model, &KFileItemModel::itemsChanged, this, &KFileItemModelRolesUpdater::slotItemsChanged);
- auto listJob = KIO::listDir(url, KIO::HideProgressInfo);
+ // Use KIO flags to exclude dot entries at the source to simplify counting
+ KIO::ListJob::ListFlags flags = KIO::ListJob::ListFlag::ExcludeDotAndDotDot;
+ if (!m_model->showHiddenFiles()) {
+ flags |= KIO::ListJob::ListFlag::ExcludeHidden;
+ }
+
+ auto listJob = KIO::listDir(url, KIO::HideProgressInfo, flags);
- QObject::connect(listJob, &KIO::ListJob::entries, this, [this, item](const KJob *job, const KIO::UDSEntryList &list) {
+ // Define a local counter to accumulate results for THIS specific job instance.
+ // Using a shared pointer allows the lambda batches to share and update the same state.
+ auto totalCount = std::make_shared<int>(0);
+
+ QObject::connect(listJob, &KIO::ListJob::entries, this, [this, item, totalCount](const KJob *job, const KIO::UDSEntryList &list) {
+ Q_UNUSED(job)
int index = m_model->index(item);
if (index < 0) {
return;
}
- auto data = m_model->data(index);
- int origCount = data.value("count").toInt();
- // 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;
+ // Accumulate entries for this batch into our job-specific counter
+ if (!m_model->showDirectoriesOnly()) {
+ *totalCount += list.size();
+ } else {
+ for (const KIO::UDSEntry &entry : list) {
+ if (entry.isDir()) {
+ (*totalCount)++;
+ }
}
}
+ const int entryCount = *totalCount;
+ auto data = m_model->data(index);
+ int origCount = data.value("count").toInt();
+
QHash<QByteArray, QVariant> newData;
QVariant expandable = data.value("isExpandable");
if (expandable.isNull() || expandable.toBool() != (entryCount > 0)) {