#include "DeviceWidget.h" #include #include #include #include #include #include #include #include #include #include #include "bank/AccountSettingsWindow.h" #include "bank/BankSettingsWindow.h" #include "DeviceSettingsWindow.h" #include "dao/ApplicationDAO.h" #include "dao/DeviceDAO.h" #include "db/ApplicationInfo.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) { Q_UNUSED(deviceId) Q_UNUSED(code) Q_UNUSED(status) // TODO: заменить на новый API } void DeviceWidget::buildBankRow(const ApplicationInfo &app, QWidget *rowWidget, QWidget *parent, bool isOffline) { 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;" ); if (isOffline) { btn1->setEnabled(false); } connect(btn1, &QPushButton::clicked, this, [app]() { const QString newStatus = app.status == "active" ? "off" : "active"; QMessageBox msgBox(nullptr); msgBox.setWindowTitle(newStatus == "off" ? "Отключить банк?" : "Включить банк?"); msgBox.setText( "Вы уверены, что хотите " + QString(newStatus == "off" ? "отключить от работы" : "включить") + " данный банк: " + app.name + "?"); QPushButton *confirmBtn = msgBox.addButton(newStatus == "off" ? "Отключить" : "Включить", QMessageBox::AcceptRole); QPushButton *cancelBtn = msgBox.addButton("Отмена", QMessageBox::RejectRole); msgBox.setDefaultButton(cancelBtn); msgBox.setModal(true); msgBox.exec(); if (msgBox.clickedButton() == confirmBtn) { if (!ApplicationDAO::update(app.id, app.pinCode, app.comment, newStatus)) { qDebug() << "Cant update bank data"; } else { sendBankStatus(app.deviceId, app.code, newStatus); } } }); 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, app); hbox->addWidget(icon); hbox->addWidget(label, 1); hbox->addWidget(circle); hbox->addWidget(btn2); // hbox->addStretch(); } void DeviceWidget::setOpenBanksSettings(QPushButton *button, const ApplicationInfo &app) { QString deviceId = m_device.id; QString deviceName = m_device.name; connect(button, &QPushButton::clicked, this, [deviceId, deviceName, app]() { static QPointer bankSettingsWindow; // Если окна нет (либо ещё не было создано, либо уже удалилось) — создаём заново if (!bankSettingsWindow) { bankSettingsWindow = new AccountSettingsWindow(nullptr, deviceId, deviceName, app); 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;"); auto *imageLabel = new QLabel(this); if (!device.image.isEmpty()) { QImage img; img.loadFromData(device.image, "JPG"); imageLabel->setPixmap(QPixmap::fromImage(img).scaled(300, 450, Qt::KeepAspectRatio, Qt::SmoothTransformation)); } else { imageLabel->setFixedSize(300, 450); imageLabel->setStyleSheet("background-color: #555;"); } imageLabel->setAlignment(Qt::AlignCenter); layout->addWidget(imageLabel, 0, 0); auto *statusLabel = new QLabel(QString("%1 %2%").arg(device.name).arg(device.battery), 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 *topRightWidget = new QWidget(this); topRightWidget->setStyleSheet("background: transparent;"); auto *topRightLayout = new QHBoxLayout(topRightWidget); topRightLayout->setContentsMargins(0, 0, 0, 0); topRightLayout->setSpacing(2); auto *settingsBtn = new QPushButton(this); settingsBtn->setIcon(QIcon(QCoreApplication::applicationDirPath() + "/images/cogwheel.png")); settingsBtn->setIconSize(QSize(20, 20)); settingsBtn->setFixedSize(28, 28); settingsBtn->setFlat(true); settingsBtn->setStyleSheet( "background-color: rgba(0, 0, 0, 0.5);" "border: none;" "border-radius: 4px;" ); connect(settingsBtn, &QPushButton::clicked, this, [this]() { auto *window = new DeviceSettingsWindow(nullptr, m_device.id, m_device.name); window->setAttribute(Qt::WA_DeleteOnClose); window->show(); window->raise(); window->activateWindow(); }); auto *deleteBtn = new QPushButton(this); deleteBtn->setIcon(QIcon(QCoreApplication::applicationDirPath() + "/images/delete.png")); deleteBtn->setIconSize(QSize(20, 20)); deleteBtn->setFixedSize(28, 28); deleteBtn->setFlat(true); deleteBtn->setStyleSheet( "background-color: rgba(0, 0, 0, 0.5);" "border: none;" "border-radius: 4px;" ); connect(deleteBtn, &QPushButton::clicked, this, [this]() { const QString deviceId = m_device.id; const QString deviceName = m_device.name; QPointer guard(this); QMessageBox msgBox(nullptr); msgBox.setWindowTitle(tr("Удалить устройство?")); msgBox.setText( "Будет удалено устройство " + deviceName + " и все связанные данные: банки, аккаунты, транзакции и события."); QPushButton *confirmBtn = msgBox.addButton(tr("Удалить"), QMessageBox::AcceptRole); QPushButton *cancelBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole); msgBox.setDefaultButton(cancelBtn); msgBox.setModal(true); msgBox.exec(); if (msgBox.clickedButton() == confirmBtn) { DeviceDAO::deleteDevice(deviceId); } }); topRightLayout->addWidget(settingsBtn); topRightLayout->addWidget(deleteBtn); layout->addWidget(topRightWidget, 0, 0, Qt::AlignTop | Qt::AlignRight); if (device.status != "device") { auto *offlineLabel = new QLabel("Офлайн", this); offlineLabel->setAlignment(Qt::AlignCenter); offlineLabel->setStyleSheet( "background-color: rgba(0, 0, 0, 0.6);" "color: white;" "font-size: 24px;" "font-weight: bold;" "padding: 10px 20px;" "border-radius: 8px;" ); layout->addWidget(offlineLabel, 0, 0, Qt::AlignCenter); } 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); const bool isOffline = device.status != "device"; QList apps = ApplicationDAO::getApplicationsByDeviceId(device.id); for (ApplicationInfo &app: apps) { if (app.install) { auto *rowWidget = new QWidget(appsView); buildBankRow(app, rowWidget, appsView, isOffline); 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); }