File indexing completed on 2024-05-12 16:25:03
0001 // SPDX-FileCopyrightText: 2022 Tobias Fella <tobias.fella@kde.org> 0002 // SPDX-License-Identifier: LGPL-2.0-or-later 0003 0004 #include "completionmodel.h" 0005 #include <QDebug> 0006 0007 #include "actionsmodel.h" 0008 #include "completionproxymodel.h" 0009 #include "customemojimodel.h" 0010 #include "emojimodel.h" 0011 #include "neochatroom.h" 0012 #include "userlistmodel.h" 0013 0014 CompletionModel::CompletionModel(QObject *parent) 0015 : QAbstractListModel(parent) 0016 , m_filterModel(new CompletionProxyModel()) 0017 , m_userListModel(new UserListModel(this)) 0018 , m_emojiModel(new QConcatenateTablesProxyModel(this)) 0019 { 0020 connect(this, &CompletionModel::textChanged, this, &CompletionModel::updateCompletion); 0021 connect(this, &CompletionModel::roomChanged, this, [this]() { 0022 m_userListModel->setRoom(m_room); 0023 }); 0024 m_emojiModel->addSourceModel(&CustomEmojiModel::instance()); 0025 m_emojiModel->addSourceModel(&EmojiModel::instance()); 0026 } 0027 0028 QString CompletionModel::text() const 0029 { 0030 return m_text; 0031 } 0032 0033 void CompletionModel::setText(const QString &text, const QString &fullText) 0034 { 0035 m_text = text; 0036 m_fullText = fullText; 0037 Q_EMIT textChanged(); 0038 } 0039 0040 int CompletionModel::rowCount(const QModelIndex &parent) const 0041 { 0042 Q_UNUSED(parent); 0043 if (m_autoCompletionType == None) { 0044 return 0; 0045 } 0046 return m_filterModel->rowCount(); 0047 } 0048 0049 QVariant CompletionModel::data(const QModelIndex &index, int role) const 0050 { 0051 if (index.row() < 0 || index.row() >= m_filterModel->rowCount()) { 0052 return {}; 0053 } 0054 auto filterIndex = m_filterModel->index(index.row(), 0); 0055 if (m_autoCompletionType == User) { 0056 if (role == DisplayNameRole) { 0057 return m_filterModel->data(filterIndex, UserListModel::DisplayNameRole); 0058 } 0059 if (role == SubtitleRole) { 0060 return m_filterModel->data(filterIndex, UserListModel::UserIdRole); 0061 } 0062 if (role == IconNameRole) { 0063 return m_filterModel->data(filterIndex, UserListModel::AvatarRole); 0064 } 0065 } 0066 0067 if (m_autoCompletionType == Command) { 0068 if (role == DisplayNameRole) { 0069 return m_filterModel->data(filterIndex, ActionsModel::Prefix).toString() + QStringLiteral(" ") 0070 + m_filterModel->data(filterIndex, ActionsModel::Parameters).toString(); 0071 } 0072 if (role == SubtitleRole) { 0073 return m_filterModel->data(filterIndex, ActionsModel::Description); 0074 } 0075 if (role == IconNameRole) { 0076 return QStringLiteral("invalid"); 0077 } 0078 if (role == ReplacedTextRole) { 0079 return m_filterModel->data(filterIndex, ActionsModel::Prefix); 0080 } 0081 } 0082 if (m_autoCompletionType == Room) { 0083 if (role == DisplayNameRole) { 0084 return m_filterModel->data(filterIndex, RoomListModel::DisplayNameRole); 0085 } 0086 if (role == SubtitleRole) { 0087 return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole); 0088 } 0089 if (role == IconNameRole) { 0090 return m_filterModel->data(filterIndex, RoomListModel::AvatarRole); 0091 } 0092 } 0093 if (m_autoCompletionType == Emoji) { 0094 if (role == DisplayNameRole) { 0095 return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole); 0096 } 0097 if (role == IconNameRole) { 0098 return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl); 0099 } 0100 if (role == ReplacedTextRole) { 0101 return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole); 0102 } 0103 if (role == SubtitleRole) { 0104 return m_filterModel->data(filterIndex, EmojiModel::DescriptionRole); 0105 } 0106 } 0107 0108 return {}; 0109 } 0110 0111 QHash<int, QByteArray> CompletionModel::roleNames() const 0112 { 0113 return { 0114 {DisplayNameRole, "displayName"}, 0115 {SubtitleRole, "subtitle"}, 0116 {IconNameRole, "iconName"}, 0117 {ReplacedTextRole, "replacedText"}, 0118 }; 0119 } 0120 0121 void CompletionModel::updateCompletion() 0122 { 0123 if (text().startsWith(QLatin1Char('@'))) { 0124 m_filterModel->setSourceModel(m_userListModel); 0125 m_filterModel->setFilterRole(UserListModel::UserIdRole); 0126 m_filterModel->setSecondaryFilterRole(UserListModel::DisplayNameRole); 0127 m_filterModel->setFullText(m_fullText); 0128 m_filterModel->setFilterText(m_text); 0129 m_autoCompletionType = User; 0130 m_filterModel->invalidate(); 0131 } else if (text().startsWith(QLatin1Char('/'))) { 0132 m_filterModel->setSourceModel(&ActionsModel::instance()); 0133 m_filterModel->setFilterRole(ActionsModel::Prefix); 0134 m_filterModel->setSecondaryFilterRole(-1); 0135 m_filterModel->setFullText(m_fullText); 0136 m_filterModel->setFilterText(m_text.mid(1)); 0137 m_autoCompletionType = Command; 0138 m_filterModel->invalidate(); 0139 } else if (text().startsWith(QLatin1Char('#'))) { 0140 m_autoCompletionType = Room; 0141 m_filterModel->setSourceModel(m_roomListModel); 0142 m_filterModel->setFilterRole(RoomListModel::CanonicalAliasRole); 0143 m_filterModel->setSecondaryFilterRole(RoomListModel::DisplayNameRole); 0144 m_filterModel->setFullText(m_fullText); 0145 m_filterModel->setFilterText(m_text); 0146 m_filterModel->invalidate(); 0147 } else if (text().startsWith(QLatin1Char(':')) && !text()[1].isUpper() 0148 && (m_fullText.indexOf(QLatin1Char(':'), 1) == -1 0149 || (m_fullText.indexOf(QLatin1Char(' ')) != -1 && m_fullText.indexOf(QLatin1Char(':'), 1) > m_fullText.indexOf(QLatin1Char(' '), 1)))) { 0150 m_filterModel->setSourceModel(m_emojiModel); 0151 m_autoCompletionType = Emoji; 0152 m_filterModel->setFilterRole(CustomEmojiModel::Name); 0153 m_filterModel->setSecondaryFilterRole(EmojiModel::DescriptionRole); 0154 m_filterModel->setFullText(m_fullText); 0155 m_filterModel->setFilterText(m_text); 0156 m_filterModel->invalidate(); 0157 } else { 0158 m_autoCompletionType = None; 0159 } 0160 beginResetModel(); 0161 endResetModel(); 0162 } 0163 0164 NeoChatRoom *CompletionModel::room() const 0165 { 0166 return m_room; 0167 } 0168 0169 void CompletionModel::setRoom(NeoChatRoom *room) 0170 { 0171 m_room = room; 0172 Q_EMIT roomChanged(); 0173 } 0174 0175 CompletionModel::AutoCompletionType CompletionModel::autoCompletionType() const 0176 { 0177 return m_autoCompletionType; 0178 } 0179 0180 void CompletionModel::setAutoCompletionType(AutoCompletionType autoCompletionType) 0181 { 0182 m_autoCompletionType = autoCompletionType; 0183 Q_EMIT autoCompletionTypeChanged(); 0184 } 0185 0186 RoomListModel *CompletionModel::roomListModel() const 0187 { 0188 return m_roomListModel; 0189 } 0190 0191 void CompletionModel::setRoomListModel(RoomListModel *roomListModel) 0192 { 0193 m_roomListModel = roomListModel; 0194 Q_EMIT roomListModelChanged(); 0195 } 0196 0197 #include "moc_completionmodel.cpp"