File indexing completed on 2024-04-14 03:49:45

0001 /*
0002     SPDX-FileCopyrightText: 2014 Vishesh Handa <me@vhanda.in>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-or-later
0005 */
0006 
0007 #include "filtereddiriterator.h"
0008 #include "fileindexerconfig.h"
0009 
0010 using namespace Baloo;
0011 
0012 FilteredDirIterator::FilteredDirIterator(const FileIndexerConfig* config, const QString& folder, Filter filter)
0013     : m_config(config)
0014     , m_currentIter(nullptr)
0015     , m_filters(QDir::NoDotAndDotDot | QDir::Readable | QDir::NoSymLinks | QDir::Hidden)
0016     , m_firstItem(false)
0017 {
0018     if (filter == DirsOnly) {
0019         m_filters |= QDir::Dirs;
0020     } else if (filter == FilesAndDirs) {
0021         m_filters |= (QDir::Files | QDir::Dirs);
0022     }
0023 
0024     if (!m_config || m_config->shouldFolderBeIndexed(folder)) {
0025         m_currentIter = new QDirIterator(folder, m_filters);
0026         m_firstItem = true;
0027     }
0028 }
0029 
0030 FilteredDirIterator::~FilteredDirIterator()
0031 {
0032     delete m_currentIter;
0033 }
0034 
0035 QString FilteredDirIterator::next()
0036 {
0037     if (m_firstItem) {
0038         m_firstItem = false;
0039         m_filePath = m_currentIter->path();
0040         m_fileInfo = QFileInfo(m_filePath);
0041         return m_filePath;
0042     }
0043 
0044     m_filePath.clear();
0045     if (!m_currentIter) {
0046         m_fileInfo = QFileInfo();
0047         return QString();
0048     }
0049 
0050     bool shouldIndexHidden = false;
0051     if (m_config) {
0052         shouldIndexHidden = m_config->indexHiddenFilesAndFolders();
0053     }
0054 
0055     while (true) {
0056         // Last entry in the current directory found, try the next
0057         // directory from the stack
0058         // Loop until the directory is non-empty, or the stack is empty
0059         while (!m_currentIter->hasNext()) {
0060             delete m_currentIter;
0061             m_currentIter = nullptr;
0062 
0063             if (m_paths.isEmpty()) {
0064                 m_fileInfo = QFileInfo();
0065                 return QString();
0066             }
0067 
0068             const QString path = m_paths.pop();
0069             m_currentIter = new QDirIterator(path, m_filters);
0070         }
0071 
0072         m_filePath = m_currentIter->next();
0073         m_fileInfo = m_currentIter->fileInfo();
0074 
0075         auto shouldIndexFolder = [&] () -> bool {
0076             if (!m_config) {
0077                 return !m_fileInfo.isHidden();
0078             }
0079             QString folder;
0080             if (!m_config->folderInFolderList(m_filePath, folder)) {
0081                 return false;
0082             }
0083         if ((folder == m_filePath) || (folder == QString(m_filePath).append(QLatin1Char('/')))) {
0084                 return true;
0085             }
0086             if (!shouldIndexHidden && m_fileInfo.isHidden()) {
0087                 return false;
0088             }
0089             return m_config->shouldFileBeIndexed(m_fileInfo.fileName());
0090         };
0091 
0092         if (m_fileInfo.isDir()) {
0093             if (shouldIndexFolder()) {
0094                 // Push the current item to the directory stack
0095                 m_paths.push(m_filePath);
0096                 return m_filePath;
0097             }
0098         }
0099         else if (m_fileInfo.isFile()) {
0100             if ((!shouldIndexHidden) && m_fileInfo.isHidden()) {
0101                 continue;
0102             }
0103             if ((!m_config) || m_config->shouldFileBeIndexed(m_fileInfo.fileName())) {
0104                 return m_filePath;
0105             }
0106         }
0107     }
0108 }
0109 
0110 QString FilteredDirIterator::filePath() const
0111 {
0112     return m_filePath;
0113 }
0114 
0115 QFileInfo FilteredDirIterator::fileInfo() const
0116 {
0117     return m_fileInfo;
0118 }