From eff857a55ebc4c1c7108c99eb536835b31a0d476 Mon Sep 17 00:00:00 2001 From: PTyTb Date: Thu, 29 Jan 2026 21:13:51 +0300 Subject: [PATCH] =?UTF-8?q?=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=B5=D0=B1=20=D1=81=D0=B5=D1=80?= =?UTF-8?q?=D0=B2=D0=B8=D1=81=D0=BE=D0=B2=20=D1=81=20=D1=87=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fcreatechat.cpp | 31 +++++- fcreatechat.h | 4 +- udatabase.cpp | 253 ++++++++++++++++++++++++++++++++++++++++++++++++ udatabase.h | 36 +++++++ ugeneral.cpp | 66 +++++++++++-- ugeneral.h | 2 +- 6 files changed, 382 insertions(+), 10 deletions(-) diff --git a/fcreatechat.cpp b/fcreatechat.cpp index 62188cb..1c65661 100644 --- a/fcreatechat.cpp +++ b/fcreatechat.cpp @@ -1,15 +1,17 @@ #include "fcreatechat.h" +#include "udatabase.h" #include "ui_fcreatechat.h" #include #include -FCreateChat::FCreateChat(QWidget *parent) +FCreateChat::FCreateChat(uDataBase *database, QWidget *parent) : QDialog(parent) , m_chatServer(nullptr) , m_StyleChat(nullptr) , ui(new Ui::FCreateChat) , m_isEditMode(false) , m_existingServerName("") + , m_database(database) { ui->setupUi(this); setWindowTitle("TTW Bot app: Создать чат"); @@ -387,7 +389,20 @@ void FCreateChat::onBtnAddClicked() if (newName.isEmpty()) { newName = QString("Чат сервер (порт %1)").arg(m_chatServer->port()); } + // Получаем список шрифтов + FFontSetting *fontSetting1 = ui->wFont; + QStringList fontList; + if (fontSetting1 && fontSetting1->cbFontStyle) { + for (int i = 0; i < fontSetting1->cbFontStyle->count(); ++i) { + fontList.append(fontSetting1->cbFontStyle->itemText(i)); + } + } + // Обновляем чат в базе данных + if (m_database) { + int oldPort = portChanged ? m_chatServer->port() : m_chatServer->port(); + m_database->updateChat(newName, m_chatServer, fontList.join(','), oldPort); + } emit serverUpdated(m_chatServer, newName); accept(); } else { @@ -406,6 +421,20 @@ void FCreateChat::onBtnAddClicked() name = QString("Чат сервер (порт %1)").arg(m_chatServer->port()); } + // Получаем список шрифтов + FFontSetting *fontSetting = ui->wFont; + QStringList fontList; + if (fontSetting && fontSetting->cbFontStyle) { + for (int i = 0; i < fontSetting->cbFontStyle->count(); ++i) { + fontList.append(fontSetting->cbFontStyle->itemText(i)); + } + } + + // Сохраняем чат в базу данных + if (m_database) { + m_database->saveChat(name, "chat", m_chatServer, fontList.join(',')); + } + emit serverCreated(m_chatServer, name); m_chatServer = nullptr; accept(); diff --git a/fcreatechat.h b/fcreatechat.h index 429d6ce..29c2d44 100644 --- a/fcreatechat.h +++ b/fcreatechat.h @@ -1,6 +1,7 @@ #ifndef FCREATECHAT_H #define FCREATECHAT_H +#include "udatabase.h" #include "webserverchat.h" #include @@ -17,7 +18,7 @@ signals: void serverUpdated(HttpServerChat *server, const QString &name); public: - explicit FCreateChat(QWidget *parent = nullptr); + explicit FCreateChat(uDataBase *database = nullptr, QWidget *parent = nullptr); ~FCreateChat(); HttpServerChat *m_chatServer; @@ -33,6 +34,7 @@ private: Ui::FCreateChat *ui; bool m_isEditMode; QString m_existingServerName; + uDataBase *m_database; void createServer(); void applyCurrentSettingsToServer(); void createTestMessage(bool isTest = false); diff --git a/udatabase.cpp b/udatabase.cpp index d077099..0d30619 100644 --- a/udatabase.cpp +++ b/udatabase.cpp @@ -5,6 +5,7 @@ #include #include "qlistwidget.h" +#include "webserverchat.h" uDataBase::uDataBase(const QString& dbFileName, QObject* parent) : QObject(parent) @@ -76,6 +77,12 @@ bool uDataBase::initializeDatabase() return false; } + // Создаем таблицу для чатов + if (!createChatsTable()) { + qWarning() << "Failed to create chats table"; + // Продолжаем, даже если не удалось создать таблицу чатов + } + return true; } @@ -925,4 +932,250 @@ QString uDataBase::lastError() const return m_lastError; } +/** + * @brief Создает таблицу для хранения настроек чатов + */ +bool uDataBase::createChatsTable() +{ + QSqlQuery query(m_db); + QString sql = + "CREATE TABLE IF NOT EXISTS chats (" + " id INTEGER PRIMARY KEY AUTOINCREMENT," + " name TEXT NOT NULL," + " type TEXT NOT NULL," // "chat" или "notification" + " port INTEGER NOT NULL," + " font_list TEXT," + " background_color TEXT," + " block_color TEXT," + " border_color TEXT," + " border_size INTEGER," + " padding INTEGER," + " transparency INTEGER," + " font_family TEXT," + " font_size INTEGER," + " font_color TEXT," + " freez BOOLEAN," + " message_timeout INTEGER," + " max_msg_count INTEGER," + " delete_by_time BOOLEAN," + " created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP" + ")"; + if (!query.exec(sql)) { + m_lastError = query.lastError().text(); + qWarning() << "Failed to create chats table:" << m_lastError; + return false; + } + + // Создаем индекс для быстрого поиска по порту + sql = "CREATE INDEX IF NOT EXISTS idx_chats_port ON chats (port)"; + query.exec(sql); + + return true; +} + +/** + * @brief Сохраняет настройки чата в базу данных + */ +bool uDataBase::saveChat(const QString &name, const QString &type, + HttpServerChat *server, const QString &fontList) +{ + if (!server) { + m_lastError = "Server is null"; + return false; + } + + if (!m_db.isOpen()) { + m_lastError = "Database is not open"; + return false; + } + + // Создаем таблицу если не существует + if (!tableExists("chats")) { + if (!createChatsTable()) { + return false; + } + } + + QSqlQuery query(m_db); + query.prepare( + "INSERT OR REPLACE INTO chats (" + " name, type, port, font_list, background_color, " + " block_color, border_color, border_size, padding, " + " transparency, font_family, font_size, font_color, " + " freez, message_timeout, max_msg_count, delete_by_time" + ") VALUES (" + " :name, :type, :port, :font_list, :background_color, " + " :block_color, :border_color, :border_size, :padding, " + " :transparency, :font_family, :font_size, :font_color, " + " :freez, :message_timeout, :max_msg_count, :delete_by_time" + ")" + ); + + query.bindValue(":name", name); + query.bindValue(":type", type); + query.bindValue(":port", server->port()); + query.bindValue(":font_list", fontList); + query.bindValue(":background_color", server->getBackgroundColor()); + query.bindValue(":block_color", server->getBlockColor()); + query.bindValue(":border_color", server->getBorderColor()); + query.bindValue(":border_size", server->getBorderSize()); + query.bindValue(":padding", server->getPadding()); + query.bindValue(":transparency", server->getTransparency()); + query.bindValue(":font_family", server->getFontFamily()); + query.bindValue(":font_size", server->getFontSize()); + query.bindValue(":font_color", server->getFontColor()); + query.bindValue(":freez", server->isFreez()); + query.bindValue(":message_timeout", server->getMessageTimeout()); + query.bindValue(":max_msg_count", server->getMaxMsgCount()); + query.bindValue(":delete_by_time", !server->isFreez()); // delete_by_time = !freez + + if (!query.exec()) { + m_lastError = query.lastError().text(); + qWarning() << "Failed to save chat:" << m_lastError; + return false; + } + + return true; +} + +/** + * @brief Загружает все сохраненные чаты из базы данных + */ +QList uDataBase::loadAllChats() +{ + QList chats; + + if (!m_db.isOpen()) { + m_lastError = "Database is not open"; + return chats; + } + + if (!tableExists("chats")) { + // Если таблицы нет, ничего не загружаем + return chats; + } + + QSqlQuery query(m_db); + QString sql = "SELECT * FROM chats ORDER BY created_at"; + + if (!query.exec(sql)) { + m_lastError = query.lastError().text(); + qWarning() << "Failed to load chats:" << m_lastError; + return chats; + } + + while (query.next()) { + ChatSettings settings; + settings.id = query.value("id").toInt(); + settings.name = query.value("name").toString(); + settings.type = query.value("type").toString(); + settings.port = query.value("port").toInt(); + settings.fontList = query.value("font_list").toString().split(',', Qt::SkipEmptyParts); + settings.backgroundColor = query.value("background_color").toString(); + settings.blockColor = query.value("block_color").toString(); + settings.borderColor = query.value("border_color").toString(); + settings.borderSize = query.value("border_size").toInt(); + settings.padding = query.value("padding").toInt(); + settings.transparency = query.value("transparency").toInt(); + settings.fontFamily = query.value("font_family").toString(); + settings.fontSize = query.value("font_size").toInt(); + settings.fontColor = query.value("font_color").toString(); + settings.freez = query.value("freez").toBool(); + settings.messageTimeout = query.value("message_timeout").toInt(); + settings.maxMsgCount = query.value("max_msg_count").toInt(); + settings.deleteByTime = query.value("delete_by_time").toBool(); + + chats.append(settings); + } + + return chats; +} + +/** + * @brief Удаляет чат из базы данных по порту + */ +bool uDataBase::deleteChat(int port) +{ + if (!m_db.isOpen()) { + m_lastError = "Database is not open"; + return false; + } + + QSqlQuery query(m_db); + query.prepare("DELETE FROM chats WHERE port = :port"); + query.bindValue(":port", port); + + if (!query.exec()) { + m_lastError = query.lastError().text(); + qWarning() << "Failed to delete chat:" << m_lastError; + return false; + } + + return true; +} + +/** + * @brief Обновляет настройки существующего чата + */ +bool uDataBase::updateChat(const QString &name, HttpServerChat *server, + const QString &fontList, int oldPort) +{ + if (!server) { + m_lastError = "Server is null"; + return false; + } + + if (!m_db.isOpen()) { + m_lastError = "Database is not open"; + return false; + } + + QSqlQuery query(m_db); + query.prepare( + "UPDATE chats SET " + " name = :name, " + " port = :port, " + " font_list = :font_list, " + " background_color = :background_color, " + " block_color = :block_color, " + " border_color = :border_color, " + " border_size = :border_size, " + " padding = :padding, " + " transparency = :transparency, " + " font_family = :font_family, " + " font_size = :font_size, " + " font_color = :font_color, " + " freez = :freez, " + " message_timeout = :message_timeout, " + " max_msg_count = :max_msg_count, " + " delete_by_time = :delete_by_time " + "WHERE port = :old_port" + ); + + query.bindValue(":name", name); + query.bindValue(":port", server->port()); + query.bindValue(":font_list", fontList); + query.bindValue(":background_color", server->getBackgroundColor()); + query.bindValue(":block_color", server->getBlockColor()); + query.bindValue(":border_color", server->getBorderColor()); + query.bindValue(":border_size", server->getBorderSize()); + query.bindValue(":padding", server->getPadding()); + query.bindValue(":transparency", server->getTransparency()); + query.bindValue(":font_family", server->getFontFamily()); + query.bindValue(":font_size", server->getFontSize()); + query.bindValue(":font_color", server->getFontColor()); + query.bindValue(":freez", server->isFreez()); + query.bindValue(":message_timeout", server->getMessageTimeout()); + query.bindValue(":max_msg_count", server->getMaxMsgCount()); + query.bindValue(":delete_by_time", !server->isFreez()); + query.bindValue(":old_port", oldPort); + + if (!query.exec()) { + m_lastError = query.lastError().text(); + qWarning() << "Failed to update chat:" << m_lastError; + return false; + } + + return true; +} diff --git a/udatabase.h b/udatabase.h index d02bc84..1366a5c 100644 --- a/udatabase.h +++ b/udatabase.h @@ -12,12 +12,35 @@ #include #include #include "timerinfo.h" +#include "webserverchat.h" + +struct ChatSettings { + int id; + QString name; + QString type; // "chat" или "notification" + int port; + QStringList fontList; + QString backgroundColor; + QString blockColor; + QString borderColor; + int borderSize; + int padding; + int transparency; + QString fontFamily; + int fontSize; + QString fontColor; + bool freez; + int messageTimeout; + int maxMsgCount; + bool deleteByTime; +}; class uDataBase : public QObject { Q_OBJECT // Информация о таймере + public: // Конструктор с указанием файла базы данных explicit uDataBase(const QString& dbFileName, QObject* parent = nullptr); @@ -25,6 +48,8 @@ public: // Деструктор ~uDataBase(); + + // Чтение настройки QString readSetting(const QString& aName, const QString& aDefault = ""); @@ -50,6 +75,16 @@ public: bool LoadRandomGroups(QListWidget *listWidget); QString ProcessResponseTemplateRecursive(const QString &templateText, int depth); + + bool createChatsTable(); + bool saveChat(const QString &name, const QString &type, + HttpServerChat *server, const QString &fontList); + bool updateChat(const QString &name, HttpServerChat *server, + const QString &fontList, int oldPort); + bool deleteChat(int port); + QList loadAllChats(); + + // Проверка подключения к БД bool isConnected() const; @@ -60,6 +95,7 @@ public: private: + // Инициализация базы данных (создание таблицы, если нужно) bool initializeDatabase(); diff --git a/ugeneral.cpp b/ugeneral.cpp index 265dbc4..12a852e 100644 --- a/ugeneral.cpp +++ b/ugeneral.cpp @@ -130,7 +130,7 @@ uGeneral::uGeneral(QWidget *parent) // Инициализируем окна создания m_createNotifyDialog = new FCreateNotify(this); - m_createChatDialog = new FCreateChat(this); + m_createChatDialog = new FCreateChat(db, this); } @@ -1344,12 +1344,11 @@ void uGeneral::loadSettings(){ form->setDatabase(db); table = form->findChild("sgNeiro"); db->LoadTableWidget(table); - db->LoadRandomGroups(ui->lbRandomGroup); - - ui->cbTheme->setCurrentIndex(db->readSetting(ui->cbTheme->objectName(), "0").toInt()); + db->LoadTableWidget(ui->sgWebServers); + loadSavedChats(); } @@ -2097,6 +2096,7 @@ void uGeneral::on_btnSaveSettings_clicked() for (QCheckBox* cb : checkBoxes) { db->writeSetting(cb->objectName(), cb->isChecked() ? "True" : "False"); } + db->SaveTableWidget(ui->sgWebServers); } void uGeneral::execCommand(const QString &sender, const QString &message) @@ -3073,9 +3073,10 @@ void uGeneral::applyStyleSheet(const QString &filename) void uGeneral::on_btnWSCreateChat_clicked() { // Создаем диалог каждый раз - FCreateChat *createDialog = new FCreateChat(this); + FCreateChat *createDialog = new FCreateChat(db, this); connect(createDialog, &FCreateChat::serverCreated, this, &uGeneral::onChatServerCreated); - createDialog->setAttribute(Qt::WA_DeleteOnClose); // Автоматическое удаление при закрытии + connect(createDialog, &FCreateChat::serverUpdated, this, &uGeneral::onChatServerUpdated); + createDialog->setAttribute(Qt::WA_DeleteOnClose); createDialog->exec(); } @@ -3398,7 +3399,7 @@ void uGeneral::on_sgWebServers_cellDoubleClicked(int row, int column) HttpServerChat *existingServer = qobject_cast(serverObj); if (existingServer) { - FCreateChat *createChatDialog = new FCreateChat(this); + FCreateChat *createChatDialog = new FCreateChat(db, this); createChatDialog->loadExistingServer(existingServer, nameItem->text()); connect(createChatDialog, &FCreateChat::serverUpdated, this, &uGeneral::onChatServerUpdated); createChatDialog->setAttribute(Qt::WA_DeleteOnClose); @@ -3670,3 +3671,54 @@ void uGeneral::on_btnThemesFolder_clicked() QDesktopServices::openUrl(url); } + +/** + * @brief Загружает сохраненные чаты из базы данных и создает серверы + */ +void uGeneral::loadSavedChats() +{ + QList chats = db->loadAllChats(); + + for (const ChatSettings &settings : chats) { + if (settings.type.toLower() == "chat") { + // Создаем сервер чата + HttpServerChat *server = new HttpServerChat( + settings.fontList, + settings.port, + settings.backgroundColor, + this + ); + + // Настраиваем сервер + server->setBlockColor(settings.blockColor); + server->setBorderColor(settings.borderColor); + server->setBorderSize(settings.borderSize); + server->setPadding(settings.padding); + server->setTransparency(settings.transparency); + server->setFontFamily(settings.fontFamily); + server->setFontSize(settings.fontSize); + server->setFontColor(settings.fontColor); + server->setFreez(settings.freez); + server->setMessageTimeout(settings.messageTimeout); + server->setDeleteMode(settings.deleteByTime, settings.maxMsgCount); + + // Запускаем сервер + if (server->start()) { + m_chatServers.append(server); + + // Добавляем в таблицу + QString url = QString("http://localhost:%1").arg(settings.port); + addServerToTable(settings.name, "Чат", settings.port, url, server); + + toLog("uGeneral", "loadSavedChats", + QString("Загружен и запущен чат '%1' на порту %2") + .arg(settings.name).arg(settings.port), 0); + } else { + delete server; + toLog("uGeneral", "loadSavedChats", + QString("Не удалось запустить чат '%1' на порту %2") + .arg(settings.name).arg(settings.port), 2); + } + } + } +} diff --git a/ugeneral.h b/ugeneral.h index ee86162..b50c6a8 100644 --- a/ugeneral.h +++ b/ugeneral.h @@ -479,7 +479,7 @@ private: // Обработка эмодзи void processEmotes(QString &message); - + void loadSavedChats(); }; #endif // UGENERAL_H