KTextAddons

textautogeneratechatmodel.cpp
1/*
2 SPDX-FileCopyrightText: 2025 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "textautogeneratechatmodel.h"
8#include "textautogeneratetextcore_debug.h"
9
10using namespace TextAutogenerateText;
11TextAutoGenerateChatModel::TextAutoGenerateChatModel(QObject *parent)
12 : QAbstractListModel{parent}
13{
14}
15
16TextAutoGenerateChatModel::~TextAutoGenerateChatModel() = default;
17
18int TextAutoGenerateChatModel::rowCount(const QModelIndex &parent) const
19{
20 if (parent.isValid()) {
21 return 0; // flat model
22 }
23 return mMessages.count();
24}
25
26QVariant TextAutoGenerateChatModel::data(const QModelIndex &index, int role) const
27{
28 if (index.row() < 0 || index.row() >= mMessages.count()) {
29 return {};
30 }
31 const auto &message = mMessages[index.row()];
32 switch (role) {
33 case Qt::DisplayRole:
34 case MessageRole:
35 return message.htmlGenerated();
36 case DateTimeStrRole:
37 return message.dateTimeStr();
38 case DateTimeRole:
39 return message.dateTime();
40 case SenderRole:
41 return QVariant::fromValue(message.sender());
42 case FinishedRole:
43 return !message.inProgress();
44 case UuidRole:
45 return message.uuid();
46 case TopicRole:
47 return message.topic();
48 case MouseHoverRole:
49 return message.mouseHover();
50 case ArchivedRole:
51 return message.archived();
52 case EditingRole:
53 return message.editingMode();
54 }
55 return {};
56}
57
58QList<TextAutoGenerateMessage> TextAutoGenerateChatModel::messages() const
59{
60 return mMessages;
61}
62
63void TextAutoGenerateChatModel::setMessages(const QList<TextAutoGenerateMessage> &newMessages)
64{
66 mMessages = newMessages;
68}
69
70void TextAutoGenerateChatModel::resetConversation()
71{
73 mMessages.clear();
75 Q_EMIT conversationCleared();
76}
77
78void TextAutoGenerateChatModel::addMessage(const TextAutoGenerateMessage &msg)
79{
80 beginInsertRows(QModelIndex(), mMessages.count(), mMessages.count());
81 mMessages.append(msg);
82 if (msg.sender() == TextAutoGenerateMessage::Sender::LLM) {
83 auto emitChanged = [this](int rowNumber, const QList<int> &roles = QList<int>()) {
84 const QModelIndex index = createIndex(rowNumber, 0);
86 };
87 emitChanged(mMessages.count() - 1, {FinishedRole});
88 }
90}
91
92QByteArray TextAutoGenerateChatModel::editMessage(const QByteArray &uuid, const QString &str)
93{
94 if (uuid.isEmpty()) {
95 return {};
96 }
97 auto matchesUuid = [&](const TextAutoGenerateMessage &msg) {
98 return msg.uuid() == uuid;
99 };
100 const auto it = std::find_if(mMessages.begin(), mMessages.end(), matchesUuid);
101 if (it != mMessages.end()) {
102 const int i = std::distance(mMessages.begin(), it);
103 const QByteArray answerUuid = it->answerUuid();
104
105 (*it).setContent(str);
106 auto emitChanged = [this](int rowNumber, const QList<int> &roles = QList<int>()) {
107 const QModelIndex index = createIndex(rowNumber, 0);
108 Q_EMIT dataChanged(index, index, roles);
109 };
110 emitChanged(i, {MessageRole});
111
112 auto matchesAnswerUuid = [&](const TextAutoGenerateMessage &msg) {
113 return msg.uuid() == answerUuid;
114 };
115 const auto answerIt = std::find_if(mMessages.begin(), mMessages.end(), matchesAnswerUuid);
116 if (answerIt != mMessages.end()) {
117 const int i = std::distance(mMessages.begin(), answerIt);
118 (*answerIt).setInProgress(true);
119 (*answerIt).setContent({});
120 emitChanged(i, {MessageRole | FinishedRole});
121 }
122 return answerUuid;
123 }
124 return {};
125}
126
127void TextAutoGenerateChatModel::changeInProgress(const QByteArray &uuid, bool inProgress)
128{
129 if (uuid.isEmpty()) {
130 return;
131 }
132 auto matchesUuid = [&](const TextAutoGenerateMessage &msg) {
133 return msg.uuid() == uuid;
134 };
135 auto it = std::find_if(mMessages.begin(), mMessages.end(), matchesUuid);
136 if (it != mMessages.end()) {
137 (*it).setInProgress(inProgress);
138 const int i = std::distance(mMessages.begin(), it);
139 auto emitChanged = [this](int rowNumber, const QList<int> &roles = QList<int>()) {
140 const QModelIndex index = createIndex(rowNumber, 0);
141 Q_EMIT dataChanged(index, index, roles);
142 };
143 emitChanged(i, {MessageRole | FinishedRole});
144 }
145}
146
147void TextAutoGenerateChatModel::replaceContent(const QByteArray &uuid, const QString &content)
148{
149 if (uuid.isEmpty()) {
150 return;
151 }
152 auto matchesUuid = [&](const TextAutoGenerateMessage &msg) {
153 return msg.uuid() == uuid;
154 };
155 auto it = std::find_if(mMessages.begin(), mMessages.end(), matchesUuid);
156 if (it != mMessages.end()) {
157 (*it).setContent(content);
158 const int i = std::distance(mMessages.begin(), it);
159 auto emitChanged = [this](int rowNumber, const QList<int> &roles = QList<int>()) {
160 const QModelIndex index = createIndex(rowNumber, 0);
161 Q_EMIT dataChanged(index, index, roles);
162 };
163 emitChanged(i, {MessageRole});
164 }
165}
166
167void TextAutoGenerateChatModel::removeDiscussion(const QByteArray &uuid)
168{
169 if (uuid.isEmpty()) {
170 return;
171 }
172 auto matchesUuid = [&](const TextAutoGenerateMessage &msg) {
173 return msg.uuid() == uuid;
174 };
175 const auto it = std::find_if(mMessages.begin(), mMessages.end(), matchesUuid);
176 if (it != mMessages.end()) {
177 const int i = std::distance(mMessages.begin(), it);
178 const QByteArray answerUuid = it->answerUuid();
179 beginRemoveRows(QModelIndex(), i, i);
180 mMessages.removeAt(i);
182
183 auto matchesAnswerUuid = [&](const TextAutoGenerateMessage &msg) {
184 return msg.uuid() == answerUuid;
185 };
186 const auto answerIt = std::find_if(mMessages.begin(), mMessages.end(), matchesAnswerUuid);
187 if (answerIt != mMessages.end()) {
188 const int i = std::distance(mMessages.begin(), answerIt);
189 beginRemoveRows(QModelIndex(), i, i);
190 mMessages.removeAt(i);
192 }
193 }
194}
195
196bool TextAutoGenerateChatModel::cancelRequest(const QModelIndex &index)
197{
198 return setData(index, false, TextAutoGenerateChatModel::FinishedRole);
199}
200
201bool TextAutoGenerateChatModel::setData(const QModelIndex &idx, const QVariant &value, int role)
202{
203 if (!idx.isValid()) {
204 qCWarning(TEXTAUTOGENERATETEXT_CORE_LOG) << "ERROR: invalid index";
205 return false;
206 }
207 const int id = idx.row();
208 TextAutoGenerateMessage &msg = mMessages[id];
209 switch (role) {
210 case ChatRoles::TopicRole: {
211 msg.setTopic(value.toString());
212 const QModelIndex newIndex = index(idx.row(), ChatRoles::TopicRole);
213 Q_EMIT dataChanged(newIndex, newIndex);
214 return true;
215 }
216 case ChatRoles::MouseHoverRole:
217 msg.setMouseHover(value.toBool());
218 Q_EMIT dataChanged(idx, idx, {ChatRoles::MouseHoverRole});
219 return true;
220 case ChatRoles::EditingRole:
221 msg.setEditingMode(value.toBool());
222 Q_EMIT dataChanged(idx, idx, {ChatRoles::EditingRole});
223 return true;
224 case ChatRoles::FinishedRole:
225 msg.setInProgress(value.toBool());
226 Q_EMIT dataChanged(idx, idx, {ChatRoles::FinishedRole});
227 return true;
228 case ChatRoles::MessageRole:
229 case ChatRoles::SenderRole:
230 case ChatRoles::DateTimeRole:
231 case ChatRoles::UuidRole:
232 case ChatRoles::ArchivedRole:
233 return false;
234 }
235 return QAbstractListModel::setData(idx, value, role);
236}
237
238QModelIndex TextAutoGenerateChatModel::indexForUuid(const QByteArray &uuid) const
239{
240 auto matchesUuid = [&](const TextAutoGenerateMessage &msg) {
241 return msg.uuid() == uuid;
242 };
243 auto it = std::find_if(mMessages.begin(), mMessages.end(), matchesUuid);
244 if (it == mMessages.end()) {
245 return {};
246 }
247 const QModelIndex idx = createIndex(std::distance(mMessages.begin(), it), 0);
248 return idx;
249}
250
251Qt::ItemFlags TextAutoGenerateChatModel::flags(const QModelIndex &index) const
252{
253 if (!index.isValid())
254 return Qt::NoItemFlags;
255
257}
258
259#include "moc_textautogeneratechatmodel.cpp"
void beginInsertRows(const QModelIndex &parent, int first, int last)
void beginRemoveRows(const QModelIndex &parent, int first, int last)
QModelIndex createIndex(int row, int column, const void *ptr) const const
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
virtual QModelIndex parent(const QModelIndex &index) const const=0
virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
virtual Qt::ItemFlags flags(const QModelIndex &index) const const override
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
bool isEmpty() const const
bool isValid() const const
int row() const const
Q_EMITQ_EMIT
DisplayRole
typedef ItemFlags
QVariant fromValue(T &&value)
bool toBool() const const
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri May 2 2025 12:06:03 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.