Добавил привязку действий к событиям
за баллы канала и за донаты можено можно выполнять списки действий, за каждое событие свой набор
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ public:
|
||||
bool deleteAction(int id);
|
||||
QList<ActionData> getAllActions() const;
|
||||
bool loadFromDatabase();
|
||||
ActionData getAction(int id) const;
|
||||
|
||||
|
||||
signals:
|
||||
void actionAdded(const ActionData &action);
|
||||
|
||||
+136
@@ -1664,3 +1664,139 @@ QList<DonationTrigger> 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<EventActionLink> uDataBase::getLinksForEvent(const QString &eventType, const QString &eventName)
|
||||
{
|
||||
QList<EventActionLink> 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;
|
||||
}
|
||||
|
||||
+13
@@ -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<DonationTrigger> loadAllDonationTriggers();
|
||||
|
||||
bool saveEventActionLink(const QString &eventType, const QString &eventName, int actionId);
|
||||
bool deleteEventActionLink(int id);
|
||||
QList<EventActionLink> getLinksForEvent(const QString &eventType, const QString &eventName);
|
||||
bool deleteLinksForEvent(const QString &eventType, const QString &eventName);
|
||||
bool deleteLinksByActionId(int actionId);
|
||||
private:
|
||||
|
||||
|
||||
|
||||
+140
-1
@@ -169,6 +169,11 @@ uGeneral::uGeneral(QWidget *parent)
|
||||
m_createChatDialog = new FCreateChat(db, this);
|
||||
|
||||
initializeNotificationSounds();
|
||||
|
||||
// connect(ui->cbDonateList, QOverload<int>::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<EventActionLink> 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(); // ← перезагружаем список
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-2
@@ -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
|
||||
|
||||
+61
-2
@@ -1492,7 +1492,7 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_30">
|
||||
<property name="topMargin">
|
||||
<number>10</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnDonateAdd">
|
||||
@@ -1533,7 +1533,66 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_34">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidget_2"/>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_31">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_38">
|
||||
<property name="text">
|
||||
<string>Событие:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cbDonateList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="lvLinks"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_32">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_39">
|
||||
<property name="text">
|
||||
<string>Действие:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cbActionsList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnLinksAdd">
|
||||
<property name="text">
|
||||
<string>Добавить</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnLinksDel">
|
||||
<property name="text">
|
||||
<string>Удалить</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
Reference in New Issue
Block a user