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
28 walkDir(const QString
&dirPath
, const bool countHiddenFiles
, const bool countDirectoriesOnly
, const uint allowedRecursiveLevel
)
32 auto dir
= QT_OPENDIR(QFile::encodeName(dirPath
));
39 while ((dirEntry
= QT_READDIR(dir
))) {
40 if (dirEntry
->d_name
[0] == '.') {
41 if (dirEntry
->d_name
[1] == '\0' || !countHiddenFiles
) {
42 // Skip "." or hidden files
45 if (dirEntry
->d_name
[1] == '.' && dirEntry
->d_name
[2] == '\0') {
51 // If only directories are counted, consider an unknown file type and links also
52 // as directory instead of trying to do an expensive stat()
53 // (see bugs 292642 and 299997).
54 const bool countEntry
= !countDirectoriesOnly
|| dirEntry
->d_type
== DT_DIR
|| dirEntry
->d_type
== DT_LNK
|| dirEntry
->d_type
== DT_UNKNOWN
;
59 if (allowedRecursiveLevel
> 0) {
60 QString nameBuf
= QStringLiteral("%1/%2").arg(dirPath
, dirEntry
->d_name
);
62 if (dirEntry
->d_type
== DT_REG
) {
63 if (QT_STAT(nameBuf
.toLocal8Bit(), &buf
) == 0) {
67 if (dirEntry
->d_type
== DT_DIR
) {
69 auto subdirResult
= walkDir(nameBuf
, countHiddenFiles
, countDirectoriesOnly
, allowedRecursiveLevel
- 1);
70 if (subdirResult
.size
> 0) {
71 size
+= subdirResult
.size
;
78 return KDirectoryContentsCounterWorker::CountResult
{count
, size
};
82 KDirectoryContentsCounterWorker::CountResult
KDirectoryContentsCounterWorker::subItemsCount(const QString
&path
, Options options
)
84 const bool countHiddenFiles
= options
& CountHiddenFiles
;
85 const bool countDirectoriesOnly
= options
& CountDirectoriesOnly
;
89 QDir::Filters filters
= QDir::NoDotAndDotDot
| QDir::System
;
90 if (countHiddenFiles
) {
91 filters
|= QDir::Hidden
;
93 if (countDirectoriesOnly
) {
94 filters
|= QDir::Dirs
;
96 filters
|= QDir::AllEntries
;
98 return {static_cast<int>(dir
.entryList(filters
).count()), 0};
101 const uint maxRecursiveLevel
= DetailsModeSettings::directorySizeCount() ? 1 : DetailsModeSettings::recursiveDirectorySizeLimit();
103 auto res
= walkDir(path
, countHiddenFiles
, countDirectoriesOnly
, maxRecursiveLevel
);
109 void KDirectoryContentsCounterWorker::countDirectoryContents(const QString
&path
, Options options
)
111 auto res
= subItemsCount(path
, options
);
112 Q_EMIT
result(path
, res
.count
, res
.size
);