diff options
Diffstat (limited to 'src/kitemviews/private')
4 files changed, 54 insertions, 20 deletions
diff --git a/src/kitemviews/private/kdirectorycontentscounter.cpp b/src/kitemviews/private/kdirectorycontentscounter.cpp index 039b79b6e..37e852ab9 100644 --- a/src/kitemviews/private/kdirectorycontentscounter.cpp +++ b/src/kitemviews/private/kdirectorycontentscounter.cpp @@ -44,6 +44,7 @@ KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel *model, QObj m_worker->moveToThread(m_workerThread); connect(this, &KDirectoryContentsCounter::requestDirectoryContentsCount, m_worker, &KDirectoryContentsCounterWorker::countDirectoryContents); + connect(this, &KDirectoryContentsCounter::stop, m_worker, &KDirectoryContentsCounterWorker::stop); connect(m_worker, &KDirectoryContentsCounterWorker::result, this, &KDirectoryContentsCounter::slotResult); m_dirWatcher = new KDirWatch(this); @@ -71,11 +72,6 @@ KDirectoryContentsCounter::~KDirectoryContentsCounter() } } -void KDirectoryContentsCounter::scanDirectory(const QString &path) -{ - startWorker(path); -} - void KDirectoryContentsCounter::slotResult(const QString &path, int count, long size) { m_workerIsBusy = false; @@ -91,11 +87,11 @@ void KDirectoryContentsCounter::slotResult(const QString &path, int count, long if (!m_priorityQueue.empty()) { const QString firstPath = m_priorityQueue.front(); m_priorityQueue.pop_front(); - startWorker(firstPath); + scanDirectory(firstPath, PathCountPriority::High); } else if (!m_queue.empty()) { const QString firstPath = m_queue.front(); m_queue.pop_front(); - startWorker(firstPath); + scanDirectory(firstPath, PathCountPriority::Normal); } if (s_cache->contains(resolvedPath)) { @@ -127,7 +123,7 @@ void KDirectoryContentsCounter::slotDirWatchDirty(const QString &path) return; } - startWorker(path); + scanDirectory(path, PathCountPriority::High); } } @@ -156,7 +152,7 @@ void KDirectoryContentsCounter::slotItemsRemoved() } } -void KDirectoryContentsCounter::startWorker(const QString &path) +void KDirectoryContentsCounter::scanDirectory(const QString &path, PathCountPriority priority) { const QString resolvedPath = QFileInfo(path).canonicalFilePath(); const bool alreadyInCache = s_cache->contains(resolvedPath); @@ -168,10 +164,16 @@ void KDirectoryContentsCounter::startWorker(const QString &path) } if (m_workerIsBusy) { + // only enqueue path not yet in queue if (std::find(m_queue.begin(), m_queue.end(), path) == m_queue.end() && std::find(m_priorityQueue.begin(), m_priorityQueue.end(), path) == m_priorityQueue.end()) { - if (alreadyInCache) { - m_queue.push_back(path); + if (priority == PathCountPriority::Normal) { + if (alreadyInCache) { + // if we already knew the dir size, it gets lower priority + m_queue.push_back(path); + } else { + m_queue.push_front(path); + } } else { // append to priority queue m_priorityQueue.push_back(path); @@ -193,4 +195,11 @@ void KDirectoryContentsCounter::startWorker(const QString &path) } } +void KDirectoryContentsCounter::stopWorker() +{ + m_queue.clear(); + m_priorityQueue.clear(); + Q_EMIT stop(); +} + QThread *KDirectoryContentsCounter::m_workerThread = nullptr; diff --git a/src/kitemviews/private/kdirectorycontentscounter.h b/src/kitemviews/private/kdirectorycontentscounter.h index f74565b73..9a5e4a86b 100644 --- a/src/kitemviews/private/kdirectorycontentscounter.h +++ b/src/kitemviews/private/kdirectorycontentscounter.h @@ -21,6 +21,8 @@ class KDirectoryContentsCounter : public QObject Q_OBJECT public: + enum PathCountPriority { Normal, High }; + explicit KDirectoryContentsCounter(KFileItemModel *model, QObject *parent = nullptr); ~KDirectoryContentsCounter() override; @@ -35,7 +37,12 @@ public: * Uses a cache internally to speed up first result, * but emit again result when the cache was updated */ - void scanDirectory(const QString &path); + void scanDirectory(const QString &path, PathCountPriority priority); + + /** + * Stops the work until new input is passed + */ + void stopWorker(); Q_SIGNALS: /** @@ -46,15 +53,14 @@ Q_SIGNALS: void requestDirectoryContentsCount(const QString &path, KDirectoryContentsCounterWorker::Options options); + void stop(); + private Q_SLOTS: void slotResult(const QString &path, int count, long size); void slotDirWatchDirty(const QString &path); void slotItemsRemoved(); private: - void startWorker(const QString &path); - -private: KFileItemModel *m_model; // Used as FIFO queues. diff --git a/src/kitemviews/private/kdirectorycontentscounterworker.cpp b/src/kitemviews/private/kdirectorycontentscounterworker.cpp index e227c1bc6..2227ebbc2 100644 --- a/src/kitemviews/private/kdirectorycontentscounterworker.cpp +++ b/src/kitemviews/private/kdirectorycontentscounterworker.cpp @@ -25,7 +25,7 @@ KDirectoryContentsCounterWorker::KDirectoryContentsCounterWorker(QObject *parent #ifndef Q_OS_WIN KDirectoryContentsCounterWorker::CountResult -walkDir(const QString &dirPath, const bool countHiddenFiles, const bool countDirectoriesOnly, const uint allowedRecursiveLevel) +KDirectoryContentsCounterWorker::walkDir(const QString &dirPath, const bool countHiddenFiles, const bool countDirectoriesOnly, const uint allowedRecursiveLevel) { int count = -1; long size = -1; @@ -36,7 +36,7 @@ walkDir(const QString &dirPath, const bool countHiddenFiles, const bool countDir QT_DIRENT *dirEntry; QT_STATBUF buf; - while ((dirEntry = QT_READDIR(dir))) { + while (!m_stopping && (dirEntry = QT_READDIR(dir))) { if (dirEntry->d_name[0] == '.') { if (dirEntry->d_name[1] == '\0' || !countHiddenFiles) { // Skip "." or hidden files @@ -64,7 +64,7 @@ walkDir(const QString &dirPath, const bool countHiddenFiles, const bool countDir size += buf.st_size; } } - if (dirEntry->d_type == DT_DIR) { + if (!m_stopping && dirEntry->d_type == DT_DIR) { // recursion for dirs auto subdirResult = walkDir(nameBuf, countHiddenFiles, countDirectoriesOnly, allowedRecursiveLevel - 1); if (subdirResult.size > 0) { @@ -106,8 +106,18 @@ KDirectoryContentsCounterWorker::CountResult KDirectoryContentsCounterWorker::su #endif } +void KDirectoryContentsCounterWorker::stop() +{ + m_stopping = true; +} + void KDirectoryContentsCounterWorker::countDirectoryContents(const QString &path, Options options) { + m_stopping = false; + auto res = subItemsCount(path, options); - Q_EMIT result(path, res.count, res.size); + + if (!m_stopping) { + Q_EMIT result(path, res.count, res.size); + } } diff --git a/src/kitemviews/private/kdirectorycontentscounterworker.h b/src/kitemviews/private/kdirectorycontentscounterworker.h index 6bbe099a5..5266960cd 100644 --- a/src/kitemviews/private/kdirectorycontentscounterworker.h +++ b/src/kitemviews/private/kdirectorycontentscounterworker.h @@ -36,7 +36,7 @@ public: * * @return The number of items. */ - static CountResult subItemsCount(const QString &path, Options options); + CountResult subItemsCount(const QString &path, Options options); Q_SIGNALS: /** @@ -53,6 +53,15 @@ public Q_SLOTS: // is needed here. Just using 'Options' is OK for the compiler, but // confuses moc. void countDirectoryContents(const QString &path, KDirectoryContentsCounterWorker::Options options); + void stop(); + +private: +#ifndef Q_OS_WIN + KDirectoryContentsCounterWorker::CountResult + walkDir(const QString &dirPath, const bool countHiddenFiles, const bool countDirectoriesOnly, const uint allowedRecursiveLevel); +#endif + + bool m_stopping = false; }; Q_DECLARE_METATYPE(KDirectoryContentsCounterWorker::Options) |
