#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->listWidgetProjects->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); 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->listWidgetProjects, 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->pushButtonCanselFilters, SIGNAL(clicked()), this, SLOT(pushButtonCancelFiltersClicked())); connect(ui->pushButtonDefault, SIGNAL(clicked()), this, SLOT(pushButtonDefaultClicked())); QFile styleFile(":/styles.qss"); if (styleFile.open(QFile::ReadOnly)) { QTextStream ts(&styleFile); QString style = ts.readAll(); qApp->setStyleSheet(style); } } MainWindow::~MainWindow() { delete ui; } void MainWindow::getStages(QMap &map) { mapStages = map; } void MainWindow::getTeams(QMap &map) { mapTeams = map; } void MainWindow::getWorkers(QMap &map) { mapWorkers = map; } void MainWindow::getDeviceTypes(QMap &map) { mapDeviceTypes = map; for (int i = 1; i <= mapDeviceTypes.size(); i++) { QString imagePath = QString(":/images/device-type-%1.png").arg(i); deviceTypeImages[i] = imagePath; } } void MainWindow::getDeviceModels(QMap &map) { mapDeviceModels = map; } void MainWindow::getProjects(QMap &map) { mapDevices = map; updateTableWidget(0); } void MainWindow::updateTableWidget(int index) { returnToDeviceList(); ui->tableWidget->clearContents(); ui->tableWidget->setRowCount(0); switch (index) { case 0: // Все устройства clearDevicesOutputSettings(); updateListWidgetDevices(0); break; case 1: // Типы устройств fillTable(mapDeviceTypes); break; case 2: // Этапы fillTable(mapStages); break; case 3: // Команды fillTable(mapTeams); break; case 4: // Работники fillTable(mapWorkers); break; case 5: // Модели проектов fillTable(mapDeviceModels); break; default: break; } } void MainWindow::updateListWidget() { returnToDeviceList(); int selectedEntityId = getSelectedIndex(); if (selectedEntityId == -1) return; clearDevicesOutputSettings(); updateListWidgetDevices(selectedEntityId); } template void MainWindow::fillTable(const QMap &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) { ui->listWidgetProjects->clear(); auto filteredDevices = logic->findDevicesByAllParameters( mapDevices, entityId, ui->comboBoxFilters->currentIndex(), searchInfo, filterParams, ui->comboBoxSort->currentText() ); if (filteredDevices.isEmpty()) { QListWidgetItem *item = new QListWidgetItem(ui->listWidgetProjects); ui->listWidgetProjects->addItem(item); QWidget *cardWidget = createMessageEmptyCard(); item->setSizeHint(cardWidget->minimumSizeHint()); item->setFlags(item->flags() & ~Qt::ItemIsEnabled); ui->listWidgetProjects->setItemWidget(item, cardWidget); } else { for (auto &device : filteredDevices) { addDeviceToList(device); } } } QWidget *MainWindow::createMessageEmptyCard() { QWidget *cardWidget = new QWidget(ui->listWidgetProjects); 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 Project &project) { QWidget *cardWidget = new QWidget(ui->listWidgetProjects); 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[project.deviceModel().idType()]; QPixmap pixmap(imagePath); imageLabel->setPixmap(pixmap.scaled(100, 100, Qt::KeepAspectRatio)); iconTextlayout->addWidget(imageLabel); QVBoxLayout *textLayout = new QVBoxLayout(); QLabel *serialNumberLabel = new QLabel(project.name(), cardWidget); QFont serialNumberFont("Arial", 14, QFont::Bold); serialNumberLabel->setFont(serialNumberFont); textLayout->addWidget(serialNumberLabel); QFont generalFont("Arial", 11); QString typeName = project.deviceModel().nameType(); typeName = typeName.left(typeName.length()); if (typeName == "Персональные компьютер") typeName = "Персональный компьютер"; QLabel *typeNameLabel = new QLabel(typeName + ": " + project.deviceModel().name(), cardWidget); typeNameLabel->setFont(generalFont); textLayout->addWidget(typeNameLabel); QLabel *statusLabel = new QLabel(project.isReady() ? "Готов" : "Не готов", cardWidget); statusLabel->setFont(generalFont); textLayout->addWidget(statusLabel); QHBoxLayout *priceLikeLayout = new QHBoxLayout(); priceLikeLayout->setSpacing(100); QLabel *priceLabel = new QLabel(QString::number(project.budget()) + " ₽", 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(project.isLiked()); likeCheckBox->setFont(generalFont); likeCheckBox->setStyleSheet(likeCheckBox->isChecked() ? "color: green;" : "color: black;"); connect(likeCheckBox, &QCheckBox::toggled, this, [this, project, likeCheckBox](bool checked) { Project& deviceRef = mapDevices[project.id()]; deviceRef.setIsLiked(checked); QString message = checked ? "Проект добавлен в избранное." : "Проект удален из избранного."; QMessageBox::information(this, "Обновление", message); likeCheckBox->setStyleSheet(checked ? "color: green;" : "color: black;"); }); 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 Project &device) { QListWidgetItem *item = new QListWidgetItem(ui->listWidgetProjects); ui->listWidgetProjects->addItem(item); QWidget *cardWidget = createDeviceCard(device); item->setSizeHint(cardWidget->minimumSizeHint()); ui->listWidgetProjects->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(); Project device = mapDevices[deviceId]; idCard = deviceId; if (!device.StartProjectDate().isValid()) qDebug() << "StartProjectDate is invalid for device ID:" << device.id(); if (!device.FinishProjectDate().isValid()) qDebug() << "FinishProjectDate is invalid for device ID:" << device.id(); ui->lineEditId->setText(QString::number(device.id())); ui->lineEditSerialNum->setText(device.name()); ui->lineEditPrice->setText(QString::number(device.budget(), 'f', 2)); ui->lineEditEmployee->setText(device.nameTeam()); ui->lineEditModel->setText(device.deviceModel().name()); ui->lineEditType->setText(device.deviceModel().nameType()); ui->textEditFurtherInformation->setPlainText(device.description()); ui->checkBoxIsWorking->setChecked(device.isReady()); ui->stackedWidget->setCurrentIndex(1); } void MainWindow::clearFilters() { ui->radioButtonWorking->setChecked(true); ui->doubleSpinBoxFrom->setValue(0.00); ui->doubleSpinBoxTo->setValue(0.00); filterParams.setIsReady(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.setIsReady(ui->radioButtonWorking->isChecked()); if (priceFrom == 0.00 && priceTo == 0.00) { filterParams.setPriceFrom(0.00); filterParams.setPriceTo(std::numeric_limits::max()); } else { filterParams.setPriceFrom(priceFrom); filterParams.setPriceTo(priceTo); } updateListWidgetDevices(getSelectedIndex()); } void MainWindow::pushButtonCancelFiltersClicked() { clearFilters(); updateListWidgetDevices(getSelectedIndex()); } void MainWindow::pushButtonDefaultClicked() { clearDevicesOutputSettings(); updateListWidgetDevices(getSelectedIndex()); } void MainWindow::closeEvent(QCloseEvent *event) { ServiceLoadDB serviceLoadDB; serviceLoadDB.updateLikesState(mapDevices); event->accept(); }