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"