File indexing completed on 2024-04-28 04:59:32

0001 // SPDX-FileCopyrightText: 2018 Black Hat <bhat@encom.eu.org>
0002 // SPDX-License-Identifier: GPL-3.0-only
0003 
0004 #pragma once
0005 
0006 #include <KConfigGroup>
0007 #include <KSharedConfig>
0008 #include <QAbstractListModel>
0009 #include <QObject>
0010 #include <QQmlEngine>
0011 
0012 struct Emoji {
0013     Emoji(QString unicode, QString shortname, bool isCustom = false)
0014         : unicode(std::move(unicode))
0015         , shortName(std::move(shortname))
0016         , isCustom(isCustom)
0017     {
0018     }
0019     Emoji(QString unicode, QString shortname, QString description)
0020         : unicode(std::move(unicode))
0021         , shortName(std::move(shortname))
0022         , description(std::move(description))
0023     {
0024     }
0025     Emoji() = default;
0026 
0027     QString unicode;
0028     QString shortName;
0029     QString description;
0030     bool isCustom = false;
0031 
0032     Q_GADGET
0033     Q_PROPERTY(QString unicode MEMBER unicode)
0034     Q_PROPERTY(QString shortName MEMBER shortName)
0035     Q_PROPERTY(QString description MEMBER description)
0036     Q_PROPERTY(bool isCustom MEMBER isCustom)
0037 };
0038 
0039 Q_DECLARE_METATYPE(Emoji)
0040 
0041 /**
0042  * @class EmojiModel
0043  *
0044  * This class defines the model for visualising a list of emojis.
0045  */
0046 class EmojiModel : public QAbstractListModel
0047 {
0048     Q_OBJECT
0049     QML_ELEMENT
0050     QML_SINGLETON
0051 
0052     /**
0053      * @brief Return a list of emoji categories.
0054      *
0055      * @note No custom emoji categories will be included.
0056      */
0057     Q_PROPERTY(QVariantList categories READ categories CONSTANT)
0058 
0059     /**
0060      * @brief Return a list of emoji categories with custom emojis.
0061      */
0062     Q_PROPERTY(QVariantList categoriesWithCustom READ categoriesWithCustom CONSTANT)
0063 
0064 public:
0065     static EmojiModel &instance()
0066     {
0067         static EmojiModel _instance;
0068         return _instance;
0069     }
0070     static EmojiModel *create(QQmlEngine *engine, QJSEngine *)
0071     {
0072         engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership);
0073         return &instance();
0074     }
0075 
0076     /**
0077      * @brief Defines the model roles.
0078      */
0079     enum RoleNames {
0080         ShortNameRole = Qt::DisplayRole, /**< The name of the emoji. */
0081         UnicodeRole, /**< The unicode character of the emoji. */
0082         InvalidRole = 50, /**< Invalid, reserved. */
0083         DisplayRole = 51, /**< The display text for an emoji. */
0084         ReplacedTextRole = 52, /**< The text to replace the short name with (i.e. the unicode character). */
0085         DescriptionRole = 53, /**< The long description of an emoji. */
0086     };
0087     Q_ENUM(RoleNames)
0088 
0089     /**
0090      * @brief Defines the potential categories an emoji can be placed in.
0091      */
0092     enum Category {
0093         Custom, /**< A custom user emoji. */
0094         Search, /**< The results of a filter. */
0095         SearchNoCustom, /**< The results of a filter with no custom emojis. */
0096         History, /**< Recently used emojis. */
0097         HistoryNoCustom, /**< Recently used emojis with no custom emojis. */
0098         Smileys, /**< Smileys & emotion emojis. */
0099         People, /**< People & Body emojis. */
0100         Nature, /**< Animals & Nature emojis. */
0101         Food, /**< Food & Drink emojis. */
0102         Activities, /**< Activities emojis. */
0103         Travel, /**< Travel & Places emojis. */
0104         Objects, /**< Objects emojis. */
0105         Symbols, /**< Symbols emojis. */
0106         Flags, /**< Flags emojis. */
0107         Component, /**< ??? */
0108     };
0109     Q_ENUM(Category)
0110 
0111     /**
0112      * @brief Get the given role value at the given index.
0113      *
0114      * @sa QAbstractItemModel::data
0115      */
0116     [[nodiscard]] QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override;
0117 
0118     /**
0119      * @brief Number of rows in the model.
0120      *
0121      * @sa  QAbstractItemModel::rowCount
0122      */
0123     [[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0124 
0125     /**
0126      * @brief Returns a mapping from Role enum values to role names.
0127      *
0128      * @sa RoleNames, QAbstractItemModel::roleNames()
0129      */
0130     [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
0131 
0132     /**
0133      * @brief Return a filtered list of emojis.
0134      *
0135      * @note This includes custom emojis, use filterModelNoCustom to return a result
0136      *       without custom emojis.
0137      *
0138      * @sa filterModelNoCustom
0139      */
0140     Q_INVOKABLE static QVariantList filterModel(const QString &filter, bool limit = true);
0141 
0142     /**
0143      * @brief Return a filtered list of emojis without custom emojis.
0144      *
0145      * @note Use filterModel to return a result with custom emojis.
0146      *
0147      * @sa filterModel
0148      */
0149     Q_INVOKABLE static QVariantList filterModelNoCustom(const QString &filter, bool limit = true);
0150 
0151     /**
0152      * @brief Return a list of emojis for the given category.
0153      */
0154     Q_INVOKABLE QVariantList emojis(Category category) const;
0155 
0156     /**
0157      * @brief Return a list of emoji tones for the given base emoji.
0158      */
0159     Q_INVOKABLE QVariantList tones(const QString &baseEmoji) const;
0160 
0161     /**
0162      * @brief Return a list of the last used emoji shortnames
0163      */
0164     QStringList lastUsedEmojis() const;
0165 
0166     QVariantList categories() const;
0167     QVariantList categoriesWithCustom() const;
0168 
0169 Q_SIGNALS:
0170     void historyChanged();
0171 
0172 public Q_SLOTS:
0173     void emojiUsed(const QVariant &modelData);
0174 
0175 private:
0176     static QHash<Category, QVariantList> _emojis;
0177 
0178     /// Returns QVariants containing the last used Emojis
0179     QVariantList emojiHistory() const;
0180 
0181     KSharedConfig::Ptr m_config;
0182     KConfigGroup m_configGroup;
0183     EmojiModel(QObject *parent = nullptr);
0184 };