Added handling for event types (Balance, Phone) and respective processing logic in EventHandler. Introduced support for tracking and updating event statuses both locally and through network APIs. Enhanced data integrity and clarity by expanding the EventInfo model and associated database management.
265 lines
9.8 KiB
C++
265 lines
9.8 KiB
C++
#include "DeviceWidget.h"
|
||
#include <QVBoxLayout>
|
||
#include <QLabel>
|
||
#include <QPixmap>
|
||
#include <QImage>
|
||
#include <QPushButton>
|
||
#include <QCoreApplication>
|
||
#include <QPointer>
|
||
#include <QPropertyAnimation>
|
||
#include <QGraphicsScene>
|
||
#include <QJsonObject>
|
||
#include <QMessageBox>
|
||
#include <QThread>
|
||
|
||
#include "bank/BankSettingsWindow.h"
|
||
#include "dao/ApplicationDAO.h"
|
||
#include "db/ApplicationInfo.h"
|
||
#include "net/NetworkService.h"
|
||
|
||
|
||
QString getColorByStatus(const ApplicationInfo &app) {
|
||
if (!app.install) {
|
||
return "black";
|
||
}
|
||
if (app.status == "active") {
|
||
if (!app.pinCodeChecked) {
|
||
return "orange";
|
||
}
|
||
return "green";
|
||
} else if (app.status == "off") {
|
||
return "red";
|
||
} else {
|
||
return "red";
|
||
}
|
||
}
|
||
|
||
void sendBankStatus(const QString &deviceId, const QString &code, const QString &status) {
|
||
QJsonObject obj;
|
||
obj["code"] = code;
|
||
obj["status"] = status;
|
||
|
||
auto *paymentThread = new QThread;
|
||
auto *networkService = new NetworkService;
|
||
networkService->moveToThread(paymentThread);
|
||
networkService->setDeviceId(deviceId);
|
||
networkService->setPayload(QJsonDocument(obj).toJson());
|
||
QObject::connect(paymentThread, &QThread::started, networkService, &NetworkService::postAppStatus);
|
||
QObject::connect(networkService, &NetworkService::finished, paymentThread, &QThread::quit);
|
||
QObject::connect(networkService, &NetworkService::finished, networkService, &QObject::deleteLater);
|
||
QObject::connect(paymentThread, &QThread::finished, paymentThread, &QThread::deleteLater);
|
||
paymentThread->start();
|
||
}
|
||
|
||
void DeviceWidget::buildBankRow(const ApplicationInfo &app, QWidget *rowWidget, QWidget *parent) {
|
||
rowWidget->setContentsMargins(0, 0, 0, 0);
|
||
rowWidget->setStyleSheet(
|
||
"background-color: rgba(0, 0, 0, 0.6);" // полупрозрачный фон
|
||
"border-radius: 4px;" // скруглённые углы, если нужно
|
||
);
|
||
|
||
// вешаем на контейнер ваш QHBoxLayout
|
||
auto *hbox = new QHBoxLayout(rowWidget);
|
||
hbox->setContentsMargins(2, 1, 1, 1);
|
||
hbox->setSpacing(0);
|
||
|
||
auto *icon = new QLabel(parent);
|
||
QPixmap pixmap(QString("%1/images/%2_icon.png").arg(QCoreApplication::applicationDirPath(), app.code));
|
||
icon->setPixmap(pixmap);
|
||
icon->setPixmap(pixmap.scaled(18, 18, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||
icon->setStyleSheet(
|
||
"background-color: transparent;"
|
||
"margin: 0px;"
|
||
);
|
||
|
||
|
||
auto *label = new QLabel(app.name, parent);
|
||
label->setStyleSheet(
|
||
"background-color: transparent;"
|
||
"margin: 0px;"
|
||
"font-size: 10px;"
|
||
"color: white;"
|
||
);
|
||
|
||
auto *circle = new QLabel(parent);
|
||
circle->setFixedSize(12, 12);
|
||
const QString color = getColorByStatus(app);
|
||
circle->setStyleSheet(
|
||
"margin: 0px;"
|
||
"background-color: " + color + "; "
|
||
"border-radius: 6px;"
|
||
);
|
||
// собираем
|
||
if (app.install && app.pinCodeChecked && (app.status == "active" || app.status == "off")) {
|
||
auto *btn1 = new QPushButton(parent);
|
||
bool turnOn = app.pinCodeChecked && app.status == "active";
|
||
QIcon btnIcon(
|
||
QCoreApplication::applicationDirPath() + (turnOn ? "/images/turn_off.png" : "/images/turn_on.png"));
|
||
btn1->setIcon(btnIcon);
|
||
btn1->setIconSize(QSize(16, 16));
|
||
btn1->setFlat(true);
|
||
btn1->setStyleSheet(
|
||
"margin: 0px;"
|
||
"background-color: transparent;"
|
||
"border: none;"
|
||
);
|
||
|
||
connect(btn1, &QPushButton::clicked, this, [app]() {
|
||
QString newStatus = app.status == "active" ? "off" : "active";
|
||
QMessageBox msgBox(nullptr);
|
||
msgBox.setWindowTitle(tr("Подтверждение"));
|
||
msgBox.setText(
|
||
"Вы уверены, что хотите "
|
||
+ QString(newStatus == "off" ? "отключить от работы" : "включить")
|
||
+ " данный банк: "
|
||
+ app.name + "?");
|
||
|
||
QPushButton *deleteBtn = msgBox.addButton(tr(newStatus == "off" ? "Отключить" : "Включить"),
|
||
QMessageBox::AcceptRole);
|
||
QPushButton *closeBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||
msgBox.setDefaultButton(closeBtn);
|
||
msgBox.setModal(true);
|
||
msgBox.exec();
|
||
|
||
if (msgBox.clickedButton() == deleteBtn) {
|
||
if (!ApplicationDAO::update(app.id, app.pinCode, app.comment, newStatus)) {
|
||
qDebug() << "Cant update bank data";
|
||
} else {
|
||
sendBankStatus(app.deviceId, app.code, newStatus);
|
||
}
|
||
} else {
|
||
// просто закрыли — ничего не делаем
|
||
}
|
||
});
|
||
hbox->addWidget(btn1);
|
||
}
|
||
|
||
auto *btn2 = new QPushButton(parent);
|
||
QIcon btn2Icon(QCoreApplication::applicationDirPath() + "/images/cogwheel.png");
|
||
btn2->setIcon(btn2Icon);
|
||
btn2->setIconSize(QSize(16, 16));
|
||
btn2->setFlat(true);
|
||
btn2->setStyleSheet(
|
||
"margin: 0px;"
|
||
"background-color: transparent;"
|
||
"border: none;"
|
||
);
|
||
// в конструкторе окна или сразу после создания btn2:
|
||
connect(btn2, &QPushButton::pressed, this, [btn2] {
|
||
auto anim = new QPropertyAnimation(btn2, "geometry");
|
||
anim->setDuration(120);
|
||
QRect orig = btn2->geometry();
|
||
QRect smaller = orig.adjusted(orig.width() * 0.05,
|
||
orig.height() * 0.05,
|
||
-orig.width() * 0.05,
|
||
-orig.height() * 0.05);
|
||
anim->setStartValue(orig);
|
||
anim->setKeyValueAt(0.5, smaller);
|
||
anim->setEndValue(orig);
|
||
anim->setEasingCurve(QEasingCurve::InOutQuad);
|
||
anim->start(QAbstractAnimation::DeleteWhenStopped);
|
||
});
|
||
|
||
setOpenBanksSettings(btn2);
|
||
|
||
hbox->addWidget(icon);
|
||
hbox->addWidget(label, 1);
|
||
hbox->addWidget(circle);
|
||
hbox->addWidget(btn2);
|
||
|
||
// hbox->addStretch();
|
||
}
|
||
|
||
void DeviceWidget::setOpenBanksSettings(QPushButton *button) {
|
||
QString deviceId = m_device.id;
|
||
QString deviceName = m_device.name;
|
||
connect(button, &QPushButton::clicked, this, [deviceId, deviceName]() {
|
||
static QPointer<BankSettingsWindow> bankSettingsWindow;
|
||
|
||
// Если окна нет (либо ещё не было создано, либо уже удалилось) — создаём заново
|
||
if (!bankSettingsWindow) {
|
||
bankSettingsWindow = new BankSettingsWindow(nullptr, deviceId, deviceName);
|
||
bankSettingsWindow->setWindowFlags(bankSettingsWindow->windowFlags() | Qt::Window);
|
||
bankSettingsWindow->setAttribute(Qt::WA_DeleteOnClose);
|
||
}
|
||
|
||
// Показать/поднять/активировать
|
||
bankSettingsWindow->show();
|
||
bankSettingsWindow->raise();
|
||
bankSettingsWindow->activateWindow();
|
||
});
|
||
}
|
||
|
||
DeviceWidget::DeviceWidget(const DeviceInfo &device, QWidget *parent): QWidget(parent), m_device(device) {
|
||
auto *layout = new QGridLayout(this);
|
||
layout->setContentsMargins(2, 2, 2, 2);
|
||
layout->setSpacing(0);
|
||
this->setStyleSheet("background-color: lightgray;padding: 2px;");
|
||
|
||
QImage img;
|
||
img.loadFromData(device.image, "JPG");
|
||
|
||
auto *imageLabel = new QLabel(this);
|
||
imageLabel->setPixmap(QPixmap::fromImage(img).scaled(300, 450, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||
imageLabel->setAlignment(Qt::AlignCenter);
|
||
layout->addWidget(imageLabel, 0, 0);
|
||
|
||
auto *statusLabel = new QLabel(device.name, this);
|
||
statusLabel->setWordWrap(true);
|
||
statusLabel->setMaximumWidth(300);
|
||
statusLabel->setStyleSheet(
|
||
"background-color: rgba(0, 0, 0, 0.5);"
|
||
"color: white;"
|
||
);
|
||
// статус — в ту же ячейку, но поверх картинки и по углу
|
||
layout->addWidget(statusLabel, 0, 0, Qt::AlignTop | Qt::AlignLeft);
|
||
|
||
auto *batteryLabel = new QLabel(QString("%1%").arg(device.battery), this);
|
||
batteryLabel->setWordWrap(true);
|
||
batteryLabel->setMaximumWidth(300);
|
||
batteryLabel->setStyleSheet(
|
||
"background-color: rgba(0, 0, 0, 0.5);"
|
||
"color: white;"
|
||
);
|
||
// статус — в ту же ячейку, но поверх картинки и по углу
|
||
layout->addWidget(batteryLabel, 0, 0, Qt::AlignTop | Qt::AlignRight);
|
||
|
||
|
||
auto *appsView = new QWidget(this);
|
||
appsView->setAttribute(Qt::WA_TransparentForMouseEvents, false);
|
||
appsView->setStyleSheet("background: transparent;");
|
||
|
||
auto *appsBoxLayout = new QVBoxLayout(appsView);
|
||
appsBoxLayout->setContentsMargins(2, 0, 0, 2);
|
||
appsBoxLayout->setSpacing(2);
|
||
|
||
QList<ApplicationInfo> apps = ApplicationDAO::getApplicationsByDeviceId(device.id);
|
||
for (ApplicationInfo &app: apps) {
|
||
if (app.install) {
|
||
auto *rowWidget = new QWidget(appsView);
|
||
buildBankRow(app, rowWidget, appsView);
|
||
appsBoxLayout->addWidget(rowWidget, 1);
|
||
}
|
||
}
|
||
// appsBoxLayout->addStretch();
|
||
|
||
// кладём overlay в ту же ячейку, что и картинку,
|
||
// но выравниваем его по левому-нижнему углу
|
||
layout->setColumnStretch(0, 1);
|
||
layout->addWidget(appsView, 0, 0, Qt::AlignLeft | Qt::AlignBottom);
|
||
// layout->addWidget(appsView, 0, 0, Qt::AlignLeft); TODO так на всю ширину
|
||
|
||
auto *addBankBtn = new QPushButton(this);
|
||
addBankBtn->setMaximumWidth(300);
|
||
addBankBtn->setText("Добавить банк +");
|
||
addBankBtn->setStyleSheet(
|
||
"background-color: #fff;"
|
||
"margin-top: 2px;"
|
||
"padding: 4px;"
|
||
"color: #000;"
|
||
);
|
||
|
||
setOpenBanksSettings(addBankBtn);
|
||
layout->addWidget(addBankBtn, 1, 0);
|
||
}
|