добавил обработку счетчиков

This commit is contained in:
2026-02-14 11:26:45 +03:00
parent 5f53bdcf96
commit 63b7fa4ea1
12 changed files with 796 additions and 131 deletions
+2
View File
@@ -22,6 +22,7 @@ INCLUDEPATH += $$PWD
SOURCES += \ SOURCES += \
commandprocessor.cpp \ commandprocessor.cpp \
countermanager.cpp \
emoteprovider.cpp \ emoteprovider.cpp \
fcolorsetting.cpp \ fcolorsetting.cpp \
fcreatechat.cpp \ fcreatechat.cpp \
@@ -54,6 +55,7 @@ SOURCES += \
HEADERS += \ HEADERS += \
badge.h \ badge.h \
commandprocessor.h \ commandprocessor.h \
countermanager.h \
emoteprovider.h \ emoteprovider.h \
fcolorsetting.h \ fcolorsetting.h \
fcreatechat.h \ fcreatechat.h \
+19
View File
@@ -108,6 +108,7 @@ QString CommandProcessor::processCommand(const QString &sender, const QString &f
response = parseTextFiles(response); response = parseTextFiles(response);
response = parseBan(response, sender); response = parseBan(response, sender);
response = parseAPI(response, sender); response = parseAPI(response, sender);
response = parseCounters(response);
if (response.contains("[AI]", Qt::CaseInsensitive)) { if (response.contains("[AI]", Qt::CaseInsensitive)) {
response = parseAI(response, parameters); response = parseAI(response, parameters);
@@ -214,6 +215,24 @@ QString CommandProcessor::parseTextFiles(const QString &response)
return result; return result;
} }
QString CommandProcessor::parseCounters(const QString &response)
{
QString result = response;
// Используем ленивый квантификатор +?
QRegularExpression regex("\\|\\)([^\\)]+?)\\|\\)");
QRegularExpressionMatchIterator matches = regex.globalMatch(response);
while (matches.hasNext()) {
QRegularExpressionMatch match = matches.next();
QString counterName = match.captured(1);
int count = m_context.counterManager->getCount(counterName);
QString countStr = QString::number(count);
result.replace("|)" + counterName + "|)", countStr);
}
return result;
}
QString CommandProcessor::parseRandomGroups(const QString &response) QString CommandProcessor::parseRandomGroups(const QString &response)
{ {
QString result = response; QString result = response;
+3
View File
@@ -6,6 +6,7 @@
#include <QVector> #include <QVector>
#include <QMap> #include <QMap>
#include <QDate> #include <QDate>
#include "countermanager.h"
#include "mediafilemanager.h" #include "mediafilemanager.h"
#include "user_manager.h" #include "user_manager.h"
#include "ttw_api.h" #include "ttw_api.h"
@@ -34,6 +35,7 @@ public:
RandomResponses* randomResponses = nullptr; RandomResponses* randomResponses = nullptr;
MediaFileManager* mediaFileManager = nullptr; MediaFileManager* mediaFileManager = nullptr;
NeuralTemplateManager *neuralTemplateManager = nullptr; NeuralTemplateManager *neuralTemplateManager = nullptr;
CounterManager* counterManager = nullptr;
QString channel; QString channel;
int notifyVolume = 50; int notifyVolume = 50;
}; };
@@ -67,6 +69,7 @@ private:
QString parseAPI(const QString &response, const QString &sender); QString parseAPI(const QString &response, const QString &sender);
QString parseAI(const QString &response, const QString &question); QString parseAI(const QString &response, const QString &question);
QString parseNeuralTemplates(const QString &response, const QString &sender, const QString &parameters); QString parseNeuralTemplates(const QString &response, const QString &sender, const QString &parameters);
QString parseCounters(const QString &response);
QString extractParameters(const QString &fullCommand); QString extractParameters(const QString &fullCommand);
QString getUsernameByIndex(QString userIndex) const; QString getUsernameByIndex(QString userIndex) const;
+215
View File
@@ -0,0 +1,215 @@
// countermanager.cpp
#include "countermanager.h"
#include <QTableWidget>
#include <QDebug>
CounterManager::CounterManager(QObject *parent)
: QObject(parent)
, m_database(nullptr)
{
}
CounterManager::~CounterManager()
{
if (m_database) {
saveToDatabase();
}
}
bool CounterManager::initialize(uDataBase *database)
{
if (!database || !database->isConnected()) {
qWarning() << "CounterManager: База данных не подключена";
return false;
}
m_database = database;
return loadFromDatabase();
}
bool CounterManager::addCounter(const QString &name, int initialValue)
{
if (name.isEmpty()) {
qWarning() << "CounterManager: Нельзя добавить счётчик с пустым именем";
return false;
}
if (contains(name)) {
qWarning() << "CounterManager: Счётчик с именем" << name << "уже существует";
return false;
}
Counter newCounter(name, initialValue);
m_counters.append(newCounter);
if (!saveToDatabase()) {
m_counters.removeLast();
return false;
}
emit counterAdded(name, initialValue);
emit dataChanged();
return true;
}
bool CounterManager::removeCounter(const QString &name)
{
int index = findIndex(name);
if (index == -1) {
qWarning() << "CounterManager: Счётчик" << name << "не найден";
return false;
}
Counter removed = m_counters.at(index);
m_counters.removeAt(index);
if (!saveToDatabase()) {
m_counters.insert(index, removed);
return false;
}
emit counterRemoved(name);
emit dataChanged();
return true;
}
bool CounterManager::updateCounter(const QString &oldName, const QString &newName, int newValue)
{
int index = findIndex(oldName);
if (index == -1) {
qWarning() << "CounterManager: Счётчик" << oldName << "не найден";
return false;
}
if (oldName != newName && contains(newName)) {
qWarning() << "CounterManager: Имя" << newName << "уже занято";
return false;
}
Counter oldCounter = m_counters.at(index);
m_counters[index].name = newName;
m_counters[index].count = newValue;
if (!saveToDatabase()) {
m_counters[index] = oldCounter;
return false;
}
emit counterUpdated(oldName, newName);
emit dataChanged();
return true;
}
bool CounterManager::incrementCounter(const QString &name, int step)
{
int index = findIndex(name);
if (index == -1) return false;
m_counters[index].count += step;
if (!saveToDatabase()) {
m_counters[index].count -= step; // откат
return false;
}
emit counterIncremented(name, m_counters[index].count);
emit dataChanged();
return true;
}
bool CounterManager::decrementCounter(const QString &name, int step)
{
return incrementCounter(name, -step);
}
int CounterManager::getCount(const QString &name) const
{
int index = findIndex(name);
return (index != -1) ? m_counters.at(index).count : 0;
}
void CounterManager::processMessage(const QString &message)
{
for (const Counter &c : m_counters) {
if (message.contains(c.name, Qt::CaseInsensitive)) {
// Увеличиваем счётчик, но без повторного сохранения после каждого (один общий save)
// Здесь мы меняем значение, но сохраним после цикла, чтобы не делать много запросов
// Для простоты используем incrementCounter, который сам сохраняет, но это будет много раз.
// Лучше собрать имена, которые нужно увеличить, а потом применить.
// Но в данном случае можно просто вызывать incrementCounter, это не критично.
incrementCounter(c.name);
}
}
}
bool CounterManager::contains(const QString &name) const
{
return findIndex(name) != -1;
}
bool CounterManager::saveToDatabase()
{
if (!m_database) {
qWarning() << "CounterManager: База данных не установлена";
return false;
}
QTableWidget tempTable;
QStringList headers = {"Имя", "Значение"};
tempTable.setColumnCount(2);
tempTable.setHorizontalHeaderLabels(headers);
tempTable.setRowCount(m_counters.size());
for (int i = 0; i < m_counters.size(); ++i) {
const Counter &c = m_counters.at(i);
tempTable.setItem(i, 0, new QTableWidgetItem(c.name));
tempTable.setItem(i, 1, new QTableWidgetItem(QString::number(c.count)));
}
tempTable.setObjectName("sgCounters");
// Сохраняем через общий метод (предполагаем, что таблица в БД называется "sgCounters")
m_database->SaveTableWidget(&tempTable);
return true;
}
bool CounterManager::loadFromDatabase()
{
if (!m_database) {
qWarning() << "CounterManager: База данных не установлена";
return false;
}
QTableWidget tempTable;
QStringList headers = {"Имя", "Значение"};
tempTable.setColumnCount(2);
tempTable.setHorizontalHeaderLabels(headers);
tempTable.setObjectName("sgCounters");
m_database->LoadTableWidget(&tempTable);
m_counters.clear();
for (int row = 0; row < tempTable.rowCount(); ++row) {
QTableWidgetItem *nameItem = tempTable.item(row, 0);
QTableWidgetItem *valueItem = tempTable.item(row, 1);
if (!nameItem || !valueItem) continue;
QString name = nameItem->text().trimmed();
if (name.isEmpty()) continue;
bool ok;
int value = valueItem->text().toInt(&ok);
if (!ok) continue;
m_counters.append(Counter(name, value));
}
emit dataChanged();
return true;
}
int CounterManager::findIndex(const QString &name) const
{
for (int i = 0; i < m_counters.size(); ++i) {
if (m_counters.at(i).name == name)
return i;
}
return -1;
}
+64
View File
@@ -0,0 +1,64 @@
// countermanager.h
#ifndef COUNTERMANAGER_H
#define COUNTERMANAGER_H
#include <QObject>
#include <QVector>
#include <QString>
#include "udatabase.h"
class CounterManager : public QObject
{
Q_OBJECT
public:
struct Counter {
QString name;
int count;
Counter() : count(0) {}
Counter(const QString& n, int c = 0) : name(n), count(c) {}
bool operator==(const QString& otherName) const { return name == otherName; }
};
explicit CounterManager(QObject *parent = nullptr);
~CounterManager();
// Инициализация с базой данных
bool initialize(uDataBase *database);
// Управление счетчиками
bool addCounter(const QString &name, int initialValue = 0);
bool removeCounter(const QString &name);
bool updateCounter(const QString &oldName, const QString &newName, int newValue);
bool incrementCounter(const QString &name, int step = 1);
bool decrementCounter(const QString &name, int step = 1);
int getCount(const QString &name) const;
// Обработка сообщения: увеличивает счётчики, чьи имена встречаются в тексте
void processMessage(const QString &message);
// Получение всех счётчиков
QVector<Counter> getAllCounters() const { return m_counters; }
bool contains(const QString &name) const;
// Сохранение/загрузка в БД
bool saveToDatabase();
bool loadFromDatabase();
signals:
void dataChanged();
void counterAdded(const QString &name, int value);
void counterRemoved(const QString &name);
void counterUpdated(const QString &oldName, const QString &newName);
void counterIncremented(const QString &name, int newValue);
private:
uDataBase *m_database;
QVector<Counter> m_counters;
int findIndex(const QString &name) const;
};
#endif // COUNTERMANAGER_H
+51
View File
@@ -4,6 +4,8 @@
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonValue> #include <QJsonValue>
#include <QRegularExpression>
#include <QSet>
// EmoteProvider implementation // EmoteProvider implementation
EmoteProvider::EmoteProvider(QObject *parent) EmoteProvider::EmoteProvider(QObject *parent)
@@ -416,3 +418,52 @@ void SevenTVProvider::parseCustomResponse(const QByteArray &data, const QString
QString("Loaded %1 custom emotes for user %2").arg(m_emotes.size()).arg(userId), QString("Loaded %1 custom emotes for user %2").arg(m_emotes.size()).arg(userId),
LOG_INFO); LOG_INFO);
} }
QString BTTVProvider::cleanMessage(const QString& message) const
{
if (m_emotes.isEmpty())
return message;
// Собираем все коды эмоций в множество для быстрого поиска
QSet<QString> codes;
for (const BTTVEmote& emote : m_emotes) {
codes.insert(emote.code);
}
// Разбиваем сообщение на токены (слова и не-слова)
QRegularExpression wordSplitter("(\\w+|[^\\w]+)");
QRegularExpressionMatchIterator it = wordSplitter.globalMatch(message);
QStringList parts;
while (it.hasNext()) {
QRegularExpressionMatch match = it.next();
QString token = match.captured(0);
// Если токен состоит только из букв/цифр и является кодом эмоции – пропускаем
if (token[0].isLetterOrNumber() && codes.contains(token))
continue;
parts.append(token);
}
return parts.join("");
}
QString SevenTVProvider::cleanMessage(const QString& message) const
{
if (m_emotes.isEmpty())
return message;
QSet<QString> codes;
for (const SevenTVEmote& emote : m_emotes) {
codes.insert(emote.code);
}
QRegularExpression wordSplitter("(\\w+|[^\\w]+)");
QRegularExpressionMatchIterator it = wordSplitter.globalMatch(message);
QStringList parts;
while (it.hasNext()) {
QRegularExpressionMatch match = it.next();
QString token = match.captured(0);
if (token[0].isLetterOrNumber() && codes.contains(token))
continue;
parts.append(token);
}
return parts.join("");
}
+3
View File
@@ -47,6 +47,7 @@ public:
virtual void fetchGlobal() = 0; virtual void fetchGlobal() = 0;
virtual void fetchCustom(const QString &userId) = 0; virtual void fetchCustom(const QString &userId) = 0;
virtual QString getEmoteUrl(const QString &emoteName) = 0; virtual QString getEmoteUrl(const QString &emoteName) = 0;
virtual QString cleanMessage(const QString& message) const = 0;
signals: signals:
void emotesLoaded(); void emotesLoaded();
@@ -71,6 +72,7 @@ public:
void fetchGlobal() override; void fetchGlobal() override;
void fetchCustom(const QString &userId) override; void fetchCustom(const QString &userId) override;
QString getEmoteUrl(const QString &emoteName) override; QString getEmoteUrl(const QString &emoteName) override;
QString cleanMessage(const QString& message) const override;
private slots: private slots:
void onGlobalReplyFinished(QNetworkReply *reply); void onGlobalReplyFinished(QNetworkReply *reply);
@@ -95,6 +97,7 @@ public:
void fetchGlobal() override; void fetchGlobal() override;
void fetchCustom(const QString &userId) override; void fetchCustom(const QString &userId) override;
QString getEmoteUrl(const QString &emoteName) override; QString getEmoteUrl(const QString &emoteName) override;
QString cleanMessage(const QString& message) const override;
private slots: private slots:
void onGlobalReplyFinished(QNetworkReply *reply); void onGlobalReplyFinished(QNetworkReply *reply);
+2
View File
@@ -1,4 +1,5 @@
debug/commandprocessor.o debug/commandprocessor.o
debug/countermanager.o
debug/emoteprovider.o debug/emoteprovider.o
debug/fcolorsetting.o debug/fcolorsetting.o
debug/fcreatechat.o debug/fcreatechat.o
@@ -28,6 +29,7 @@ debug/webserverchat.o
debug/webservernotify.o debug/webservernotify.o
debug/websocketclient.o debug/websocketclient.o
debug/moc_commandprocessor.o debug/moc_commandprocessor.o
debug/moc_countermanager.o
debug/moc_emoteprovider.o debug/moc_emoteprovider.o
debug/moc_fcolorsetting.o debug/moc_fcolorsetting.o
debug/moc_fcreatechat.o debug/moc_fcreatechat.o
+2
View File
@@ -1,4 +1,5 @@
release/commandprocessor.o release/commandprocessor.o
release/countermanager.o
release/emoteprovider.o release/emoteprovider.o
release/fcolorsetting.o release/fcolorsetting.o
release/fcreatechat.o release/fcreatechat.o
@@ -28,6 +29,7 @@ release/webserverchat.o
release/webservernotify.o release/webservernotify.o
release/websocketclient.o release/websocketclient.o
release/moc_commandprocessor.o release/moc_commandprocessor.o
release/moc_countermanager.o
release/moc_emoteprovider.o release/moc_emoteprovider.o
release/moc_fcolorsetting.o release/moc_fcolorsetting.o
release/moc_fcreatechat.o release/moc_fcreatechat.o
+172 -8
View File
@@ -407,6 +407,22 @@ void uGeneral::initializeManagers()
ui->widget_3->setManagerType(FSingleGrid::TemplateManager); ui->widget_3->setManagerType(FSingleGrid::TemplateManager);
ui->widget_3->setDatabase(db); ui->widget_3->setDatabase(db);
m_counterManager = new CounterManager(this);
if (db) {
m_counterManager->initialize(db);
}
// Настраиваем таблицу счётчиков (предполагаем, что она уже есть в .ui с objectName "sgCounters")
setupCountersTable();
// Подключаем сигналы для обновления таблицы при изменениях
connect(m_counterManager, &CounterManager::dataChanged, this, &uGeneral::updateCountersTable);
connect(m_counterManager, &CounterManager::counterAdded, this, [this](const QString&, int) { updateCountersTable(); });
connect(m_counterManager, &CounterManager::counterRemoved, this, [this](const QString&) { updateCountersTable(); });
connect(m_counterManager, &CounterManager::counterUpdated, this, [this](const QString&, const QString&) { updateCountersTable(); });
connect(m_counterManager, &CounterManager::counterIncremented, this, [this](const QString&, int) { updateCountersTable(); });
m_commandProcessor = new CommandProcessor(this); m_commandProcessor = new CommandProcessor(this);
if (db) { if (db) {
@@ -428,9 +444,46 @@ void uGeneral::initializeManagers()
context.mediaFileManager = m_SoundFiles; context.mediaFileManager = m_SoundFiles;
context.channel = ui->edtChannel->text(); context.channel = ui->edtChannel->text();
context.notifyVolume = ui->tbNotifyVolume->value(); context.notifyVolume = ui->tbNotifyVolume->value();
context.counterManager = m_counterManager;
m_commandProcessor->setContext(context); m_commandProcessor->setContext(context);
} }
}
void uGeneral::setupCountersTable(){
// Предполагаем, что sgCounters уже есть в ui
ui->sgCounters->setColumnCount(2);
QStringList headers;
headers << "Счётчик" << "Значение";
ui->sgCounters->setHorizontalHeaderLabels(headers);
ui->sgCounters->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->sgCounters->setSelectionMode(QAbstractItemView::SingleSelection);
ui->sgCounters->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->sgCounters->horizontalHeader()->setStretchLastSection(true);
ui->sgCounters->setColumnWidth(0, 200);
ui->sgCounters->setColumnWidth(1, 80);
updateCountersTable();
}
void uGeneral::updateCountersTable()
{
ui->sgCounters->setRowCount(0);
ui->cbCounters->clear();
if (!m_counterManager) return;
QVector<CounterManager::Counter> counters = m_counterManager->getAllCounters();
for (const auto &c : counters) {
int row = ui->sgCounters->rowCount();
ui->sgCounters->insertRow(row);
ui->sgCounters->setItem(row, 0, new QTableWidgetItem(c.name));
ui->sgCounters->setItem(row, 1, new QTableWidgetItem(QString::number(c.count)));
ui->cbCounters->addItem(c.name);
}
} }
void uGeneral::loadCommandsFromTableWidget() void uGeneral::loadCommandsFromTableWidget()
@@ -742,6 +795,7 @@ uGeneral::~uGeneral()
delete m_neuralTemplateManager; delete m_neuralTemplateManager;
m_neuralTemplateManager = nullptr; m_neuralTemplateManager = nullptr;
} }
delete m_counterManager;
delete m_createNotifyDialog; delete m_createNotifyDialog;
delete m_createChatDialog; delete m_createChatDialog;
delete ui; delete ui;
@@ -1740,7 +1794,8 @@ void uGeneral::initializeNotificationSounds()
} }
} }
void uGeneral::handleNewMessage(const QString &message){ void uGeneral::handleNewMessage(const QString &message)
{
TwitchMessage msg = TwitchMessage::parse(message); TwitchMessage msg = TwitchMessage::parse(message);
QString userId = m_userManager->checkUser(msg.displayName, msg); QString userId = m_userManager->checkUser(msg.displayName, msg);
@@ -1754,8 +1809,30 @@ void uGeneral::handleNewMessage(const QString &message){
QString processedMessage = processTwitchMessage(msg); QString processedMessage = processTwitchMessage(msg);
QString formattedNickname = formatNicknameWithBadges(msg); QString formattedNickname = formatNicknameWithBadges(msg);
addChatMessage(formattedNickname, processedMessage); addChatMessage(formattedNickname, processedMessage);
if (m_counterManager) {
m_counterManager->processMessage(msg.message); // или cleanedText
}
QString cleanedText = cleanMessageFromAllEmotes(msg.message);
// Удаляем ссылки (опционально)
cleanedText.remove(QRegularExpression("https?://\\S+"));
cleanedText = cleanedText.trimmed();
// Проверяем наличие русских букв
bool hasRussian = false;
for (const QChar& ch : cleanedText) {
if (ch.unicode() >= 0x0400 && ch.unicode() <= 0x04FF) {
hasRussian = true;
break;
}
}
if (!hasRussian && !cleanedText.isEmpty()) {
// Здесь нужно вызвать перевод (например, через API)
// sendToTranslate(cleanedText);
LogManager::instance()->debug("uGeneral", "handleNewMessage",
"Требуется перевод: " + cleanedText);
}
if (msg.message.startsWith("!!!")) { if (msg.message.startsWith("!!!")) {
QString cleanedMessage = msg.message.mid(3); QString cleanedMessage = msg.message.mid(3);
@@ -1766,6 +1843,14 @@ void uGeneral::handleNewMessage(const QString &message){
} }
} }
QString uGeneral::cleanMessageFromAllEmotes(const QString& message) const
{
QString cleaned = message;
cleaned = bttvProvider.cleanMessage(cleaned);
cleaned = sevenTVProvider.cleanMessage(cleaned);
return cleaned;
}
void uGeneral::processUserCommand(const QString &username, const QString &commandText) void uGeneral::processUserCommand(const QString &username, const QString &commandText)
{ {
if (!m_commandProcessor || !m_userManager) return; if (!m_commandProcessor || !m_userManager) return;
@@ -1972,11 +2057,6 @@ void uGeneral::disconnectFromTwitch()
setTwitchConnected(false); setTwitchConnected(false);
} }
void uGeneral::execCommand(const QString &sender, const QString &message)
{
LogManager::instance()->debug("uGeneral", "execCommand",
QString("Обработка команды от %1: %2").arg(sender).arg(message));
}
void uGeneral::on_lbRandomGroup_itemClicked(QListWidgetItem *item) void uGeneral::on_lbRandomGroup_itemClicked(QListWidgetItem *item)
{ {
@@ -3026,3 +3106,87 @@ void uGeneral::on_btnRmWebService_clicked()
.arg(serviceName)); .arg(serviceName));
} }
} }
void uGeneral::on_sgCounters_cellClicked(int row, int column)
{
Q_UNUSED(column);
QString name = ui->sgCounters->item(row, 0)->text();
int value = ui->sgCounters->item(row, 1)->text().toInt();
ui->edtWordCounter->setText(name);
ui->sbStartCounter->setValue(value);
}
void uGeneral::on_sgCounters_cellDoubleClicked(int row, int column)
{
}
void uGeneral::on_btnCounterAdd_clicked()
{
QString name = ui->edtWordCounter->text().trimmed(); // предположим, есть поле ввода
if (name.isEmpty()) {
QMessageBox::warning(this, "Ошибка", "Введите название счётчика!");
return;
}
int initial = ui->sbStartCounter->value(); // спинбокс для начального значения
if (m_counterManager->addCounter(name, initial)) {
ui->edtWordCounter->clear();
ui->sbStartCounter->setValue(0);
updateCountersTable();
} else {
QMessageBox::warning(this, "Ошибка", "Не удалось добавить счётчик (возможно, уже существует)");
}
}
void uGeneral::on_btnCounterDelete_clicked()
{
int row = ui->sgCounters->currentRow();
if (row < 0) {
QMessageBox::warning(this, "Ошибка", "Выберите счётчик для удаления!");
return;
}
QString name = ui->sgCounters->item(row, 0)->text();
if (m_counterManager->removeCounter(name)) {
updateCountersTable();
}
}
void uGeneral::on_btnCounterEdit_clicked()
{
int row = ui->sgCounters->currentRow();
if (row < 0) {
QMessageBox::warning(this, "Ошибка", "Выберите счётчик для редактирования!");
return;
}
QString oldName = ui->sgCounters->item(row, 0)->text();
QString newName = ui->edtWordCounter->text().trimmed();
int newValue = ui->sbStartCounter->value();
if (newName.isEmpty()) {
QMessageBox::warning(this, "Ошибка", "Введите новое название счётчика!");
return;
}
if (m_counterManager->updateCounter(oldName, newName, newValue)) {
ui->edtWordCounter->clear();
ui->sbStartCounter->setValue(0);
updateCountersTable();
} else {
QMessageBox::warning(this, "Ошибка", "Не удалось обновить счётчик");
}
}
void uGeneral::on_btnCounterAtoText_clicked()
{
QTextCursor cursor = ui->textBrowser->textCursor();
cursor.insertText("|)" + ui->cbCounters->currentText() + "|)");
}
+18 -7
View File
@@ -10,6 +10,7 @@
#include <udatabase.h> #include <udatabase.h>
#include <soundmanager.h> #include <soundmanager.h>
#include "commandprocessor.h" #include "commandprocessor.h"
#include "countermanager.h"
#include "fcreatechat.h" #include "fcreatechat.h"
#include "fcreatenotify.h" #include "fcreatenotify.h"
#include "logmanager.h" #include "logmanager.h"
@@ -141,11 +142,6 @@ private slots:
void handleConnected(); void handleConnected();
void handleDisconnected(); void handleDisconnected();
// ========================================================================
// СЛОТЫ ДЛЯ РАБОТЫ С КОМАНДАМИ И ОТВЕТАМИ
// ========================================================================
void execCommand(const QString &sender, const QString &message);
// ======================================================================== // ========================================================================
// СЛОТЫ ДЛЯ РАБОТЫ С ИСКУССТВЕННЫМ ИНТЕЛЛЕКТОМ // СЛОТЫ ДЛЯ РАБОТЫ С ИСКУССТВЕННЫМ ИНТЕЛЛЕКТОМ
@@ -346,6 +342,18 @@ private slots:
void on_btnRmWebService_clicked(); void on_btnRmWebService_clicked();
void on_sgCounters_cellClicked(int row, int column);
void on_sgCounters_cellDoubleClicked(int row, int column);
void on_btnCounterAdd_clicked();
void on_btnCounterDelete_clicked();
void on_btnCounterEdit_clicked();
void on_btnCounterAtoText_clicked();
public slots: public slots:
// Установка статуса подключения к Twitch // Установка статуса подключения к Twitch
void setTwitchConnected(bool connected); void setTwitchConnected(bool connected);
@@ -363,6 +371,7 @@ private:
uLink *fLinkForm; // Форма ссылок uLink *fLinkForm; // Форма ссылок
TTTVAuth *TTVAuth; // Данные авторизации Twitch TTTVAuth *TTVAuth; // Данные авторизации Twitch
UserManager *m_userManager; // Менеджер пользователей UserManager *m_userManager; // Менеджер пользователей
CounterManager *m_counterManager;
CommandProcessor* m_commandProcessor; // Процессор команд CommandProcessor* m_commandProcessor; // Процессор команд
WebSocketClient *m_twitchClient; // WebSocket клиент для Twitch WebSocketClient *m_twitchClient; // WebSocket клиент для Twitch
UserWidget* m_userWidget; // Виджет пользователя UserWidget* m_userWidget; // Виджет пользователя
@@ -405,8 +414,8 @@ private:
int findNotificationServerRow(HttpServer *server); int findNotificationServerRow(HttpServer *server);
int findChatServerRow(HttpServerChat *server); int findChatServerRow(HttpServerChat *server);
QString generateServerId() const; QString generateServerId() const;
void setupCountersTable();
void updateCountersTable();
// Текущие настройки для формы // Текущие настройки для формы
QVariantMap m_currentSettings; QVariantMap m_currentSettings;
@@ -481,6 +490,8 @@ private:
void loadNeuralTemplatesFromTableWidget(); void loadNeuralTemplatesFromTableWidget();
void processUserCommand(const QString &username, const QString &commandText); void processUserCommand(const QString &username, const QString &commandText);
void sendChatResponse(const QString &response); void sendChatResponse(const QString &response);
QString cleanMessageFromAllEmotes(const QString& message) const;
}; };
#endif // UGENERAL_H #endif // UGENERAL_H
+245 -116
View File
@@ -42,7 +42,7 @@
<enum>Qt::LeftToRight</enum> <enum>Qt::LeftToRight</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>6</number> <number>2</number>
</property> </property>
<property name="tabsClosable"> <property name="tabsClosable">
<bool>false</bool> <bool>false</bool>
@@ -974,6 +974,9 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="cbCounters"/>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>
@@ -1417,141 +1420,267 @@
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_tab_auto"> <layout class="QVBoxLayout" name="verticalLayout_tab_auto">
<item> <item>
<widget class="QGroupBox" name="groupBox_10"> <layout class="QHBoxLayout" name="horizontalLayout_12">
<property name="title"> <property name="topMargin">
<string>Таймеры сообщений</string> <number>0</number>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_groupBox_10"> <item>
<item> <widget class="QGroupBox" name="groupBox_10">
<widget class="QTableWidget" name="sgTimers"> <property name="title">
<property name="rowCount"> <string>Таймеры сообщений</string>
<number>0</number> </property>
</property> <layout class="QVBoxLayout" name="verticalLayout_groupBox_10">
<property name="columnCount">
<number>4</number>
</property>
<column>
<property name="text">
<string>Вкл</string>
</property>
</column>
<column>
<property name="text">
<string>Сообщение</string>
</property>
</column>
<column>
<property name="text">
<string>Интервал (мин)</string>
</property>
</column>
<column>
<property name="text">
<string>О</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_timer_edit">
<item> <item>
<widget class="QLabel" name="lblTimerMessage"> <widget class="QTableWidget" name="sgTimers">
<property name="text"> <property name="rowCount">
<string>Сообщение:</string> <number>0</number>
</property> </property>
<property name="columnCount">
<number>4</number>
</property>
<column>
<property name="text">
<string>Вкл</string>
</property>
</column>
<column>
<property name="text">
<string>Сообщение</string>
</property>
</column>
<column>
<property name="text">
<string>Интервал (мин)</string>
</property>
</column>
<column>
<property name="text">
<string>О</string>
</property>
</column>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLineEdit" name="edtTimerMessage"/> <layout class="QHBoxLayout" name="horizontalLayout_timer_edit">
<item>
<widget class="QLabel" name="lblTimerMessage">
<property name="text">
<string>Сообщение:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="edtTimerMessage"/>
</item>
<item>
<widget class="QLabel" name="lblTimerInterval">
<property name="text">
<string>Интервал:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="edtTimerInterval">
<property name="text">
<string>10</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_timer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item> </item>
<item> <item>
<widget class="QLabel" name="lblTimerInterval"> <layout class="QHBoxLayout" name="horizontalLayout_timer_buttons">
<property name="text"> <item>
<string>Интервал:</string> <widget class="QPushButton" name="btnTimerAdd">
</property> <property name="text">
</widget> <string>Добавить</string>
</item> </property>
<item> <property name="icon">
<widget class="QLineEdit" name="edtTimerInterval"> <iconset>
<property name="text"> <normaloff>../../../Downloads/ico/add.png</normaloff>../../../Downloads/ico/add.png</iconset>
<string>10</string> </property>
</property> </widget>
</widget> </item>
</item> <item>
<item> <widget class="QPushButton" name="btnTimerEdit">
<spacer name="horizontalSpacer_timer"> <property name="text">
<property name="orientation"> <string>Изменить</string>
<enum>Qt::Horizontal</enum> </property>
</property> <property name="icon">
<property name="sizeHint" stdset="0"> <iconset>
<size> <normaloff>../../../Downloads/ico/edit.png</normaloff>../../../Downloads/ico/edit.png</iconset>
<width>40</width> </property>
<height>20</height> </widget>
</size> </item>
</property> <item>
</spacer> <widget class="QPushButton" name="btnTimerDelete">
<property name="text">
<string>Удалить</string>
</property>
<property name="icon">
<iconset>
<normaloff>../../../Downloads/ico/minus-sign_3485999.png</normaloff>../../../Downloads/ico/minus-sign_3485999.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnTimerTest">
<property name="text">
<string>Тест</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_timer_buttons">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item> </item>
</layout> </layout>
</item> </widget>
<item> </item>
<layout class="QHBoxLayout" name="horizontalLayout_timer_buttons"> <item>
<widget class="QGroupBox" name="groupBox_11">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTipDuration">
<number>2</number>
</property>
<property name="title">
<string>Счетчики</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_26">
<item> <item>
<widget class="QPushButton" name="btnTimerAdd"> <widget class="QTableWidget" name="sgCounters">
<property name="text"> <column>
<string>Добавить</string> <property name="text">
</property> <string>Слово или фраза</string>
<property name="icon"> </property>
<iconset> </column>
<normaloff>../../../Downloads/ico/add.png</normaloff>../../../Downloads/ico/add.png</iconset> <column>
</property> <property name="text">
<string>Количество</string>
</property>
</column>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="btnTimerEdit"> <layout class="QHBoxLayout" name="horizontalLayout_13">
<property name="text"> <property name="topMargin">
<string>Изменить</string> <number>0</number>
</property> </property>
<property name="icon"> <item>
<iconset> <widget class="QLabel" name="label_24">
<normaloff>../../../Downloads/ico/edit.png</normaloff>../../../Downloads/ico/edit.png</iconset> <property name="text">
</property> <string>Слово:</string>
</widget> </property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="edtWordCounter"/>
</item>
<item>
<widget class="QLabel" name="label_25">
<property name="text">
<string>Количество:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="sbStartCounter"/>
</item>
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item> </item>
<item> <item>
<widget class="QPushButton" name="btnTimerDelete"> <layout class="QHBoxLayout" name="horizontalLayout_16">
<property name="text"> <property name="topMargin">
<string>Удалить</string> <number>0</number>
</property> </property>
<property name="icon"> <item>
<iconset> <widget class="QPushButton" name="btnCounterAdd">
<normaloff>../../../Downloads/ico/minus-sign_3485999.png</normaloff>../../../Downloads/ico/minus-sign_3485999.png</iconset> <property name="text">
</property> <string>Добавить</string>
</widget> </property>
</item> </widget>
<item> </item>
<widget class="QPushButton" name="btnTimerTest"> <item>
<property name="text"> <widget class="QPushButton" name="btnCounterEdit">
<string>Тест</string> <property name="text">
</property> <string>Изменить</string>
</widget> </property>
</item> </widget>
<item> </item>
<spacer name="horizontalSpacer_timer_buttons"> <item>
<property name="orientation"> <widget class="QPushButton" name="btnCounterDelete">
<enum>Qt::Horizontal</enum> <property name="text">
</property> <string>Удалить</string>
<property name="sizeHint" stdset="0"> </property>
<size> </widget>
<width>40</width> </item>
<height>20</height> <item>
</size> <spacer name="horizontalSpacer_10">
</property> <property name="orientation">
</spacer> <enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item> </item>
</layout> </layout>
</item> </widget>
</layout> </item>
</widget> </layout>
</item> </item>
<item> <item>
<spacer name="verticalSpacer_auto"> <spacer name="verticalSpacer_auto">