File indexing completed on 2024-05-05 17:33:21

0001 /*
0002  *   SPDX-FileCopyrightText: 2010 Jonathan Thomas <echidnaman@kubuntu.org>
0003  *   SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
0004  *
0005  *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006  */
0007 
0008 #pragma once
0009 
0010 #include <QQmlParserStatus>
0011 #include <QSortFilterProxyModel>
0012 #include <QString>
0013 #include <QStringList>
0014 #include <QTimer>
0015 
0016 #include <Category/Category.h>
0017 
0018 #include "AbstractResource.h"
0019 #include "AbstractResourcesBackend.h"
0020 #include "discovercommon_export.h"
0021 
0022 class AggregatedResultsStream;
0023 
0024 /*
0025  * This class encapsulates model's counter. The string property is a
0026  * pre-formatted number possibly with extra symbols for a "rough" appearance.
0027  * If counter is not valid, accessing its number and string is pointless.
0028  */
0029 class DISCOVERCOMMON_EXPORT ResourcesCount
0030 {
0031     Q_GADGET
0032     Q_PROPERTY(bool valid MEMBER m_valid CONSTANT FINAL)
0033     Q_PROPERTY(int number MEMBER m_number CONSTANT FINAL)
0034     Q_PROPERTY(QString string MEMBER m_string CONSTANT FINAL)
0035 
0036 public:
0037     explicit ResourcesCount();
0038     explicit ResourcesCount(int number);
0039     explicit ResourcesCount(int number, const QString &string);
0040 
0041 private:
0042     bool m_valid;
0043     int m_number;
0044     QString m_string;
0045 };
0046 
0047 Q_DECLARE_METATYPE(ResourcesCount)
0048 
0049 class DISCOVERCOMMON_EXPORT ResourcesProxyModel : public QAbstractListModel, public QQmlParserStatus
0050 {
0051     Q_OBJECT
0052     Q_INTERFACES(QQmlParserStatus)
0053     Q_PROPERTY(Roles sortRole READ sortRole WRITE setSortRole NOTIFY sortRoleChanged)
0054     Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
0055     Q_PROPERTY(Category *filteredCategory READ filteredCategory WRITE setFiltersFromCategory NOTIFY categoryChanged)
0056     Q_PROPERTY(QString filteredCategoryName READ filteredCategoryName WRITE setFilteredCategoryName NOTIFY categoryChanged)
0057     Q_PROPERTY(QString originFilter READ originFilter WRITE setOriginFilter)
0058     Q_PROPERTY(AbstractResource::State stateFilter READ stateFilter WRITE setStateFilter NOTIFY stateFilterChanged)
0059     Q_PROPERTY(bool filterMinimumState READ filterMinimumState WRITE setFilterMinimumState NOTIFY filterMinimumStateChanged)
0060     Q_PROPERTY(QString mimeTypeFilter READ mimeTypeFilter WRITE setMimeTypeFilter)
0061     Q_PROPERTY(AbstractResourcesBackend *backendFilter READ backendFilter WRITE setBackendFilter)
0062     Q_PROPERTY(QString search READ lastSearch WRITE setSearch NOTIFY searchChanged)
0063     Q_PROPERTY(QUrl resourcesUrl READ resourcesUrl WRITE setResourcesUrl NOTIFY resourcesUrlChanged)
0064     Q_PROPERTY(QString extending READ extends WRITE setExtends)
0065     Q_PROPERTY(bool allBackends READ allBackends WRITE setAllBackends)
0066     Q_PROPERTY(QVariantList subcategories READ subcategories NOTIFY subcategoriesChanged)
0067     Q_PROPERTY(bool isBusy READ isBusy NOTIFY busyChanged)
0068     Q_PROPERTY(bool sortByRelevancy READ sortByRelevancy NOTIFY sortByRelevancyChanged)
0069     Q_PROPERTY(ResourcesCount count READ count NOTIFY countChanged FINAL)
0070 public:
0071     explicit ResourcesProxyModel(QObject *parent = nullptr);
0072     enum Roles {
0073         NameRole = Qt::UserRole,
0074         IconRole,
0075         CommentRole,
0076         StateRole,
0077         RatingRole,
0078         RatingPointsRole,
0079         RatingCountRole,
0080         SortableRatingRole,
0081         InstalledRole,
0082         ApplicationRole,
0083         OriginRole,
0084         DisplayOriginRole,
0085         CanUpgrade,
0086         PackageNameRole,
0087         CategoryRole,
0088         SectionRole,
0089         MimeTypes,
0090         SizeRole,
0091         LongDescriptionRole,
0092         SourceIconRole,
0093         ReleaseDateRole,
0094     };
0095     Q_ENUM(Roles)
0096 
0097     QHash<int, QByteArray> roleNames() const override;
0098 
0099     void setSearch(const QString &text);
0100     QString lastSearch() const;
0101     void setOriginFilter(const QString &origin);
0102     QString originFilter() const;
0103     void setFiltersFromCategory(Category *category);
0104     void setStateFilter(AbstractResource::State s);
0105     AbstractResource::State stateFilter() const;
0106     void setSortRole(Roles sortRole);
0107     Roles sortRole() const
0108     {
0109         return m_sortRole;
0110     }
0111     void setSortOrder(Qt::SortOrder sortOrder);
0112     Qt::SortOrder sortOrder() const
0113     {
0114         return m_sortOrder;
0115     }
0116     void setFilterMinimumState(bool filterMinimumState);
0117     bool filterMinimumState() const;
0118 
0119     Category *filteredCategory() const;
0120     QString filteredCategoryName() const;
0121     void setFilteredCategoryName(const QString &cat);
0122 
0123     QString mimeTypeFilter() const;
0124     void setMimeTypeFilter(const QString &mime);
0125 
0126     QString extends() const;
0127     void setExtends(const QString &extends);
0128 
0129     QUrl resourcesUrl() const;
0130     void setResourcesUrl(const QUrl &resourcesUrl);
0131 
0132     bool allBackends() const;
0133     void setAllBackends(bool allBackends);
0134 
0135     AbstractResourcesBackend *backendFilter() const;
0136     void setBackendFilter(AbstractResourcesBackend *filtered);
0137 
0138     QVariantList subcategories() const;
0139 
0140     QVariant data(const QModelIndex &index, int role) const override;
0141     int rowCount(const QModelIndex &parent = {}) const override;
0142 
0143     Q_SCRIPTABLE int indexOf(AbstractResource *res);
0144     Q_SCRIPTABLE AbstractResource *resourceAt(int row) const;
0145 
0146     bool isBusy() const
0147     {
0148         return m_currentStream != nullptr;
0149     }
0150 
0151     bool lessThan(AbstractResource *rl, AbstractResource *rr) const;
0152     Q_SCRIPTABLE void invalidateFilter();
0153     void invalidateSorting();
0154 
0155     bool canFetchMore(const QModelIndex &parent) const override;
0156     void fetchMore(const QModelIndex &parent) override;
0157     bool sortByRelevancy() const;
0158 
0159     void classBegin() override
0160     {
0161     }
0162     void componentComplete() override;
0163 
0164     ResourcesCount count() const;
0165 
0166 private Q_SLOTS:
0167     void refreshBackend(AbstractResourcesBackend *backend, const QVector<QByteArray> &properties);
0168     void refreshResource(AbstractResource *resource, const QVector<QByteArray> &properties);
0169     void removeResource(AbstractResource *resource);
0170 
0171 private:
0172     void sortedInsertion(const QVector<AbstractResource *> &res);
0173     QVariant roleToValue(AbstractResource *res, int role) const;
0174 
0175     QVector<int> propertiesToRoles(const QVector<QByteArray> &properties) const;
0176     void addResources(const QVector<AbstractResource *> &res);
0177     void fetchSubcategories();
0178     void removeDuplicates(QVector<AbstractResource *> &newResources);
0179     bool isSorted(const QVector<AbstractResource *> &resources);
0180 
0181     Roles m_sortRole;
0182     Qt::SortOrder m_sortOrder;
0183 
0184     bool m_sortByRelevancy;
0185     bool m_setup = false;
0186     QString m_categoryName;
0187 
0188     AbstractResourcesBackend::Filters m_filters;
0189     QVariantList m_subcategories;
0190 
0191     QVector<AbstractResource *> m_displayedResources;
0192     static const QHash<int, QByteArray> s_roles;
0193     ResultsStream *m_currentStream;
0194     QTimer m_countTimer;
0195 
0196 Q_SIGNALS:
0197     void busyChanged(bool isBusy);
0198     void sortRoleChanged(int sortRole);
0199     void sortOrderChanged(Qt::SortOrder order);
0200     void categoryChanged();
0201     void stateFilterChanged();
0202     void searchChanged(const QString &search);
0203     void subcategoriesChanged(const QVariantList &subcategories);
0204     void resourcesUrlChanged(const QUrl &url);
0205     void countChanged();
0206     void filterMinimumStateChanged(bool filterMinimumState);
0207     void sortByRelevancyChanged(bool sortByRelevancy);
0208 };