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
,
30 const uint allowedRecursiveLevel
)
34 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) {
65 QString nameBuf
= QStringLiteral("%1/%2").arg(dirPath
, dirEntry
->d_name
);
67 if (dirEntry
->d_type
== DT_REG
) {
68 if (QT_STAT(nameBuf
.toLocal8Bit(), &buf
) == 0) {
72 if (dirEntry
->d_type
== DT_DIR
) {
74 auto subdirResult
= walkDir(nameBuf
, countHiddenFiles
, countDirectoriesOnly
, allowedRecursiveLevel
- 1);
75 if (subdirResult
.size
> 0) {
76 size
+= subdirResult
.size
;
83 return KDirectoryContentsCounterWorker::CountResult
{count
, size
};
87 KDirectoryContentsCounterWorker::CountResult
KDirectoryContentsCounterWorker::subItemsCount(const QString
& path
, Options options
)
89 const bool countHiddenFiles
= options
& CountHiddenFiles
;
90 const bool countDirectoriesOnly
= options
& CountDirectoriesOnly
;
94 QDir::Filters filters
= QDir::NoDotAndDotDot
| QDir::System
;
95 if (countHiddenFiles
) {
96 filters
|= QDir::Hidden
;
98 if (countDirectoriesOnly
) {
99 filters
|= QDir::Dirs
;
101 filters
|= QDir::AllEntries
;
103 return {static_cast<int>(dir
.entryList(filters
).count()), 0};
106 const uint maxRecursiveLevel
= DetailsModeSettings::directorySizeCount() ? 1 : DetailsModeSettings::recursiveDirectorySizeLimit();
108 auto res
= walkDir(path
, countHiddenFiles
, countDirectoriesOnly
, maxRecursiveLevel
);
114 void KDirectoryContentsCounterWorker::countDirectoryContents(const QString
& path
, Options options
)
116 auto res
= subItemsCount(path
, options
);
117 Q_EMIT
result(path
, res
.count
, res
.size
);