From f5b95f25b5a9d3fb3ec4008cc357e44bf59e2ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=BB=D1=8C=D1=8F?= <Илья@WIN-RANNDDD> Date: Tue, 14 Jan 2025 21:33:47 +0400 Subject: [PATCH] Final version --- HardwareAccountingClient.pro | 2 - apiclient.cpp | 10 +- apiclient.h | 12 +- main.cpp | 11 +- mainwindow.cpp | 432 ++++++++++-------- mainwindow.h | 49 +- mainwindow.ui | 65 ++- models/baseentity.h | 2 +- models/device.cpp | 4 +- models/filterparams.cpp | 12 +- models/filterparams.h | 8 +- presenter.cpp | 86 ---- presenter.h | 29 -- ...4.png => device-type-Мониторы.png} | Bin ...3.png => device-type-Ноутбуки.png} | Bin ...ональные компьютеры.png} | Bin ...5.png => device-type-Принтеры.png} | Bin ...png => device-type-Проекторы.png} | Bin ...e-6.png => device-type-Роутеры.png} | Bin ...e-1.png => device-type-Сервера.png} | Bin ...8.png => device-type-Телефоны.png} | Bin resources/images/placeholder.png | Bin 0 -> 7916 bytes resources/resources.qrc | 21 +- resources/styles.qss | 6 +- utils/buttonhoverwatcher.cpp | 2 +- utils/buttonhoverwatcher.h | 1 + 26 files changed, 355 insertions(+), 397 deletions(-) delete mode 100644 presenter.cpp delete mode 100644 presenter.h rename resources/images/{device-type-4.png => device-type-Мониторы.png} (100%) rename resources/images/{device-type-3.png => device-type-Ноутбуки.png} (100%) rename resources/images/{device-type-2.png => device-type-Персональные компьютеры.png} (100%) rename resources/images/{device-type-5.png => device-type-Принтеры.png} (100%) rename resources/images/{device-type-7.png => device-type-Проекторы.png} (100%) rename resources/images/{device-type-6.png => device-type-Роутеры.png} (100%) rename resources/images/{device-type-1.png => device-type-Сервера.png} (100%) rename resources/images/{device-type-8.png => device-type-Телефоны.png} (100%) create mode 100644 resources/images/placeholder.png diff --git a/HardwareAccountingClient.pro b/HardwareAccountingClient.pro index 32c3dd8..d6fbd19 100644 --- a/HardwareAccountingClient.pro +++ b/HardwareAccountingClient.pro @@ -21,7 +21,6 @@ SOURCES += \ models/filterparams.cpp \ models/location.cpp \ models/manufacturer.cpp \ - presenter.cpp \ utils/buttonhoverwatcher.cpp HEADERS += \ @@ -37,7 +36,6 @@ HEADERS += \ models/location.h \ models/manufacturer.h \ models/types.h \ - presenter.h \ utils/buttonhoverwatcher.h FORMS += \ diff --git a/apiclient.cpp b/apiclient.cpp index 11e2582..9aa1e22 100644 --- a/apiclient.cpp +++ b/apiclient.cpp @@ -1,7 +1,7 @@ #include "apiclient.h" ApiClient::ApiClient(QObject *parent) - : QObject{parent}, networkManager(new QNetworkAccessManager(this)) + : QObject{parent}, _networkManager(new QNetworkAccessManager(this)) {} void ApiClient::getFilteredDevices(bool isWorking, double priceFrom, double priceTo, bool applyFilters, bool disregardState, int entityId, int currentEntity, @@ -19,7 +19,7 @@ void ApiClient::getFilteredDevices(bool isWorking, double priceFrom, double pric .arg(sortOrder); QNetworkRequest request(baseUrl + url); - QNetworkReply *reply = networkManager->get(request); + QNetworkReply *reply = _networkManager->get(request); connect(reply, &QNetworkReply::finished, this, [this, reply]() { parseData(reply); @@ -30,7 +30,7 @@ void ApiClient::getFilteredDevices(bool isWorking, double priceFrom, double pric void ApiClient::getEntities(const QString &url) { QNetworkRequest request(baseUrl + url); - QNetworkReply *reply = networkManager->get(request); + QNetworkReply *reply = _networkManager->get(request); connect(reply, &QNetworkReply::finished, this, [this, reply]() { parseData(reply); }); @@ -46,7 +46,7 @@ void ApiClient::updateDevice(int id, const Device &device) QJsonDocument doc(device.toJson()); QByteArray data = doc.toJson(); - QNetworkReply *reply = networkManager->put(request, data); + QNetworkReply *reply = _networkManager->put(request, data); connect(reply, &QNetworkReply::finished, this, [this, reply]() { handleDeviceUpdated(reply); }); @@ -98,7 +98,7 @@ void ApiClient::handleDeviceUpdated(QNetworkReply *reply) void ApiClient::handleError(QNetworkReply::NetworkError error) { - qWarning() << "Network error:" << error; + qDebug() << "Ошибка во время запроса: " << error; } Device ApiClient::deserializeDevice(const QJsonObject &json) diff --git a/apiclient.h b/apiclient.h index a6b630f..ebebe44 100644 --- a/apiclient.h +++ b/apiclient.h @@ -10,6 +10,7 @@ class ApiClient : public QObject { Q_OBJECT + public: explicit ApiClient(QObject *parent = nullptr); @@ -28,19 +29,20 @@ signals: void devicesReceived(const QList &devices); void deviceUpdated(bool success); +private: + template + QMap deserializeEntities(const QByteArray &data, const QString &itemsKey); + Device deserializeDevice(const QJsonObject &json); + private slots: void parseData(QNetworkReply *reply); void handleDeviceUpdated(QNetworkReply *reply); void handleError(QNetworkReply::NetworkError error); private: - QNetworkAccessManager *networkManager; - const QString baseUrl = "http://localhost:8080"; - template - QMap deserializeEntities(const QByteArray &data, const QString &itemsKey); - Device deserializeDevice(const QJsonObject &json); + QNetworkAccessManager *_networkManager; }; template diff --git a/main.cpp b/main.cpp index 5ea4a48..ae640a0 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,18 @@ -#include "presenter.h" #include +#include "mainwindow.h" +#include "apiclient.h" + int main(int argc, char *argv[]) { QApplication a(argc, argv); - new Presenter(); + ApiClient* client = new ApiClient(); + MainWindow* window = new MainWindow(); + + window->setClient(client); + + window->show(); return a.exec(); } diff --git a/mainwindow.cpp b/mainwindow.cpp index 7da3d5e..6a05fad 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -16,26 +16,6 @@ MainWindow::MainWindow(QWidget *parent) int screenHeight = screen->geometry().height(); setGeometry((screenWidth/2)-(width/2), (screenHeight/2)-(height/2), width, height); - returnToDeviceList(); - - ui->tableWidget->verticalHeader()->setVisible(false); - ui->tableWidget->setColumnCount(2); - QStringList headers = QString("ID, Название").split(','); - ui->tableWidget->setHorizontalHeaderLabels(headers); - QHeaderView *header = ui->tableWidget->horizontalHeader(); - header->setSectionResizeMode(0, QHeaderView::Stretch); - header->setSectionResizeMode(1, QHeaderView::Stretch); - QFont headerFont = header->font(); - headerFont.setBold(true); - header->setFont(headerFont); - ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - - ui->listWidgetDevices->setSpacing(10); - - ui->checkBoxIsWorking->setAttribute(Qt::WA_TransparentForMouseEvents); - ui->checkBoxIsWorking->setFocusPolicy(Qt::NoFocus); - QStringList filterItems = { "Все устройства", "Типы устройств", @@ -44,7 +24,6 @@ MainWindow::MainWindow(QWidget *parent) "Производители", "Модели устройств" }; - ui->comboBoxFilters->addItems(filterItems); QStringList sortItems = { @@ -54,24 +33,32 @@ MainWindow::MainWindow(QWidget *parent) "Сначала дорогие", "Сначала с лайком" }; - ui->comboBoxSort->addItems(sortItems); + ui->tableWidget->verticalHeader()->setVisible(false); + ui->tableWidget->setColumnCount(2); + QStringList headers = {"ID", "Название"}; + ui->tableWidget->setHorizontalHeaderLabels(headers); + QHeaderView *header = ui->tableWidget->horizontalHeader(); + QFont headerFont = header->font(); + headerFont.setBold(true); + header->setFont(headerFont); + header->setSectionResizeMode(QHeaderView::Stretch); + + ui->listWidgetDevices->setSpacing(10); + QLineEdit *searchEdit = ui->lineEditSearch; QPushButton *searchButton = new QPushButton(this); - ButtonHoverWatcher *watcher = new ButtonHoverWatcher(this); searchButton->installEventFilter(watcher); searchButton->setCursor(Qt::PointingHandCursor); searchButton->setStyleSheet("background: transparent; border: none;"); searchButton->setIcon(QIcon(":/images/search.png")); searchButton->setFixedSize(22, 22); - QMargins margins = searchEdit->textMargins(); searchEdit->setTextMargins(margins.left(), margins.top(), searchButton->width(), margins.bottom()); searchEdit->setPlaceholderText(QStringLiteral("Поиск устройств по модели, типу или серийному номеру...")); searchEdit->setMaxLength(200); - QHBoxLayout *searchLayout = new QHBoxLayout(); searchLayout->addStretch(); searchLayout->addWidget(searchButton); @@ -85,6 +72,18 @@ MainWindow::MainWindow(QWidget *parent) buttonGroup->addButton(ui->radioButtonDisregard); ui->radioButtonWorking->setChecked(true); + ui->checkBoxIsWorking->setAttribute(Qt::WA_TransparentForMouseEvents); + ui->checkBoxIsWorking->setFocusPolicy(Qt::NoFocus); + + ui->pushButtonDisregardPrice->setToolTip("Цена не учитывается при том условии, если оба значения из диапазона равны нулю"); + + QFile *styleFile = new QFile(":/styles.qss"); + if (styleFile->open(QFile::ReadOnly)) { + QTextStream ts(styleFile); + QString style = ts.readAll(); + qApp->setStyleSheet(style); + } + connect(ui->comboBoxFilters, SIGNAL(activated(int)), this, SLOT(updateTableWidget(int))); connect(ui->comboBoxSort, SIGNAL(activated(int)), this, SLOT(changeSortOrder())); connect(ui->tableWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(updateListWidget())); @@ -93,18 +92,14 @@ MainWindow::MainWindow(QWidget *parent) connect(ui->pushButtonClear, SIGNAL(clicked()), this, SLOT(pushButtonClearClicked())); connect(searchEdit, SIGNAL(returnPressed()), this, SLOT(pushButtonSearchClicked())); connect(searchButton, SIGNAL(clicked()), this, SLOT(pushButtonSearchClicked())); + connect(ui->pushButtonDisregardPrice, SIGNAL(clicked()), this, SLOT(pushButtonDisregardPriceClicked())); connect(ui->pushButtonApplyFilters, SIGNAL(clicked()), this, SLOT(pushButtonApplyFiltersClicked())); connect(ui->pushButtonCancelFilters, SIGNAL(clicked()), this, SLOT(pushButtonCancelFiltersClicked())); connect(ui->pushButtonDefault, SIGNAL(clicked()), this, SLOT(pushButtonDefaultClicked())); connect(ui->pushButtonStructure, SIGNAL(clicked()), this, SLOT(pushButtonStructureClicked())); connect(ui->pushButtonCharacteristics, SIGNAL(clicked()), this, SLOT(pushButtonCharacteristicsClicked())); - QFile *styleFile = new QFile(":/styles.qss"); - if (styleFile->open(QFile::ReadOnly)) { - QTextStream ts(styleFile); - QString style = ts.readAll(); - qApp->setStyleSheet(style); - } + returnToDeviceList(); } MainWindow::~MainWindow() @@ -122,22 +117,22 @@ void MainWindow::updateTableWidget(int index) switch (index) { case 0: // Все устройства clearDevicesOutputSettings(); - updateListWidgetDevices(0); + updateDevices(-1); break; case 1: // Типы устройств - fillTable(mapDeviceTypes); + _client->getEntities("/api/devicetypes"); break; case 2: // Помещения - fillTable(mapLocations); + _client->getEntities("/api/locations"); break; case 3: // Отделы - fillTable(mapDepartments); + _client->getEntities("/api/departments"); break; case 4: // Производители - fillTable(mapManufacturers); + _client->getEntities("/api/manufacturers"); break; case 5: // Модели устройств - fillTable(mapDeviceModels); + _client->getEntities("/api/devicemodels"); break; default: break; @@ -148,13 +143,46 @@ void MainWindow::updateListWidget() { returnToDeviceList(); - int selectedEntityId = getSelectedIndex(); + int selectedElementId = getSelectedElementId(); - if (selectedEntityId == -1) + if (selectedElementId == -1) return; clearDevicesOutputSettings(); - updateListWidgetDevices(selectedEntityId); + updateDevices(selectedElementId); +} + +void MainWindow::changeSortOrder() +{ + updateDevices(getSelectedElementId()); +} + +void MainWindow::updateDevices(int entityId) +{ + _client->getFilteredDevices( + _filterParams.isWorking(), + _filterParams.priceFrom(), + _filterParams.priceTo(), + _filterParams.apllyFilters(), + _filterParams.disregardState(), + entityId, + ui->comboBoxFilters->currentIndex(), + _searchInfo, + ui->comboBoxSort->currentText() + ); +} + +int MainWindow::getSelectedElementId() +{ + QModelIndexList selectedIndexes = ui->tableWidget->selectionModel()->selectedRows(); + + if (selectedIndexes.isEmpty()) { + return -1; + } + + int rowIndex = selectedIndexes.first().row(); + + return ui->tableWidget->item(rowIndex, 0)->text().toInt(); } template @@ -180,19 +208,43 @@ void MainWindow::fillTable(const QMap &map) } } -void MainWindow::updateListWidgetDevices(int entityId) +void MainWindow::fillListWidget(const QList &devices) { - client->getFilteredDevices( - filterParams.isWorking(), - filterParams.priceFrom(), - filterParams.priceTo(), - filterParams.getApllyFilters(), - filterParams.getDisregardState(), - entityId, - ui->comboBoxFilters->currentIndex(), - searchInfo, - ui->comboBoxSort->currentText() - ); + ui->listWidgetDevices->clear(); + + if (devices.isEmpty()) { + addMessageEmptyToList(); + } else { + for (const auto &device : devices) { + addDeviceToList(device); + } + } +} + +void MainWindow::addMessageEmptyToList() +{ + QListWidgetItem *item = new QListWidgetItem(ui->listWidgetDevices); + ui->listWidgetDevices->addItem(item); + + QWidget *cardWidget = createMessageEmptyCard(); + + item->setSizeHint(cardWidget->minimumSizeHint()); + item->setFlags(item->flags() & ~Qt::ItemIsEnabled); + + ui->listWidgetDevices->setItemWidget(item, cardWidget); +} + +void MainWindow::addDeviceToList(const Device &device) +{ + QListWidgetItem *item = new QListWidgetItem(ui->listWidgetDevices); + ui->listWidgetDevices->addItem(item); + + QWidget *cardWidget = createDeviceCard(device); + + item->setSizeHint(cardWidget->minimumSizeHint()); + ui->listWidgetDevices->setItemWidget(item, cardWidget); + + item->setData(Qt::UserRole, device.id()); } QWidget *MainWindow::createMessageEmptyCard() @@ -231,7 +283,7 @@ QWidget *MainWindow::createDeviceCard(const Device &device) QHBoxLayout *iconTextlayout = new QHBoxLayout(); QLabel *imageLabel = new QLabel(cardWidget); - QString imagePath = deviceTypeImages[device.deviceModel().idType()]; + QString imagePath = _deviceTypeImages[device.deviceModel().idType()]; QPixmap pixmap(imagePath); imageLabel->setPixmap(pixmap.scaled(100, 100, Qt::KeepAspectRatio)); @@ -242,20 +294,20 @@ QWidget *MainWindow::createDeviceCard(const Device &device) QLabel *serialNumberLabel = new QLabel(device.serialNumber(), cardWidget); QFont serialNumberFont("Arial", 14, QFont::Bold); serialNumberLabel->setFont(serialNumberFont); + textLayout->addWidget(serialNumberLabel); QFont generalFont("Arial", 11); - QString typeName = device.deviceModel().nameType(); - typeName = typeName.left(typeName.length() - 1); - if (typeName == "Персональные компьютер") - typeName = "Персональный компьютер"; + QString typeName = normalizeTypeName(device.deviceModel().nameType()); QLabel *typeNameLabel = new QLabel(typeName + ": " + device.deviceModel().name(), cardWidget); typeNameLabel->setFont(generalFont); + textLayout->addWidget(typeNameLabel); QLabel *statusLabel = new QLabel(device.isWorking() ? "Работает" : "Сломано", cardWidget); statusLabel->setFont(generalFont); + textLayout->addWidget(statusLabel); QHBoxLayout *priceLikeLayout = new QHBoxLayout(); @@ -264,6 +316,7 @@ QWidget *MainWindow::createDeviceCard(const Device &device) QLabel *priceLabel = new QLabel(QString::number(device.price()) + " ₽", cardWidget); priceLabel->setFont(generalFont); priceLabel->setFixedWidth(100); + priceLikeLayout->addWidget(priceLabel); priceLikeLayout->addSpacerItem(new QSpacerItem(40, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); @@ -272,20 +325,19 @@ QWidget *MainWindow::createDeviceCard(const Device &device) likeCheckBox->setChecked(device.isLiked()); likeCheckBox->setFont(generalFont); likeCheckBox->setStyleSheet(likeCheckBox->isChecked() ? "color: green;" : "color: black;"); - connect(likeCheckBox, &QCheckBox::toggled, this, [this, device, likeCheckBox](bool checked) { - Device updDevice = device; - updDevice.setIsLiked(checked); - client->updateDevice(updDevice.id(), updDevice); + Device updatedDevice = device; + updatedDevice.setIsLiked(checked); + _client->updateDevice(updatedDevice.id(), updatedDevice); - connect(client, &ApiClient::deviceUpdated, this, [this, checked, device, likeCheckBox](bool success) { - disconnect(client, &ApiClient::deviceUpdated, this, nullptr); + connect(_client, &ApiClient::deviceUpdated, this, [this, checked, device, likeCheckBox](bool success) { + disconnect(_client, &ApiClient::deviceUpdated, this, nullptr); if (success) { QString message = checked ? "Устройство добавлено в избранное." : "Устройство удалено из избранного."; QMessageBox::information(this, "Обновление", message); - Device& deviceRef = mapDevices[device.id()]; + Device& deviceRef = _mapDevices[device.id()]; deviceRef.setIsLiked(checked); likeCheckBox->setStyleSheet(checked ? "color: green;" : "color: black;"); @@ -314,23 +366,12 @@ QWidget *MainWindow::createDeviceCard(const Device &device) return cardWidget; } -void MainWindow::addDeviceToList(const Device &device) +QString MainWindow::normalizeTypeName(const QString &name) { - QListWidgetItem *item = new QListWidgetItem(ui->listWidgetDevices); - ui->listWidgetDevices->addItem(item); - - QWidget *cardWidget = createDeviceCard(device); - - item->setSizeHint(cardWidget->minimumSizeHint()); - ui->listWidgetDevices->setItemWidget(item, cardWidget); - - item->setData(Qt::UserRole, device.id()); -} - -void MainWindow::returnToDeviceList() -{ - idCard = 0; - ui->stackedWidget->setCurrentIndex(0); + QString typeName = name.left(name.length() - 1); + if (typeName == "Персональные компьютер") + typeName = "Персональный компьютер"; + return typeName; } void MainWindow::showItemInfo(QListWidgetItem *item) @@ -338,10 +379,12 @@ void MainWindow::showItemInfo(QListWidgetItem *item) if (!item) return; - int deviceId = item->data(Qt::UserRole).toInt(); - Device device = mapDevices[deviceId]; + ui->listWidgetDevices->scrollToItem(item, QAbstractItemView::PositionAtCenter); - idCard = deviceId; + int deviceId = item->data(Qt::UserRole).toInt(); + Device device = _mapDevices[deviceId]; + + _idCard = deviceId; ui->lineEditId->setText(QString::number(device.id())); ui->lineEditSerialNum->setText(device.serialNumber()); @@ -360,6 +403,12 @@ void MainWindow::showItemInfo(QListWidgetItem *item) ui->stackedWidget->setCurrentIndex(1); } +void MainWindow::returnToDeviceList() +{ + _idCard = 0; + ui->stackedWidget->setCurrentIndex(0); +} + void MainWindow::showTableWithStructureElements(const QList &elements) { QDialog* dialog = new QDialog(this); @@ -460,41 +509,6 @@ void MainWindow::showTableWithDeviceModelCharacteristics(const DeviceModel &mode dialog->exec(); } -void MainWindow::clearFilters() -{ - ui->radioButtonWorking->setChecked(true); - ui->doubleSpinBoxFrom->setValue(0.00); - ui->doubleSpinBoxTo->setValue(0.00); - filterParams.setIsWorking(true); - filterParams.setPriceFrom(-1); - filterParams.setPriceTo(-1); - filterParams.setDisregardState(false); - filterParams.setApllyFilters(false); -} - -void MainWindow::clearDevicesOutputSettings() -{ - ui->comboBoxSort->setCurrentIndex(0); - - ui->lineEditSearch->setText(""); - searchInfo = ""; - - clearFilters(); -} - -int MainWindow::getSelectedIndex() -{ - QModelIndexList selectedIndexes = ui->tableWidget->selectionModel()->selectedRows(); - - if (selectedIndexes.isEmpty()) { - return -1; - } - - int rowIndex = selectedIndexes.first().row(); - - return ui->tableWidget->item(rowIndex, 0)->text().toInt(); -} - void MainWindow::pushButtonBackClicked() { returnToDeviceList(); @@ -505,21 +519,21 @@ void MainWindow::pushButtonClearClicked() ui->lineEditSearch->setText(""); } -void MainWindow::changeSortOrder() -{ - updateListWidgetDevices(getSelectedIndex()); -} - void MainWindow::pushButtonSearchClicked() { - searchInfo = ui->lineEditSearch->text(); - if (searchInfo.isEmpty()) { + _searchInfo = ui->lineEditSearch->text(); + if (_searchInfo.isEmpty()) { QMessageBox::warning(this, "Ошибка", "Пожалуйста, введите текст для поиска."); return; } ui->comboBoxSort->setCurrentIndex(0); clearFilters(); - updateListWidgetDevices(getSelectedIndex()); + updateDevices(getSelectedElementId()); +} + +void MainWindow::pushButtonDisregardPriceClicked() +{ + clearSpinBoxes(); } void MainWindow::pushButtonApplyFiltersClicked() @@ -528,113 +542,139 @@ void MainWindow::pushButtonApplyFiltersClicked() double priceTo = ui->doubleSpinBoxTo->value(); if (priceFrom > priceTo) { QMessageBox::warning(this, "Ошибка", "Начальное значение диапазона не может быть больше конечного значения."); - - ui->doubleSpinBoxFrom->setValue(filterParams.priceFrom()); - ui->doubleSpinBoxTo->setValue(filterParams.priceTo()); - + clearSpinBoxes(); return; } - filterParams.setApllyFilters(true); - filterParams.setDisregardState(ui->radioButtonDisregard->isChecked()); - filterParams.setIsWorking(ui->radioButtonWorking->isChecked()); + _filterParams.setApllyFilters(true); + _filterParams.setDisregardState(ui->radioButtonDisregard->isChecked()); + _filterParams.setIsWorking(ui->radioButtonWorking->isChecked()); if (priceFrom == 0.00 && priceTo == 0.00) { - filterParams.setPriceFrom(0.00); - filterParams.setPriceTo(std::numeric_limits::max()); + _filterParams.setPriceFrom(0.00); + _filterParams.setPriceTo(std::numeric_limits::max()); } else { - filterParams.setPriceFrom(priceFrom); - filterParams.setPriceTo(priceTo); + _filterParams.setPriceFrom(priceFrom); + _filterParams.setPriceTo(priceTo); } - updateListWidgetDevices(getSelectedIndex()); + updateDevices(getSelectedElementId()); } void MainWindow::pushButtonCancelFiltersClicked() { clearFilters(); - updateListWidgetDevices(getSelectedIndex()); + updateDevices(getSelectedElementId()); } void MainWindow::pushButtonStructureClicked() { - showTableWithStructureElements(mapDevices[idCard].deviceModel().structureElements()); + showTableWithStructureElements(_mapDevices[_idCard].deviceModel().structureElements()); } void MainWindow::pushButtonCharacteristicsClicked() { - showTableWithDeviceModelCharacteristics(mapDevices[idCard].deviceModel()); + showTableWithDeviceModelCharacteristics(_mapDevices[_idCard].deviceModel()); } void MainWindow::pushButtonDefaultClicked() { clearDevicesOutputSettings(); - updateListWidgetDevices(getSelectedIndex()); + updateDevices(getSelectedElementId()); } -QMap MainWindow::getMapDeviceModels() const +void MainWindow::clearDevicesOutputSettings() { - return mapDeviceModels; + ui->comboBoxSort->setCurrentIndex(0); + + ui->lineEditSearch->setText(""); + _searchInfo = ""; + + clearFilters(); } -void MainWindow::setMapDevices(const QMap &newMapDevices) +void MainWindow::clearFilters() { - mapDevices = newMapDevices; - updateTableWidget(0); - connect(client, &ApiClient::devicesReceived, this, [this](const QList &filteredDevices) { - ui->listWidgetDevices->clear(); - if (filteredDevices.isEmpty()) { - QListWidgetItem *item = new QListWidgetItem(ui->listWidgetDevices); - ui->listWidgetDevices->addItem(item); - QWidget *cardWidget = createMessageEmptyCard(); - item->setSizeHint(cardWidget->minimumSizeHint()); - item->setFlags(item->flags() & ~Qt::ItemIsEnabled); - ui->listWidgetDevices->setItemWidget(item, cardWidget); - } else { - for (const auto &device : filteredDevices) { - int deviceModelId = device.deviceModel().id(); - if (mapDeviceModels.contains(deviceModelId)) { - Device updatedDevice = device; - updatedDevice.setDeviceModel(mapDeviceModels[deviceModelId]); - addDeviceToList(updatedDevice); - } else { - addDeviceToList(device); - } - } - } - }); + ui->radioButtonWorking->setChecked(true); + clearSpinBoxes(); + _filterParams.setIsWorking(true); + _filterParams.setPriceFrom(-1); + _filterParams.setPriceTo(-1); + _filterParams.setDisregardState(false); + _filterParams.setApllyFilters(false); } -void MainWindow::setMapDeviceModels(const QMap &newMapDeviceModels) +void MainWindow::clearSpinBoxes() { - mapDeviceModels = newMapDeviceModels; -} - -void MainWindow::setMapDeviceTypes(const QMap &newMapDeviceTypes) -{ - mapDeviceTypes = newMapDeviceTypes; - for (int i = 1; i <= mapDeviceTypes.size(); i++) { - QString imagePath = QString(":/images/device-type-%1.png").arg(i); - deviceTypeImages[i] = imagePath; - } -} - -void MainWindow::setMapManufacturers(const QMap &newMapManufacturers) -{ - mapManufacturers = newMapManufacturers; -} - -void MainWindow::setMapDepartments(const QMap &newMapDepartments) -{ - mapDepartments = newMapDepartments; -} - -void MainWindow::setMapLocations(const QMap &newMapLocations) -{ - mapLocations = newMapLocations; + ui->doubleSpinBoxFrom->setValue(0.00); + ui->doubleSpinBoxTo->setValue(0.00); } void MainWindow::setClient(ApiClient *newClient) { - client = newClient; + _client = newClient; + connect(_client, &ApiClient::devicesReceived, this, &MainWindow::onDevicesReceived); + connect(_client, &ApiClient::departmentsReceived, this, &MainWindow::onDepartmentsReceived); + connect(_client, &ApiClient::deviceModelsReceived, this, &MainWindow::onDeviceModelsReceived); + connect(_client, &ApiClient::deviceTypesReceived, this, &MainWindow::onDeviceTypesReceived); + connect(_client, &ApiClient::locationsReceived, this, &MainWindow::onLocationsReceived); + connect(_client, &ApiClient::manufacturersReceived, this, &MainWindow::onManufacturersReceived); + _client->getEntities("/api/devicetypes"); + updateTableWidget(0); +} + +void MainWindow::onDevicesReceived(const QList &devices) +{ + _mapDevices = getDevicesMap(devices); + + fillListWidget(devices); +} + +void MainWindow::onDepartmentsReceived(const QMap &departments) +{ + fillTable(departments); +} + +void MainWindow::onDeviceModelsReceived(const QMap &deviceModels) +{ + fillTable(deviceModels); +} + +void MainWindow::onDeviceTypesReceived(const QMap &deviceTypes) +{ + if (_initialTypesLoad) { + _initialTypesLoad = false; + } else { + fillTable(deviceTypes); + } + for (const DeviceType &type : deviceTypes) { + QString imagePath = QString(":/images/device-type-%1.png").arg(type.name()); + + if (QFile::exists(imagePath)) { + _deviceTypeImages[type.id()] = imagePath; + } else { + _deviceTypeImages[type.id()] = ":/images/placeholder.png"; + } + } +} + +void MainWindow::onManufacturersReceived(const QMap &manufacturers) +{ + fillTable(manufacturers); +} + +void MainWindow::onLocationsReceived(const QMap &locations) +{ + fillTable(locations); +} + +QMap MainWindow::getDevicesMap(const QList &devices) +{ + QMap devicesMap; + + for (const Device &device : devices) { + devicesMap.insert(device.id(), device); + } + + return devicesMap; } diff --git a/mainwindow.h b/mainwindow.h index 0ca6e52..2af1e4b 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -33,65 +33,62 @@ public: void setClient(ApiClient *newClient); - void setMapLocations(const QMap &newMapLocations); - - void setMapDepartments(const QMap &newMapDepartments); - - void setMapManufacturers(const QMap &newMapManufacturers); - - void setMapDeviceTypes(const QMap &newMapDeviceTypes); - - QMap getMapDeviceModels() const; - void setMapDeviceModels(const QMap &newMapDeviceModels); - - void setMapDevices(const QMap &newMapDevices); - private: template void fillTable(const QMap &map); - void updateListWidgetDevices(int entityId); + void fillListWidget(const QList &devices); + void updateDevices(int entityId); QWidget* createMessageEmptyCard(); QWidget* createDeviceCard(const Device &device); + QString normalizeTypeName(const QString &name); + void addMessageEmptyToList(); void addDeviceToList(const Device &device); void returnToDeviceList(); void showTableWithStructureElements(const QList& elements); void showTableWithDeviceModelCharacteristics(const DeviceModel& model); + void clearSpinBoxes(); void clearFilters(); void clearDevicesOutputSettings(); - int getSelectedIndex(); + int getSelectedElementId(); + QMap getDevicesMap(const QList &devices); private slots: void updateTableWidget(int index); void updateListWidget(); void showItemInfo(QListWidgetItem*); void changeSortOrder(); + void pushButtonBackClicked(); void pushButtonClearClicked(); void pushButtonSearchClicked(); + void pushButtonDisregardPriceClicked(); void pushButtonApplyFiltersClicked(); void pushButtonCancelFiltersClicked(); void pushButtonStructureClicked(); void pushButtonCharacteristicsClicked(); void pushButtonDefaultClicked(); + void onDevicesReceived(const QList &devices); + void onDepartmentsReceived(const QMap &departments); + void onDeviceModelsReceived(const QMap &deviceModels); + void onDeviceTypesReceived(const QMap &deviceTypes); + void onManufacturersReceived(const QMap &manufacturers); + void onLocationsReceived(const QMap &locations); + private: Ui::MainWindow *ui; - ApiClient *client; + ApiClient *_client; - QString searchInfo = ""; - FilterParams filterParams; + QString _searchInfo = ""; + FilterParams _filterParams; - int idCard = 0; + bool _initialTypesLoad = true; + int _idCard = 0; - QMap deviceTypeImages; + QMap _deviceTypeImages; - QMap mapLocations; - QMap mapDepartments; - QMap mapManufacturers; - QMap mapDeviceTypes; - QMap mapDeviceModels; - QMap mapDevices; + QMap _mapDevices; }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 51836ab..7a7f493 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -76,7 +76,10 @@ - QAbstractItemView::SelectionMode::SingleSelection + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows @@ -124,7 +127,7 @@ Устройства - Qt::AlignmentFlag::AlignCenter + Qt::AlignCenter @@ -136,6 +139,9 @@ 461 + + QAbstractItemView::ScrollPerPixel + @@ -267,7 +273,7 @@ Фильтры - Qt::AlignmentFlag::AlignCenter + Qt::AlignCenter @@ -289,9 +295,6 @@ Состояние - - Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter - @@ -312,9 +315,6 @@ Цена - - Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter - @@ -327,8 +327,8 @@ - Arial - 10 + Ubuntu Sans + 11 @@ -346,8 +346,8 @@ - Arial - 10 + Ubuntu Sans + 11 @@ -369,6 +369,9 @@ 10 + + + 2 @@ -391,6 +394,9 @@ 10 + + + 1000000000000000000000.000000000000000 @@ -438,16 +444,38 @@ 120 67 - 111 + 121 20 - Arial + Ubuntu Sans + 11 + + + + Не учитывать + + + + + + 410 + 166 + 101 + 24 + + + + + Ubuntu Sans 10 + + PointingHandCursor + Не учитывать @@ -497,7 +525,7 @@ Информация об устройстве - Qt::AlignmentFlag::AlignCenter + Qt::AlignCenter @@ -955,9 +983,6 @@ <html><head/><body><p>Дополнительная информация</p></body></html> - - Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter - @@ -1078,7 +1103,7 @@ 0 0 1136 - 20 + 22 diff --git a/models/baseentity.h b/models/baseentity.h index beebd43..7c24ec5 100644 --- a/models/baseentity.h +++ b/models/baseentity.h @@ -11,7 +11,7 @@ public: int id() const; void setId(int newId); - virtual void fromJson(const QJsonObject &) {} + virtual void fromJson(const QJsonObject &) = 0; virtual QJsonObject toJson() const = 0; private: diff --git a/models/device.cpp b/models/device.cpp index a834707..a2d3584 100644 --- a/models/device.cpp +++ b/models/device.cpp @@ -164,7 +164,7 @@ void Device::fromJson(const QJsonObject &json) setIsLiked(json["isLiked"].toBool()); DeviceModel model; - model.setId(json["idDeviceModel"].toInt()); + model.fromJson(json["deviceModel"].toObject()); setDeviceModel(model); } @@ -184,7 +184,7 @@ QJsonObject Device::toJson() const obj["nameEmployee"] = nameEmployee(); obj["idDepartment"] = idDepartment(); obj["nameDepartment"] = nameDepartment(); - obj["idDeviceModel"] = deviceModel().id(); + obj["deviceModel"] = deviceModel().toJson(); obj["isLiked"] = isLiked(); return obj; } diff --git a/models/filterparams.cpp b/models/filterparams.cpp index 6fe84aa..9a4a83a 100644 --- a/models/filterparams.cpp +++ b/models/filterparams.cpp @@ -33,22 +33,22 @@ void FilterParams::setPriceTo(double newPriceTo) _priceTo = newPriceTo; } -bool FilterParams::getDisregardState() const +bool FilterParams::disregardState() const { - return disregardState; + return _disregardState; } void FilterParams::setDisregardState(bool newDisregardState) { - disregardState = newDisregardState; + _disregardState = newDisregardState; } -bool FilterParams::getApllyFilters() const +bool FilterParams::apllyFilters() const { - return apllyFilters; + return _apllyFilters; } void FilterParams::setApllyFilters(bool newApllyFilters) { - apllyFilters = newApllyFilters; + _apllyFilters = newApllyFilters; } diff --git a/models/filterparams.h b/models/filterparams.h index 5267e90..3ebea6e 100644 --- a/models/filterparams.h +++ b/models/filterparams.h @@ -15,18 +15,18 @@ public: double priceTo() const; void setPriceTo(double newPriceTo); - bool getDisregardState() const; + bool disregardState() const; void setDisregardState(bool newDisregardState); - bool getApllyFilters() const; + bool apllyFilters() const; void setApllyFilters(bool newApllyFilters); private: bool _isWorking = true; double _priceFrom = -1; double _priceTo = -1; - bool disregardState = false; - bool apllyFilters = false; + bool _disregardState = false; + bool _apllyFilters = false; }; #endif // FILTERPARAMS_H diff --git a/presenter.cpp b/presenter.cpp deleted file mode 100644 index 6e02cd9..0000000 --- a/presenter.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "presenter.h" - -Presenter::Presenter(QObject *parent) : QObject(parent) -{ - client = new ApiClient(); - window = new MainWindow(); - - connect(client, &ApiClient::devicesReceived, this, &Presenter::onDevicesReceived); - connect(client, &ApiClient::departmentsReceived, this, &Presenter::onDepartmentsReceived); - connect(client, &ApiClient::deviceModelsReceived, this, &Presenter::onDeviceModelsReceived); - connect(client, &ApiClient::deviceTypesReceived, this, &Presenter::onDeviceTypesReceived); - connect(client, &ApiClient::locationsReceived, this, &Presenter::onLocationsReceived); - connect(client, &ApiClient::manufacturersReceived, this, &Presenter::onManufacturersReceived); - - window->setClient(client); - - client->getEntities("/api/locations"); - client->getEntities("/api/departments"); - client->getEntities("/api/manufacturers"); - client->getEntities("/api/devicetypes"); - client->getEntities("/api/devicemodels"); -} - -Presenter::~Presenter() -{ - client->deleteLater(); - window->deleteLater(); -} - -void Presenter::onLocationsReceived(const QMap &locations) -{ - window->setMapLocations(locations); -} - -void Presenter::onDepartmentsReceived(const QMap &departments) -{ - window->setMapDepartments(departments); -} - -void Presenter::onManufacturersReceived(const QMap &manufacturers) -{ - window->setMapManufacturers(manufacturers); -} - -void Presenter::onDeviceTypesReceived(const QMap &deviceTypes) -{ - window->setMapDeviceTypes(deviceTypes); -} - -void Presenter::onDeviceModelsReceived(const QMap &deviceModels) -{ - window->setMapDeviceModels(deviceModels); - client->getFilteredDevices( - false, - 0.00, - std::numeric_limits::max(), - false, - false, - -1, - -1, - "", - "Сначала новые" - ); -} - -void Presenter::onDevicesReceived(const QList &devices) -{ - disconnect(client, &ApiClient::devicesReceived, this, &Presenter::onDevicesReceived); - - QMap devicesMap; - QMap deviceModels = window->getMapDeviceModels(); - - for (const Device &device : devices) { - int deviceModelId = device.deviceModel().id(); - - if (deviceModels.contains(deviceModelId)) { - Device updatedDevice = device; - updatedDevice.setDeviceModel(deviceModels[deviceModelId]); - devicesMap.insert(updatedDevice.id(), updatedDevice); - } else { - devicesMap.insert(device.id(), device); - } - } - window->setMapDevices(devicesMap); - window->show(); -} diff --git a/presenter.h b/presenter.h deleted file mode 100644 index 8cd6771..0000000 --- a/presenter.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef PRESENTER_H -#define PRESENTER_H - -#include - -#include "apiclient.h" -#include "mainwindow.h" - -class Presenter : public QObject -{ - Q_OBJECT -public: - Presenter(QObject *parent = nullptr); - ~Presenter(); - -private slots: - void onDevicesReceived(const QList &devices); - void onDepartmentsReceived(const QMap &departments); - void onDeviceModelsReceived(const QMap &deviceModels); - void onDeviceTypesReceived(const QMap &deviceTypes); - void onManufacturersReceived(const QMap &manufacturers); - void onLocationsReceived(const QMap &locations); - -private: - ApiClient *client; - MainWindow *window; -}; - -#endif // PRESENTER_H diff --git a/resources/images/device-type-4.png b/resources/images/device-type-Мониторы.png similarity index 100% rename from resources/images/device-type-4.png rename to resources/images/device-type-Мониторы.png diff --git a/resources/images/device-type-3.png b/resources/images/device-type-Ноутбуки.png similarity index 100% rename from resources/images/device-type-3.png rename to resources/images/device-type-Ноутбуки.png diff --git a/resources/images/device-type-2.png b/resources/images/device-type-Персональные компьютеры.png similarity index 100% rename from resources/images/device-type-2.png rename to resources/images/device-type-Персональные компьютеры.png diff --git a/resources/images/device-type-5.png b/resources/images/device-type-Принтеры.png similarity index 100% rename from resources/images/device-type-5.png rename to resources/images/device-type-Принтеры.png diff --git a/resources/images/device-type-7.png b/resources/images/device-type-Проекторы.png similarity index 100% rename from resources/images/device-type-7.png rename to resources/images/device-type-Проекторы.png diff --git a/resources/images/device-type-6.png b/resources/images/device-type-Роутеры.png similarity index 100% rename from resources/images/device-type-6.png rename to resources/images/device-type-Роутеры.png diff --git a/resources/images/device-type-1.png b/resources/images/device-type-Сервера.png similarity index 100% rename from resources/images/device-type-1.png rename to resources/images/device-type-Сервера.png diff --git a/resources/images/device-type-8.png b/resources/images/device-type-Телефоны.png similarity index 100% rename from resources/images/device-type-8.png rename to resources/images/device-type-Телефоны.png diff --git a/resources/images/placeholder.png b/resources/images/placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..f0ee95ea788d3985ef7b4d38ea65efaa8a3e6b44 GIT binary patch literal 7916 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/down-arrow.png - images/device-type-1.png + images/device-type-Сервера.png - images/device-type-2.png + images/device-type-Персональные компьютеры.png - images/device-type-3.png + images/device-type-Ноутбуки.png - images/device-type-4.png + images/device-type-Мониторы.png - images/device-type-5.png + images/device-type-Принтеры.png - images/device-type-6.png + images/device-type-Роутеры.png - images/device-type-7.png + images/device-type-Проекторы.png - images/device-type-8.png + images/device-type-Телефоны.png + + + images/placeholder.png styles.qss - \ No newline at end of file + diff --git a/resources/styles.qss b/resources/styles.qss index 8596cec..2a86ad9 100644 --- a/resources/styles.qss +++ b/resources/styles.qss @@ -8,11 +8,11 @@ QComboBox, QPushButton, QLineEdit, QTextEdit, QListWidget, QTableWidget, QGroupB } QGroupBox#groupBoxFilters, QStackedWidget#stackedWidget { - background-color: white; + background-color: white; } QLineEdit { - border-radius: 5px; + border-radius: 5px; } QComboBox { @@ -44,4 +44,4 @@ QPushButton:pressed { border-radius: 4px; border-width: 2px; color: white; -} \ No newline at end of file +} diff --git a/utils/buttonhoverwatcher.cpp b/utils/buttonhoverwatcher.cpp index d08a508..6716860 100644 --- a/utils/buttonhoverwatcher.cpp +++ b/utils/buttonhoverwatcher.cpp @@ -5,7 +5,7 @@ ButtonHoverWatcher::ButtonHoverWatcher(QObject *parent) : QObject(parent) bool ButtonHoverWatcher::eventFilter(QObject *watched, QEvent *event) { - QPushButton * button = qobject_cast(watched); + QPushButton *button = qobject_cast(watched); if (!button) { return false; } diff --git a/utils/buttonhoverwatcher.h b/utils/buttonhoverwatcher.h index 659e8a6..0c84a62 100644 --- a/utils/buttonhoverwatcher.h +++ b/utils/buttonhoverwatcher.h @@ -8,6 +8,7 @@ class ButtonHoverWatcher : public QObject { Q_OBJECT + public: explicit ButtonHoverWatcher(QObject *parent = nullptr); virtual bool eventFilter(QObject * watched, QEvent * event) Q_DECL_OVERRIDE;