Changeset View
Changeset View
Standalone View
Standalone View
src/kitemviews/private/kdirectorycontentscounter.cpp
Show All 22 Lines | |||||
23 | 23 | | |||
24 | #include <KDirWatch> | 24 | #include <KDirWatch> | ||
25 | 25 | | |||
26 | #include <QFileInfo> | 26 | #include <QFileInfo> | ||
27 | #include <QThread> | 27 | #include <QThread> | ||
28 | 28 | | |||
29 | KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObject* parent) : | 29 | KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObject* parent) : | ||
30 | QObject(parent), | 30 | QObject(parent), | ||
31 | m_model(model), | 31 | m_model(model), | ||
meven: It would be great to be able to share this cache with baloo-widgets, so that those data can be… | |||||
meven: The Status bar info could be updated to get this data. | |||||
32 | m_queue(), | 32 | m_queue(), | ||
33 | m_worker(nullptr), | 33 | m_worker(nullptr), | ||
34 | m_workerIsBusy(false), | 34 | m_workerIsBusy(false), | ||
35 | m_dirWatcher(nullptr), | 35 | m_dirWatcher(nullptr), | ||
36 | m_watchedDirs() | 36 | m_watchedDirs() | ||
37 | { | 37 | { | ||
38 | connect(m_model, &KFileItemModel::itemsRemoved, | 38 | connect(m_model, &KFileItemModel::itemsRemoved, | ||
39 | this, &KDirectoryContentsCounter::slotItemsRemoved); | 39 | this, &KDirectoryContentsCounter::slotItemsRemoved); | ||
40 | 40 | | |||
41 | if (!m_workerThread) { | 41 | if (!m_workerThread) { | ||
42 | m_workerThread = new QThread(); | 42 | m_workerThread = new QThread(); | ||
43 | m_workerThread->start(); | 43 | m_workerThread->start(); | ||
44 | } | 44 | } | ||
45 | 45 | | |||
46 | m_worker = new KDirectoryContentsCounterWorker(); | 46 | m_worker = new KDirectoryContentsCounterWorker(); | ||
47 | m_worker->moveToThread(m_workerThread); | 47 | m_worker->moveToThread(m_workerThread); | ||
48 | ++m_workersCount; | | |||
49 | 48 | | |||
50 | connect(this, &KDirectoryContentsCounter::requestDirectoryContentsCount, | 49 | connect(this, &KDirectoryContentsCounter::requestDirectoryContentsCount, | ||
51 | m_worker, &KDirectoryContentsCounterWorker::countDirectoryContents); | 50 | m_worker, &KDirectoryContentsCounterWorker::countDirectoryContents); | ||
52 | connect(m_worker, &KDirectoryContentsCounterWorker::result, | 51 | connect(m_worker, &KDirectoryContentsCounterWorker::result, | ||
53 | this, &KDirectoryContentsCounter::slotResult); | 52 | this, &KDirectoryContentsCounter::slotResult); | ||
54 | 53 | | |||
55 | m_dirWatcher = new KDirWatch(this); | 54 | m_dirWatcher = new KDirWatch(this); | ||
55 | m_dirWatcher->moveToThread(m_workerThread); | ||||
56 | connect(m_dirWatcher, &KDirWatch::dirty, this, &KDirectoryContentsCounter::slotDirWatchDirty); | 56 | connect(m_dirWatcher, &KDirWatch::dirty, this, &KDirectoryContentsCounter::slotDirWatchDirty); | ||
57 | } | 57 | } | ||
58 | 58 | | |||
59 | KDirectoryContentsCounter::~KDirectoryContentsCounter() | 59 | KDirectoryContentsCounter::~KDirectoryContentsCounter() | ||
60 | { | 60 | { | ||
61 | --m_workersCount; | 61 | if (m_workerThread->isRunning()) { | ||
elvisangelaccio: Why this change? What's wrong with `m_workersCount` ? | |||||
I intend to have a single worker KDirectoryContentsCounter, so why bother reimplementing a refCount ? meven: I intend to have a single worker KDirectoryContentsCounter, so why bother reimplementing a… | |||||
I see. This is valuable information, please put it in the commit message :) elvisangelaccio: I see. This is valuable information, please put it in the commit message :) | |||||
62 | | ||||
63 | if (m_workersCount > 0) { | | |||
64 | // The worker thread will continue running. It could even be running | 62 | // The worker thread will continue running. It could even be running | ||
65 | // a method of m_worker at the moment, so we delete it using | 63 | // a method of m_worker at the moment, so we delete it using | ||
66 | // deleteLater() to prevent a crash. | 64 | // deleteLater() to prevent a crash. | ||
67 | m_worker->deleteLater(); | 65 | m_worker->deleteLater(); | ||
68 | } else { | 66 | } else { | ||
69 | // There are no remaining workers -> stop the worker thread. | 67 | // There are no remaining workers -> stop the worker thread. | ||
70 | m_workerThread->quit(); | 68 | m_workerThread->quit(); | ||
71 | m_workerThread->wait(); | 69 | m_workerThread->wait(); | ||
72 | delete m_workerThread; | 70 | delete m_workerThread; | ||
73 | m_workerThread = nullptr; | 71 | m_workerThread = nullptr; | ||
74 | 72 | | |||
75 | // The worker thread has finished running now, so it's safe to delete | 73 | // The worker thread has finished running now, so it's safe to delete | ||
76 | // m_worker. deleteLater() would not work at all because the event loop | 74 | // m_worker. deleteLater() would not work at all because the event loop | ||
77 | // which would deliver the event to m_worker is not running any more. | 75 | // which would deliver the event to m_worker is not running any more. | ||
78 | delete m_worker; | 76 | delete m_worker; | ||
79 | } | 77 | } | ||
80 | } | 78 | } | ||
81 | 79 | | |||
82 | void KDirectoryContentsCounter::addDirectory(const QString& path) | 80 | void KDirectoryContentsCounter::addDirectory(const QString& path) | ||
83 | { | 81 | { | ||
84 | startWorker(path); | 82 | startWorker(path); | ||
85 | } | 83 | } | ||
86 | 84 | | |||
87 | int KDirectoryContentsCounter::countDirectoryContentsSynchronously(const QString& path) | 85 | KDirectoryContentsCounterWorker::CountResult KDirectoryContentsCounter::countDirectoryContentsSynchronously(const QString& path) | ||
88 | { | 86 | { | ||
89 | const QString resolvedPath = QFileInfo(path).canonicalFilePath(); | 87 | const QString resolvedPath = QFileInfo(path).canonicalFilePath(); | ||
90 | 88 | | |||
91 | if (!m_dirWatcher->contains(resolvedPath)) { | 89 | if (!m_dirWatcher->contains(resolvedPath)) { | ||
92 | m_dirWatcher->addDir(resolvedPath); | 90 | m_dirWatcher->addDir(resolvedPath); | ||
93 | m_watchedDirs.insert(resolvedPath); | 91 | m_watchedDirs.insert(resolvedPath); | ||
94 | } | 92 | } | ||
95 | 93 | | |||
96 | KDirectoryContentsCounterWorker::Options options; | 94 | KDirectoryContentsCounterWorker::Options options; | ||
97 | 95 | | |||
98 | if (m_model->showHiddenFiles()) { | 96 | if (m_model->showHiddenFiles()) { | ||
99 | options |= KDirectoryContentsCounterWorker::CountHiddenFiles; | 97 | options |= KDirectoryContentsCounterWorker::CountHiddenFiles; | ||
100 | } | 98 | } | ||
101 | 99 | | |||
102 | if (m_model->showDirectoriesOnly()) { | 100 | if (m_model->showDirectoriesOnly()) { | ||
103 | options |= KDirectoryContentsCounterWorker::CountDirectoriesOnly; | 101 | options |= KDirectoryContentsCounterWorker::CountDirectoriesOnly; | ||
104 | } | 102 | } | ||
105 | 103 | | |||
106 | return KDirectoryContentsCounterWorker::subItemsCount(path, options); | 104 | return KDirectoryContentsCounterWorker::subItemsCount(path, options); | ||
107 | } | 105 | } | ||
108 | 106 | | |||
109 | void KDirectoryContentsCounter::slotResult(const QString& path, int count) | 107 | void KDirectoryContentsCounter::slotResult(const QString& path, int count, long size) | ||
110 | { | 108 | { | ||
111 | m_workerIsBusy = false; | 109 | m_workerIsBusy = false; | ||
112 | 110 | | |||
113 | const QString resolvedPath = QFileInfo(path).canonicalFilePath(); | 111 | const QString resolvedPath = QFileInfo(path).canonicalFilePath(); | ||
114 | 112 | | |||
115 | if (!m_dirWatcher->contains(resolvedPath)) { | 113 | if (!m_dirWatcher->contains(resolvedPath)) { | ||
116 | m_dirWatcher->addDir(resolvedPath); | 114 | m_dirWatcher->addDir(resolvedPath); | ||
117 | m_watchedDirs.insert(resolvedPath); | 115 | m_watchedDirs.insert(resolvedPath); | ||
118 | } | 116 | } | ||
119 | 117 | | |||
120 | if (!m_queue.isEmpty()) { | 118 | if (!m_queue.isEmpty()) { | ||
121 | startWorker(m_queue.dequeue()); | 119 | startWorker(m_queue.dequeue()); | ||
122 | } | 120 | } | ||
123 | 121 | | |||
124 | emit result(path, count); | 122 | emit result(path, count, size); | ||
125 | } | 123 | } | ||
126 | 124 | | |||
127 | void KDirectoryContentsCounter::slotDirWatchDirty(const QString& path) | 125 | void KDirectoryContentsCounter::slotDirWatchDirty(const QString& path) | ||
128 | { | 126 | { | ||
129 | const int index = m_model->index(QUrl::fromLocalFile(path)); | 127 | const int index = m_model->index(QUrl::fromLocalFile(path)); | ||
130 | if (index >= 0) { | 128 | if (index >= 0) { | ||
131 | if (!m_model->fileItem(index).isDir()) { | 129 | if (!m_model->fileItem(index).isDir()) { | ||
132 | // If INotify is used, KDirWatch issues the dirty() signal | 130 | // If INotify is used, KDirWatch issues the dirty() signal | ||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Line(s) | 169 | } else { | |||
180 | } | 178 | } | ||
181 | 179 | | |||
182 | emit requestDirectoryContentsCount(path, options); | 180 | emit requestDirectoryContentsCount(path, options); | ||
183 | m_workerIsBusy = true; | 181 | m_workerIsBusy = true; | ||
184 | } | 182 | } | ||
185 | } | 183 | } | ||
186 | 184 | | |||
187 | QThread* KDirectoryContentsCounter::m_workerThread = nullptr; | 185 | QThread* KDirectoryContentsCounter::m_workerThread = nullptr; | ||
188 | int KDirectoryContentsCounter::m_workersCount = 0; | |
It would be great to be able to share this cache with baloo-widgets, so that those data can be used in the metadata widget