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 0000000..f0ee95e Binary files /dev/null and b/resources/images/placeholder.png differ diff --git a/resources/resources.qrc b/resources/resources.qrc index b47921c..aaddfc2 100644 --- a/resources/resources.qrc +++ b/resources/resources.qrc @@ -16,30 +16,33 @@ images/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;