]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kdirectorycontentscounterworker.cpp
Fix selection rect after porting from QFontMetrics::width()
[dolphin.git] / src / kitemviews / private / kdirectorycontentscounterworker.cpp
1 /***************************************************************************
2 * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
3 * Copyright (C) 2013 by Frank Reininghaus <frank78ac@googlemail.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
19 ***************************************************************************/
20
21 #include "kdirectorycontentscounterworker.h"
22
23 // Required includes for subItemsCount():
24 #ifdef Q_OS_WIN
25 #include <QDir>
26 #else
27 #include <QFile>
28 #include <qplatformdefs.h>
29 #endif
30
31 #include "dolphin_detailsmodesettings.h"
32
33 KDirectoryContentsCounterWorker::KDirectoryContentsCounterWorker(QObject* parent) :
34 QObject(parent)
35 {
36 qRegisterMetaType<KDirectoryContentsCounterWorker::Options>();
37 }
38
39 #ifndef Q_OS_WIN
40 KDirectoryContentsCounterWorker::CountResult walkDir(const QString &dirPath,
41 const bool countHiddenFiles,
42 const bool countDirectoriesOnly,
43 QT_DIRENT *dirEntry,
44 const uint allowedRecursiveLevel)
45 {
46 int count = -1;
47 long size = -1;
48 auto dir = QT_OPENDIR(QFile::encodeName(dirPath));
49 if (dir) {
50 count = 0;
51 QT_STATBUF buf;
52
53 while ((dirEntry = QT_READDIR(dir))) {
54 if (dirEntry->d_name[0] == '.') {
55 if (dirEntry->d_name[1] == '\0' || !countHiddenFiles) {
56 // Skip "." or hidden files
57 continue;
58 }
59 if (dirEntry->d_name[1] == '.' && dirEntry->d_name[2] == '\0') {
60 // Skip ".."
61 continue;
62 }
63 }
64
65 // If only directories are counted, consider an unknown file type and links also
66 // as directory instead of trying to do an expensive stat()
67 // (see bugs 292642 and 299997).
68 const bool countEntry = !countDirectoriesOnly ||
69 dirEntry->d_type == DT_DIR ||
70 dirEntry->d_type == DT_LNK ||
71 dirEntry->d_type == DT_UNKNOWN;
72 if (countEntry) {
73 ++count;
74 }
75
76 if (allowedRecursiveLevel > 0) {
77
78 bool linkFound = false;
79 QString nameBuf = QStringLiteral("%1/%2").arg(dirPath, dirEntry->d_name);
80
81 if (dirEntry->d_type == DT_REG || dirEntry->d_type == DT_LNK) {
82 if (QT_STAT(nameBuf.toLocal8Bit(), &buf) == 0) {
83 if (S_ISDIR(buf.st_mode)) {
84 // was a dir link, recurse
85 linkFound = true;
86 }
87 size += buf.st_size;
88 }
89 }
90 if (dirEntry->d_type == DT_DIR || linkFound) {
91 // recursion for dirs and dir links
92 size += walkDir(nameBuf, countHiddenFiles, countDirectoriesOnly, dirEntry, allowedRecursiveLevel - 1).size;
93 }
94 }
95 }
96 QT_CLOSEDIR(dir);
97 }
98 return KDirectoryContentsCounterWorker::CountResult{count, size};
99 }
100 #endif
101
102 KDirectoryContentsCounterWorker::CountResult KDirectoryContentsCounterWorker::subItemsCount(const QString& path, Options options)
103 {
104 const bool countHiddenFiles = options & CountHiddenFiles;
105 const bool countDirectoriesOnly = options & CountDirectoriesOnly;
106
107 #ifdef Q_OS_WIN
108 QDir dir(path);
109 QDir::Filters filters = QDir::NoDotAndDotDot | QDir::System;
110 if (countHiddenFiles) {
111 filters |= QDir::Hidden;
112 }
113 if (countDirectoriesOnly) {
114 filters |= QDir::Dirs;
115 } else {
116 filters |= QDir::AllEntries;
117 }
118 return {dir.entryList(filters).count(), 0};
119 #else
120
121 const uint maxRecursiveLevel = DetailsModeSettings::directorySizeCount() ? 1 : DetailsModeSettings::recursiveDirectorySizeLimit();
122
123 QT_DIRENT *dirEntry = nullptr;
124
125 auto res = walkDir(QFile::encodeName(path), countHiddenFiles, countDirectoriesOnly, dirEntry, maxRecursiveLevel);
126
127 return res;
128 #endif
129 }
130
131 void KDirectoryContentsCounterWorker::countDirectoryContents(const QString& path, Options options)
132 {
133 auto res = subItemsCount(path, options);
134 emit result(path, res.count, res.size);
135 }