File indexing completed on 2024-12-15 03:45:02

0001 /*
0002     SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: MIT
0005 */
0006 
0007 #include "aggregationeditwidget.h"
0008 #include "ui_aggregationeditwidget.h"
0009 #include "schemaentryitemeditorfactory.h"
0010 
0011 #include <core/aggregation.h>
0012 #include <model/aggregationeditormodel.h>
0013 #include <model/aggregationelementeditmodel.h>
0014 
0015 #include <QMenu>
0016 #include <QMessageBox>
0017 #include <QStyledItemDelegate>
0018 
0019 using namespace KUserFeedback::Console;
0020 
0021 AggregationEditWidget::AggregationEditWidget(QWidget* parent) :
0022     QWidget(parent),
0023     ui(new Ui::AggregationEditWidget),
0024     m_model(new AggregationEditorModel(this)),
0025     m_editorFactory(new SchemaEntryItemEditorFactory),
0026     m_elementModel(new AggregationElementEditModel(this))
0027 {
0028     ui->setupUi(this);
0029 
0030     ui->aggregationView->setModel(m_model);
0031     ui->aggregationView->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
0032     qobject_cast<QStyledItemDelegate*>(ui->aggregationView->itemDelegate())->setItemEditorFactory(m_editorFactory.get());
0033     connect(ui->aggregationView, &QWidget::customContextMenuRequested, this, &AggregationEditWidget::contextMenu);
0034     connect(ui->aggregationView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &AggregationEditWidget::selectionChanged);
0035     connect(m_model, &QAbstractItemModel::dataChanged, this, &AggregationEditWidget::productChanged);
0036     connect(m_model, &QAbstractItemModel::dataChanged, this, &AggregationEditWidget::updateState);
0037 
0038     connect(ui->actionAddAggregation, &QAction::triggered, this, &AggregationEditWidget::addAggregation);
0039     connect(ui->actionDeleteAggregation, &QAction::triggered, this, &AggregationEditWidget::deleteAggregation);
0040 
0041     ui->elementView->setModel(m_elementModel);
0042     ui->elementView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
0043     qobject_cast<QStyledItemDelegate*>(ui->elementView->itemDelegate())->setItemEditorFactory(m_editorFactory.get());
0044     connect(ui->elementView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &AggregationEditWidget::updateState);
0045     connect(m_elementModel, &QAbstractItemModel::dataChanged, this, [this]() {
0046         auto p = product();
0047         auto aggrs = p.aggregations();
0048         aggrs[ui->aggregationView->selectionModel()->selectedRows().at(0).row()] = m_elementModel->aggregation();
0049         p.setAggregations(aggrs);
0050         m_model->setProduct(p);
0051         Q_EMIT productChanged();
0052     });
0053     connect(ui->addButton, &QPushButton::clicked, this, &AggregationEditWidget::addElement);
0054     connect(ui->deleteButton, &QPushButton::clicked, this, &AggregationEditWidget::deleteElement);
0055 
0056     addActions({ ui->actionAddAggregation, ui->actionDeleteAggregation });
0057     updateState();
0058 }
0059 
0060 AggregationEditWidget::~AggregationEditWidget() = default;
0061 
0062 Product AggregationEditWidget::product() const
0063 {
0064     return m_model->product();
0065 }
0066 
0067 void AggregationEditWidget::setProduct(const Product& product)
0068 {
0069     m_model->setProduct(product);
0070     m_editorFactory->setProduct(product);
0071     updateState();
0072 }
0073 
0074 Aggregation AggregationEditWidget::currentAggregation() const
0075 {
0076     const auto rows = ui->aggregationView->selectionModel()->selectedRows();
0077     if (rows.isEmpty())
0078         return {};
0079 
0080     return product().aggregations().at(rows.at(0).row());
0081 }
0082 
0083 void AggregationEditWidget::addAggregation()
0084 {
0085     auto p = product();
0086     auto aggrs = p.aggregations();
0087     aggrs += Aggregation();
0088     p.setAggregations(aggrs);
0089     setProduct(p);
0090     Q_EMIT productChanged();
0091 }
0092 
0093 void AggregationEditWidget::deleteAggregation()
0094 {
0095     const auto rows = ui->aggregationView->selectionModel()->selectedRows();
0096     if (rows.isEmpty())
0097         return;
0098 
0099     const auto r = QMessageBox::critical(this, tr("Delete Aggregation"),
0100         tr("Do you want to delete the currently selected aggregation?"),
0101         QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard);
0102     if (r != QMessageBox::Discard)
0103         return;
0104 
0105     const auto idx = rows.at(0);
0106     auto p = product();
0107     auto aggrs = p.aggregations();
0108     aggrs.remove(idx.row());
0109     p.setAggregations(aggrs);
0110     setProduct(p);
0111     Q_EMIT productChanged();
0112 }
0113 
0114 void AggregationEditWidget::addElement()
0115 {
0116     auto aggr = m_elementModel->aggregation();
0117     auto elems = aggr.elements();
0118     elems.push_back({});
0119     aggr.setElements(elems);
0120     m_elementModel->setAggregation(aggr);
0121 }
0122 
0123 void AggregationEditWidget::deleteElement()
0124 {
0125     auto aggr = m_elementModel->aggregation();
0126     auto elems = aggr.elements();
0127     elems.removeAt(ui->elementView->selectionModel()->selectedRows().at(0).row());
0128     aggr.setElements(elems);
0129     m_elementModel->setAggregation(aggr);
0130 
0131     auto p = product();
0132     auto aggrs = p.aggregations();
0133     aggrs[ui->aggregationView->selectionModel()->selectedRows().at(0).row()] = aggr;
0134     p.setAggregations(aggrs);
0135     m_model->setProduct(p);
0136     Q_EMIT productChanged();
0137 }
0138 
0139 void AggregationEditWidget::updateState()
0140 {
0141     ui->actionAddAggregation->setEnabled(product().isValid());
0142     ui->actionDeleteAggregation->setEnabled(ui->aggregationView->selectionModel()->hasSelection());
0143 
0144     const auto aggr = currentAggregation();
0145     const auto isMultiElement = aggr.type() == Aggregation::Category;
0146     ui->elementView->setEnabled(isMultiElement);
0147     ui->addButton->setEnabled(isMultiElement);
0148     ui->deleteButton->setEnabled(isMultiElement && ui->elementView->selectionModel()->hasSelection());
0149 }
0150 
0151 void AggregationEditWidget::contextMenu(QPoint pos)
0152 {
0153     QMenu menu;
0154     menu.addActions({ ui->actionAddAggregation, ui->actionDeleteAggregation });
0155     menu.exec(ui->aggregationView->viewport()->mapToGlobal(pos));
0156 }
0157 
0158 void AggregationEditWidget::selectionChanged()
0159 {
0160     m_elementModel->setAggregation(currentAggregation());
0161     updateState();
0162 }
0163 
0164 #include "moc_aggregationeditwidget.cpp"