Client part ready

This commit is contained in:
Илья 2024-12-24 18:13:22 +04:00
parent 4665e6c65f
commit 048da06230
45 changed files with 3311 additions and 0 deletions

View File

@ -0,0 +1,52 @@
QT += core gui httpserver
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
apiclient.cpp \
main.cpp \
mainwindow.cpp \
models/baseentity.cpp \
models/department.cpp \
models/device.cpp \
models/devicemodel.cpp \
models/devicestructureelement.cpp \
models/devicetype.cpp \
models/filterparams.cpp \
models/location.cpp \
models/manufacturer.cpp \
presenter.cpp \
utils/buttonhoverwatcher.cpp
HEADERS += \
apiclient.h \
mainwindow.h \
models/baseentity.h \
models/department.h \
models/device.h \
models/devicemodel.h \
models/devicestructureelement.h \
models/devicetype.h \
models/filterparams.h \
models/location.h \
models/manufacturer.h \
models/types.h \
presenter.h \
utils/buttonhoverwatcher.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
resources/resources.qrc

109
apiclient.cpp Normal file
View File

@ -0,0 +1,109 @@
#include "apiclient.h"
ApiClient::ApiClient(QObject *parent)
: QObject{parent}, networkManager(new QNetworkAccessManager(this))
{}
void ApiClient::getFilteredDevices(bool isWorking, double priceFrom, double priceTo, bool applyFilters, bool disregardState, int entityId, int currentEntity,
const QString &searchText, const QString &sortOrder)
{
QString url = QString("/api/devices?isWorking=%1&priceFrom=%2&priceTo=%3&applyFilters=%4&disregardState=%5&entityId=%6&currentEntity=%7&searchText=%8&sortOrder=%9")
.arg(isWorking ? "true" : "false")
.arg(priceFrom)
.arg(priceTo)
.arg(applyFilters ? "true" : "false")
.arg(disregardState ? "true" : "false")
.arg(entityId)
.arg(currentEntity)
.arg(searchText)
.arg(sortOrder);
QNetworkRequest request(baseUrl + url);
QNetworkReply *reply = networkManager->get(request);
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
parseData(reply);
});
connect(reply, &QNetworkReply::errorOccurred, this, &ApiClient::handleError);
}
void ApiClient::getEntities(const QString &url)
{
QNetworkRequest request(baseUrl + url);
QNetworkReply *reply = networkManager->get(request);
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
parseData(reply);
});
connect(reply, &QNetworkReply::errorOccurred, this, &ApiClient::handleError);
}
void ApiClient::updateDevice(int id, const Device &device)
{
QString url = QString("/api/devices/%1").arg(id);
QNetworkRequest request(baseUrl + url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QJsonDocument doc(device.toJson());
QByteArray data = doc.toJson();
QNetworkReply *reply = networkManager->put(request, data);
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
handleDeviceUpdated(reply);
});
connect(reply, &QNetworkReply::errorOccurred, this, &ApiClient::handleError);
}
void ApiClient::parseData(QNetworkReply *reply)
{
if (reply->error() == QNetworkReply::NoError) {
QByteArray data = reply->readAll();
QString urlPath = reply->url().path();
if (urlPath.contains("/api/devices")) {
QJsonDocument doc = QJsonDocument::fromJson(data);
QJsonArray devicesArray = doc.object().value("devices").toArray();
QList<Device> devices;
for (const QJsonValue &value : devicesArray) {
devices.append(deserializeDevice(value.toObject()));
}
emit devicesReceived(devices);
}
if (urlPath.contains("/api/locations")) {
emit locationsReceived(deserializeEntities<Location>(data, "locations"));
}
if (urlPath.contains("/api/departments")) {
emit departmentsReceived(deserializeEntities<Department>(data, "departments"));
}
if (urlPath.contains("/api/manufacturers")) {
emit manufacturersReceived(deserializeEntities<Manufacturer>(data, "manufacturers"));
}
if (urlPath.contains("/api/devicetypes")) {
emit deviceTypesReceived(deserializeEntities<DeviceType>(data, "deviceTypes"));
}
if (urlPath.contains("/api/devicemodels")) {
emit deviceModelsReceived(deserializeEntities<DeviceModel>(data, "deviceModels"));
}
}
}
void ApiClient::handleDeviceUpdated(QNetworkReply *reply)
{
if (reply->error() == QNetworkReply::NoError) {
emit deviceUpdated(true);
} else {
emit deviceUpdated(false);
}
}
void ApiClient::handleError(QNetworkReply::NetworkError error)
{
qWarning() << "Network error:" << error;
}
Device ApiClient::deserializeDevice(const QJsonObject &json)
{
Device device;
device.fromJson(json);
return device;
}

62
apiclient.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef APICLIENT_H
#define APICLIENT_H
#include <QtCore>
#include <QtNetwork>
#include <QObject>
#include "models/types.h" // IWYU pragma: keep
class ApiClient : public QObject
{
Q_OBJECT
public:
explicit ApiClient(QObject *parent = nullptr);
void getEntities(const QString &url);
void getFilteredDevices(bool isWorking, double priceFrom, double priceTo, bool applyFilters,
bool disregardState, int entityId, int currentEntity, const QString &searchText,
const QString &sortOrder);
void updateDevice(int id, const Device &device);
signals:
void departmentsReceived(const QMap<int, Department> &departments);
void deviceModelsReceived(const QMap<int, DeviceModel> &deviceModels);
void deviceTypesReceived(const QMap<int, DeviceType> &deviceType);
void locationsReceived(const QMap<int, Location> &locations);
void manufacturersReceived(const QMap<int, Manufacturer> &manufacturers);
void devicesReceived(const QList<Device> &devices);
void deviceUpdated(bool success);
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);
};
template<typename T>
QMap<int, T> ApiClient::deserializeEntities(const QByteArray &data, const QString &itemsKey)
{
QMap<int, T> entities;
QJsonDocument doc = QJsonDocument::fromJson(data);
QJsonArray itemsArray = doc.object().value(itemsKey).toArray();
for (const QJsonValue &value : itemsArray) {
T entity;
entity.fromJson(value.toObject());
entities.insert(entity.id(), entity);
}
return entities;
}
#endif // APICLIENT_H

11
main.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "presenter.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
new Presenter();
return a.exec();
}

640
mainwindow.cpp Normal file
View File

@ -0,0 +1,640 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowIcon(QIcon(":/images/mw-icon.png"));
int width = frameGeometry().width();
int height = frameGeometry().height();
QScreen *screen = qApp->primaryScreen();
int screenWidth = screen->geometry().width();
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 = {
"Все устройства",
"Типы устройств",
"Помещения",
"Отделы",
"Производители",
"Модели устройств"
};
ui->comboBoxFilters->addItems(filterItems);
QStringList sortItems = {
"Сначала новые",
"Сначала старые",
"Сначала дешевые",
"Сначала дорогие",
"Сначала с лайком"
};
ui->comboBoxSort->addItems(sortItems);
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);
searchLayout->setSpacing(0);
searchLayout->setContentsMargins(3, 2, 3, 2);
searchEdit->setLayout(searchLayout);
QButtonGroup *buttonGroup = new QButtonGroup(this);
buttonGroup->addButton(ui->radioButtonWorking);
buttonGroup->addButton(ui->radioButtonNotWorking);
buttonGroup->addButton(ui->radioButtonDisregard);
ui->radioButtonWorking->setChecked(true);
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()));
connect(ui->listWidgetDevices, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(showItemInfo(QListWidgetItem*)));
connect(ui->pushButtonBack, SIGNAL(clicked()), this, SLOT(pushButtonBackClicked()));
connect(ui->pushButtonClear, SIGNAL(clicked()), this, SLOT(pushButtonClearClicked()));
connect(searchEdit, SIGNAL(returnPressed()), this, SLOT(pushButtonSearchClicked()));
connect(searchButton, SIGNAL(clicked()), this, SLOT(pushButtonSearchClicked()));
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);
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::updateTableWidget(int index)
{
returnToDeviceList();
ui->tableWidget->clearContents();
ui->tableWidget->setRowCount(0);
switch (index) {
case 0: // Все устройства
clearDevicesOutputSettings();
updateListWidgetDevices(0);
break;
case 1: // Типы устройств
fillTable<DeviceType>(mapDeviceTypes);
break;
case 2: // Помещения
fillTable<Location>(mapLocations);
break;
case 3: // Отделы
fillTable<Department>(mapDepartments);
break;
case 4: // Производители
fillTable<Manufacturer>(mapManufacturers);
break;
case 5: // Модели устройств
fillTable<DeviceModel>(mapDeviceModels);
break;
default:
break;
}
}
void MainWindow::updateListWidget()
{
returnToDeviceList();
int selectedEntityId = getSelectedIndex();
if (selectedEntityId == -1)
return;
clearDevicesOutputSettings();
updateListWidgetDevices(selectedEntityId);
}
template <typename T>
void MainWindow::fillTable(const QMap<int, T> &map)
{
int row = 0;
for (auto &item : map) {
ui->tableWidget->insertRow(row);
QTableWidgetItem *idItem = new QTableWidgetItem(QString::number(item.id()));
QTableWidgetItem *nameItem = new QTableWidgetItem(item.name());
idItem->setFlags(idItem->flags() & ~Qt::ItemIsEditable);
nameItem->setFlags(nameItem->flags() & ~Qt::ItemIsEditable);
ui->tableWidget->setItem(row, 0, idItem);
ui->tableWidget->setItem(row, 1, nameItem);
idItem->setTextAlignment(Qt::AlignCenter);
nameItem->setTextAlignment(Qt::AlignCenter);
row++;
}
}
void MainWindow::updateListWidgetDevices(int entityId)
{
client->getFilteredDevices(
filterParams.isWorking(),
filterParams.priceFrom(),
filterParams.priceTo(),
filterParams.getApllyFilters(),
filterParams.getDisregardState(),
entityId,
ui->comboBoxFilters->currentIndex(),
searchInfo,
ui->comboBoxSort->currentText()
);
}
QWidget *MainWindow::createMessageEmptyCard()
{
QWidget *cardWidget = new QWidget(ui->listWidgetDevices);
QVBoxLayout *cardLayout = new QVBoxLayout(cardWidget);
QLabel *titleLabel = new QLabel("По заданным параметрам ничего не найдено", cardWidget);
QFont titleFont("Arial", 17, QFont::Bold);
titleLabel->setFont(titleFont);
cardLayout->addWidget(titleLabel, 0, Qt::AlignCenter);
cardLayout->setSpacing(12);
QLabel *imageLabel = new QLabel(cardWidget);
QPixmap pixmap(":/images/question.png");
imageLabel->setPixmap(pixmap.scaled(256, 256, Qt::KeepAspectRatio));
cardLayout->addWidget(imageLabel, 0, Qt::AlignCenter);
return cardWidget;
}
QWidget *MainWindow::createDeviceCard(const Device &device)
{
QWidget *cardWidget = new QWidget(ui->listWidgetDevices);
QVBoxLayout *cardLayout = new QVBoxLayout(cardWidget);
QFrame *topBorder = new QFrame(cardWidget);
topBorder->setFrameShape(QFrame::HLine);
topBorder->setFrameShadow(QFrame::Sunken);
cardLayout->addWidget(topBorder);
QHBoxLayout *iconTextlayout = new QHBoxLayout();
QLabel *imageLabel = new QLabel(cardWidget);
QString imagePath = deviceTypeImages[device.deviceModel().idType()];
QPixmap pixmap(imagePath);
imageLabel->setPixmap(pixmap.scaled(100, 100, Qt::KeepAspectRatio));
iconTextlayout->addWidget(imageLabel);
QVBoxLayout *textLayout = new QVBoxLayout();
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 = "Персональный компьютер";
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();
priceLikeLayout->setSpacing(100);
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));
QCheckBox *likeCheckBox = new QCheckBox("Нравится", cardWidget);
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);
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()];
deviceRef.setIsLiked(checked);
likeCheckBox->setStyleSheet(checked ? "color: green;" : "color: black;");
} else {
QMessageBox::critical(this, "Ошибка", "Не удалось изменить состояние устройства.");
}
});
});
priceLikeLayout->addWidget(likeCheckBox);
textLayout->addLayout(priceLikeLayout);
iconTextlayout->addSpacerItem(new QSpacerItem(40, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
iconTextlayout->addLayout(textLayout);
cardLayout->addLayout(iconTextlayout);
QFrame *bottomBorder = new QFrame(cardWidget);
bottomBorder->setFrameShape(QFrame::HLine);
bottomBorder->setFrameShadow(QFrame::Sunken);
cardLayout->addWidget(bottomBorder);
cardLayout->setContentsMargins(2, 0, 2, 0);
return 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());
}
void MainWindow::returnToDeviceList()
{
idCard = 0;
ui->stackedWidget->setCurrentIndex(0);
}
void MainWindow::showItemInfo(QListWidgetItem *item)
{
if (!item)
return;
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());
ui->lineEditPurchaseDate->setText(device.purchaseDate().toString("dd.MM.yyyy HH:mm:ss"));
ui->lineEditPrice->setText(QString::number(device.price(), 'f', 2));
ui->lineEditWarranty->setText(device.warrantyExpireDate().toString("dd.MM.yyyy HH:mm:ss"));
ui->lineEditLocation->setText(device.nameLocation());
ui->lineEditEmployee->setText(device.nameEmployee());
ui->lineEditDepartment->setText(device.nameDepartment());
ui->lineEditModel->setText(device.deviceModel().name());
ui->lineEditType->setText(device.deviceModel().nameType());
ui->lineEditManuf->setText(device.deviceModel().nameManuf());
ui->textEditFurtherInformation->setPlainText(device.furtherInformation());
ui->checkBoxIsWorking->setChecked(device.isWorking());
ui->stackedWidget->setCurrentIndex(1);
}
void MainWindow::showTableWithStructureElements(const QList<DeviceStructureElement> &elements)
{
QDialog* dialog = new QDialog(this);
dialog->setWindowTitle("Элементы структуры устройства");
dialog->resize(1100, 600);
QTableWidget* tableWidget = new QTableWidget(dialog);
tableWidget->setColumnCount(5);
QFont font("Arial", 12);
tableWidget->setFont(font);
QStringList headers = {"Название модели", "Производитель", "Описание элемента", "Тип элемента", "Количество"};
tableWidget->setHorizontalHeaderLabels(headers);
QFont headerFont("Arial", 12, QFont::Bold);
for (int i = 0; i < tableWidget->columnCount(); i++) {
tableWidget->horizontalHeaderItem(i)->setFont(headerFont);
}
tableWidget->setRowCount(elements.size());
for (int row = 0; row < elements.size(); row++) {
const DeviceStructureElement& element = elements[row];
tableWidget->setItem(row, 0, new QTableWidgetItem(element.nameModel()));
tableWidget->setItem(row, 1, new QTableWidgetItem(element.nameManuf()));
tableWidget->setItem(row, 2, new QTableWidgetItem(element.description()));
tableWidget->setItem(row, 3, new QTableWidgetItem(element.nameType()));
tableWidget->setItem(row, 4, new QTableWidgetItem(QString::number(element.count())));
for (int col = 0; col < tableWidget->columnCount(); col++) {
tableWidget->item(row, col)->setFlags(tableWidget->item(row, col)->flags() & ~Qt::ItemIsEditable);
}
}
connect(tableWidget, &QTableWidget::cellClicked, [tableWidget](int row, int col) {
QString text = tableWidget->item(row, col)->text();
QToolTip::showText(QCursor::pos(), text);
});
tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
tableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
tableWidget->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Interactive);
tableWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
tableWidget->horizontalHeader()->setSectionResizeMode(4, QHeaderView::ResizeToContents);
tableWidget->setColumnWidth(2, tableWidget->columnWidth(0) * 2);
tableWidget->setFocusPolicy(Qt::NoFocus);
QVBoxLayout* layout = new QVBoxLayout(dialog);
layout->addWidget(tableWidget);
dialog->setLayout(layout);
dialog->exec();
}
void MainWindow::showTableWithDeviceModelCharacteristics(const DeviceModel &model)
{
QDialog* dialog = new QDialog(this);
dialog->setWindowTitle("Характеристики устройства");
dialog->setFixedSize(1200, 75);
QTableWidget* tableWidget = new QTableWidget(dialog);
tableWidget->setColumnCount(6);
QFont font("Arial", 11);
tableWidget->setFont(font);
QStringList headers = {"Эффективность работы", "Надежность", "Энергоэффективность", "Удобство использования", "Долговечность", "Эстетические качества"};
tableWidget->setHorizontalHeaderLabels(headers);
QFont headerFont("Arial", 11, QFont::Bold);
for (int i = 0; i < tableWidget->columnCount(); i++) {
tableWidget->horizontalHeaderItem(i)->setFont(headerFont);
}
tableWidget->setRowCount(1);
tableWidget->setItem(0, 0, new QTableWidgetItem(QString::number(model.workEfficiency())));
tableWidget->setItem(0, 1, new QTableWidgetItem(QString::number(model.reliability())));
tableWidget->setItem(0, 2, new QTableWidgetItem(QString::number(model.energyEfficiency())));
tableWidget->setItem(0, 3, new QTableWidgetItem(QString::number(model.userFriendliness())));
tableWidget->setItem(0, 4, new QTableWidgetItem(QString::number(model.durability())));
tableWidget->setItem(0, 5, new QTableWidgetItem(QString::number(model.aestheticQualities())));
for (int col = 0; col < tableWidget->columnCount(); col++) {
tableWidget->item(0, col)->setFlags(tableWidget->item(0, col)->flags() & ~Qt::ItemIsEditable);
tableWidget->item(0, col)->setTextAlignment(Qt::AlignCenter);
tableWidget->horizontalHeader()->setSectionResizeMode(col, QHeaderView::Stretch);
}
tableWidget->verticalHeader()->setVisible(false);
tableWidget->setFocusPolicy(Qt::NoFocus);
QVBoxLayout* layout = new QVBoxLayout(dialog);
layout->addWidget(tableWidget);
dialog->setLayout(layout);
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();
}
void MainWindow::pushButtonClearClicked()
{
ui->lineEditSearch->setText("");
}
void MainWindow::changeSortOrder()
{
updateListWidgetDevices(getSelectedIndex());
}
void MainWindow::pushButtonSearchClicked()
{
searchInfo = ui->lineEditSearch->text();
if (searchInfo.isEmpty()) {
QMessageBox::warning(this, "Ошибка", "Пожалуйста, введите текст для поиска.");
return;
}
ui->comboBoxSort->setCurrentIndex(0);
clearFilters();
updateListWidgetDevices(getSelectedIndex());
}
void MainWindow::pushButtonApplyFiltersClicked()
{
double priceFrom = ui->doubleSpinBoxFrom->value();
double priceTo = ui->doubleSpinBoxTo->value();
if (priceFrom > priceTo) {
QMessageBox::warning(this, "Ошибка", "Начальное значение диапазона не может быть больше конечного значения.");
ui->doubleSpinBoxFrom->setValue(filterParams.priceFrom());
ui->doubleSpinBoxTo->setValue(filterParams.priceTo());
return;
}
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());
} else {
filterParams.setPriceFrom(priceFrom);
filterParams.setPriceTo(priceTo);
}
updateListWidgetDevices(getSelectedIndex());
}
void MainWindow::pushButtonCancelFiltersClicked()
{
clearFilters();
updateListWidgetDevices(getSelectedIndex());
}
void MainWindow::pushButtonStructureClicked()
{
showTableWithStructureElements(mapDevices[idCard].deviceModel().structureElements());
}
void MainWindow::pushButtonCharacteristicsClicked()
{
showTableWithDeviceModelCharacteristics(mapDevices[idCard].deviceModel());
}
void MainWindow::pushButtonDefaultClicked()
{
clearDevicesOutputSettings();
updateListWidgetDevices(getSelectedIndex());
}
QMap<int, DeviceModel> MainWindow::getMapDeviceModels() const
{
return mapDeviceModels;
}
void MainWindow::setMapDevices(const QMap<int, Device> &newMapDevices)
{
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);
}
}
}
});
}
void MainWindow::setMapDeviceModels(const QMap<int, DeviceModel> &newMapDeviceModels)
{
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;
}
void MainWindow::setClient(ApiClient *newClient)
{
client = newClient;
}

97
mainwindow.h Normal file
View File

@ -0,0 +1,97 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QCloseEvent>
#include <QDialog>
#include <QButtonGroup>
#include <QScreen>
#include <QListWidget>
#include <QToolTip>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QTextStream>
#include <QFile>
#include "apiclient.h"
#include "models/types.h" // IWYU pragma: keep
#include "models/filterparams.h"
#include "utils/buttonhoverwatcher.h" // IWYU pragma: keep
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
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);
QWidget* createMessageEmptyCard();
QWidget* createDeviceCard(const Device &device);
void addDeviceToList(const Device &device);
void returnToDeviceList();
void showTableWithStructureElements(const QList<DeviceStructureElement>& elements);
void showTableWithDeviceModelCharacteristics(const DeviceModel& model);
void clearFilters();
void clearDevicesOutputSettings();
int getSelectedIndex();
private slots:
void updateTableWidget(int index);
void updateListWidget();
void showItemInfo(QListWidgetItem*);
void changeSortOrder();
void pushButtonBackClicked();
void pushButtonClearClicked();
void pushButtonSearchClicked();
void pushButtonApplyFiltersClicked();
void pushButtonCancelFiltersClicked();
void pushButtonStructureClicked();
void pushButtonCharacteristicsClicked();
void pushButtonDefaultClicked();
private:
Ui::MainWindow *ui;
ApiClient *client;
QString searchInfo = "";
FilterParams filterParams;
int idCard = 0;
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;
};
#endif // MAINWINDOW_H

1088
mainwindow.ui Normal file

File diff suppressed because it is too large Load Diff

14
models/baseentity.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "baseentity.h"
BaseEntity::BaseEntity()
{}
int BaseEntity::id() const
{
return _id;
}
void BaseEntity::setId(int newId)
{
_id = newId;
}

21
models/baseentity.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef BASEENTITY_H
#define BASEENTITY_H
#include <QJsonObject>
class BaseEntity
{
public:
BaseEntity();
int id() const;
void setId(int newId);
virtual void fromJson(const QJsonObject &) {}
virtual QJsonObject toJson() const = 0;
private:
int _id = 0;
};
#endif // BASEENTITY_H

31
models/department.cpp Normal file
View File

@ -0,0 +1,31 @@
#include "department.h"
Department::Department()
{}
Department::~Department()
{}
QString Department::name() const
{
return _name;
}
void Department::setName(const QString &newName)
{
_name = newName;
}
void Department::fromJson(const QJsonObject &json)
{
setId(json["id"].toInt());
setName(json["name"].toString());
}
QJsonObject Department::toJson() const
{
QJsonObject obj;
obj["id"] = id();
obj["name"] = name();
return obj;
}

24
models/department.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef DEPARTMENT_H
#define DEPARTMENT_H
#include <QString>
#include "baseentity.h"
class Department : public BaseEntity
{
public:
Department();
virtual ~Department();
QString name() const;
void setName(const QString &newName);
void fromJson(const QJsonObject &json) override;
QJsonObject toJson() const override;
private:
QString _name = "";
};
#endif // DEPARTMENT_H

190
models/device.cpp Normal file
View File

@ -0,0 +1,190 @@
#include "device.h"
Device::Device()
{}
Device::~Device()
{}
QString Device::serialNumber() const
{
return _serialNumber;
}
void Device::setSerialNumber(const QString &newSerialNumber)
{
_serialNumber = newSerialNumber;
}
QDateTime Device::purchaseDate() const
{
return _purchaseDate;
}
void Device::setPurchaseDate(const QDateTime &newPurchaseDate)
{
_purchaseDate = newPurchaseDate;
}
double Device::price() const
{
return _price;
}
void Device::setPrice(double newPrice)
{
_price = newPrice;
}
QDateTime Device::warrantyExpireDate() const
{
return _warrantyExpireDate;
}
void Device::setWarrantyExpireDate(const QDateTime &newWarrantyExpireDate)
{
_warrantyExpireDate = newWarrantyExpireDate;
}
bool Device::isWorking() const
{
return _isWorking;
}
void Device::setIsWorking(bool newIsWorking)
{
_isWorking = newIsWorking;
}
QString Device::furtherInformation() const
{
return _furtherInformation;
}
void Device::setFurtherInformation(const QString &newFurtherInformation)
{
_furtherInformation = newFurtherInformation;
}
int Device::idLocation() const
{
return _idLocation;
}
void Device::setIdLocation(int newIdLocation)
{
_idLocation = newIdLocation;
}
QString Device::nameLocation() const
{
return _nameLocation;
}
void Device::setNameLocation(const QString &newNameLocation)
{
_nameLocation = newNameLocation;
}
int Device::idEmployee() const
{
return _idEmployee;
}
void Device::setIdEmployee(int newIdEmployee)
{
_idEmployee = newIdEmployee;
}
QString Device::nameEmployee() const
{
return _nameEmployee;
}
void Device::setNameEmployee(const QString &newNameEmployee)
{
_nameEmployee = newNameEmployee;
}
int Device::idDepartment() const
{
return _idDepartment;
}
void Device::setIdDepartment(int newIdDepartment)
{
_idDepartment = newIdDepartment;
}
QString Device::nameDepartment() const
{
return _nameDepartment;
}
void Device::setNameDepartment(const QString &newNameDepartment)
{
_nameDepartment = newNameDepartment;
}
DeviceModel Device::deviceModel() const
{
return _deviceModel;
}
void Device::setDeviceModel(const DeviceModel &newDeviceModel)
{
_deviceModel = newDeviceModel;
}
bool Device::isLiked() const
{
return _isLiked;
}
void Device::setIsLiked(bool newIsLiked)
{
_isLiked = newIsLiked;
}
void Device::fromJson(const QJsonObject &json)
{
setId(json["id"].toInt());
setSerialNumber(json["serialNumber"].toString());
setPurchaseDate(QDateTime::fromString(json["purchaseDate"].toString(), Qt::ISODate));
setPrice(json["price"].toDouble());
setWarrantyExpireDate(QDateTime::fromString(json["warrantyExpireDate"].toString(), Qt::ISODate));
setIsWorking(json["isWorking"].toBool());
setFurtherInformation(json["furtherInformation"].toString());
setIdLocation(json["idLocation"].toInt());
setNameLocation(json["nameLocation"].toString());
setIdEmployee(json["idEmployee"].toInt());
setNameEmployee(json["nameEmployee"].toString());
setIdDepartment(json["idDepartment"].toInt());
setNameDepartment(json["nameDepartment"].toString());
setIsLiked(json["isLiked"].toBool());
DeviceModel model;
model.setId(json["idDeviceModel"].toInt());
setDeviceModel(model);
}
QJsonObject Device::toJson() const
{
QJsonObject obj;
obj["id"] = id();
obj["serialNumber"] = serialNumber();
obj["purchaseDate"] = purchaseDate().toString(Qt::ISODate);
obj["price"] = price();
obj["warrantyExpireDate"] = warrantyExpireDate().toString(Qt::ISODate);
obj["isWorking"] = isWorking();
obj["furtherInformation"] = furtherInformation();
obj["idLocation"] = idLocation();
obj["nameLocation"] = nameLocation();
obj["idEmployee"] = idEmployee();
obj["nameEmployee"] = nameEmployee();
obj["idDepartment"] = idDepartment();
obj["nameDepartment"] = nameDepartment();
obj["idDeviceModel"] = deviceModel().id();
obj["isLiked"] = isLiked();
return obj;
}

78
models/device.h Normal file
View File

@ -0,0 +1,78 @@
#ifndef DEVICE_H
#define DEVICE_H
#include <QString>
#include <QDateTime>
#include "devicemodel.h"
#include "baseentity.h"
class Device : public BaseEntity
{
public:
Device();
virtual ~Device();
QString serialNumber() const;
void setSerialNumber(const QString &newSerialNumber);
QDateTime purchaseDate() const;
void setPurchaseDate(const QDateTime &newPurchaseDate);
double price() const;
void setPrice(double newPrice);
QDateTime warrantyExpireDate() const;
void setWarrantyExpireDate(const QDateTime &newWarrantyExpireDate);
bool isWorking() const;
void setIsWorking(bool newIsWorking);
QString furtherInformation() const;
void setFurtherInformation(const QString &newFurtherInformation);
int idLocation() const;
void setIdLocation(int newIdLocation);
QString nameLocation() const;
void setNameLocation(const QString &newNameLocation);
int idEmployee() const;
void setIdEmployee(int newIdEmployee);
QString nameEmployee() const;
void setNameEmployee(const QString &newNameEmployee);
int idDepartment() const;
void setIdDepartment(int newIdDepartment);
QString nameDepartment() const;
void setNameDepartment(const QString &newNameDepartment);
DeviceModel deviceModel() const;
void setDeviceModel(const DeviceModel &newDeviceModel);
bool isLiked() const;
void setIsLiked(bool newIsLiked);
void fromJson(const QJsonObject &json) override;
QJsonObject toJson() const override;
private:
QString _serialNumber = "";
QDateTime _purchaseDate = QDateTime();
double _price = 1;
QDateTime _warrantyExpireDate = QDateTime();
bool _isWorking = true;
QString _furtherInformation = "";
int _idLocation = 0;
QString _nameLocation = "";
int _idEmployee = 0;
QString _nameEmployee = "";
int _idDepartment = 0;
QString _nameDepartment = "";
DeviceModel _deviceModel;
bool _isLiked = false;
};
#endif // DEVICE_H

190
models/devicemodel.cpp Normal file
View File

@ -0,0 +1,190 @@
#include "devicemodel.h"
DeviceModel::DeviceModel()
{}
DeviceModel::~DeviceModel()
{}
QString DeviceModel::name() const
{
return _name;
}
void DeviceModel::setName(const QString &newName)
{
_name = newName;
}
QString DeviceModel::description() const
{
return _description;
}
void DeviceModel::setDescription(const QString &newDescription)
{
_description = newDescription;
}
int DeviceModel::workEfficiency() const
{
return _workEfficiency;
}
void DeviceModel::setWorkEfficiency(int newWorkEfficiency)
{
_workEfficiency = newWorkEfficiency;
}
int DeviceModel::reliability() const
{
return _reliability;
}
void DeviceModel::setReliability(int newReliability)
{
_reliability = newReliability;
}
int DeviceModel::energyEfficiency() const
{
return _energyEfficiency;
}
void DeviceModel::setEnergyEfficiency(int newEnergyEfficiency)
{
_energyEfficiency = newEnergyEfficiency;
}
int DeviceModel::userFriendliness() const
{
return _userFriendliness;
}
void DeviceModel::setUserFriendliness(int newUserFriendliness)
{
_userFriendliness = newUserFriendliness;
}
int DeviceModel::durability() const
{
return _durability;
}
void DeviceModel::setDurability(int newDurability)
{
_durability = newDurability;
}
int DeviceModel::aestheticQualities() const
{
return _aestheticQualities;
}
void DeviceModel::setAestheticQualities(int newAestheticQualities)
{
_aestheticQualities = newAestheticQualities;
}
int DeviceModel::idType() const
{
return _idType;
}
void DeviceModel::setIdType(int newIdType)
{
_idType = newIdType;
}
QString DeviceModel::nameType() const
{
return _nameType;
}
void DeviceModel::setNameType(const QString &newNameType)
{
_nameType = newNameType;
}
int DeviceModel::idManuf() const
{
return _idManuf;
}
void DeviceModel::setIdManuf(int newIdManuf)
{
_idManuf = newIdManuf;
}
QString DeviceModel::nameManuf() const
{
return _nameManuf;
}
void DeviceModel::setNameManuf(const QString &newNameManuf)
{
_nameManuf = newNameManuf;
}
QList<DeviceStructureElement> DeviceModel::structureElements() const
{
return _structureElements;
}
void DeviceModel::setStructureElements(const QList<DeviceStructureElement> &newStructureElements)
{
_structureElements = newStructureElements;
}
void DeviceModel::fromJson(const QJsonObject &json)
{
setId(json["id"].toInt());
setName(json["name"].toString());
setDescription(json["description"].toString());
setWorkEfficiency(json["workEfficiency"].toInt());
setReliability(json["reliability"].toInt());
setEnergyEfficiency(json["energyEfficiency"].toInt());
setUserFriendliness(json["userFriendliness"].toInt());
setDurability(json["durability"].toInt());
setAestheticQualities(json["aestheticQualities"].toInt());
setIdType(json["idType"].toInt());
setNameType(json["nameType"].toString());
setIdManuf(json["idManuf"].toInt());
setNameManuf(json["nameManuf"].toString());
QJsonArray structureElementsArray = json["structureElements"].toArray();
QList<DeviceStructureElement> elements;
for (const QJsonValue &value : structureElementsArray) {
DeviceStructureElement element;
element.fromJson(value.toObject());
elements.append(element);
}
setStructureElements(elements);
}
QJsonObject DeviceModel::toJson() const
{
QJsonObject obj;
obj["id"] = id();
obj["name"] = name();
obj["description"] = description();
obj["workEfficiency"] = workEfficiency();
obj["reliability"] = reliability();
obj["energyEfficiency"] = energyEfficiency();
obj["userFriendliness"] = userFriendliness();
obj["durability"] = durability();
obj["aestheticQualities"] = aestheticQualities();
obj["idType"] = idType();
obj["nameType"] = nameType();
obj["idManuf"] = idManuf();
obj["nameManuf"] = nameManuf();
QJsonArray structureElementsArray;
for (const DeviceStructureElement &element : structureElements()) {
structureElementsArray.append(element.toJson());
}
obj["structureElements"] = structureElementsArray;
return obj;
}

75
models/devicemodel.h Normal file
View File

@ -0,0 +1,75 @@
#ifndef DEVICEMODEL_H
#define DEVICEMODEL_H
#include <QString>
#include <QList>
#include <QJsonArray>
#include "baseentity.h"
#include "devicestructureelement.h"
class DeviceModel : public BaseEntity
{
public:
DeviceModel();
virtual ~DeviceModel();
QString name() const;
void setName(const QString &newName);
QString description() const;
void setDescription(const QString &newDescription);
int workEfficiency() const;
void setWorkEfficiency(int newWorkEfficiency);
int reliability() const;
void setReliability(int newReliability);
int energyEfficiency() const;
void setEnergyEfficiency(int newEnergyEfficiency);
int userFriendliness() const;
void setUserFriendliness(int newUserFriendliness);
int durability() const;
void setDurability(int newDurability);
int aestheticQualities() const;
void setAestheticQualities(int newAestheticQualities);
int idType() const;
void setIdType(int newIdType);
QString nameType() const;
void setNameType(const QString &newNameType);
int idManuf() const;
void setIdManuf(int newIdManuf);
QString nameManuf() const;
void setNameManuf(const QString &newNameManuf);
QList<DeviceStructureElement> structureElements() const;
void setStructureElements(const QList<DeviceStructureElement> &newStructureElements);
void fromJson(const QJsonObject &json) override;
QJsonObject toJson() const override;
private:
QString _name = "";
QString _description = "";
int _workEfficiency = 0;
int _reliability = 0;
int _energyEfficiency = 0;
int _userFriendliness = 0;
int _durability = 0;
int _aestheticQualities = 0;
int _idType = 0;
QString _nameType = "";
int _idManuf = 0;
QString _nameManuf = "";
QList<DeviceStructureElement> _structureElements;
};
#endif // DEVICEMODEL_H

View File

@ -0,0 +1,79 @@
#include "devicestructureelement.h"
DeviceStructureElement::DeviceStructureElement()
{}
DeviceStructureElement::~DeviceStructureElement()
{}
QString DeviceStructureElement::nameModel() const
{
return _nameModel;
}
void DeviceStructureElement::setNameModel(const QString &newNameModel)
{
_nameModel = newNameModel;
}
QString DeviceStructureElement::nameManuf() const
{
return _nameManuf;
}
void DeviceStructureElement::setNameManuf(const QString &newNameManuf)
{
_nameManuf = newNameManuf;
}
QString DeviceStructureElement::description() const
{
return _description;
}
void DeviceStructureElement::setDescription(const QString &newDescription)
{
_description = newDescription;
}
QString DeviceStructureElement::nameType() const
{
return _nameType;
}
void DeviceStructureElement::setNameType(const QString &newNameType)
{
_nameType = newNameType;
}
int DeviceStructureElement::count() const
{
return _count;
}
void DeviceStructureElement::setCount(int newCount)
{
_count = newCount;
}
void DeviceStructureElement::fromJson(const QJsonObject &json)
{
setId(json["id"].toInt());
setNameModel(json["nameModel"].toString());
setNameManuf(json["nameManuf"].toString());
setDescription(json["description"].toString());
setNameType(json["nameType"].toString());
setCount(json["count"].toInt());
}
QJsonObject DeviceStructureElement::toJson() const
{
QJsonObject obj;
obj["id"] = id();
obj["nameModel"] = nameModel();
obj["nameManuf"] = nameManuf();
obj["description"] = description();
obj["nameType"] = nameType();
obj["count"] = count();
return obj;
}

View File

@ -0,0 +1,40 @@
#ifndef DEVICESTRUCTUREELEMENT_H
#define DEVICESTRUCTUREELEMENT_H
#include <QString>
#include "baseentity.h"
class DeviceStructureElement : public BaseEntity
{
public:
DeviceStructureElement();
virtual ~DeviceStructureElement();
QString nameModel() const;
void setNameModel(const QString &newNameModel);
QString nameManuf() const;
void setNameManuf(const QString &newNameManuf);
QString description() const;
void setDescription(const QString &newDescription);
QString nameType() const;
void setNameType(const QString &newNameType);
int count() const;
void setCount(int newCount);
void fromJson(const QJsonObject &json) override;
QJsonObject toJson() const override;
private:
QString _nameModel = "";
QString _nameManuf = "";
QString _description = "";
QString _nameType = "";
int _count = 1;
};
#endif // DEVICESTRUCTUREELEMENT_H

31
models/devicetype.cpp Normal file
View File

@ -0,0 +1,31 @@
#include "devicetype.h"
DeviceType::DeviceType()
{}
DeviceType::~DeviceType()
{}
QString DeviceType::name() const
{
return _name;
}
void DeviceType::setName(const QString &newName)
{
_name = newName;
}
void DeviceType::fromJson(const QJsonObject &json)
{
setId(json["id"].toInt());
setName(json["name"].toString());
}
QJsonObject DeviceType::toJson() const
{
QJsonObject obj;
obj["id"] = id();
obj["name"] = name();
return obj;
}

24
models/devicetype.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef DEVICETYPE_H
#define DEVICETYPE_H
#include <QString>
#include "baseentity.h"
class DeviceType : public BaseEntity
{
public:
DeviceType();
virtual ~DeviceType();
QString name() const;
void setName(const QString &newName);
void fromJson(const QJsonObject &json) override;
QJsonObject toJson() const override;
private:
QString _name = "";
};
#endif // DEVICETYPE_H

54
models/filterparams.cpp Normal file
View File

@ -0,0 +1,54 @@
#include "filterparams.h"
FilterParams::FilterParams()
{}
bool FilterParams::isWorking() const
{
return _isWorking;
}
void FilterParams::setIsWorking(bool newIsWorking)
{
_isWorking = newIsWorking;
}
double FilterParams::priceFrom() const
{
return _priceFrom;
}
void FilterParams::setPriceFrom(double newPriceFrom)
{
_priceFrom = newPriceFrom;
}
double FilterParams::priceTo() const
{
return _priceTo;
}
void FilterParams::setPriceTo(double newPriceTo)
{
_priceTo = newPriceTo;
}
bool FilterParams::getDisregardState() const
{
return disregardState;
}
void FilterParams::setDisregardState(bool newDisregardState)
{
disregardState = newDisregardState;
}
bool FilterParams::getApllyFilters() const
{
return apllyFilters;
}
void FilterParams::setApllyFilters(bool newApllyFilters)
{
apllyFilters = newApllyFilters;
}

32
models/filterparams.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef FILTERPARAMS_H
#define FILTERPARAMS_H
class FilterParams
{
public:
FilterParams();
bool isWorking() const;
void setIsWorking(bool newIsWorking);
double priceFrom() const;
void setPriceFrom(double newPriceFrom);
double priceTo() const;
void setPriceTo(double newPriceTo);
bool getDisregardState() const;
void setDisregardState(bool newDisregardState);
bool getApllyFilters() const;
void setApllyFilters(bool newApllyFilters);
private:
bool _isWorking = true;
double _priceFrom = -1;
double _priceTo = -1;
bool disregardState = false;
bool apllyFilters = false;
};
#endif // FILTERPARAMS_H

31
models/location.cpp Normal file
View File

@ -0,0 +1,31 @@
#include "location.h"
Location::Location()
{}
Location::~Location()
{}
QString Location::name() const
{
return _name;
}
void Location::setName(const QString &newName)
{
_name = newName;
}
void Location::fromJson(const QJsonObject &json)
{
setId(json["id"].toInt());
setName(json["name"].toString());
}
QJsonObject Location::toJson() const
{
QJsonObject obj;
obj["id"] = id();
obj["name"] = name();
return obj;
}

24
models/location.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef LOCATION_H
#define LOCATION_H
#include <QString>
#include "baseentity.h"
class Location : public BaseEntity
{
public:
Location();
virtual ~Location();
QString name() const;
void setName(const QString &newName);
void fromJson(const QJsonObject &json) override;
QJsonObject toJson() const override;
private:
QString _name = "";
};
#endif // LOCATION_H

31
models/manufacturer.cpp Normal file
View File

@ -0,0 +1,31 @@
#include "manufacturer.h"
Manufacturer::Manufacturer()
{}
Manufacturer::~Manufacturer()
{}
QString Manufacturer::name() const
{
return _name;
}
void Manufacturer::setName(const QString &newName)
{
_name = newName;
}
void Manufacturer::fromJson(const QJsonObject &json)
{
setId(json["id"].toInt());
setName(json["name"].toString());
}
QJsonObject Manufacturer::toJson() const
{
QJsonObject obj;
obj["id"] = id();
obj["name"] = name();
return obj;
}

24
models/manufacturer.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef MANUFACTURER_H
#define MANUFACTURER_H
#include <QString>
#include "baseentity.h"
class Manufacturer : public BaseEntity
{
public:
Manufacturer();
virtual ~Manufacturer();
QString name() const;
void setName(const QString &newName);
void fromJson(const QJsonObject &json) override;
QJsonObject toJson() const override;
private:
QString _name = "";
};
#endif // MANUFACTURER_H

12
models/types.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef TYPES_H
#define TYPES_H
#include "location.h" // IWYU pragma: keep
#include "department.h" // IWYU pragma: keep
#include "manufacturer.h" // IWYU pragma: keep
#include "devicetype.h" // IWYU pragma: keep
#include "devicestructureelement.h" // IWYU pragma: keep
#include "devicemodel.h" // IWYU pragma: keep
#include "device.h" // IWYU pragma: keep
#endif // TYPES_H

86
presenter.cpp Normal file
View File

@ -0,0 +1,86 @@
#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();
}

29
presenter.h Normal file
View File

@ -0,0 +1,29 @@
#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

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
resources/images/search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

45
resources/resources.qrc Normal file
View File

@ -0,0 +1,45 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file>images/mw-icon.png</file>
</qresource>
<qresource>
<file>images/search.png</file>
</qresource>
<qresource>
<file>images/search-hover.png</file>
</qresource>
<qresource>
<file>images/question.png</file>
</qresource>
<qresource>
<file>images/down-arrow.png</file>
</qresource>
<qresource>
<file>images/device-type-1.png</file>
</qresource>
<qresource>
<file>images/device-type-2.png</file>
</qresource>
<qresource>
<file>images/device-type-3.png</file>
</qresource>
<qresource>
<file>images/device-type-4.png</file>
</qresource>
<qresource>
<file>images/device-type-5.png</file>
</qresource>
<qresource>
<file>images/device-type-6.png</file>
</qresource>
<qresource>
<file>images/device-type-7.png</file>
</qresource>
<qresource>
<file>images/device-type-8.png</file>
</qresource>
<qresource prefix="/">
<file>styles.qss</file>
</qresource>
</RCC>

47
resources/styles.qss Normal file
View File

@ -0,0 +1,47 @@
QMainWindow {
background-color: rgb(246, 246, 246);
}
QComboBox, QPushButton, QLineEdit, QTextEdit, QListWidget, QTableWidget, QGroupBox, QStackedWidget {
border: 1px solid black;
border-radius: 2px;
}
QGroupBox#groupBoxFilters, QStackedWidget#stackedWidget {
background-color: white;
}
QLineEdit {
border-radius: 5px;
}
QComboBox {
background-color: white;
}
QComboBox::drop-down {
border: 0px;
}
QComboBox::down-arrow {
width: 10px;
height: 10px;
image: url(:/images/down-arrow.png);
}
QPushButton {
background-color: white;
padding: 5px;
}
QPushButton:hover {
background-color: green;
color: white;
}
QPushButton:pressed {
background-color: green;
border-radius: 4px;
border-width: 2px;
color: white;
}

View File

@ -0,0 +1,24 @@
#include "buttonhoverwatcher.h"
ButtonHoverWatcher::ButtonHoverWatcher(QObject *parent) : QObject(parent)
{}
bool ButtonHoverWatcher::eventFilter(QObject *watched, QEvent *event)
{
QPushButton * button = qobject_cast<QPushButton*>(watched);
if (!button) {
return false;
}
if (event->type() == QEvent::Enter) {
button->setIcon(QIcon(":/images/search-hover.png"));
return true;
}
if (event->type() == QEvent::Leave){
button->setIcon(QIcon(":/images/search.png"));
return true;
}
return false;
}

View File

@ -0,0 +1,16 @@
#ifndef BUTTONHOVERWATCHER_H
#define BUTTONHOVERWATCHER_H
#include <QObject>
#include <QPushButton>
#include <QEvent>
class ButtonHoverWatcher : public QObject
{
Q_OBJECT
public:
explicit ButtonHoverWatcher(QObject *parent = nullptr);
virtual bool eventFilter(QObject * watched, QEvent * event) Q_DECL_OVERRIDE;
};
#endif // BUTTONHOVERWATCHER_H