Warning, file /network/ruqola/src/core/model/inputcompletermodel.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2018-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "inputcompletermodel.h" 0008 #include "rocketchataccount.h" 0009 #include <KLocalizedString> 0010 0011 #include <QJsonArray> 0012 0013 #include <QIcon> 0014 #include <QModelIndex> 0015 0016 InputCompleterModel::InputCompleterModel(RocketChatAccount *account, QObject *parent) 0017 : QAbstractListModel(parent) 0018 , mRocketChatAccount(account) 0019 { 0020 } 0021 0022 InputCompleterModel::~InputCompleterModel() = default; 0023 0024 QString InputCompleterModel::here() 0025 { 0026 return QStringLiteral("here"); 0027 } 0028 0029 QString InputCompleterModel::all() 0030 { 0031 return QStringLiteral("all"); 0032 } 0033 0034 ChannelUserCompleter InputCompleterModel::createHereChannel() 0035 { 0036 ChannelUserCompleter here; 0037 here.setName(InputCompleterModel::here()); 0038 here.setDescription(i18n("Notify all in this room")); 0039 here.setType(ChannelUserCompleter::ChannelUserCompleterType::Notification); 0040 return here; 0041 } 0042 0043 ChannelUserCompleter InputCompleterModel::noFoundChannelUser() 0044 { 0045 ChannelUserCompleter noFound; 0046 noFound.setDescription(i18n("No result found.")); 0047 noFound.setType(ChannelUserCompleter::ChannelUserCompleterType::Unknown); 0048 return noFound; 0049 } 0050 0051 ChannelUserCompleter InputCompleterModel::createAllChannel() 0052 { 0053 ChannelUserCompleter all; 0054 all.setName(InputCompleterModel::all()); 0055 all.setDescription(i18n("Notify active users in this room")); 0056 all.setType(ChannelUserCompleter::ChannelUserCompleterType::Notification); 0057 return all; 0058 } 0059 0060 void InputCompleterModel::setDefaultUserCompletion() 0061 { 0062 // Show here/all when we only use "@" 0063 QVector<ChannelUserCompleter> customCompletion; 0064 0065 customCompletion.append(createHereChannel()); 0066 customCompletion.append(createAllChannel()); 0067 0068 setChannels(customCompletion); 0069 } 0070 0071 void InputCompleterModel::setChannels(const QVector<ChannelUserCompleter> &channels) 0072 { 0073 clear(); 0074 if (!channels.isEmpty()) { 0075 beginInsertRows(QModelIndex(), 0, channels.count() - 1); 0076 mChannelUserCompleters = channels; 0077 endInsertRows(); 0078 } 0079 } 0080 0081 QVector<ChannelUserCompleter> InputCompleterModel::searchOpenedRooms() 0082 { 0083 QVector<ChannelUserCompleter> channels; 0084 if (mRocketChatAccount) { 0085 if (!mSearchInfo.searchString.isEmpty()) { 0086 const QVector<Room *> rooms = mRocketChatAccount->roomModel()->findRoomNameConstains(mSearchInfo.searchString); 0087 for (const Room *room : rooms) { 0088 if (room->channelType() == Room::RoomType::Channel) { // Only direct channel. 0089 ChannelUserCompleter channel; 0090 channel.setType(ChannelUserCompleter::ChannelUserCompleterType::Room); 0091 channel.setName(room->displayFName()); 0092 channel.setIdentifier(room->roomId()); 0093 channel.setChannelIcon(); 0094 channel.setAvatarInfo(room->avatarInfo()); 0095 channels.append(std::move(channel)); 0096 } 0097 } 0098 } 0099 } 0100 return channels; 0101 } 0102 0103 void InputCompleterModel::setSearchInfo(const SearchInfo &newSearchInfo) 0104 { 0105 mSearchInfo = newSearchInfo; 0106 } 0107 0108 void InputCompleterModel::parseSearchChannels(const QJsonObject &obj) 0109 { 0110 QVector<ChannelUserCompleter> channelList; 0111 const QJsonArray rooms = obj.value(QLatin1String("items")).toArray(); 0112 const auto roomsSize(rooms.size()); 0113 channelList.reserve(roomsSize); 0114 for (auto i = 0; i < roomsSize; i++) { 0115 const QJsonObject o = rooms.at(i).toObject(); 0116 ChannelUserCompleter channel; 0117 channel.parseChannel(o, ChannelUserCompleter::ChannelUserCompleterType::Room); 0118 // Verify that it's valid 0119 channelList.append(std::move(channel)); 0120 } 0121 if (channelList.isEmpty()) { 0122 channelList.append(noFoundChannelUser()); 0123 } 0124 setChannels(channelList); 0125 } 0126 0127 void InputCompleterModel::parseChannels(const QJsonObject &obj) 0128 { 0129 QVector<ChannelUserCompleter> channelList; 0130 if (mSearchInfo.searchType == SearchInfo::Channels || mSearchInfo.searchType == SearchInfo::ChannelsAndUsers) { 0131 const QJsonArray rooms = obj.value(QLatin1String("rooms")).toArray(); 0132 channelList.reserve(rooms.size()); 0133 for (int i = 0; i < rooms.size(); i++) { 0134 const QJsonObject o = rooms.at(i).toObject(); 0135 ChannelUserCompleter channel; 0136 channel.parseChannel(o, ChannelUserCompleter::ChannelUserCompleterType::Room); 0137 // Verify that it's valid 0138 channelList.append(std::move(channel)); 0139 } 0140 channelList.append(searchOpenedRooms()); 0141 } 0142 if (mSearchInfo.searchType == SearchInfo::Users || mSearchInfo.searchType == SearchInfo::ChannelsAndUsers) { 0143 const QJsonArray users = obj.value(QLatin1String("users")).toArray(); 0144 bool needToAddAll = false; 0145 bool needToAddHere = false; 0146 for (int i = 0; i < users.size(); i++) { 0147 const QJsonObject o = users.at(i).toObject(); 0148 ChannelUserCompleter user; 0149 user.parseChannel(o, ChannelUserCompleter::ChannelUserCompleterType::DirectChannel); 0150 if (!mSearchInfo.searchString.isEmpty()) { 0151 if (!needToAddAll && InputCompleterModel::all().startsWith(mSearchInfo.searchString)) { 0152 needToAddAll = true; 0153 } 0154 if (!needToAddHere && InputCompleterModel::here().startsWith(mSearchInfo.searchString)) { 0155 needToAddHere = true; 0156 } 0157 } 0158 // Verify that it's valid 0159 channelList.append(std::move(user)); 0160 } 0161 if (needToAddAll) { 0162 channelList.append(createAllChannel()); 0163 } 0164 if (needToAddHere) { 0165 channelList.append(createHereChannel()); 0166 } 0167 } 0168 if (channelList.isEmpty()) { 0169 channelList.append(noFoundChannelUser()); 0170 } 0171 setChannels(channelList); 0172 } 0173 0174 void InputCompleterModel::clear() 0175 { 0176 if (!mChannelUserCompleters.isEmpty()) { 0177 beginResetModel(); 0178 mChannelUserCompleters.clear(); 0179 endResetModel(); 0180 } 0181 } 0182 0183 int InputCompleterModel::rowCount(const QModelIndex &parent) const 0184 { 0185 Q_UNUSED(parent) 0186 return mChannelUserCompleters.count(); 0187 } 0188 0189 QVariant InputCompleterModel::data(const QModelIndex &index, int role) const 0190 { 0191 if (index.row() < 0 || index.row() >= mChannelUserCompleters.count()) { 0192 return {}; 0193 } 0194 const ChannelUserCompleter channelUserCompleter = mChannelUserCompleters.at(index.row()); 0195 switch (role) { 0196 case InputCompleterModel::DisplayName: 0197 case Qt::DisplayRole: 0198 return channelUserCompleter.name(); 0199 case InputCompleterModel::CompleterName: 0200 return channelUserCompleter.completerName(); 0201 case InputCompleterModel::IconStatus: 0202 case Qt::DecorationRole: 0203 return channelUserCompleter.statusIcon(); 0204 case InputCompleterModel::AvatarInfo: 0205 return QVariant::fromValue(channelUserCompleter.avatarInfo()); 0206 case InputCompleterModel::Description: 0207 return channelUserCompleter.description(); 0208 case InputCompleterModel::UserName: 0209 return channelUserCompleter.userName(); 0210 case InputCompleterModel::OutsideRoom: 0211 return channelUserCompleter.outsideRoom(); 0212 case InputCompleterModel::ChannelType: 0213 return channelUserCompleter.type(); 0214 case InputCompleterModel::Identifier: 0215 return channelUserCompleter.identifier(); 0216 } 0217 return {}; 0218 } 0219 0220 #include "moc_inputcompletermodel.cpp"