C++ / fmt (pull_request) Failing after 4s
C++ / build (pull_request) Failing after 9s
JS/TS / lint (pull_request) Successful in 9s
JS/TS / fmt (pull_request) Successful in 16s
C++ / clang-tidy (pull_request) Failing after 43s
Python / static (pull_request) Failing after 57s
Rust / fmt (pull_request) Successful in 1m30s
Rust / build (pull_request) Successful in 2m5s
Rust / clippy (pull_request) Successful in 1m55s
Python / verify (pull_request) Successful in 2m23s
114 lines
2.9 KiB
C++
114 lines
2.9 KiB
C++
#include "messagemodel.hpp"
|
|
|
|
#include "session.hpp"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace ZShell::llm {
|
|
|
|
ChatMessageModel::ChatMessageModel(ChatSession* session, QObject* parent)
|
|
: QAbstractListModel(parent), m_session(session) {}
|
|
|
|
ChatMessageModel::~ChatMessageModel() = default;
|
|
|
|
int ChatMessageModel::rowCount(const QModelIndex& parent) const {
|
|
if (parent.isValid()) return 0;
|
|
return static_cast<int>(m_messages.size());
|
|
}
|
|
|
|
QVariant ChatMessageModel::data(const QModelIndex& index, int role) const {
|
|
if (role != Qt::UserRole || !index.isValid() || index.row() < 0 ||
|
|
index.row() >= m_messages.size())
|
|
return {};
|
|
return QVariant::fromValue(m_messages.at(index.row()));
|
|
}
|
|
|
|
QHash<int, QByteArray> ChatMessageModel::roleNames() const {
|
|
return {{Qt::UserRole, "modelData"}};
|
|
}
|
|
|
|
ChatMessage* ChatMessageModel::at(int row) const {
|
|
if (row < 0 || row >= m_messages.size()) return nullptr;
|
|
return m_messages.at(row);
|
|
}
|
|
|
|
int ChatMessageModel::rowOf(const ChatMessage* message) const {
|
|
for (int i = 0; i < m_messages.size(); ++i)
|
|
if (m_messages.at(i) == message) return i;
|
|
return -1;
|
|
}
|
|
|
|
ChatMessage* ChatMessageModel::createMessage(
|
|
ChatMessage::Role role, qint64 timestamp) {
|
|
return new ChatMessage(role, timestamp, this);
|
|
}
|
|
|
|
ChatMessage* ChatMessageModel::appendNewest(
|
|
ChatMessage::Role role, const QString& content, qint64 timestamp) {
|
|
auto* message = new ChatMessage(role, timestamp, this);
|
|
auto* generation = message->addGeneration(timestamp);
|
|
generation->setContent(content);
|
|
|
|
beginInsertRows(QModelIndex(), 0, 0);
|
|
m_messages.prepend(message);
|
|
endInsertRows();
|
|
|
|
emit lastMessageChanged();
|
|
|
|
return message;
|
|
}
|
|
|
|
void ChatMessageModel::removeMessage(ChatMessage* message) {
|
|
const int row = rowOf(message);
|
|
if (row < 0) return;
|
|
|
|
const bool wasLastMessage = row == 0;
|
|
|
|
beginRemoveRows(QModelIndex(), row, row);
|
|
m_messages.removeAt(row);
|
|
endRemoveRows();
|
|
|
|
delete message;
|
|
|
|
if (wasLastMessage) emit lastMessageChanged();
|
|
}
|
|
|
|
void ChatMessageModel::removeRange(int firstRow, int lastRow) {
|
|
if (firstRow < 0 || firstRow > lastRow || lastRow >= m_messages.size())
|
|
return;
|
|
|
|
const bool changesLastMessage = firstRow == 0;
|
|
|
|
beginRemoveRows(QModelIndex(), firstRow, lastRow);
|
|
for (int row = lastRow; row >= firstRow; --row)
|
|
delete m_messages.takeAt(row);
|
|
endRemoveRows();
|
|
|
|
if (changesLastMessage) emit lastMessageChanged();
|
|
}
|
|
|
|
void ChatMessageModel::clear() {
|
|
if (m_messages.isEmpty()) return;
|
|
|
|
beginRemoveRows(QModelIndex(), 0, static_cast<int>(m_messages.size() - 1));
|
|
qDeleteAll(m_messages);
|
|
m_messages.clear();
|
|
endRemoveRows();
|
|
|
|
emit lastMessageChanged();
|
|
}
|
|
|
|
void ChatMessageModel::loadMessages(QList<ChatMessage*> messages) {
|
|
beginResetModel();
|
|
for (ChatMessage* message : m_messages)
|
|
if (std::find(messages.begin(), messages.end(), message) ==
|
|
messages.end())
|
|
delete message;
|
|
m_messages = std::move(messages);
|
|
endResetModel();
|
|
|
|
emit lastMessageChanged();
|
|
}
|
|
|
|
} // namespace ZShell::llm
|