PNPkurs-PIbd-31-Alekseev-I-S/mainwindow.cpp
Иван Алексеев f522412382 готово
2025-01-15 22:57:00 +04:00

500 lines
16 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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<int, Stages> &map)
{
mapStages = map;
}
void MainWindow::getTeams(QMap<int, Team> &map)
{
mapTeams = map;
}
void MainWindow::getWorkers(QMap<int, Worker> &map)
{
mapWorkers = map;
}
void MainWindow::getDeviceTypes(QMap<int, DeviceType> &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<int, DeviceModel> &map)
{
mapDeviceModels = map;
}
void MainWindow::getProjects(QMap<int, Project> &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<DeviceType>(mapDeviceTypes);
break;
case 2: // Этапы
fillTable<Stages>(mapStages);
break;
case 3: // Команды
fillTable<Team>(mapTeams);
break;
case 4: // Работники
fillTable<Worker>(mapWorkers);
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)
{
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<double>::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();
}