Changeset View
Changeset View
Standalone View
Standalone View
src/kitemviews/private/kdirectorycontentscounterworker.cpp
Show All 22 Lines | |||||
23 | // Required includes for subItemsCount(): | 23 | // Required includes for subItemsCount(): | ||
24 | #ifdef Q_OS_WIN | 24 | #ifdef Q_OS_WIN | ||
25 | #include <QDir> | 25 | #include <QDir> | ||
26 | #else | 26 | #else | ||
27 | #include <QFile> | 27 | #include <QFile> | ||
28 | #include <qplatformdefs.h> | 28 | #include <qplatformdefs.h> | ||
29 | #endif | 29 | #endif | ||
30 | 30 | | |||
31 | #include "dolphin_detailsmodesettings.h" | ||||
32 | | ||||
31 | KDirectoryContentsCounterWorker::KDirectoryContentsCounterWorker(QObject* parent) : | 33 | KDirectoryContentsCounterWorker::KDirectoryContentsCounterWorker(QObject* parent) : | ||
32 | QObject(parent) | 34 | QObject(parent) | ||
33 | { | 35 | { | ||
34 | qRegisterMetaType<KDirectoryContentsCounterWorker::Options>(); | 36 | qRegisterMetaType<KDirectoryContentsCounterWorker::Options>(); | ||
35 | } | 37 | } | ||
36 | 38 | | |||
37 | int KDirectoryContentsCounterWorker::subItemsCount(const QString& path, Options options) | 39 | KDirectoryContentsCounterWorker::CountResult walkDir(const QString &dirPath, | ||
40 | const bool countHiddenFiles, | ||||
41 | const bool countDirectoriesOnly, | ||||
42 | QT_DIRENT *dirEntry, | ||||
43 | const uint allowedRecursiveLevel) | ||||
38 | { | 44 | { | ||
39 | const bool countHiddenFiles = options & CountHiddenFiles; | | |||
40 | const bool countDirectoriesOnly = options & CountDirectoriesOnly; | | |||
41 | | ||||
42 | #ifdef Q_OS_WIN | | |||
43 | QDir dir(path); | | |||
44 | QDir::Filters filters = QDir::NoDotAndDotDot | QDir::System; | | |||
45 | if (countHiddenFiles) { | | |||
46 | filters |= QDir::Hidden; | | |||
47 | } | | |||
48 | if (countDirectoriesOnly) { | | |||
49 | filters |= QDir::Dirs; | | |||
50 | } else { | | |||
51 | filters |= QDir::AllEntries; | | |||
52 | } | | |||
53 | return dir.entryList(filters).count(); | | |||
54 | #else | | |||
55 | // Taken from kio/src/widgets/kdirmodel.cpp | | |||
56 | // Copyright (C) 2006 David Faure <faure@kde.org> | | |||
57 | | ||||
58 | int count = -1; | 45 | int count = -1; | ||
59 | auto dir = QT_OPENDIR(QFile::encodeName(path)); | 46 | long size = 0; | ||
47 | auto dir = QT_OPENDIR(dirPath.toLocal8Bit()); | ||||
elvisangelaccio: Why `toLocal8Bit()` ? | |||||
meven: QtCreator was giving me a weird warning. | |||||
60 | if (dir) { | 48 | if (dir) { | ||
61 | count = 0; | 49 | count = 0; | ||
62 | QT_DIRENT *dirEntry = nullptr; | 50 | QT_STATBUF buf; | ||
51 | | ||||
52 | bool linkFound = false; | ||||
63 | while ((dirEntry = QT_READDIR(dir))) { | 53 | while ((dirEntry = QT_READDIR(dir))) { | ||
elvisangelaccio: These can be declared below, where they are actually used. | |||||
64 | if (dirEntry->d_name[0] == '.') { | 54 | if (dirEntry->d_name[0] == '.') { | ||
65 | if (dirEntry->d_name[1] == '\0' || !countHiddenFiles) { | 55 | if (dirEntry->d_name[1] == '\0' || !countHiddenFiles) { | ||
66 | // Skip "." or hidden files | 56 | // Skip "." or hidden files | ||
67 | continue; | 57 | continue; | ||
68 | } | 58 | } | ||
69 | if (dirEntry->d_name[1] == '.' && dirEntry->d_name[2] == '\0') { | 59 | if (dirEntry->d_name[1] == '.' && dirEntry->d_name[2] == '\0') { | ||
70 | // Skip ".." | 60 | // Skip ".." | ||
71 | continue; | 61 | continue; | ||
72 | } | 62 | } | ||
73 | } | 63 | } | ||
74 | 64 | | |||
75 | // If only directories are counted, consider an unknown file type and links also | 65 | // If only directories are counted, consider an unknown file type and links also | ||
76 | // as directory instead of trying to do an expensive stat() | 66 | // as directory instead of trying to do an expensive stat() | ||
77 | // (see bugs 292642 and 299997). | 67 | // (see bugs 292642 and 299997). | ||
78 | const bool countEntry = !countDirectoriesOnly || | 68 | const bool countEntry = !countDirectoriesOnly || | ||
79 | dirEntry->d_type == DT_DIR || | 69 | dirEntry->d_type == DT_DIR || | ||
80 | dirEntry->d_type == DT_LNK || | 70 | dirEntry->d_type == DT_LNK || | ||
81 | dirEntry->d_type == DT_UNKNOWN; | 71 | dirEntry->d_type == DT_UNKNOWN; | ||
82 | if (countEntry) { | 72 | if (countEntry) { | ||
83 | ++count; | 73 | ++count; | ||
84 | } | 74 | } | ||
75 | | ||||
76 | if (allowedRecursiveLevel > 0) { | ||||
77 | QString nameBuf = QString("%1/%2").arg(dirPath, dirEntry->d_name); | ||||
elvisangelaccio: `QStringLiteral` | |||||
78 | | ||||
79 | if (dirEntry->d_type == DT_REG || dirEntry->d_type == DT_LNK) { | ||||
80 | if (QT_STAT(nameBuf.toLocal8Bit(), &buf) == 0) { | ||||
81 | if (S_ISDIR(buf.st_mode)) { | ||||
82 | // was a dir link, recurse | ||||
83 | linkFound = true; | ||||
84 | } | ||||
85 | size += buf.st_size; | ||||
86 | } | ||||
87 | } | ||||
88 | if (dirEntry->d_type == DT_DIR || linkFound) { | ||||
89 | // recursion for dirs and dir links | ||||
90 | size += walkDir(nameBuf, countHiddenFiles, countDirectoriesOnly, dirEntry, allowedRecursiveLevel - 1).size; | ||||
91 | } | ||||
92 | } | ||||
85 | } | 93 | } | ||
86 | QT_CLOSEDIR(dir); | 94 | QT_CLOSEDIR(dir); | ||
87 | } | 95 | } | ||
88 | return count; | 96 | return KDirectoryContentsCounterWorker::CountResult{count, size}; | ||
97 | } | ||||
98 | | ||||
99 | KDirectoryContentsCounterWorker::CountResult KDirectoryContentsCounterWorker::subItemsCount(const QString& path, Options options) | ||||
100 | { | ||||
101 | const bool countHiddenFiles = options & CountHiddenFiles; | ||||
102 | const bool countDirectoriesOnly = options & CountDirectoriesOnly; | ||||
103 | | ||||
104 | #ifdef Q_OS_WIN | ||||
105 | QDir dir(path); | ||||
106 | QDir::Filters filters = QDir::NoDotAndDotDot | QDir::System; | ||||
107 | if (countHiddenFiles) { | ||||
108 | filters |= QDir::Hidden; | ||||
109 | } | ||||
110 | if (countDirectoriesOnly) { | ||||
111 | filters |= QDir::Dirs; | ||||
112 | } else { | ||||
113 | filters |= QDir::AllEntries; | ||||
114 | } | ||||
115 | return dir.entryList(filters).count(); | ||||
116 | #else | ||||
117 | | ||||
118 | const uint maxRecursiveLevel = DetailsModeSettings::recursiveDirectorySizeLimit(); | ||||
anthonyfieroni: Same, don't allow value more than 128. | |||||
meven: Btw The UI currently max it at 20 viewsettingstab.cpp:123 | |||||
119 | QByteArray dirPath = QFile::encodeName(path); | ||||
elvisangelaccio: Why call `QFile::encodeName()` here and not inside `walkDir()` ? | |||||
120 | | ||||
121 | QT_DIRENT *dirEntry = nullptr; | ||||
122 | | ||||
123 | auto res = walkDir(dirPath, countHiddenFiles, countDirectoriesOnly, dirEntry, maxRecursiveLevel); | ||||
124 | | ||||
125 | return res;; | ||||
89 | #endif | 126 | #endif | ||
90 | } | 127 | } | ||
91 | 128 | | |||
92 | void KDirectoryContentsCounterWorker::countDirectoryContents(const QString& path, Options options) | 129 | void KDirectoryContentsCounterWorker::countDirectoryContents(const QString& path, Options options) | ||
93 | { | 130 | { | ||
94 | emit result(path, subItemsCount(path, options)); | 131 | auto res = subItemsCount(path, options); | ||
132 | emit result(path, res.count, res.size); | ||||
95 | } | 133 | } |
Why toLocal8Bit() ?