File indexing completed on 2024-04-28 15:35:51

0001 // SPDX-FileCopyrightText: 2015 Dan Leinir Turthra Jensen <admin@leinir.dk>
0002 // SPDX-License-Identifier: LGPL-2.1-only or LGPL-3.0-only or LicenseRef-KDE-Accepted-LGPL
0003 
0004 #pragma once
0005 
0006 #include <QAbstractListModel>
0007 #include <QDateTime>
0008 #include <memory>
0009 #include <optional>
0010 
0011 class CategoryEntriesModel;
0012 /**
0013  * \brief A struct for an Entry to the Book Database.
0014  */
0015 struct BookEntry {
0016     Q_GADGET
0017     Q_PROPERTY(QString filename MEMBER filename CONSTANT)
0018     Q_PROPERTY(QString filetitle MEMBER filetitle CONSTANT)
0019     Q_PROPERTY(QString title MEMBER title CONSTANT)
0020     Q_PROPERTY(QStringList genres MEMBER genres CONSTANT)
0021     Q_PROPERTY(QStringList keywords MEMBER keywords CONSTANT)
0022     Q_PROPERTY(QStringList characters MEMBER characters CONSTANT)
0023     Q_PROPERTY(QStringList series MEMBER series CONSTANT)
0024     Q_PROPERTY(QStringList seriesNumbers MEMBER seriesNumbers CONSTANT)
0025     Q_PROPERTY(QStringList seriesVolumes MEMBER seriesVolumes CONSTANT)
0026     Q_PROPERTY(QStringList author MEMBER author CONSTANT)
0027     Q_PROPERTY(QString rights MEMBER rights CONSTANT)
0028     Q_PROPERTY(QString publisher MEMBER publisher CONSTANT)
0029     Q_PROPERTY(QDateTime created MEMBER created CONSTANT)
0030     Q_PROPERTY(QDateTime lastOpenedTime MEMBER lastOpenedTime CONSTANT)
0031     Q_PROPERTY(QString currentLocation MEMBER currentLocation CONSTANT)
0032     Q_PROPERTY(int currentProgress MEMBER currentProgress CONSTANT)
0033     Q_PROPERTY(QString thumbnail MEMBER thumbnail CONSTANT)
0034     Q_PROPERTY(QStringList description MEMBER description CONSTANT)
0035     Q_PROPERTY(QString comment MEMBER comment CONSTANT)
0036     Q_PROPERTY(QStringList tags MEMBER tags CONSTANT)
0037     Q_PROPERTY(QString locations MEMBER locations CONSTANT)
0038     Q_PROPERTY(QString identifier MEMBER identifier CONSTANT)
0039     Q_PROPERTY(QString source MEMBER source CONSTANT)
0040     Q_PROPERTY(QString language MEMBER language CONSTANT)
0041     Q_PROPERTY(int rating MEMBER rating CONSTANT)
0042 
0043 public:
0044     explicit BookEntry()
0045     {
0046     }
0047     QString filename;
0048     QString filetitle;
0049     QString title;
0050     QStringList genres;
0051     QStringList keywords;
0052     QStringList characters;
0053     QStringList series;
0054     QStringList seriesNumbers;
0055     QStringList seriesVolumes;
0056     QStringList author;
0057     QString rights;
0058     QString publisher;
0059     QDateTime created;
0060     QDateTime lastOpenedTime;
0061     QString currentLocation;
0062     int currentProgress = 0;
0063     QString thumbnail;
0064     QStringList description;
0065     QString comment;
0066     QStringList tags;
0067     QString locations;
0068     QString identifier;
0069     QString source;
0070     QString language;
0071     int rating = 0;
0072 };
0073 
0074 bool operator==(const BookEntry &a1, const BookEntry &a2) noexcept;
0075 
0076 /**
0077  * \brief Model to handle the filter categories.
0078  *
0079  * This model in specific handles which categories there are
0080  * and which books are assigned to a category, if so, which.
0081  *
0082  * Used to handle sorting by author, title and so forth.
0083  * Is extended by BookListModel.
0084  *
0085  * categories and book entries are both in the same model
0086  * because there can be books that are not assigned categories.
0087  * Similarly, categories can contain categories, like in the case
0088  * of folder category.
0089  */
0090 class CategoryEntriesModel : public QAbstractListModel
0091 {
0092     Q_OBJECT
0093     /**
0094      * \brief count holds how many entries there are in the model - equivalent to rowCount, except as a property
0095      */
0096     Q_PROPERTY(int count READ count NOTIFY countChanged)
0097 public:
0098     explicit CategoryEntriesModel(QObject *parent = nullptr);
0099     ~CategoryEntriesModel() override;
0100 
0101     /**
0102      * \brief Extra roles for the book entry access.
0103      */
0104     enum Roles {
0105         UnknownRole = Qt::UserRole,
0106         FilenameRole = Qt::UserRole + 1, /// For getting a string with the full path to the book.
0107         FiletitleRole, /// For getting a string with the basename of the book.
0108         TitleRole, /// For getting a string with the proper title of the book.
0109         SeriesRole, /// For getting a stringlist of series this book is part of.
0110         SeriesNumbersRole, /// For getting a stringlist of numbers, which represent the sequence number the book has within each series.
0111         SeriesVolumesRole, /// For getting a stringlist of numbers, which represent the volume number the book has within a series. This is optional.
0112         AuthorRole, /// For getting a stringlist of all the authors.
0113         PublisherRole, /// For getting a string with the publisher name.
0114         CreatedRole, /// For getting the creation date of the book as a QDateTime.
0115         LastOpenedTimeRole, /// For getting the last time the book was opened as a QDateTime.
0116         CurrentLocationRole, /// For getting the current page as an epubjs location.
0117         CurrentProgressRole, /// For getting the current progress as an int (percentage).
0118         CategoryEntriesModelRole, /// For getting the model of this category.
0119         CategoryEntryCountRole, /// For getting the an int with the number of books within this category.
0120         ThumbnailRole, /// For getting a thumbnail url for this book.
0121         DescriptionRole, /// For getting a stringlist with a book description.
0122         CommentRole, /// For getting a string with user assigned comment.
0123         TagsRole, /// For getting a stringlist with user assigned tags.
0124         RatingRole, /// For getting an int with the rating of the comic. This is gotten from KFileMeta and thus goes from 1-10 with 0 being no rating.
0125         GenreRole, /// For getting a stringlist with genres assigned to this book.
0126         KeywordRole, /// For getting a stringlist with keywords assigned to this book. Where tags are user assigned, keywords come from the book itself.
0127         CharacterRole, /// For getting a stringlist with names of characters in this book.
0128         LocationsRole /// Epub locations cache
0129     };
0130     Q_ENUM(Roles)
0131 
0132     /**
0133      * @returns names for the extra roles defined.
0134      */
0135     QHash<int, QByteArray> roleNames() const override;
0136     /**
0137      * \brief Access the data inside the CategoryEntriesModel.
0138      * @param index The QModelIndex at which you wish to access the data.
0139      * @param role An enumerator of the type of data you want to access.
0140      * Is extended by the Roles enum.
0141      *
0142      * @return a QVariant with the book entry's data.
0143      */
0144     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
0145     /**
0146      * @param parent The QModel index of the parent. This only counts for
0147      * tree like page structures, and thus defaults to a freshly constructed
0148      * QModelIndex. A wellformed QModelIndex will cause this function to return 0
0149      * @returns the number of total rows(bookentries and categories) there are.
0150      */
0151     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0152 
0153     /**
0154      * @returns how many entries there are in the catalogue.
0155      */
0156     int count() const;
0157     /**
0158      * \brief Fires when the count has changed.
0159      */
0160     Q_SIGNAL void countChanged();
0161 
0162     /**
0163      * \brief Add a book entry to the CategoryEntriesModel.
0164      *
0165      * @param entry The BookEntry to add.
0166      * @param compareRole The role that determines the data to sort the entry into.
0167      * Defaults to the Book title.
0168      */
0169     Q_INVOKABLE void append(const BookEntry &entry, CategoryEntriesModel::Roles compareRole = TitleRole);
0170 
0171     /**
0172      * \brief Remove all entries from the model
0173      */
0174     Q_INVOKABLE void clear();
0175 
0176     /**
0177      * \brief Add a book entry to a category.
0178      *
0179      * This also adds it to the model's list of entries.
0180      */
0181     void addCategoryEntry(const QString &categoryName, const BookEntry &entry, CategoryEntriesModel::Roles compareRole = TitleRole);
0182 
0183     /**
0184      * @param index an integer index pointing at the desired book.
0185      * @returns the BookEntry struct for the given index (owned by this model, do not delete)
0186      */
0187     Q_INVOKABLE std::optional<BookEntry> getBookEntry(int index);
0188 
0189     /**
0190      * @return an entry object for the given filename. Used to get the recently
0191      * read books.
0192      * @param filename the filename associated with an entry object.
0193      */
0194     Q_INVOKABLE std::optional<BookEntry> bookFromFile(const QString &filename);
0195     /**
0196      * @return an entry index for the given filename.
0197      * @param filename the filename associated with an entry object.
0198      */
0199     Q_INVOKABLE int indexOfFile(const QString &filename);
0200     /**
0201      * @return whether the entry is a bookentry or a category entry.
0202      * @param index the index of the entry.
0203      */
0204     Q_INVOKABLE bool indexIsBook(int index);
0205     /**
0206      * @return an integer with the total books in the model.
0207      */
0208     int bookCount() const;
0209 
0210     /**
0211      * \brief Fires when a book entry is updated.
0212      * @param entry The updated entry
0213      *
0214      * Used in the BookListModel::setBookData()
0215      */
0216     Q_SIGNAL void entryDataUpdated(const BookEntry &entry);
0217     /**
0218      * \brief set a book entry as changed.
0219      * @param entry The changed entry.
0220      */
0221     Q_SLOT void entryDataChanged(const BookEntry &entry);
0222     /**
0223      * \brief Fires when a book entry is removed.
0224      * @param entry The removed entry
0225      */
0226     Q_SIGNAL void entryRemoved(const BookEntry &entry);
0227     /**
0228      * \brief Remove a book entry.
0229      * @param entry The entry to remove.
0230      */
0231     Q_SLOT void entryRemove(const BookEntry &entry);
0232 
0233     // This will iterate over all sub-models and find the model which contains
0234     // the entry, or null if not found
0235     CategoryEntriesModel *leafModelForEntry(const BookEntry &entry);
0236 
0237     Roles role() const;
0238     void setRole(Roles role);
0239 
0240 protected:
0241     /**
0242      * @return the name of the model.
0243      */
0244     const QString &name() const;
0245     /**
0246      * \brief set the name of the model.
0247      * @param newName QString with the name.
0248      */
0249     void setName(const QString &newName);
0250 
0251 private:
0252     class Private;
0253     std::unique_ptr<Private> d;
0254 };