diff --git a/src/contentlist/FilesystemContentLister.cpp b/src/contentlist/FilesystemContentLister.cpp index faa1644..7f3dcc3 100644 --- a/src/contentlist/FilesystemContentLister.cpp +++ b/src/contentlist/FilesystemContentLister.cpp @@ -1,119 +1,134 @@ /* * Copyright (C) 2015 Dan Leinir Turthra Jensen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . * */ #include "FilesystemContentLister.h" #include #include #include #include #include #include #include #include +#include +#include + +#include "ContentQuery.h" + +class FileSystemSearcher : public QObject, public QRunnable +{ + Q_OBJECT +public: + FileSystemSearcher(ContentQuery* query) : QObject() { m_query = query; } + + void run() override + { + QMimeDatabase mimeDb; + + auto locations = m_query->locations(); + if(locations.isEmpty()) + locations.append(QDir::homePath()); + + for(const auto& location : m_query->locations()) + { + QDirIterator it(location, QDirIterator::Subdirectories); + while (it.hasNext()) + { + auto filePath = it.next(); + + if(it.fileInfo().isDir()) + continue; + + QString mimeType = mimeDb.mimeTypeForFile(filePath).name(); + if(!m_query->mimeTypes().isEmpty() && !m_query->mimeTypes().contains(mimeType)) + continue; + + auto metadata = ContentListerBase::metaDataForFile(filePath); + + emit fileFound(filePath, metadata); + } + } + + emit finished(this); + } + +Q_SIGNALS: + void fileFound(const QString& path, const QVariantMap& metaData); + void finished(FileSystemSearcher* searcher); + +private: + ContentQuery* m_query; +}; class FilesystemContentLister::Private { public: Private() { } + QList runnables; }; FilesystemContentLister::FilesystemContentLister(QObject* parent) : ContentListerBase(parent) , d(new Private) { + } FilesystemContentLister::~FilesystemContentLister() { + QThreadPool::globalInstance()->waitForDone(); delete d; } void FilesystemContentLister::startSearch(const QList& queries) { + for(const auto& query : queries) + { + auto runnable = new FileSystemSearcher{query}; + connect(runnable, &FileSystemSearcher::fileFound, this, &FilesystemContentLister::fileFound); + connect(runnable, &FileSystemSearcher::finished, this, &FilesystemContentLister::queryFinished); + d->runnables.append(runnable); + } + if(!d->runnables.isEmpty()) + QThreadPool::globalInstance()->start(d->runnables.first()); } +void FilesystemContentLister::queryFinished(QRunnable* runnable) { - QMimeDatabase mimeDb; - bool useThis(false); + d->runnables.removeAll(static_cast(runnable)); - qDebug() << "Searching in" << d->locations; - Q_FOREACH(const QString& folder, d->locations) + if(!d->runnables.isEmpty()) { - QDirIterator it(folder, QDirIterator::Subdirectories); - while (it.hasNext()) - { - QString filePath = it.next(); - if(d->knownFiles.contains(filePath)) { - continue; - } - - QFileInfo info(filePath); - - if(info.isDir()) - { - qApp->processEvents(); - continue; - } - useThis = false; - QString mimetype = mimeDb.mimeTypeForFile(filePath, QMimeDatabase::MatchExtension).name(); -// qDebug() << useThis << mimetype << filePath; - Q_FOREACH(const QString& type, d->mimetypes) - { - if(type == mimetype) { - useThis = true; - break; - } - } - - if(useThis) - { - QVariantHash metadata; - metadata["created"] = info.created(); - - KFileMetaData::UserMetaData data(filePath); - if (data.hasAttribute("peruse.currentPage")) { - int currentPage = data.attribute("peruse.currentPage").toInt(); - metadata["currentPage"] = QVariant::fromValue(currentPage); - } - if (data.hasAttribute("peruse.totalPages")) { - int totalPages = data.attribute("peruse.totalPages").toInt(); - metadata["totalPages"] = QVariant::fromValue(totalPages); - } - - emit fileFound(filePath, metadata); - } - qApp->processEvents(); - } + QThreadPool::globalInstance()->start(d->runnables.first()); + } + else + { + emit searchCompleted(); } - // This ensures that, should we decide to search more stuff later, we can do so granularly - d->locations.clear(); - - // Not entirely happy about this, but it makes things not break... - // Previously, the welcome page in Peruse would end up unpopulated because a signal - // was unreceived from the main window upon search completion (and consequently - // application readiness) - QTimer::singleShot(0, this, SIGNAL(searchCompleted())); } + +// This needs to be included since we define a QObject subclass here in the C++ file. +#include "FilesystemContentLister.moc" diff --git a/src/contentlist/FilesystemContentLister.h b/src/contentlist/FilesystemContentLister.h index cf8cff0..a2abd97 100644 --- a/src/contentlist/FilesystemContentLister.h +++ b/src/contentlist/FilesystemContentLister.h @@ -1,41 +1,45 @@ /* * Copyright (C) 2015 Dan Leinir Turthra Jensen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . * */ #ifndef FILESYSTEMCONTENTLISTER_H #define FILESYSTEMCONTENTLISTER_H +#include + #include "ContentListerBase.h" class FilesystemContentLister : public ContentListerBase { Q_OBJECT public: explicit FilesystemContentLister(QObject* parent = nullptr); ~FilesystemContentLister() override; void startSearch(const QList& queries) override; private: + void queryFinished(QRunnable* runnable); + class Private; Private* d; }; #endif//FILESYSTEMCONTENTLISTER_H