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

0001 /*
0002  *   SPDX-FileCopyrightText: 2010 Jonathan Thomas <echidnaman@kubuntu.org>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #pragma once
0008 
0009 #include <QObject>
0010 #include <QPair>
0011 #include <QSet>
0012 #include <QString>
0013 #include <QUrl>
0014 #include <QVector>
0015 #include <variant>
0016 
0017 #include "discovercommon_export.h"
0018 
0019 class QXmlStreamReader;
0020 class QTimer;
0021 
0022 class CategoryFilter
0023 {
0024     Q_GADGET
0025 public:
0026     enum FilterType {
0027         CategoryNameFilter,
0028         PkgSectionFilter,
0029         PkgWildcardFilter,
0030         PkgNameFilter,
0031         AppstreamIdWildcardFilter,
0032         OrFilter,
0033         AndFilter,
0034         NotFilter,
0035     };
0036     Q_ENUM(FilterType)
0037 
0038     FilterType type;
0039     std::variant<QString, QVector<CategoryFilter>> value;
0040 
0041     bool operator==(const CategoryFilter &other) const;
0042     bool operator!=(const CategoryFilter &other) const
0043     {
0044         return !operator==(other);
0045     }
0046 };
0047 
0048 class DISCOVERCOMMON_EXPORT Category : public QObject
0049 {
0050     Q_OBJECT
0051 public:
0052     Q_PROPERTY(QString name READ name NOTIFY nameChanged)
0053     Q_PROPERTY(QString icon READ icon CONSTANT)
0054     Q_PROPERTY(QObject *parent READ parent CONSTANT)
0055     Q_PROPERTY(QVariantList subcategories READ subCategoriesVariant NOTIFY subCategoriesChanged)
0056     explicit Category(QSet<QString> pluginNames, QObject *parent = nullptr);
0057 
0058     Category(const QString &name,
0059              const QString &iconName,
0060              const CategoryFilter &filters,
0061              const QSet<QString> &pluginName,
0062              const QVector<Category *> &subCategories,
0063              bool isAddons);
0064     ~Category() override;
0065 
0066     QString name() const;
0067     // You should never attempt to change the name of anything that is not a leaf category
0068     // as the results could be potentially detremental to the function of the category filters
0069     void setName(const QString &name);
0070     QString icon() const;
0071     void setFilter(const CategoryFilter &filter);
0072     CategoryFilter filter() const;
0073     QVector<Category *> subCategories() const;
0074     QVariantList subCategoriesVariant() const;
0075 
0076     static void sortCategories(QVector<Category *> &cats);
0077     static void addSubcategory(QVector<Category *> &cats, Category *cat);
0078     /**
0079      * Add a subcategory to this category. This function should only
0080      * be used during the initialisation stage, before adding the local
0081      * root category to the global root category model.
0082      */
0083     void addSubcategory(Category *cat);
0084     void parseData(const QString &path, QXmlStreamReader *xml);
0085     bool blacklistPlugins(const QSet<QString> &pluginName);
0086     bool isAddons() const
0087     {
0088         return m_isAddons;
0089     }
0090     qint8 priority() const
0091     {
0092         return m_priority;
0093     }
0094     bool matchesCategoryName(const QString &name) const;
0095 
0096     Q_SCRIPTABLE bool contains(Category *cat) const;
0097     Q_SCRIPTABLE bool contains(const QVariantList &cats) const;
0098 
0099     static bool categoryLessThan(Category *c1, const Category *c2);
0100     static bool blacklistPluginsInVector(const QSet<QString> &pluginNames, QVector<Category *> &subCategories);
0101 
0102     QStringList involvedCategories() const;
0103     QString untranslatedName() const
0104     {
0105         return m_untranslatedName;
0106     }
0107 
0108 Q_SIGNALS:
0109     void subCategoriesChanged();
0110     void nameChanged();
0111 
0112 private:
0113     QString m_name;
0114     QString m_untranslatedName;
0115     QString m_iconString;
0116     CategoryFilter m_filter;
0117     QVector<Category *> m_subCategories;
0118 
0119     CategoryFilter parseIncludes(QXmlStreamReader *xml);
0120     QSet<QString> m_plugins;
0121     bool m_isAddons = false;
0122     qint8 m_priority = 0;
0123     QTimer *m_subCategoriesChanged;
0124 };