File indexing completed on 2024-05-12 05:53:56

0001 /*
0002  * Copyright (c) 2018 Sune Vuorela <sune@vuorela.dk>
0003  *
0004  * Permission is hereby granted, free of charge, to any person
0005  * obtaining a copy of this software and associated documentation
0006  * files (the "Software"), to deal in the Software without
0007  * restriction, including without limitation the rights to use,
0008  * copy, modify, merge, publish, distribute, sublicense, and/or sell
0009  * copies of the Software, and to permit persons to whom the
0010  * Software is furnished to do so, subject to the following
0011  * conditions:
0012  *
0013  * The above copyright notice and this permission notice shall be
0014  * included in all copies or substantial portions of the Software.
0015  *
0016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0017  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
0018  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0019  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
0020  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
0021  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0022  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0023  * OTHER DEALINGS IN THE SOFTWARE.
0024  */
0025 
0026 #pragma once
0027 #include <QObject>
0028 #include <mutex>
0029 #include "recipeparser.h"
0030 #include <memory>
0031 #include <QHash>
0032 #include <future>
0033 
0034 class QAbstractItemModel;
0035 /**
0036  * File system scanner to index the recipes in the recipe collection.
0037  *
0038  * As a implementation detail, a worker thread is used for
0039  * the file system access and parsing and stuff.
0040  */
0041 class Scanner : public QObject
0042 {
0043     Q_OBJECT
0044 public:
0045     Scanner(QObject* parent = nullptr);
0046     /**
0047      * \return tree model of parsed tags
0048      */
0049     std::shared_ptr<QAbstractItemModel> parsedTags() const;
0050     /**
0051      * \return tree model of parsed ingredients
0052      */
0053     std::shared_ptr<QAbstractItemModel> parsedIngredients() const;
0054     /**
0055      * \return list model of parsed title
0056      */
0057     std::shared_ptr<QAbstractItemModel> parsedTitleList() const;
0058     /**
0059      * \return map from file path to recipe title
0060      */
0061     QHash<QString,QString> parsedFileNameTitleMap() const;
0062     /**
0063      * Sets the (new) root path and triggers a re-indexing of everything.
0064      */
0065     void setRootPath(const QString& path);
0066     QString rootPath() const;
0067     ~Scanner();
0068 public Q_SLOTS:
0069     /**
0070      * Re-indexes with current root path
0071      */
0072     void doUpdate();
0073 Q_SIGNALS:
0074     /**
0075      * Emitted update is done (and new models and maps and such can be read)
0076      */
0077     void dataUpdated();
0078     /**
0079      * \internal - thread switching for dataUpdated.
0080      */
0081     void dataUpdatedInternal(QPrivateSignal p = QPrivateSignal());
0082 private:
0083     mutable std::mutex m_mutex;
0084     std::shared_ptr<QAbstractItemModel> m_parsedTags;
0085     std::shared_ptr<QAbstractItemModel> m_parsedIngredients;
0086     std::shared_ptr<QAbstractItemModel> m_titleList;
0087     QHash<QString,QString> m_parsedFileNameTitleMap;
0088     /**
0089      * Function to be run in a different thread.
0090      * \param path Root path to start indexing from
0091      * \param targetThread The QThread to move created QObjects to (main thread) before switching back.
0092      */
0093     void parseThingsInDifferentThread(const QString& path, QThread* targetThread);
0094     QString m_rootPath;
0095     std::atomic_bool m_running;
0096     std::future<void> m_future;
0097 };