]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kdirectorycontentscounterworker.cpp
Output of licensedigger + manual cleanup afterwards.
[dolphin.git] / src / kitemviews / private / kdirectorycontentscounterworker.cpp
1 /*
2 * SPDX-FileCopyrightText: 2011 Peter Penz <peter.penz19@gmail.com>
3 * SPDX-FileCopyrightText: 2013 Frank Reininghaus <frank78ac@googlemail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8 #include "kdirectorycontentscounterworker.h"
9
10 // Required includes for subItemsCount():
11 #ifdef Q_OS_WIN
12 #include <QDir>
13 #else
14 #include <QFile>
15 #include <qplatformdefs.h>
16 #endif
17
18 #include "dolphin_detailsmodesettings.h"
19
20 KDirectoryContentsCounterWorker::KDirectoryContentsCounterWorker(QObject* parent) :
21 QObject(parent)
22 {
23 qRegisterMetaType<KDirectoryContentsCounterWorker::Options>();
24 }
25
26 #ifndef Q_OS_WIN
27 KDirectoryContentsCounterWorker::CountResult walkDir(const QString &dirPath,
28 const bool countHiddenFiles,
29 const bool countDirectoriesOnly,
30 QT_DIRENT *dirEntry,
31 const uint allowedRecursiveLevel)
32 {
33 int count = -1;
34 long size = -1;
35 auto dir = QT_OPENDIR(QFile::encodeName(dirPath));
36 if (dir) {
37 count = 0;
38 QT_STATBUF buf;
39
40 while ((dirEntry = QT_READDIR(dir))) {
41 if (dirEntry->d_name[0] == '.') {
42 if (dirEntry->d_name[1] == '\0' || !countHiddenFiles) {
43 // Skip "." or hidden files
44 continue;
45 }
46 if (dirEntry->d_name[1] == '.' && dirEntry->d_name[2] == '\0') {
47 // Skip ".."
48 continue;
49 }
50 }
51
52 // If only directories are counted, consider an unknown file type and links also
53 // as directory instead of trying to do an expensive stat()
54 // (see bugs 292642 and 299997).
55 const bool countEntry = !countDirectoriesOnly ||
56 dirEntry->d_type == DT_DIR ||
57 dirEntry->d_type == DT_LNK ||
58 dirEntry->d_type == DT_UNKNOWN;
59 if (countEntry) {
60 ++count;
61 }
62
63 if (allowedRecursiveLevel > 0) {
64
65 bool linkFound = false;
66 QString nameBuf = QStringLiteral("%1/%2").arg(dirPath, dirEntry->d_name);
67
68 if (dirEntry->d_type == DT_REG || dirEntry->d_type == DT_LNK) {
69 if (QT_STAT(nameBuf.toLocal8Bit(), &buf) == 0) {
70 if (S_ISDIR(buf.st_mode)) {
71 // was a dir link, recurse
72 linkFound = true;
73 }
74 size += buf.st_size;
75 }
76 }
77 if (dirEntry->d_type == DT_DIR || linkFound) {
78 // recursion for dirs and dir links
79 size += walkDir(nameBuf, countHiddenFiles, countDirectoriesOnly, dirEntry, allowedRecursiveLevel - 1).size;
80 }
81 }
82 }
83 QT_CLOSEDIR(dir);
84 }
85 return KDirectoryContentsCounterWorker::CountResult{count, size};
86 }
87 #endif
88
89 KDirectoryContentsCounterWorker::CountResult KDirectoryContentsCounterWorker::subItemsCount(const QString& path, Options options)
90 {
91 const bool countHiddenFiles = options & CountHiddenFiles;
92 const bool countDirectoriesOnly = options & CountDirectoriesOnly;
93
94 #ifdef Q_OS_WIN
95 QDir dir(path);
96 QDir::Filters filters = QDir::NoDotAndDotDot | QDir::System;
97 if (countHiddenFiles) {
98 filters |= QDir::Hidden;
99 }
100 if (countDirectoriesOnly) {
101 filters |= QDir::Dirs;
102 } else {
103 filters |= QDir::AllEntries;
104 }
105 return {dir.entryList(filters).count(), 0};
106 #else
107
108 const uint maxRecursiveLevel = DetailsModeSettings::directorySizeCount() ? 1 : DetailsModeSettings::recursiveDirectorySizeLimit();
109
110 QT_DIRENT *dirEntry = nullptr;
111
112 auto res = walkDir(QFile::encodeName(path), countHiddenFiles, countDirectoriesOnly, dirEntry, maxRecursiveLevel);
113
114 return res;
115 #endif
116 }
117
118 void KDirectoryContentsCounterWorker::countDirectoryContents(const QString& path, Options options)
119 {
120 auto res = subItemsCount(path, options);
121 emit result(path, res.count, res.size);
122 }