#include "ctai_history_widget.h" ctai_history_widget::ctai_history_widget(QWidget *parent) : QTableWidget(parent) { setup_table(); } void ctai_history_widget::setup_table() { setColumnCount(1); setShowGrid(false); verticalHeader()->hide(); horizontalHeader()->hide(); horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); // 设置自动滚动属性 setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); // 滚动步长 verticalScrollBar()->setSingleStep(5); } ctai_history_widget::~ctai_history_widget() { for (auto &pair : message_map_) { delete pair.second.first; // 删除model_data } clear(); } void ctai_history_widget::add_message(const model_data &message) { QString send_id; if (message.msg_type_mode == SYSTEM) { send_id = QSL(message.postback_send_id); } else { send_id = QSL(message.send_user_id); } auto it = message_map_.find(send_id); if (it != message_map_.end() && it->second.first->msg_type_mode == SYSTEM) { // 更新现有消息 model_data *stored_data = it->second.first; int row = it->second.second; // 如果传入的对象属性为null或者[DONE]表示传输完毕或者其他情况 // 此时需要将tokens更新掉所有其他属性不更新传输数据 QWidget *widget = cellWidget(row, 0); if (!QSL(message.postback_model_data).isEmpty() && !QSL(message.postback_model_data).contains("[DONE]")) { // 更新传入信息 stored_data->postback_model_data += message.postback_model_data; if (auto message_widget = qobject_cast(widget)) { message_widget->add_system_message(message); } } else { // 更新tokens信息 update_stored_data(stored_data, message); if (auto message_widget = qobject_cast(widget)) { message_widget->update_tokens_message(message); } } } else { // 添加新消息 model_data *new_data = new model_data(message); ctai_history_textedit *message_widget = new ctai_history_textedit(this); message_widget->init_layout(new_data->msg_type_mode); message_widget->show(); if (new_data->msg_type_mode == SYSTEM) { message_widget->add_header_message(*new_data); message_widget->update_tokens_message(*new_data); message_widget->add_system_message(*new_data); } else { message_widget->add_header_message(*new_data); message_widget->add_user_message(*new_data); } // 创建新行 int row = rowCount(); insertRow(row); setCellWidget(row, 0, message_widget); // 存储到map中 message_map_[send_id] = std::make_pair(new_data, row); // 连接删除信号 connect(message_widget, SIGNAL(delete_requested(QString)), this, SLOT(on_msg_remove(QString))); // 连接高度变化信号 connect(message_widget, SIGNAL(row_height_changed(bool)), this, SLOT(on_rows_height_changed(bool))); // 滚动到新消息 scrollToItem(item(row, 0)); } // 立即滚动到底部 scrollToBottom(); } // 自适应信息高度 void ctai_history_widget::on_rows_height_changed(bool fold_state) { if (fold_state) { // 全部行高自适应 for (int row = 0; row < rowCount(); ++row) { setRowHeight(row, 87); resizeRowToContents(row); } } else { int row = rowCount() - 1; if (row >= 0 && row < rowCount()) { int currentHeight = rowHeight(row); setRowHeight(row, currentHeight + 100); resizeRowToContents(row); } } scrollToBottom(); } void ctai_history_widget::on_msg_remove(QString send_id) { // 添加更多调试信息 qDebug() << "Removing message with send_id:" << send_id; qDebug() << "Current row count:" << rowCount(); auto it = message_map_.find(send_id); if (it != message_map_.end()) { int row_to_remove = it->second.second; qDebug() << "it row count:" << it->second.second; // 验证行号是否有效 if (row_to_remove < 0 || row_to_remove >= rowCount()) { qDebug() << "Invalid row index:" << row_to_remove; return; } // 1. 先处理cell widget QWidget *widget = cellWidget(row_to_remove, 0); if (widget) { // 断开该widget的所有信号连接 widget->disconnect(); // 从表格中移除widget removeCellWidget(row_to_remove, 0); // 标记widget待删除 widget->deleteLater(); } // 2. 删除model数据 if (it->second.first) { delete it->second.first; it->second.first = nullptr; } // 3. 从map中移除 message_map_.erase(it); // 4. 最后删除行 blockSignals(true); // 暂时阻止信号 removeRow(row_to_remove); blockSignals(false); // 恢复信号 // 5. 更新其他行的索引 for (auto &pair : message_map_) { if (pair.second.second > row_to_remove) { pair.second.second--; } } qDebug() << "Row removed successfully. New row count:" << rowCount(); } } ctai_history_textedit *ctai_history_widget::current_message() const { int current_row = currentRow(); if (current_row >= 0) { return qobject_cast(cellWidget(current_row, 0)); } return nullptr; } void ctai_history_widget::update_stored_data(model_data *stored_data, const model_data &message) { stored_data->api_key = message.api_key; stored_data->api_url = message.api_url; stored_data->postback_completion_tokens = message.postback_completion_tokens; stored_data->postback_finish_reason = message.postback_finish_reason; stored_data->postback_prompt_cache_hit_tokens = message.postback_prompt_cache_hit_tokens; stored_data->postback_prompt_cache_miss_tokens = message.postback_prompt_cache_miss_tokens; stored_data->postback_prompt_tokens = message.postback_prompt_tokens; stored_data->postback_send_id = message.postback_send_id; stored_data->postback_server_model = message.postback_server_model; stored_data->postback_stream_mode = message.postback_stream_mode; stored_data->postback_system_fingerprint = message.postback_system_fingerprint; stored_data->postback_time = message.postback_time; stored_data->postback_total_tokens = message.postback_total_tokens; stored_data->request_body = message.request_body; stored_data->send_accept_header = message.send_accept_header; stored_data->send_content_header = message.send_content_header; stored_data->send_user_data = message.send_user_data; stored_data->user_model = message.user_model; // postback_model_data 不在这里赋值 }