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