/* * Copyright (C) 2024 Petr Mironychev * * This file is part of QodeAssist. * * QodeAssist is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * QodeAssist is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with QodeAssist. If not, see . */ #include "ChatWidget.h" #include "QodeAssistUtils.hpp" #include #include #include #include #include namespace QodeAssist::Chat { ChatWidget::ChatWidget(QWidget *parent) : QWidget(parent) , m_showTimestamp(false) , m_chatClient(new ChatClientInterface(this)) { setupUi(); connect(m_sendButton, &QPushButton::clicked, this, &ChatWidget::sendMessage); connect(m_messageInput, &QLineEdit::returnPressed, this, &ChatWidget::sendMessage); connect(m_chatClient, &ChatClientInterface::messageReceived, this, &ChatWidget::receiveMessage); connect(m_chatClient, &ChatClientInterface::errorOccurred, this, &ChatWidget::handleError); logMessage("ChatWidget initialized"); } void ChatWidget::setupUi() { m_chatDisplay = new QTextEdit(this); m_chatDisplay->setReadOnly(true); m_messageInput = new QLineEdit(this); m_sendButton = new QPushButton("Send", this); QHBoxLayout *inputLayout = new QHBoxLayout; inputLayout->addWidget(m_messageInput); inputLayout->addWidget(m_sendButton); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->addWidget(m_chatDisplay); mainLayout->addLayout(inputLayout); setLayout(mainLayout); } void ChatWidget::sendMessage() { QString message = m_messageInput->text().trimmed(); if (!message.isEmpty()) { logMessage("Sending message: " + message); addMessage(message, true); m_chatClient->sendMessage(message); m_messageInput->clear(); addMessage("AI is typing...", false); } } void ChatWidget::receiveMessage(const QString &message) { updateLastAIMessage(message); } void ChatWidget::receivePartialMessage(const QString &partialMessage) { logMessage("Received partial message: " + partialMessage); m_currentAIResponse += partialMessage; updateLastAIMessage(m_currentAIResponse); } void ChatWidget::onMessageCompleted() { updateLastAIMessage(m_currentAIResponse); m_currentAIResponse.clear(); scrollToBottom(); } void ChatWidget::handleError(const QString &error) { logMessage("Error occurred: " + error); addMessage("Error: " + error, false); } void ChatWidget::addMessage(const QString &message, bool fromUser) { auto prefix = fromUser ? "You: " : "AI: "; QString timestamp = m_showTimestamp ? QDateTime::currentDateTime().toString("[hh:mm:ss] ") : ""; QString fullMessage = timestamp + prefix + message; m_chatDisplay->append(fullMessage); scrollToBottom(); } void ChatWidget::updateLastAIMessage(const QString &message) { QTextCursor cursor = m_chatDisplay->textCursor(); cursor.movePosition(QTextCursor::End); cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); cursor.removeSelectedText(); QString timestamp = m_showTimestamp ? QDateTime::currentDateTime().toString("[hh:mm:ss] ") : ""; cursor.insertText(timestamp + "AI: " + message); cursor.movePosition(QTextCursor::End); m_chatDisplay->setTextCursor(cursor); scrollToBottom(); m_chatDisplay->repaint(); } void ChatWidget::clear() { m_chatDisplay->clear(); m_currentAIResponse.clear(); m_chatClient->clearMessages(); } void ChatWidget::scrollToBottom() { QScrollBar *scrollBar = m_chatDisplay->verticalScrollBar(); scrollBar->setValue(scrollBar->maximum()); } void ChatWidget::setShowTimestamp(bool show) { m_showTimestamp = show; } } // namespace QodeAssist::Chat