2 * SPDX-FileCopyrightText: 2011 Peter Penz <peter.penz19@gmail.com>
3 * SPDX-FileCopyrightText: 2013 Frank Reininghaus <frank78ac@googlemail.com>
5 * SPDX-License-Identifier: GPL-2.0-or-later
8 #include "kdirectorycontentscounterworker.h"
10 // Required includes for subItemsCount():
15 #include <qplatformdefs.h>
18 #include "dolphin_detailsmodesettings.h"
20 KDirectoryContentsCounterWorker::KDirectoryContentsCounterWorker(QObject
* parent
) :
23 qRegisterMetaType
<KDirectoryContentsCounterWorker::Options
>();
27 KDirectoryContentsCounterWorker::CountResult
walkDir(const QString
&dirPath
,
28 const bool countHiddenFiles
,
29 const bool countDirectoriesOnly
,
31 const uint allowedRecursiveLevel
)
35 auto dir
= QT_OPENDIR(QFile::encodeName(dirPath
));
41 while ((dirEntry
= QT_READDIR(dir
))) {
42 if (dirEntry
->d_name
[0] == '.') {
43 if (dirEntry
->d_name
[1] == '\0' || !countHiddenFiles
) {
44 // Skip "." or hidden files
47 if (dirEntry
->d_name
[1] == '.' && dirEntry
->d_name
[2] == '\0') {
53 // If only directories are counted, consider an unknown file type and links also
54 // as directory instead of trying to do an expensive stat()
55 // (see bugs 292642 and 299997).
56 const bool countEntry
= !countDirectoriesOnly
||
57 dirEntry
->d_type
== DT_DIR
||
58 dirEntry
->d_type
== DT_LNK
||
59 dirEntry
->d_type
== DT_UNKNOWN
;
64 if (allowedRecursiveLevel
> 0) {
66 bool linkFound
= false;
67 QString nameBuf
= QStringLiteral("%1/%2").arg(dirPath
, dirEntry
->d_name
);
69 if (dirEntry
->d_type
== DT_REG
|| dirEntry
->d_type
== DT_LNK
) {
70 if (QT_STAT(nameBuf
.toLocal8Bit(), &buf
) == 0) {
71 if (S_ISDIR(buf
.st_mode
)) {
72 // was a dir link, recurse
78 if (dirEntry
->d_type
== DT_DIR
|| linkFound
) {
79 // recursion for dirs and dir links
80 size
+= walkDir(nameBuf
, countHiddenFiles
, countDirectoriesOnly
, dirEntry
, allowedRecursiveLevel
- 1).size
;
86 return KDirectoryContentsCounterWorker::CountResult
{count
, size
};
90 KDirectoryContentsCounterWorker::CountResult
KDirectoryContentsCounterWorker::subItemsCount(const QString
& path
, Options options
)
92 const bool countHiddenFiles
= options
& CountHiddenFiles
;
93 const bool countDirectoriesOnly
= options
& CountDirectoriesOnly
;
97 QDir::Filters filters
= QDir::NoDotAndDotDot
| QDir::System
;
98 if (countHiddenFiles
) {
99 filters
|= QDir::Hidden
;
101 if (countDirectoriesOnly
) {
102 filters
|= QDir::Dirs
;
104 filters
|= QDir::AllEntries
;
106 return {dir
.entryList(filters
).count(), 0};
109 const uint maxRecursiveLevel
= DetailsModeSettings::directorySizeCount() ? 1 : DetailsModeSettings::recursiveDirectorySizeLimit();
111 QT_DIRENT
*dirEntry
= nullptr;
113 auto res
= walkDir(path
, countHiddenFiles
, countDirectoriesOnly
, dirEntry
, maxRecursiveLevel
);
119 void KDirectoryContentsCounterWorker::countDirectoryContents(const QString
& path
, Options options
)
121 auto res
= subItemsCount(path
, options
);
122 Q_EMIT
result(path
, res
.count
, res
.size
);