File indexing completed on 2024-10-27 04:39:10

0001 // SPDX-FileCopyrightText: 2017 Konstantinos Sideris <siderisk@auth.gr>
0002 // SPDX-License-Identifier: GPL-3.0-or-later
0003 
0004 #include <QVariant>
0005 
0006 #include "emojiModel.h"
0007 #include "emojiTones.h"
0008 #include <QDebug>
0009 
0010 #include <algorithm>
0011 
0012 #include <KLocalizedString>
0013 
0014 EmojiModel::EmojiModel(QObject *parent)
0015     : QAbstractListModel(parent)
0016     , m_config(KSharedConfig::openStateConfig())
0017     , m_configGroup(KConfigGroup(m_config, QStringLiteral("Editor")))
0018 {
0019     if (_emojis.isEmpty()) {
0020 #include "emojis.h"
0021     }
0022 }
0023 
0024 int EmojiModel::rowCount(const QModelIndex &parent) const
0025 {
0026     Q_UNUSED(parent);
0027     int total = 0;
0028     for (const auto &category : _emojis) {
0029         total += category.count();
0030     }
0031     return total;
0032 }
0033 
0034 QVariant EmojiModel::data(const QModelIndex &index, int role) const
0035 {
0036     auto row = index.row();
0037     for (const auto &category : _emojis) {
0038         if (row >= category.count()) {
0039             row -= category.count();
0040             continue;
0041         }
0042         auto emoji = category[row].value<Emoji>();
0043         switch (role) {
0044         case ShortNameRole:
0045             return QStringLiteral(":%1:").arg(emoji.shortName);
0046         case UnicodeRole:
0047         case ReplacedTextRole:
0048             return emoji.unicode;
0049         case InvalidRole:
0050             return QStringLiteral("invalid");
0051         case DisplayRole:
0052             return QStringLiteral("%2   :%1:").arg(emoji.shortName, emoji.unicode);
0053         case DescriptionRole:
0054             return emoji.description;
0055         }
0056     }
0057     return {};
0058 }
0059 
0060 QHash<int, QByteArray> EmojiModel::roleNames() const
0061 {
0062     return {{ShortNameRole, "shortName"}, {UnicodeRole, "unicode"}};
0063 }
0064 
0065 QStringList EmojiModel::lastUsedEmojis() const
0066 {
0067     return m_configGroup.readEntry(QStringLiteral("lastUsedEmojis"), QStringList());
0068 }
0069 
0070 QVariantList EmojiModel::filterModel(const QString &filter, bool limit)
0071 {
0072     // auto emojis = CustomEmojiModel::instance().filterModel(filter);
0073     auto emojis = filterModelNoCustom(filter, limit);
0074     return emojis;
0075 }
0076 
0077 QVariantList EmojiModel::filterModelNoCustom(const QString &filter, bool limit)
0078 {
0079     QVariantList result;
0080 
0081     for (const auto &e : _emojis.values()) {
0082         for (const auto &variant : e) {
0083             const auto &emoji = qvariant_cast<Emoji>(variant);
0084             if (emoji.shortName.contains(filter, Qt::CaseInsensitive)) {
0085                 result.append(variant);
0086                 if (result.length() > 10 && limit) {
0087                     return result;
0088                 }
0089             }
0090         }
0091     }
0092     return result;
0093 }
0094 
0095 void EmojiModel::emojiUsed(const QVariant &modelData)
0096 {
0097     auto list = lastUsedEmojis();
0098     const auto emoji = modelData.value<Emoji>();
0099 
0100     auto it = list.begin();
0101     while (it != list.end()) {
0102         if (*it == emoji.shortName) {
0103             it = list.erase(it);
0104         } else {
0105             it++;
0106         }
0107     }
0108 
0109     list.push_front(emoji.shortName);
0110 
0111     m_configGroup.writeEntry(QStringLiteral("lastUsedEmojis"), list);
0112 
0113     Q_EMIT historyChanged();
0114 }
0115 
0116 QVariantList EmojiModel::emojis(Category category) const
0117 {
0118     if (category == History) {
0119         return emojiHistory();
0120     }
0121     if (category == HistoryNoCustom) {
0122         QVariantList list;
0123         for (const auto &e : emojiHistory()) {
0124             auto emoji = qvariant_cast<Emoji>(e);
0125             if (!emoji.isCustom) {
0126                 list.append(e);
0127             }
0128         }
0129         return list;
0130     }
0131     // if (category == Custom) {
0132     //     return CustomEmojiModel::instance().filterModel({});
0133     // }
0134     return _emojis[category];
0135 }
0136 
0137 QVariantList EmojiModel::tones(const QString &baseEmoji)
0138 {
0139     if (baseEmoji.endsWith(QStringLiteral("tone"))) {
0140         return EmojiTones::_tones.values(baseEmoji.split(QStringLiteral(":"))[0]);
0141     }
0142     return EmojiTones::_tones.values(baseEmoji);
0143 }
0144 
0145 QHash<EmojiModel::Category, QVariantList> EmojiModel::_emojis;
0146 
0147 QVariantList EmojiModel::categories() const
0148 {
0149     return QVariantList{
0150         {QVariantMap{
0151             {QStringLiteral("category"), EmojiModel::HistoryNoCustom},
0152             {QStringLiteral("name"), i18nc("Previously used emojis", "History")},
0153             {QStringLiteral("emoji"), QStringLiteral("⌛️")},
0154         }},
0155         {QVariantMap{
0156             {QStringLiteral("category"), EmojiModel::Smileys},
0157             {QStringLiteral("name"), i18nc("'Smileys' is a category of emoji", "Smileys")},
0158             {QStringLiteral("emoji"), QStringLiteral("😏")},
0159         }},
0160         {QVariantMap{
0161             {QStringLiteral("category"), EmojiModel::People},
0162             {QStringLiteral("name"), i18nc("'People' is a category of emoji", "People")},
0163             {QStringLiteral("emoji"), QStringLiteral("🙋‍♂️")},
0164         }},
0165         {QVariantMap{
0166             {QStringLiteral("category"), EmojiModel::Nature},
0167             {QStringLiteral("name"), i18nc("'Nature' is a category of emoji", "Nature")},
0168             {QStringLiteral("emoji"), QStringLiteral("🌲")},
0169         }},
0170         {QVariantMap{
0171             {QStringLiteral("category"), EmojiModel::Food},
0172             {QStringLiteral("name"), i18nc("'Food' is a category of emoji", "Food")},
0173             {QStringLiteral("emoji"), QStringLiteral("🍛")},
0174         }},
0175         {QVariantMap{
0176             {QStringLiteral("category"), EmojiModel::Activities},
0177             {QStringLiteral("name"), i18nc("'Activities' is a category of emoji", "Activities")},
0178             {QStringLiteral("emoji"), QStringLiteral("🚁")},
0179         }},
0180         {QVariantMap{
0181             {QStringLiteral("category"), EmojiModel::Travel},
0182             {QStringLiteral("name"), i18nc("'Travel' is  a category of emoji", "Travel")},
0183             {QStringLiteral("emoji"), QStringLiteral("🚅")},
0184         }},
0185         {QVariantMap{
0186             {QStringLiteral("category"), EmojiModel::Objects},
0187             {QStringLiteral("name"), i18nc("'Objects' is a category of emoji", "Objects")},
0188             {QStringLiteral("emoji"), QStringLiteral("💡")},
0189         }},
0190         {QVariantMap{
0191             {QStringLiteral("category"), EmojiModel::Symbols},
0192             {QStringLiteral("name"), i18nc("'Symbols' is a category of emoji", "Symbols")},
0193             {QStringLiteral("emoji"), QStringLiteral("🔣")},
0194         }},
0195         {QVariantMap{
0196             {QStringLiteral("category"), EmojiModel::Flags},
0197             {QStringLiteral("name"), i18nc("'Flags' is a category of emoji", "Flags")},
0198             {QStringLiteral("emoji"), QStringLiteral("🏁")},
0199         }},
0200     };
0201 }
0202 
0203 QVariantList EmojiModel::categoriesWithCustom() const
0204 {
0205     auto cats = categories();
0206     cats.removeAt(0);
0207     cats.insert(0,
0208                 QVariantMap{
0209                     {QStringLiteral("category"), EmojiModel::History},
0210                     {QStringLiteral("name"), i18nc("Previously used emojis", "History")},
0211                     {QStringLiteral("emoji"), QStringLiteral("⌛️")},
0212                 });
0213     cats.insert(1,
0214                 QVariantMap{
0215                     {QStringLiteral("category"), EmojiModel::Custom},
0216                     {QStringLiteral("name"), i18nc("'Custom' is a category of emoji", "Custom")},
0217                     {QStringLiteral("emoji"), QStringLiteral("🖼️")},
0218                 });
0219     ;
0220     return cats;
0221 }
0222 
0223 QVariantList EmojiModel::emojiHistory() const
0224 {
0225     QVariantList list;
0226     for (const auto &historicEmoji : lastUsedEmojis()) {
0227         for (const auto &emojiCategory : _emojis) {
0228             for (const auto &emoji : emojiCategory) {
0229                 if (qvariant_cast<Emoji>(emoji).shortName == historicEmoji) {
0230                     list.append(emoji);
0231                 }
0232             }
0233         }
0234     }
0235     return list;
0236 }
0237 
0238 #include "moc_emojiModel.cpp"