File indexing completed on 2024-12-15 04:14:22
0001 /* 0002 * Copyright (C) 2015 Dan Leinir Turthra Jensen <admin@leinir.dk> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) version 3, or any 0008 * later version accepted by the membership of KDE e.V. (or its 0009 * successor approved by the membership of KDE e.V.), which shall 0010 * act as a proxy defined in Section 6 of version 3 of the license. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Lesser General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Lesser General Public 0018 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 0019 * 0020 */ 0021 0022 #include "FilesystemContentLister.h" 0023 0024 #include <KFileMetaData/UserMetaData> 0025 0026 #include <QCoreApplication> 0027 #include <QDateTime> 0028 #include <QDirIterator> 0029 #include <QMimeDatabase> 0030 #include <QTimer> 0031 #include <QVariantHash> 0032 #include <QThreadPool> 0033 #include <QRunnable> 0034 0035 #include "ContentQuery.h" 0036 0037 class FileSystemSearcher : public QObject, public QRunnable 0038 { 0039 Q_OBJECT 0040 public: 0041 FileSystemSearcher(ContentQuery* query) : QObject() { m_query = query; } 0042 0043 void run() override 0044 { 0045 QMimeDatabase mimeDb; 0046 0047 auto locations = m_query->locations(); 0048 if(locations.isEmpty()) 0049 locations.append(QDir::homePath()); 0050 0051 for(const auto& location : locations) 0052 { 0053 QDirIterator it(location, QDirIterator::Subdirectories); 0054 while (it.hasNext()) 0055 { 0056 auto filePath = it.next(); 0057 0058 if(it.fileInfo().isDir()) 0059 continue; 0060 0061 if(!m_query->mimeTypes().isEmpty()) { 0062 QString mimeType = mimeDb.mimeTypeForFile(filePath).name(); 0063 if(!m_query->mimeTypes().contains(mimeType)) 0064 continue; 0065 } 0066 0067 auto metadata = ContentListerBase::metaDataForFile(filePath); 0068 0069 emit fileFound(filePath, metadata); 0070 } 0071 } 0072 0073 emit finished(this); 0074 } 0075 0076 Q_SIGNALS: 0077 void fileFound(const QString& path, const QVariantMap& metaData); 0078 void finished(FileSystemSearcher* searcher); 0079 0080 private: 0081 ContentQuery* m_query; 0082 }; 0083 0084 class FilesystemContentLister::Private 0085 { 0086 public: 0087 Private() { } 0088 0089 QList<FileSystemSearcher*> runnables; 0090 }; 0091 0092 FilesystemContentLister::FilesystemContentLister(QObject* parent) 0093 : ContentListerBase(parent) 0094 , d(new Private) 0095 { 0096 0097 } 0098 0099 FilesystemContentLister::~FilesystemContentLister() 0100 { 0101 QThreadPool::globalInstance()->waitForDone(); 0102 delete d; 0103 } 0104 0105 void FilesystemContentLister::startSearch(const QList<ContentQuery*>& queries) 0106 { 0107 for(const auto& query : queries) 0108 { 0109 auto runnable = new FileSystemSearcher{query}; 0110 connect(runnable, &FileSystemSearcher::fileFound, this, &FilesystemContentLister::fileFound); 0111 connect(runnable, &FileSystemSearcher::finished, this, &FilesystemContentLister::queryFinished); 0112 0113 d->runnables.append(runnable); 0114 } 0115 0116 if(!d->runnables.isEmpty()) 0117 QThreadPool::globalInstance()->start(d->runnables.first()); 0118 } 0119 0120 void FilesystemContentLister::queryFinished(QRunnable* runnable) 0121 { 0122 d->runnables.removeAll(static_cast<FileSystemSearcher*>(runnable)); 0123 0124 if(!d->runnables.isEmpty()) 0125 { 0126 QThreadPool::globalInstance()->start(d->runnables.first()); 0127 } 0128 else 0129 { 0130 emit searchCompleted(); 0131 } 0132 } 0133 0134 // This needs to be included since we define a QObject subclass here in the C++ file. 0135 #include "FilesystemContentLister.moc"