210 lines
6.9 KiB
C++
210 lines
6.9 KiB
C++
#include "MainWindow.h"
|
||
#include "bank/AccountWindow.h"
|
||
|
||
#include <QLabel>
|
||
#include <QPixmap>
|
||
#include <QResizeEvent>
|
||
#include <QScrollArea>
|
||
#include <QMenuBar>
|
||
#include <QStackedWidget>
|
||
|
||
#include "TutorialWindow.h"
|
||
#include "bank/BankListWindow.h"
|
||
#include "event/EventWindow.h"
|
||
#include "log/LogWindow.h"
|
||
#include "log/FileLogWindow.h"
|
||
#include "db/DeviceInfo.h"
|
||
#include "device/DeviceWidget.h"
|
||
#include "dao/DeviceDAO.h"
|
||
#include "dao/SettingsDAO.h"
|
||
#include <QTimer>
|
||
#include <QCoreApplication>
|
||
#include "widget/common/FlowLayout.h"
|
||
|
||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
|
||
setWindowTitle("ARC");
|
||
|
||
// Инициализируем таймер обновления
|
||
timer = new QTimer(this);
|
||
connect(timer, &QTimer::timeout, this, &MainWindow::loadDevices);
|
||
|
||
stackedWidget = new QStackedWidget(this);
|
||
setCentralWidget(stackedWidget);
|
||
|
||
createDevicePage();
|
||
stackedWidget->addWidget(m_devicesWindow);
|
||
stackedWidget->setCurrentWidget(m_devicesWindow);
|
||
|
||
// FIXME переделать на ленивое создание
|
||
// m_accountsWindow = new AccountWindow(this);
|
||
// stackedWidget->addWidget(m_accountsWindow);
|
||
// stackedWidget->setCurrentWidget(accountPage);
|
||
|
||
resize(800, 600);
|
||
|
||
// Работа с меню
|
||
QMenu *menu = menuBar()->addMenu("Меню");
|
||
auto *devicesPageAction = new QAction("Активные устройства", this);
|
||
// auto *accountPageAction = new QAction("Аккаунты", this);
|
||
auto *bankListAction = new QAction("Банки", this);
|
||
auto *tutorialPageAction = new QAction("Инструкция", this);
|
||
auto *eventAction = new QAction("События", this);
|
||
auto *fileLogAction = new QAction("Логи", this);
|
||
menu->addAction(devicesPageAction);
|
||
// menu->addAction(accountPageAction);
|
||
menu->addAction(bankListAction);
|
||
menu->addAction(eventAction);
|
||
menu->addAction(tutorialPageAction);
|
||
menu->addAction(fileLogAction);
|
||
|
||
connect(devicesPageAction, &QAction::triggered, this, [=]() {
|
||
if (!m_devicesWindow) {
|
||
createDevicePage();
|
||
}
|
||
stackedWidget->setCurrentWidget(m_devicesWindow);
|
||
});
|
||
|
||
// connect(accountPageAction, &QAction::triggered, this, [=]() {
|
||
// stackedWidget->setCurrentWidget(m_accountsWindow);
|
||
// deleteDevicePage(); // освобождаем ресурсы
|
||
// });
|
||
|
||
connect(bankListAction, &QAction::triggered, this, [=]() {
|
||
if (!m_bankListWindow) {
|
||
m_bankListWindow = new BankListWindow(this);
|
||
}
|
||
m_bankListWindow->show();
|
||
m_bankListWindow->raise();
|
||
m_bankListWindow->activateWindow();
|
||
});
|
||
|
||
connect(tutorialPageAction, &QAction::triggered, this, [=]() {
|
||
if (!m_tutorialWindow) {
|
||
m_tutorialWindow = new TutorialWindow(this);
|
||
}
|
||
m_tutorialWindow->show();
|
||
m_tutorialWindow->raise();
|
||
m_tutorialWindow->activateWindow();
|
||
});
|
||
|
||
connect(eventAction, &QAction::triggered, this, [=]() {
|
||
if (!m_eventWindow) {
|
||
m_eventWindow = new EventWindow(this);
|
||
}
|
||
m_eventWindow->show();
|
||
m_eventWindow->raise();
|
||
m_eventWindow->activateWindow();
|
||
});
|
||
|
||
connect(fileLogAction, &QAction::triggered, this, [=]() {
|
||
if (!m_fileLogWindow) {
|
||
m_fileLogWindow = new FileLogWindow(this);
|
||
}
|
||
m_fileLogWindow->show();
|
||
m_fileLogWindow->raise();
|
||
m_fileLogWindow->activateWindow();
|
||
});
|
||
|
||
if (SettingsDAO::get("tutorial_shown").isEmpty()) {
|
||
QTimer::singleShot(0, this, [this]() {
|
||
m_tutorialWindow = new TutorialWindow(this);
|
||
m_tutorialWindow->show();
|
||
m_tutorialWindow->raise();
|
||
m_tutorialWindow->activateWindow();
|
||
SettingsDAO::set("tutorial_shown", "1");
|
||
});
|
||
}
|
||
}
|
||
|
||
|
||
void MainWindow::createDevicePage() {
|
||
if (m_devicesWindow) {
|
||
return;
|
||
}
|
||
|
||
auto *container = new QWidget(this);
|
||
auto *containerLayout = new QVBoxLayout(container);
|
||
containerLayout->setContentsMargins(0, 0, 0, 0);
|
||
|
||
m_noDevicesLabel = new QLabel(container);
|
||
m_noDevicesPixmap = QPixmap(QCoreApplication::applicationDirPath() + "/no_devices.png");
|
||
m_noDevicesLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
|
||
m_noDevicesLabel->setAlignment(Qt::AlignCenter);
|
||
containerLayout->addWidget(m_noDevicesLabel);
|
||
|
||
m_scrollArea = new QScrollArea(container);
|
||
auto *contentWidget = new QWidget;
|
||
flowLayout = new FlowLayout(contentWidget, 0, 0, 0);
|
||
|
||
QVector<DeviceInfo> devices = DeviceDAO::getAllDevices(false);
|
||
for (const auto &device: devices) {
|
||
flowLayout->addWidget(new DeviceWidget(device));
|
||
}
|
||
|
||
contentWidget->setLayout(flowLayout);
|
||
static_cast<QScrollArea*>(m_scrollArea)->setWidget(contentWidget);
|
||
static_cast<QScrollArea*>(m_scrollArea)->setWidgetResizable(true);
|
||
containerLayout->addWidget(m_scrollArea);
|
||
|
||
m_noDevicesLabel->setVisible(devices.isEmpty());
|
||
m_scrollArea->setVisible(!devices.isEmpty());
|
||
|
||
m_devicesWindow = container;
|
||
stackedWidget->addWidget(m_devicesWindow);
|
||
|
||
timer->start(1000);
|
||
|
||
if (devices.isEmpty()) {
|
||
QTimer::singleShot(0, this, [this]() {
|
||
if (m_noDevicesLabel && !m_noDevicesPixmap.isNull()) {
|
||
m_noDevicesLabel->setPixmap(m_noDevicesPixmap.scaled(
|
||
m_noDevicesLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
void MainWindow::deleteDevicePage() {
|
||
if (!m_devicesWindow) {
|
||
return;
|
||
}
|
||
|
||
timer->stop();
|
||
|
||
stackedWidget->removeWidget(m_devicesWindow);
|
||
m_devicesWindow->deleteLater();
|
||
m_devicesWindow = nullptr;
|
||
flowLayout = nullptr;
|
||
}
|
||
|
||
/**
|
||
* Однако, в нем вы вызываете delete для элементов, что изменяет память.
|
||
* Для того, чтобы не нарушать константность, этот метод должен быть неконстантным (без const в сигнатуре).
|
||
*/
|
||
void MainWindow::loadDevices() {
|
||
const auto devices = DeviceDAO::getAllDevices(false);
|
||
// Очистить старые виджеты
|
||
QLayoutItem *item;
|
||
while ((item = flowLayout->takeAt(0)) != nullptr) {
|
||
if (item->widget()) {
|
||
item->widget()->deleteLater();
|
||
}
|
||
delete item;
|
||
}
|
||
// Добавляем новые виджеты для каждого устройства
|
||
for (const auto &device: devices) {
|
||
flowLayout->addWidget(new DeviceWidget(device));
|
||
}
|
||
|
||
m_noDevicesLabel->setVisible(devices.isEmpty());
|
||
m_scrollArea->setVisible(!devices.isEmpty());
|
||
}
|
||
|
||
void MainWindow::resizeEvent(QResizeEvent *event) {
|
||
QMainWindow::resizeEvent(event);
|
||
if (m_noDevicesLabel && m_noDevicesLabel->isVisible() && !m_noDevicesPixmap.isNull()) {
|
||
m_noDevicesLabel->setPixmap(m_noDevicesPixmap.scaled(
|
||
m_noDevicesLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||
}
|
||
}
|