Added support for Ziraat Bank in BankSettingsWindow and parsing scripts. Refactored XML parsing code for improved readability, removing unused methods and renaming functions for consistency. Updated configuration and app data to include Ziraat Bank.
351 lines
14 KiB
C++
351 lines
14 KiB
C++
#include "BankSettingsWindow.h"
|
||
#include <QVBoxLayout>
|
||
#include <QDir>
|
||
#include <QFile>
|
||
#include <QHeaderView>
|
||
#include <QScrollArea>
|
||
#include <QCoreApplication>
|
||
#include <QPushButton>
|
||
#include <QTableWidget>
|
||
#include <utility>
|
||
#include <QMessageBox>
|
||
#include <QLabel>
|
||
#include <QDialog>
|
||
#include <QJsonArray>
|
||
#include <QJsonObject>
|
||
#include <QThread>
|
||
|
||
#include "dao/ApplicationDAO.h"
|
||
#include "db/ApplicationInfo.h"
|
||
#include "common/PaddedItemDelegate.h"
|
||
#include "device/EditBankDialog.h"
|
||
#include "net/NetworkService.h"
|
||
#include "rshb/LoginAndCheckAccountsScript.h"
|
||
#include "widget/common/CollapsibleSection.h"
|
||
#include "ziraat/LoginAndCheckAccountsZiraatScript.h"
|
||
|
||
QTableWidgetItem *BankSettingsWindow::createTableWidget(const QString &text) {
|
||
QTableWidgetItem *item = new QTableWidgetItem(text);
|
||
item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
return item;
|
||
}
|
||
|
||
QString parseStatus(const ApplicationInfo &app) {
|
||
if (!app.install) {
|
||
return "не установлен";
|
||
}
|
||
if (app.status == "active") {
|
||
if (!app.pinCodeChecked) {
|
||
return app.pinCode.isEmpty() ? "нет пин-код" : "пин-код не проверен";
|
||
}
|
||
return "работает";
|
||
} else if (app.status == "off") {
|
||
return "выключено";
|
||
} else {
|
||
return app.status;
|
||
}
|
||
}
|
||
|
||
void BankSettingsWindow::startCheckPinCode(const QString &appCode) {
|
||
if (appCode == "rshb") {
|
||
const auto thread = new QThread(nullptr);
|
||
auto *worker = new LoginAndCheckAccountsScript(m_deviceId, appCode, nullptr);
|
||
|
||
worker->moveToThread(thread);
|
||
connect(thread, &QThread::started, worker, &LoginAndCheckAccountsScript::start);
|
||
connect(worker, &LoginAndCheckAccountsScript::finished, thread, &QThread::quit);
|
||
connect(worker, &LoginAndCheckAccountsScript::finished, worker, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||
thread->start();
|
||
} else if (appCode == "ziraat") {
|
||
const auto thread = new QThread(nullptr);
|
||
auto *worker = new LoginAndCheckAccountsZiraatScript(m_deviceId, appCode, nullptr);
|
||
|
||
worker->moveToThread(thread);
|
||
connect(thread, &QThread::started, worker, &LoginAndCheckAccountsZiraatScript::start);
|
||
connect(worker, &LoginAndCheckAccountsZiraatScript::finished, thread, &QThread::quit);
|
||
connect(worker, &LoginAndCheckAccountsZiraatScript::finished, worker, &QObject::deleteLater);
|
||
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||
thread->start();
|
||
}
|
||
}
|
||
|
||
void sendAppStatus(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 BankSettingsWindow::reloadContent(QTableWidget *tableWidget) {
|
||
QList<ApplicationInfo> applications = ApplicationDAO::getApplicationsByDeviceId(m_deviceId);
|
||
|
||
tableWidget->setRowCount(applications.length());
|
||
tableWidget->setColumnCount(7);
|
||
tableWidget->setHorizontalHeaderLabels({
|
||
"",
|
||
"Имя",
|
||
"Пин-код",
|
||
"Статус",
|
||
"Комментарий",
|
||
"",
|
||
""
|
||
});
|
||
|
||
tableWidget->setWordWrap(true);
|
||
tableWidget->setTextElideMode(Qt::ElideNone);
|
||
|
||
QMargins cellPadding{8, 4, 8, 4};
|
||
auto *delegate = new PaddedItemDelegate(cellPadding, tableWidget);
|
||
// tableWidget->setItemDelegateForColumn(1, delegate);
|
||
// tableWidget->setItemDelegateForColumn(2, delegate);
|
||
// tableWidget->setItemDelegateForColumn(3, delegate);
|
||
// tableWidget->setItemDelegateForColumn(4, delegate);
|
||
|
||
tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
for (int i = 0; i < 7; ++i) {
|
||
tableWidget->horizontalHeader()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
|
||
tableWidget->verticalHeader()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
|
||
}
|
||
tableWidget->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Stretch);
|
||
|
||
|
||
for (int k = 0; k < applications.size(); ++k) {
|
||
const ApplicationInfo &app = applications[k];
|
||
|
||
|
||
auto *icon = new QLabel(tableWidget);
|
||
QPixmap pixmap(QCoreApplication::applicationDirPath() + "/images/" + app.code + "_icon.png");
|
||
icon->setPixmap(pixmap);
|
||
icon->setPixmap(pixmap.scaled(20, 20, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||
icon->setStyleSheet(
|
||
"background-color: transparent;"
|
||
"text-align: center;"
|
||
"padding:0 4px 0 0;"
|
||
);
|
||
icon->setMinimumSize(24, 20);
|
||
tableWidget->setCellWidget(k, 0, icon);
|
||
|
||
tableWidget->setItem(k, 1, createTableWidget(app.name));
|
||
|
||
|
||
// QTableWidgetItem *picCodeItem = new QTableWidgetItem(app.pinCode);
|
||
// picCodeItem->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||
auto *picCode = new QLabel(app.pinCode);
|
||
if (!app.pinCode.isEmpty() && !app.pinCodeChecked) {
|
||
picCode->setStyleSheet(
|
||
"background-color: orange;"
|
||
"color: white;"
|
||
);
|
||
}
|
||
picCode->setAlignment(Qt::AlignCenter);
|
||
tableWidget->setCellWidget(k, 2, picCode);
|
||
|
||
tableWidget->setItem(k, 3, createTableWidget(parseStatus(app)));
|
||
|
||
// tableWidget->setItem(k, 4, createTableWidget(app.comment));
|
||
|
||
QTableWidgetItem *item = new QTableWidgetItem(app.comment);
|
||
item->setTextAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
|
||
// item->setSizeHint(QSize(100, app.comment.length() / 2)); // Минимальная высота ячейки для переноса
|
||
tableWidget->setItem(k, 4, item);
|
||
|
||
|
||
if (app.install) {
|
||
if (!app.pinCode.isEmpty() && !app.pinCodeChecked) {
|
||
auto *pinCodeBtn = new QPushButton(" Проверить пин-код ", tableWidget);
|
||
pinCodeBtn->setProperty("btnClass", "pincode");
|
||
tableWidget->setCellWidget(k, 5, pinCodeBtn);
|
||
|
||
connect(pinCodeBtn, &QPushButton::clicked, this, [this, app]() {
|
||
QMessageBox msgBox(this);
|
||
msgBox.setWindowTitle(tr("Проверка пин-код"));
|
||
msgBox.setText("Сейчас запустится скрипт проверки пин-код в приложении: " + app.name);
|
||
|
||
QPushButton *deleteBtn = msgBox.addButton(tr("Запустить"), QMessageBox::AcceptRole);
|
||
QPushButton *closeBtn = msgBox.addButton(tr("Отмена"), QMessageBox::RejectRole);
|
||
msgBox.setDefaultButton(closeBtn);
|
||
msgBox.setModal(true);
|
||
msgBox.exec();
|
||
|
||
if (msgBox.clickedButton() == deleteBtn) {
|
||
startCheckPinCode(app.code);
|
||
}
|
||
});
|
||
} else {
|
||
if (app.status == "active" && !app.pinCode.isEmpty()) {
|
||
auto *deleteBtn = new QPushButton(" Отключить ", tableWidget);
|
||
deleteBtn->setProperty("btnClass", "delete");
|
||
// deleteBtn->setStyleSheet("padding: 4px 8px;");
|
||
// deleteBtn->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||
tableWidget->setCellWidget(k, 5, deleteBtn);
|
||
|
||
connect(deleteBtn, &QPushButton::clicked, this, [this,tableWidget, app]() {
|
||
QMessageBox msgBox(this);
|
||
msgBox.setWindowTitle(tr("Подтверждение"));
|
||
msgBox.setText("Вы уверены, что хотите отключить от работы данный банк: " + app.name + "?");
|
||
|
||
QPushButton *deleteBtn = msgBox.addButton(tr("Отключить"), 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, "off")) {
|
||
qDebug() << "Cant update bank data";
|
||
} else {
|
||
sendAppStatus(app.deviceId, app.code, "off");
|
||
tableWidget->clearContents();
|
||
reloadContent(tableWidget);
|
||
tableWidget->resizeRowsToContents();
|
||
}
|
||
} else {
|
||
// просто закрыли — ничего не делаем
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
|
||
// auto *editBtn = new QTableWidgetItem;
|
||
// tableWidget->setItem(k, 5, editBtn);
|
||
auto *btn = new QPushButton(" Редактировать ", tableWidget);
|
||
btn->setProperty("btnClass", "edit");
|
||
// btn->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||
tableWidget->setCellWidget(k, 6, btn);
|
||
connect(btn, &QPushButton::clicked, this, [this, tableWidget, k,app]() {
|
||
BankEditDialog dlg(app, this);
|
||
if (dlg.exec() == QDialog::Accepted) {
|
||
const QString pinCode = dlg.firstValue();
|
||
const QString comment = dlg.secondValue();
|
||
bool on = dlg.toggled();
|
||
|
||
if (!ApplicationDAO::update(app.id, pinCode, comment, on ? "active" : "off")) {
|
||
qDebug() << "Cant update bank data";
|
||
} else {
|
||
sendAppStatus(app.deviceId, app.code, on ? "active" : "off");
|
||
tableWidget->clearContents();
|
||
reloadContent(tableWidget);
|
||
tableWidget->resizeRowsToContents();
|
||
}
|
||
} else {
|
||
// Пользователь нажал «Cancel» или закрыл окно
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
BankSettingsWindow::BankSettingsWindow(QWidget *parent, QString deviceId, QString deviceName)
|
||
: QWidget(parent,
|
||
Qt::Window
|
||
| Qt::WindowTitleHint
|
||
| Qt::WindowSystemMenuHint
|
||
| Qt::WindowCloseButtonHint
|
||
| Qt::WindowMinMaxButtonsHint),
|
||
m_deviceId(std::move(deviceId)),
|
||
m_deviceName(std::move(deviceName)
|
||
) {
|
||
setWindowTitle("Настройки банков [" + m_deviceName + "]");
|
||
setMinimumSize(800, 400);
|
||
setMaximumSize(1000, 800);
|
||
resize(800, 400);
|
||
|
||
auto *mainLayout = new QVBoxLayout(this);
|
||
|
||
// Скролл-область
|
||
auto *scrollArea = new QScrollArea(this);
|
||
scrollArea->setWidgetResizable(true);
|
||
|
||
// Виджет-контейнер, в котором будет layout с таблицами и лейблами
|
||
auto *contentWidget = new QWidget;
|
||
auto *layout = new QVBoxLayout(contentWidget);
|
||
|
||
// Убираем отступы и рамку
|
||
contentWidget->setContentsMargins(0, 0, 0, 0); // Убираем отступы
|
||
layout->setContentsMargins(0, 0, 0, 0); // Убираем отступы у layout
|
||
scrollArea->setStyleSheet("border: none;"); // Убираем рамку
|
||
layout->setAlignment(Qt::AlignTop);
|
||
|
||
|
||
QTableWidget *tableWidget = new QTableWidget(this);
|
||
tableWidget->setSelectionMode(QAbstractItemView::NoSelection);
|
||
tableWidget->setFocusPolicy(Qt::NoFocus);
|
||
tableWidget->setStyleSheet(
|
||
"QTableWidget {"
|
||
" border: 1px solid grey;"
|
||
// " gridline-color: lightgrey;"
|
||
// " background-color: #f9f9f9;"
|
||
" font-size: 14px;"
|
||
"}"
|
||
"QHeaderView::section {"
|
||
// " background-color: #e0e0e0;"
|
||
// " border: 1px solid grey;"
|
||
" padding: 4px;"
|
||
" font-weight: bold;"
|
||
" text-align: left center;"
|
||
"}"
|
||
"QTableWidget::item {"
|
||
" padding: 2px;"
|
||
" border: none;"
|
||
" text-align: left;"
|
||
" vertical-align: middle; "
|
||
"}"
|
||
"QTableWidget::item:selected {"
|
||
// " background-color: #cce5ff;"
|
||
// " color: #003366;"
|
||
"}"
|
||
"QTableCornerButton::section {"
|
||
// " background-color: #e0e0e0;"
|
||
// " border: 1px solid grey;"
|
||
"}"
|
||
"QPushButton {"
|
||
"border-radius: 4px;"
|
||
"height: 26px;"
|
||
"}"
|
||
"QPushButton[btnClass='delete'] {"
|
||
"background-color: red;"
|
||
"}"
|
||
"QPushButton[btnClass='pincode'] {"
|
||
"background-color: orange;"
|
||
"}"
|
||
"QPushButton[btnClass='edit'] {"
|
||
"background-color: green;"
|
||
"}"
|
||
"QPushButton[btnClass='delete']:pressed {"
|
||
"background-color: blue;"
|
||
"}"
|
||
"QPushButton[btnClass='edit']:pressed {"
|
||
"background-color: blue;"
|
||
"}"
|
||
);
|
||
|
||
tableWidget->clearContents();
|
||
reloadContent(tableWidget);
|
||
tableWidget->resizeColumnsToContents();
|
||
|
||
layout->addWidget(tableWidget);
|
||
tableWidget->resizeRowsToContents();
|
||
|
||
// Добавим вертикальный Spacer в конец, чтобы прокручиваемая область не растягивала контент
|
||
// QSpacerItem *spacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||
// layout->addItem(spacer);
|
||
|
||
contentWidget->setLayout(layout);
|
||
scrollArea->setWidget(contentWidget);
|
||
mainLayout->addWidget(scrollArea);
|
||
setLayout(mainLayout);
|
||
}
|