Count the items inside directories in another thread

Review Request #111920 - Created Aug. 6, 2013 and submitted

Frank Reininghaus
I think that counting the items inside directories (this number is shown, e.g., in the "Size" column in Details View) could be done in another thread. This not only prevents that the GUI freezes while counting many items in a folder on a slow device [1]. Moving the code that is needed for the counting and directory watching to another class also makes KFileItemModelRolesUpdater, which is complex enough already, a bit simpler.

Some remarks:

(a) When sorting by "Size", we still count synchronously in the main thread for 200 ms when new items are inserted into the model. If that succeeds, we can show the items in the correct order immediately.

(b) KDirectoryContentsCounter is a helper class that lives in the GUI thread. It organizes the dir watching and tells KFileItemModelRolesUpdater via a signal about the results of the counting.

(c) The actual counting is done in a secondary thread by KDirectoryContentsCounterWorker (Hm, the name might be a bit too long). It communicates with KDirectoryContentsCounter via signals and slots. One problem is that the "Worker" needs to know if it should count hidden files/files and folders/etc. First I used 2 bool arguments for that, but then bool parameters don't really make the code easy to read, so I decided to do it with a flags type KDirectoryContentsCounterWorker::Options. Getting that to work correctly with cross-thread signals was surprisingly complicated, but it works now. I'm not really sure any more if it was worth the effort, but I still think that this is slightly better than the two bools.

(d) There is one change in

KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QString& path, int count)

that is similar to the old function

KFileItemModelRolesUpdater::slotDirWatchDirty(const QString& path)

which may not be obvious: when telling the model about the "size" of the directory, it disconnects from the model's "itemsChanged" signal. The effect is that no new preview will be generated if an image is added to/removed from a subfolder shown in the view. This "feature" was only available when the "Size" was shown anyway, so it added some inconsistency. Moreover, one consequence was that a "dirty" signal from KDirWatch resulted in counting the folder contents *twice*: once after the signal was received, and another time after the model's itemsChanged signal was received. Therefore, I think that it makes sense to drop this "feature".

Any comments are welcome.

[1] This can be simulated by adding something like

    QElapsedTimer timer;
    while (timer.elapsed() < 5000);


int KFileItemModelRolesUpdater::subItemsCount(const QString& path) const
Scrolling the view always feels smooth, even when the items inside a large directory are being counted.
Mark Gaiser
Emmanuel Pescosta
Commit Hook
Frank Reininghaus
Review request changed

Status: Closed (submitted)