diff --git a/actionmanager.cpp b/actionmanager.cpp index 6825fa4..a545c73 100644 --- a/actionmanager.cpp +++ b/actionmanager.cpp @@ -37,6 +37,8 @@ bool ActionManager::deleteAction(int id) { if (!m_db) return false; if (!m_db->deleteAction(id)) return false; + // Удаляем все связи с этим действием + m_db->deleteLinksByActionId(id); for (int i = 0; i < m_actions.size(); ++i) { if (m_actions[i].id == id) { @@ -60,3 +62,11 @@ bool ActionManager::loadFromDatabase() emit dataChanged(); return true; } + +ActionData ActionManager::getAction(int id) const +{ + for (const ActionData &a : m_actions) { + if (a.id == id) return a; + } + return ActionData(); // с id = -1 +} diff --git a/actionmanager.h b/actionmanager.h index 75c142a..c4b82f8 100644 --- a/actionmanager.h +++ b/actionmanager.h @@ -15,6 +15,8 @@ public: bool deleteAction(int id); QList getAllActions() const; bool loadFromDatabase(); + ActionData getAction(int id) const; + signals: void actionAdded(const ActionData &action); diff --git a/udatabase.cpp b/udatabase.cpp index 351662f..d7d7bc4 100644 --- a/udatabase.cpp +++ b/udatabase.cpp @@ -1664,3 +1664,139 @@ QList uDataBase::loadAllDonationTriggers() } return list; } + +bool uDataBase::saveEventActionLink(const QString &eventType, const QString &eventName, int actionId) +{ + if (!m_db.isOpen()) { + m_lastError = "Database is not open"; + return false; + } + QString et = eventType.trimmed(); + QString en = eventName.trimmed(); + // Создаём таблицу, если её нет + if (!tableExists("event_action_links")) { + QSqlQuery query(m_db); + QString sql = "CREATE TABLE IF NOT EXISTS event_action_links (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "event_type TEXT NOT NULL," + "event_name TEXT NOT NULL," + "action_id INTEGER NOT NULL," + "created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP" + ")"; + if (!query.exec(sql)) { + m_lastError = query.lastError().text(); + qWarning() << "Failed to create event_action_links table:" << m_lastError; + return false; + } + } + qDebug()<<"Я ТУТ НАХУЙ"; + // Проверяем, нет ли уже такой связи + QSqlQuery checkQuery(m_db); + checkQuery.prepare("SELECT id FROM event_action_links WHERE event_type=:et AND event_name=:en AND action_id=:aid"); + checkQuery.bindValue(":et", et); + checkQuery.bindValue(":en", en); + checkQuery.bindValue(":aid", actionId); + if (checkQuery.exec() && checkQuery.next()) { + m_lastError = "Такая связь уже существует"; + return false; + } + + QSqlQuery query(m_db); + query.prepare("INSERT INTO event_action_links (event_type, event_name, action_id) VALUES (:et, :en, :aid)"); + query.bindValue(":et", eventType); + query.bindValue(":en", eventName); + query.bindValue(":aid", actionId); + + if (!query.exec()) { + m_lastError = query.lastError().text(); + qWarning() << "Failed to save event-action link:" << m_lastError; + return false; + } + return true; +} + +bool uDataBase::deleteEventActionLink(int id) +{ + if (!m_db.isOpen()) { + m_lastError = "Database is not open"; + return false; + } + QSqlQuery query(m_db); + query.prepare("DELETE FROM event_action_links WHERE id = :id"); + query.bindValue(":id", id); + if (!query.exec()) { + m_lastError = query.lastError().text(); + qWarning() << "Failed to delete event-action link:" << m_lastError; + return false; + } + if (query.numRowsAffected() == 0) { + m_lastError = "Связь с указанным ID не найдена"; + return false; + } + return true; +} + +QList uDataBase::getLinksForEvent(const QString &eventType, const QString &eventName) +{ + QList links; + if (!m_db.isOpen()) { + m_lastError = "Database is not open"; + return links; + } + if (!tableExists("event_action_links")) { + return links; + } + QSqlQuery query(m_db); + query.prepare("SELECT id, event_type, event_name, action_id FROM event_action_links WHERE event_type=:et AND event_name=:en"); + query.bindValue(":et", eventType); + query.bindValue(":en", eventName); + if (!query.exec()) { + m_lastError = query.lastError().text(); + qWarning() << "Failed to get links for event:" << m_lastError; + return links; + } + while (query.next()) { + EventActionLink link; + link.id = query.value(0).toInt(); + link.eventType = query.value(1).toString(); + link.eventName = query.value(2).toString(); + link.actionId = query.value(3).toInt(); + links.append(link); + } + return links; +} + +bool uDataBase::deleteLinksForEvent(const QString &eventType, const QString &eventName) +{ + if (!m_db.isOpen()) { + m_lastError = "Database is not open"; + return false; + } + QSqlQuery query(m_db); + query.prepare("DELETE FROM event_action_links WHERE event_type=:et AND event_name=:en"); + query.bindValue(":et", eventType); + query.bindValue(":en", eventName); + if (!query.exec()) { + m_lastError = query.lastError().text(); + qWarning() << "Failed to delete links for event:" << m_lastError; + return false; + } + return true; +} + +bool uDataBase::deleteLinksByActionId(int actionId) +{ + if (!m_db.isOpen()) { + m_lastError = "Database is not open"; + return false; + } + QSqlQuery query(m_db); + query.prepare("DELETE FROM event_action_links WHERE action_id = :aid"); + query.bindValue(":aid", actionId); + if (!query.exec()) { + m_lastError = query.lastError().text(); + qWarning() << "Failed to delete links by action id:" << m_lastError; + return false; + } + return true; +} diff --git a/udatabase.h b/udatabase.h index 9bed1b6..ea2de8d 100644 --- a/udatabase.h +++ b/udatabase.h @@ -68,6 +68,13 @@ struct ActionData { QString notificationSound; }; +struct EventActionLink { + int id; + QString eventType; + QString eventName; + int actionId; +}; + class uDataBase : public QObject { Q_OBJECT @@ -142,6 +149,12 @@ public: int saveDonationTrigger(const DonationTrigger &trigger); bool deleteDonationTrigger(int id); QList loadAllDonationTriggers(); + + bool saveEventActionLink(const QString &eventType, const QString &eventName, int actionId); + bool deleteEventActionLink(int id); + QList getLinksForEvent(const QString &eventType, const QString &eventName); + bool deleteLinksForEvent(const QString &eventType, const QString &eventName); + bool deleteLinksByActionId(int actionId); private: diff --git a/ugeneral.cpp b/ugeneral.cpp index 46338e9..f853277 100644 --- a/ugeneral.cpp +++ b/ugeneral.cpp @@ -169,6 +169,11 @@ uGeneral::uGeneral(QWidget *parent) m_createChatDialog = new FCreateChat(db, this); initializeNotificationSounds(); + + // connect(ui->cbDonateList, QOverload::of(&QComboBox::currentIndexChanged), this, &uGeneral::on_cbDonateList_currentIndexChanged); + // connect(ui->btnLinksAdd, &QPushButton::clicked, this, &uGeneral::on_btnLinksAdd_clicked); + // connect(ui->btnLinksDel, &QPushButton::clicked, this, &uGeneral::on_btnLinksDel_clicked); + updateLinksList(); } // ============================================================================ @@ -3294,6 +3299,7 @@ void uGeneral::on_btnCRGet_clicked() ui->sbCRCost->setValue(0); ui->btnCREdit->setEnabled(false); ui->btnCRDelete->setEnabled(false); + updateDonateList(); } @@ -3492,7 +3498,9 @@ void uGeneral::on_btnCRDelete_clicked() QMessageBox::critical(this, "Ошибка", "Не удалось удалить награду. Проверьте подключение к Twitch и права токена."); return; } - + db->deleteLinksForEvent("reward", title); + updateDonateList(); + updateLinksList(); // 7. Уведомляем об успехе QMessageBox::information(this, "Успех", "Награда успешно удалена."); @@ -3721,6 +3729,7 @@ void uGeneral::updateActionsTable() ui->sgActions->setItem(row, 0, typeItem); ui->sgActions->setItem(row, 1, new QTableWidgetItem(paramStr)); } + updateActionsList(); } void uGeneral::clearActionInputs() @@ -3745,6 +3754,7 @@ void uGeneral::updateDonationTriggersTable() // Сохраним id в UserRole первого столбца для удаления ui->sgDotateTriggers->item(row, 0)->setData(Qt::UserRole, t.id); } + updateDonateList(); } void uGeneral::on_btnDonateAdd_clicked() @@ -3773,11 +3783,17 @@ void uGeneral::on_btnDonateDel_clicked() } int id = ui->sgDotateTriggers->item(row, 0)->data(Qt::UserRole).toInt(); + QString name = ui->sgDotateTriggers->item(row, 0)->text(); // ← добавляем эту строку + if (QMessageBox::question(this, "Подтверждение", "Удалить выбранный триггер?") == QMessageBox::Yes) { m_donationManager->deleteTrigger(id); + db->deleteLinksForEvent("donation", name); + updateDonateList(); // обновляем список событий + updateLinksList(); // обновляем список связей для текущего события } } + void uGeneral::on_sgDotateTriggers_cellDoubleClicked(int row, int column) { Q_UNUSED(column); @@ -3786,3 +3802,126 @@ void uGeneral::on_sgDotateTriggers_cellDoubleClicked(int row, int column) ui->lineEdit->setText(name); ui->lineEdit_2->setText(rule); } + + +void uGeneral::updateDonateList() +{ + ui->cbDonateList->clear(); + + // Награды + for (int row = 0; row < ui->sgCustomRewards->rowCount(); ++row) { + QString name = ui->sgCustomRewards->item(row, 0)->text(); + QVariantMap data; + data["type"] = "reward"; + data["name"] = name; + ui->cbDonateList->addItem("Награды: " + name, data); + } + + // Триггеры донатов + for (int row = 0; row < ui->sgDotateTriggers->rowCount(); ++row) { + QString name = ui->sgDotateTriggers->item(row, 0)->text(); + QVariantMap data; + data["type"] = "donation"; + data["name"] = name; + ui->cbDonateList->addItem("Донаты: " + name, data); + } +} + +void uGeneral::updateActionsList() +{ + ui->cbActionsList->clear(); + auto actions = m_actionManager->getAllActions(); // предполагается, что такой метод есть + for (const ActionData &a : actions) { + QString typeStr; + switch (a.type) { + case 0: typeStr = "Нажатие"; break; + case 1: typeStr = "Звук"; break; + case 2: typeStr = "Уведомление"; break; + default: typeStr = "Неизвестно"; + } + QString param = (a.type == 0) ? a.keyCombination : + (a.type == 1) ? QFileInfo(a.audioFile).fileName() : a.notificationTitle; + ui->cbActionsList->addItem(typeStr + ": " + param, a.id); + } +} + +void uGeneral::updateLinksList() +{ + ui->lvLinks->clear(); + int idx = ui->cbDonateList->currentIndex(); + if (idx < 0) return; + + QVariant data = ui->cbDonateList->itemData(idx); + if (!data.isValid()) return; + QVariantMap map = data.toMap(); + QString eventType = map["type"].toString(); + QString eventName = map["name"].toString(); + + QList links = db->getLinksForEvent(eventType, eventName); + for (const EventActionLink &link : links) { + ActionData action = m_actionManager->getAction(link.actionId); + if (action.id < 0) continue; + QString typeStr; + switch (action.type) { + case 0: typeStr = "Нажатие"; break; + case 1: typeStr = "Звук"; break; + case 2: typeStr = "Уведомление"; break; + } + QString param = (action.type == 0) ? action.keyCombination : + (action.type == 1) ? QFileInfo(action.audioFile).fileName() : action.notificationTitle; + QListWidgetItem *item = new QListWidgetItem(typeStr + ": " + param); + item->setData(Qt::UserRole, link.id); // храним ID связи для удаления + ui->lvLinks->addItem(item); + } +} + +void uGeneral::on_cbDonateList_currentIndexChanged(int index) +{ + Q_UNUSED(index); + updateLinksList(); +} + +void uGeneral::on_btnLinksAdd_clicked() +{ + int eventIdx = ui->cbDonateList->currentIndex(); + int actionIdx = ui->cbActionsList->currentIndex(); + + if (eventIdx < 0 || actionIdx < 0) { + QMessageBox::warning(this, "Ошибка", "Выберите событие и действие"); + return; + } + + QVariant eventData = ui->cbDonateList->itemData(eventIdx); + if (!eventData.isValid()) return; + QVariantMap map = eventData.toMap(); + QString eventType = map["type"].toString(); + QString eventName = map["name"].toString(); + int actionId = ui->cbActionsList->itemData(actionIdx).toInt(); + qDebug() << "НАЖАЛ КНОПКУ"; + if (!db->saveEventActionLink(eventType, eventName, actionId)) { + QMessageBox::critical(this, "Ошибка", "Не удалось добавить связь:\n" + db->lastError()); + } else { + updateLinksList(); + } +} + +void uGeneral::on_btnLinksDel_clicked() +{ + int row = ui->lvLinks->currentRow(); + if (row < 0) { + QMessageBox::warning(this, "Ошибка", "Выберите связь для удаления"); + return; + } + + QListWidgetItem *item = ui->lvLinks->item(row); + int linkId = item->data(Qt::UserRole).toInt(); + + if (QMessageBox::question(this, "Подтверждение", "Удалить выбранную связь?") == QMessageBox::Yes) { + if (!db->deleteEventActionLink(linkId)) { + QMessageBox::critical(this, "Ошибка", "Не удалось удалить связь:\n" + db->lastError()); + } else { + updateLinksList(); // ← перезагружаем список + } + } +} + diff --git a/ugeneral.h b/ugeneral.h index 0f81b3e..3c74c98 100644 --- a/ugeneral.h +++ b/ugeneral.h @@ -387,6 +387,12 @@ private slots: void on_sgDotateTriggers_cellDoubleClicked(int row, int column); void updateDonationTriggersTable(); + void on_cbDonateList_currentIndexChanged(int index); + + void on_btnLinksAdd_clicked(); + + void on_btnLinksDel_clicked(); + public slots: // Установка статуса подключения к Twitch void setTwitchConnected(bool connected); @@ -530,8 +536,9 @@ private: void sendChatResponse(const QString &response); QString cleanMessageFromAllEmotes(const QString& message) const; - - + void updateDonateList(); + void updateActionsList(); + void updateLinksList(); }; #endif // UGENERAL_H diff --git a/ugeneral.ui b/ugeneral.ui index 978a829..69bddb8 100644 --- a/ugeneral.ui +++ b/ugeneral.ui @@ -1492,7 +1492,7 @@ - 10 + 0 @@ -1533,7 +1533,66 @@ - + + + + + Событие: + + + + + + + + 0 + 0 + + + + + + + + + + + + + 0 + + + + + Действие: + + + + + + + + 0 + 0 + + + + + + + + Добавить + + + + + + + Удалить + + + +