1 | /* |
2 | SPDX-FileCopyrightText: 2014 Vishesh Handa <me@vhanda.in> |
3 | |
4 | SPDX-License-Identifier: LGPL-2.1-or-later |
5 | */ |
6 | |
7 | #include "filtereddiriterator.h" |
8 | #include "fileindexerconfig.h" |
9 | |
10 | using namespace Baloo; |
11 | |
12 | FilteredDirIterator::FilteredDirIterator(const FileIndexerConfig* config, const QString& folder, Filter filter) |
13 | : m_config(config) |
14 | , m_currentIter(nullptr) |
15 | , m_filters(QDir::NoDotAndDotDot | QDir::Readable | QDir::NoSymLinks | QDir::Hidden) |
16 | , m_firstItem(false) |
17 | { |
18 | if (filter == DirsOnly) { |
19 | m_filters |= QDir::Dirs; |
20 | } else if (filter == FilesAndDirs) { |
21 | m_filters |= (QDir::Files | QDir::Dirs); |
22 | } |
23 | |
24 | if (!m_config || m_config->shouldFolderBeIndexed(path: folder)) { |
25 | m_currentIter = new QDirIterator(folder, m_filters); |
26 | m_firstItem = true; |
27 | } |
28 | } |
29 | |
30 | FilteredDirIterator::~FilteredDirIterator() |
31 | { |
32 | delete m_currentIter; |
33 | } |
34 | |
35 | QString FilteredDirIterator::next() |
36 | { |
37 | if (m_firstItem) { |
38 | m_firstItem = false; |
39 | m_filePath = m_currentIter->path(); |
40 | m_fileInfo = QFileInfo(m_filePath); |
41 | return m_filePath; |
42 | } |
43 | |
44 | m_filePath.clear(); |
45 | if (!m_currentIter) { |
46 | m_fileInfo = QFileInfo(); |
47 | return QString(); |
48 | } |
49 | |
50 | bool shouldIndexHidden = false; |
51 | if (m_config) { |
52 | shouldIndexHidden = m_config->indexHiddenFilesAndFolders(); |
53 | } |
54 | |
55 | while (true) { |
56 | // Last entry in the current directory found, try the next |
57 | // directory from the stack |
58 | // Loop until the directory is non-empty, or the stack is empty |
59 | while (!m_currentIter->hasNext()) { |
60 | delete m_currentIter; |
61 | m_currentIter = nullptr; |
62 | |
63 | if (m_paths.isEmpty()) { |
64 | m_fileInfo = QFileInfo(); |
65 | return QString(); |
66 | } |
67 | |
68 | const QString path = m_paths.pop(); |
69 | m_currentIter = new QDirIterator(path, m_filters); |
70 | } |
71 | |
72 | m_filePath = m_currentIter->next(); |
73 | m_fileInfo = m_currentIter->fileInfo(); |
74 | |
75 | auto shouldIndexFolder = [&] () -> bool { |
76 | if (!m_config) { |
77 | return !m_fileInfo.isHidden(); |
78 | } |
79 | QString folder; |
80 | if (!m_config->folderInFolderList(path: m_filePath, folder)) { |
81 | return false; |
82 | } |
83 | if ((folder == m_filePath) || (folder == QString(m_filePath).append(c: QLatin1Char('/')))) { |
84 | return true; |
85 | } |
86 | if (!shouldIndexHidden && m_fileInfo.isHidden()) { |
87 | return false; |
88 | } |
89 | return m_config->shouldFileBeIndexed(fileName: m_fileInfo.fileName()); |
90 | }; |
91 | |
92 | if (m_fileInfo.isDir()) { |
93 | if (shouldIndexFolder()) { |
94 | // Push the current item to the directory stack |
95 | m_paths.push(t: m_filePath); |
96 | return m_filePath; |
97 | } |
98 | } |
99 | else if (m_fileInfo.isFile()) { |
100 | if ((!shouldIndexHidden) && m_fileInfo.isHidden()) { |
101 | continue; |
102 | } |
103 | if ((!m_config) || m_config->shouldFileBeIndexed(fileName: m_fileInfo.fileName())) { |
104 | return m_filePath; |
105 | } |
106 | } |
107 | } |
108 | } |
109 | |
110 | QString FilteredDirIterator::filePath() const |
111 | { |
112 | return m_filePath; |
113 | } |
114 | |
115 | QFileInfo FilteredDirIterator::fileInfo() const |
116 | { |
117 | return m_fileInfo; |
118 | } |
119 | |