1 /*
2    SPDX-FileCopyrightText: 2018-2021 Laurent Montel <montel@kde.org>
3 
4    SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "emoticonmodel.h"
8 #include "emoticons/emojimanager.h"
9 #include "rocketchataccount.h"
10 #include "ruqola.h"
11 #include <KLocalizedString>
12 #include <QIcon>
13 #include <QUrl>
14 
EmoticonModel(QObject * parent)15 EmoticonModel::EmoticonModel(QObject *parent)
16     : QAbstractListModel(parent)
17 {
18 }
19 
20 EmoticonModel::~EmoticonModel() = default;
21 
rowCount(const QModelIndex & parent) const22 int EmoticonModel::rowCount(const QModelIndex &parent) const
23 {
24     if (parent.isValid()) {
25         return 0; // flat model
26     }
27     return mUnicodeRows.count() + mCustomRows.count();
28 }
29 
createCustomIcon(const QString & name) const30 QIcon EmoticonModel::createCustomIcon(const QString &name) const
31 {
32     auto rcAccount = Ruqola::self()->rocketChatAccount();
33     if (rcAccount) {
34         const QString fileName = rcAccount->emojiManager()->customEmojiFileName(name);
35         if (!fileName.isEmpty()) {
36             const QUrl emojiUrl = rcAccount->attachmentUrlFromLocalCache(fileName);
37             if (!emojiUrl.isEmpty()) {
38                 const QIcon icon(emojiUrl.toLocalFile());
39                 return icon;
40             }
41         }
42     }
43     return {};
44 }
45 
data(const QModelIndex & index,int role) const46 QVariant EmoticonModel::data(const QModelIndex &index, int role) const
47 {
48     if (index.row() < 0 || index.row() >= (mUnicodeRows.count() + mCustomRows.count())) {
49         return {};
50     }
51 
52     if (index.row() < mUnicodeRows.count()) {
53         const auto &row = mUnicodeRows.at(index.row());
54         if (row.first < mEmoticons.count()) {
55             const UnicodeEmoticon &unicodeEmoti = mEmoticons.at(row.first);
56 
57             switch (role) {
58             case CompleterName:
59                 return unicodeEmoti.identifier().mid(1);
60 #if 0
61             case Qt::DecorationRole: {
62                 QPixmap px(8,8);
63                 px.fill(Qt::transparent);
64                 QPainter painter(&px);
65                 painter.drawText(QRect(0, 0, 8, 8),Qt::AlignCenter,unicodeEmoti.unicode());
66                 QIcon icon(px);
67                 return icon;
68             }
69 #endif
70             case Qt::DisplayRole: // for the completion popup (until we have a delegate)
71             case UnicodeEmoji:
72                 return unicodeEmoti.unicode();
73             case Category:
74                 return unicodeEmoti.category();
75             case Qt::ToolTipRole:
76             case Identifier:
77                 if (row.second == -1) {
78                     return unicodeEmoti.identifier();
79                 }
80                 return unicodeEmoti.aliases().value(row.second);
81             }
82         }
83     } else {
84         const auto &row = mCustomRows.at(index.row() - mUnicodeRows.count());
85         if (row.first < mUnicodeRows.count()) {
86             const CustomEmoji &customEmoti = mCustomEmojiList.at(row.first);
87             switch (role) {
88             case CompleterName:
89                 return customEmoti.emojiIdentifier().mid(1);
90             case Qt::DisplayRole:
91                 return customEmoti.emojiIdentifier();
92             case UnicodeEmoji:
93                 return customEmoti.name(); // Display name for the moment. In the future we need to display "icon"
94             case Category:
95                 return i18n("Custom");
96             case Qt::DecorationRole:
97                 return createCustomIcon(customEmoti.emojiIdentifier());
98             case Qt::ToolTipRole:
99             case Identifier:
100                 if (row.second == -1) {
101                     return customEmoti.emojiIdentifier();
102                 }
103                 return customEmoti.aliases().value(row.second);
104             }
105         }
106     }
107     return {};
108 }
109 
unicodeEmoticons() const110 QVector<UnicodeEmoticon> EmoticonModel::unicodeEmoticons() const
111 {
112     return mEmoticons;
113 }
114 
setUnicodeEmoticons(const QVector<UnicodeEmoticon> & emoticons)115 void EmoticonModel::setUnicodeEmoticons(const QVector<UnicodeEmoticon> &emoticons)
116 {
117     beginResetModel();
118     mEmoticons = emoticons;
119     mUnicodeRows.clear();
120     int row = 0;
121     for (const auto &emoticon : emoticons) {
122         mUnicodeRows.append({row, -1});
123         const auto numAliases = emoticon.aliases().size();
124         for (int i = 0; i < numAliases; ++i) {
125             mUnicodeRows.append({row, i});
126         }
127         ++row;
128     }
129     endResetModel();
130 }
131 
customEmojiList() const132 const QVector<CustomEmoji> &EmoticonModel::customEmojiList() const
133 {
134     return mCustomEmojiList;
135 }
136 
setCustomEmojiList(const QVector<CustomEmoji> & newCustomEmojiList)137 void EmoticonModel::setCustomEmojiList(const QVector<CustomEmoji> &newCustomEmojiList)
138 {
139     beginResetModel();
140     mCustomEmojiList = newCustomEmojiList;
141     mCustomRows.clear();
142     int row = 0;
143     for (const auto &emoticon : newCustomEmojiList) {
144         mCustomRows.append({row, -1});
145         const auto numAliases = emoticon.aliases().size();
146         for (int i = 0; i < numAliases; ++i) {
147             mCustomRows.append({row, i});
148         }
149         ++row;
150     }
151     endResetModel();
152 }
153 
deleteEmojiCustom(const QStringList & lst)154 void EmoticonModel::deleteEmojiCustom(const QStringList &lst)
155 {
156     // TODO
157 }
158 
addEmojiCustomList(const QVector<CustomEmoji> & newCustomEmojiList)159 void EmoticonModel::addEmojiCustomList(const QVector<CustomEmoji> &newCustomEmojiList)
160 {
161     // TODO
162 }
163