Final version

This commit is contained in:
Илья 2025-01-14 21:33:47 +04:00
parent 048da06230
commit f5b95f25b5
26 changed files with 355 additions and 397 deletions

View File

@ -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 += \

View File

@ -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)

View File

@ -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<Device> &devices);
void deviceUpdated(bool success);
private:
template <typename T>
QMap<int, T> 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 <typename T>
QMap<int, T> deserializeEntities(const QByteArray &data, const QString &itemsKey);
Device deserializeDevice(const QJsonObject &json);
QNetworkAccessManager *_networkManager;
};
template<typename T>

View File

@ -1,11 +1,18 @@
#include "presenter.h"
#include <QApplication>
#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();
}

View File

@ -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<DeviceType>(mapDeviceTypes);
_client->getEntities("/api/devicetypes");
break;
case 2: // Помещения
fillTable<Location>(mapLocations);
_client->getEntities("/api/locations");
break;
case 3: // Отделы
fillTable<Department>(mapDepartments);
_client->getEntities("/api/departments");
break;
case 4: // Производители
fillTable<Manufacturer>(mapManufacturers);
_client->getEntities("/api/manufacturers");
break;
case 5: // Модели устройств
fillTable<DeviceModel>(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 <typename T>
@ -180,19 +208,43 @@ void MainWindow::fillTable(const QMap<int, T> &map)
}
}
void MainWindow::updateListWidgetDevices(int entityId)
void MainWindow::fillListWidget(const QList<Device> &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<DeviceStructureElement> &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<double>::max());
_filterParams.setPriceFrom(0.00);
_filterParams.setPriceTo(std::numeric_limits<double>::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<int, DeviceModel> MainWindow::getMapDeviceModels() const
void MainWindow::clearDevicesOutputSettings()
{
return mapDeviceModels;
ui->comboBoxSort->setCurrentIndex(0);
ui->lineEditSearch->setText("");
_searchInfo = "";
clearFilters();
}
void MainWindow::setMapDevices(const QMap<int, Device> &newMapDevices)
void MainWindow::clearFilters()
{
mapDevices = newMapDevices;
updateTableWidget(0);
connect(client, &ApiClient::devicesReceived, this, [this](const QList<Device> &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<int, DeviceModel> &newMapDeviceModels)
void MainWindow::clearSpinBoxes()
{
mapDeviceModels = newMapDeviceModels;
}
void MainWindow::setMapDeviceTypes(const QMap<int, DeviceType> &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<int, Manufacturer> &newMapManufacturers)
{
mapManufacturers = newMapManufacturers;
}
void MainWindow::setMapDepartments(const QMap<int, Department> &newMapDepartments)
{
mapDepartments = newMapDepartments;
}
void MainWindow::setMapLocations(const QMap<int, Location> &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<Device> &devices)
{
_mapDevices = getDevicesMap(devices);
fillListWidget(devices);
}
void MainWindow::onDepartmentsReceived(const QMap<int, Department> &departments)
{
fillTable<Department>(departments);
}
void MainWindow::onDeviceModelsReceived(const QMap<int, DeviceModel> &deviceModels)
{
fillTable<DeviceModel>(deviceModels);
}
void MainWindow::onDeviceTypesReceived(const QMap<int, DeviceType> &deviceTypes)
{
if (_initialTypesLoad) {
_initialTypesLoad = false;
} else {
fillTable<DeviceType>(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<int, Manufacturer> &manufacturers)
{
fillTable<Manufacturer>(manufacturers);
}
void MainWindow::onLocationsReceived(const QMap<int, Location> &locations)
{
fillTable<Location>(locations);
}
QMap<int, Device> MainWindow::getDevicesMap(const QList<Device> &devices)
{
QMap<int, Device> devicesMap;
for (const Device &device : devices) {
devicesMap.insert(device.id(), device);
}
return devicesMap;
}

View File

@ -33,65 +33,62 @@ public:
void setClient(ApiClient *newClient);
void setMapLocations(const QMap<int, Location> &newMapLocations);
void setMapDepartments(const QMap<int, Department> &newMapDepartments);
void setMapManufacturers(const QMap<int, Manufacturer> &newMapManufacturers);
void setMapDeviceTypes(const QMap<int, DeviceType> &newMapDeviceTypes);
QMap<int, DeviceModel> getMapDeviceModels() const;
void setMapDeviceModels(const QMap<int, DeviceModel> &newMapDeviceModels);
void setMapDevices(const QMap<int, Device> &newMapDevices);
private:
template <typename T>
void fillTable(const QMap<int, T> &map);
void updateListWidgetDevices(int entityId);
void fillListWidget(const QList<Device> &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<DeviceStructureElement>& elements);
void showTableWithDeviceModelCharacteristics(const DeviceModel& model);
void clearSpinBoxes();
void clearFilters();
void clearDevicesOutputSettings();
int getSelectedIndex();
int getSelectedElementId();
QMap<int, Device> getDevicesMap(const QList<Device> &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<Device> &devices);
void onDepartmentsReceived(const QMap<int, Department> &departments);
void onDeviceModelsReceived(const QMap<int, DeviceModel> &deviceModels);
void onDeviceTypesReceived(const QMap<int, DeviceType> &deviceTypes);
void onManufacturersReceived(const QMap<int, Manufacturer> &manufacturers);
void onLocationsReceived(const QMap<int, Location> &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<int, QString> deviceTypeImages;
QMap<int, QString> _deviceTypeImages;
QMap<int, Location> mapLocations;
QMap<int, Department> mapDepartments;
QMap<int, Manufacturer> mapManufacturers;
QMap<int, DeviceType> mapDeviceTypes;
QMap<int, DeviceModel> mapDeviceModels;
QMap<int, Device> mapDevices;
QMap<int, Device> _mapDevices;
};
#endif // MAINWINDOW_H

View File

@ -76,7 +76,10 @@
</font>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SelectionMode::SingleSelection</enum>
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
</widget>
<widget class="QStackedWidget" name="stackedWidget">
@ -124,7 +127,7 @@
<string>Устройства</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QListWidget" name="listWidgetDevices">
@ -136,6 +139,9 @@
<height>461</height>
</rect>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
<widget class="QComboBox" name="comboBoxSort">
<property name="geometry">
@ -267,7 +273,7 @@
<string>Фильтры</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QLabel" name="labelWorkingState">
@ -289,9 +295,6 @@
<property name="text">
<string>Состояние</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
<widget class="QLabel" name="labelPrice">
<property name="geometry">
@ -312,9 +315,6 @@
<property name="text">
<string>Цена</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
<widget class="QRadioButton" name="radioButtonWorking">
<property name="geometry">
@ -327,8 +327,8 @@
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>10</pointsize>
<family>Ubuntu Sans</family>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
@ -346,8 +346,8 @@
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>10</pointsize>
<family>Ubuntu Sans</family>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
@ -369,6 +369,9 @@
<pointsize>10</pointsize>
</font>
</property>
<property name="suffix">
<string> ₽</string>
</property>
<property name="decimals">
<number>2</number>
</property>
@ -391,6 +394,9 @@
<pointsize>10</pointsize>
</font>
</property>
<property name="suffix">
<string> ₽</string>
</property>
<property name="maximum">
<double>1000000000000000000000.000000000000000</double>
</property>
@ -438,16 +444,38 @@
<rect>
<x>120</x>
<y>67</y>
<width>111</width>
<width>121</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<family>Ubuntu Sans</family>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>Не учитывать</string>
</property>
</widget>
<widget class="QPushButton" name="pushButtonDisregardPrice">
<property name="geometry">
<rect>
<x>410</x>
<y>166</y>
<width>101</width>
<height>24</height>
</rect>
</property>
<property name="font">
<font>
<family>Ubuntu Sans</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>Не учитывать</string>
</property>
@ -497,7 +525,7 @@
<string>Информация об устройстве</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QLineEdit" name="lineEditId">
@ -955,9 +983,6 @@
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Дополнительная информация&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxIsWorking">
<property name="enabled">
@ -1078,7 +1103,7 @@
<x>0</x>
<y>0</y>
<width>1136</width>
<height>20</height>
<height>22</height>
</rect>
</property>
</widget>

View File

@ -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:

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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<int, Location> &locations)
{
window->setMapLocations(locations);
}
void Presenter::onDepartmentsReceived(const QMap<int, Department> &departments)
{
window->setMapDepartments(departments);
}
void Presenter::onManufacturersReceived(const QMap<int, Manufacturer> &manufacturers)
{
window->setMapManufacturers(manufacturers);
}
void Presenter::onDeviceTypesReceived(const QMap<int, DeviceType> &deviceTypes)
{
window->setMapDeviceTypes(deviceTypes);
}
void Presenter::onDeviceModelsReceived(const QMap<int, DeviceModel> &deviceModels)
{
window->setMapDeviceModels(deviceModels);
client->getFilteredDevices(
false,
0.00,
std::numeric_limits<double>::max(),
false,
false,
-1,
-1,
"",
"Сначала новые"
);
}
void Presenter::onDevicesReceived(const QList<Device> &devices)
{
disconnect(client, &ApiClient::devicesReceived, this, &Presenter::onDevicesReceived);
QMap<int, Device> devicesMap;
QMap<int, DeviceModel> 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();
}

View File

@ -1,29 +0,0 @@
#ifndef PRESENTER_H
#define PRESENTER_H
#include <QObject>
#include "apiclient.h"
#include "mainwindow.h"
class Presenter : public QObject
{
Q_OBJECT
public:
Presenter(QObject *parent = nullptr);
~Presenter();
private slots:
void onDevicesReceived(const QList<Device> &devices);
void onDepartmentsReceived(const QMap<int, Department> &departments);
void onDeviceModelsReceived(const QMap<int, DeviceModel> &deviceModels);
void onDeviceTypesReceived(const QMap<int, DeviceType> &deviceTypes);
void onManufacturersReceived(const QMap<int, Manufacturer> &manufacturers);
void onLocationsReceived(const QMap<int, Location> &locations);
private:
ApiClient *client;
MainWindow *window;
};
#endif // PRESENTER_H

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@ -16,30 +16,33 @@
<file>images/down-arrow.png</file>
</qresource>
<qresource>
<file>images/device-type-1.png</file>
<file>images/device-type-Сервера.png</file>
</qresource>
<qresource>
<file>images/device-type-2.png</file>
<file>images/device-type-Персональные компьютеры.png</file>
</qresource>
<qresource>
<file>images/device-type-3.png</file>
<file>images/device-type-Ноутбуки.png</file>
</qresource>
<qresource>
<file>images/device-type-4.png</file>
<file>images/device-type-Мониторы.png</file>
</qresource>
<qresource>
<file>images/device-type-5.png</file>
<file>images/device-type-Принтеры.png</file>
</qresource>
<qresource>
<file>images/device-type-6.png</file>
<file>images/device-type-Роутеры.png</file>
</qresource>
<qresource>
<file>images/device-type-7.png</file>
<file>images/device-type-Проекторы.png</file>
</qresource>
<qresource>
<file>images/device-type-8.png</file>
<file>images/device-type-Телефоны.png</file>
</qresource>
<qresource>
<file>images/placeholder.png</file>
</qresource>
<qresource prefix="/">
<file>styles.qss</file>
</qresource>
</RCC>
</RCC>

View File

@ -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;
}
}

View File

@ -5,7 +5,7 @@ ButtonHoverWatcher::ButtonHoverWatcher(QObject *parent) : QObject(parent)
bool ButtonHoverWatcher::eventFilter(QObject *watched, QEvent *event)
{
QPushButton * button = qobject_cast<QPushButton*>(watched);
QPushButton *button = qobject_cast<QPushButton*>(watched);
if (!button) {
return false;
}

View File

@ -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;