File indexing completed on 2024-05-05 04:39:18

0001 /*
0002     SPDX-FileCopyrightText: 2020 Friedrich W. H. Kossebau <kossebau@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "checksetmanagewidget.h"
0008 
0009 // plugin
0010 #include "checksetselectionlistmodel.h"
0011 #include "checksetselectionmanager.h"
0012 #include "debug.h"
0013 // KDevPlatform
0014 #include <util/scopeddialog.h>
0015 // KF
0016 #include <KLocalizedString>
0017 // Qt
0018 #include <QDialog>
0019 #include <QDialogButtonBox>
0020 #include <QPushButton>
0021 #include <QLineEdit>
0022 #include <QLabel>
0023 #include <QVBoxLayout>
0024 #include <QHBoxLayout>
0025 #include <QValidator>
0026 
0027 using namespace KDevelop;
0028 
0029 namespace Clazy {
0030 
0031 class CheckSetNameValidator : public QValidator
0032 {
0033     Q_OBJECT
0034 
0035 public:
0036     explicit CheckSetNameValidator(CheckSetSelectionListModel* checkSetSelectionListModel,
0037                                    QObject* parent = nullptr);
0038     QValidator::State validate(QString& input, int& pos) const override;
0039 
0040 private:
0041     const CheckSetSelectionListModel* const m_checkSetSelectionListModel;
0042 };
0043 
0044 CheckSetNameValidator::CheckSetNameValidator(CheckSetSelectionListModel* checkSetSelectionListModel,
0045                                            QObject* parent)
0046     : QValidator(parent)
0047     , m_checkSetSelectionListModel(checkSetSelectionListModel)
0048 {
0049 }
0050 
0051 QValidator::State CheckSetNameValidator::validate(QString& input, int& pos) const
0052 {
0053     Q_UNUSED(pos);
0054 
0055     if (input.isEmpty()) {
0056         return QValidator::Intermediate;
0057     }
0058     if (m_checkSetSelectionListModel->hasCheckSetSelection(input)) {
0059         return QValidator::Intermediate;
0060     }
0061     return QValidator::Acceptable;
0062 }
0063 
0064 
0065 class CheckSetNameEditor : public QDialog
0066 {
0067     Q_OBJECT
0068 
0069 public:
0070     explicit CheckSetNameEditor(CheckSetSelectionListModel* checkSetSelectionListModel,
0071                                 const QString& defaultName, QWidget* parent = nullptr);
0072 
0073 public:
0074     QString name() const;
0075 
0076 private:
0077     void handleNameEdit(const QString& text);
0078 
0079 private:
0080     CheckSetNameValidator* m_validator;
0081     QLineEdit* m_nameEdit;
0082     QPushButton* m_okButton;
0083 };
0084 
0085 CheckSetNameEditor::CheckSetNameEditor(CheckSetSelectionListModel* checkSetSelectionListModel,
0086                                        const QString& defaultName, QWidget* parent)
0087     : QDialog(parent)
0088 {
0089     setWindowTitle(i18nc("@title:window", "Enter Name of New Check Set"));
0090 
0091     auto* layout = new QVBoxLayout(this);
0092 
0093     auto* editLayout = new QHBoxLayout;
0094 
0095     auto* label = new QLabel(i18nc("@label:textbox", "Name:"));
0096     editLayout->addWidget(label);
0097     m_nameEdit = new QLineEdit;
0098     m_nameEdit->setClearButtonEnabled(true);
0099     editLayout->addWidget(m_nameEdit);
0100     layout->addLayout(editLayout);
0101 
0102     auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0103     m_okButton = buttonBox->button(QDialogButtonBox::Ok);
0104     m_okButton->setEnabled(false);
0105     m_okButton->setDefault(true);
0106     connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0107     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0108     layout->addWidget(buttonBox);
0109 
0110     m_validator = new CheckSetNameValidator(checkSetSelectionListModel, this);
0111     connect(m_nameEdit, &QLineEdit::textChanged, this, &CheckSetNameEditor::handleNameEdit);
0112 
0113     m_nameEdit->setText(defaultName);
0114     m_nameEdit->selectAll();
0115 }
0116 
0117 QString CheckSetNameEditor::name() const
0118 {
0119     return m_nameEdit->text();
0120 }
0121 
0122 void CheckSetNameEditor::handleNameEdit(const QString& _text)
0123 {
0124     int pos;
0125     QString text(_text);
0126     const bool isValidCheckSetSelectionName = (m_validator->validate(text, pos) == QValidator::Acceptable);
0127 
0128     m_okButton->setEnabled(isValidCheckSetSelectionName);
0129 }
0130 
0131 
0132 CheckSetManageWidget::CheckSetManageWidget(QWidget* parent)
0133     : QWidget(parent)
0134 {
0135     m_ui.setupUi(this);
0136 }
0137 
0138 void CheckSetManageWidget::setCheckSetSelectionManager(CheckSetSelectionManager* checkSetSelectionManager,
0139                                                        const QSharedPointer<const ChecksDB>& db)
0140 {
0141     m_ui.enabledChecks->setChecksDb(db);
0142     m_checkSetSelectionListModel = new CheckSetSelectionListModel(checkSetSelectionManager, this);
0143     m_ui.checkSetSelect->setModel(m_checkSetSelectionListModel);
0144 
0145     connect(m_ui.cloneCheckSetSelectionButton, &QPushButton::clicked,
0146             this, &CheckSetManageWidget::cloneSelectedCheckSetSelection);
0147     connect(m_ui.addCheckSetSelectionButton, &QPushButton::clicked,
0148             this, &CheckSetManageWidget::addCheckSetSelection);
0149     connect(m_ui.removeCheckSetSelectionButton, &QPushButton::clicked,
0150             this, &CheckSetManageWidget::removeSelectedCheckSetSelection);
0151     connect(m_ui.setAsDefaultCheckSetSelectionButton, &QPushButton::clicked,
0152             this, &CheckSetManageWidget::setSelectedCheckSetSelectionAsDefault);
0153     connect(m_ui.editCheckSetSelectionNameButton, &QPushButton::clicked,
0154             this, &CheckSetManageWidget::editSelectedCheckSetSelectionName);
0155     connect(m_ui.checkSetSelect, QOverload<int>::of(&KComboBox::currentIndexChanged),
0156             this, &CheckSetManageWidget::onSelectedCheckSetSelectionChanged);
0157 
0158     connect(m_checkSetSelectionListModel, &CheckSetSelectionListModel::defaultCheckSetSelectionChanged,
0159             this, &CheckSetManageWidget::onDefaultCheckSetSelectionChanged);
0160 
0161     connect(m_checkSetSelectionListModel, &CheckSetSelectionListModel::rowsInserted,
0162             this, &CheckSetManageWidget::changed);
0163     connect(m_checkSetSelectionListModel, &CheckSetSelectionListModel::rowsRemoved,
0164             this, &CheckSetManageWidget::changed);
0165     connect(m_checkSetSelectionListModel, &CheckSetSelectionListModel::checkSetSelectionChanged,
0166             this, &CheckSetManageWidget::changed);
0167     connect(m_checkSetSelectionListModel, &CheckSetSelectionListModel::defaultCheckSetSelectionChanged,
0168             this, &CheckSetManageWidget::changed);
0169 
0170     connect(m_ui.enabledChecks, &ChecksWidget::checksChanged,
0171             this, &CheckSetManageWidget::onEnabledChecksChanged);
0172 
0173     const int defaultIndex = m_checkSetSelectionListModel->defaultCheckSetSelectionRow();
0174     m_ui.checkSetSelect->setCurrentIndex(defaultIndex);
0175 }
0176 
0177 void CheckSetManageWidget::setSelectedCheckSetSelectionAsDefault()
0178 {
0179     const int selectedIndex = m_ui.checkSetSelect->currentIndex();
0180     m_checkSetSelectionListModel->setDefaultCheckSetSelection(selectedIndex);
0181 }
0182 
0183 void CheckSetManageWidget::reload()
0184 {
0185     if (!m_checkSetSelectionListModel) {
0186         return;
0187     }
0188 
0189     const int currentIndexBefore = m_ui.checkSetSelect->currentIndex();
0190     const QString currentId = m_checkSetSelectionListModel->checkSetSelectionId(currentIndexBefore);
0191     m_checkSetSelectionListModel->reload();
0192 
0193     const int currentIndexAfter = m_checkSetSelectionListModel->row(currentId);
0194     m_ui.checkSetSelect->setCurrentIndex(currentIndexAfter);
0195 }
0196 
0197 void CheckSetManageWidget::store() const
0198 {
0199     if (!m_checkSetSelectionListModel) {
0200         return;
0201     }
0202 
0203     m_checkSetSelectionListModel->store();
0204 }
0205 
0206 QString CheckSetManageWidget::askNewCheckSetSelectionName(const QString& defaultName)
0207 {
0208     ScopedDialog<CheckSetNameEditor> dialog(m_checkSetSelectionListModel, defaultName, this);
0209 
0210     if (dialog->exec() != QDialog::Accepted) {
0211         return {};
0212     }
0213 
0214     return dialog->name();
0215 }
0216 
0217 void CheckSetManageWidget::editSelectedCheckSetSelectionName()
0218 {
0219     const int currentIndex = m_ui.checkSetSelect->currentIndex();
0220     const auto currentCheckSetSelectionName = m_checkSetSelectionListModel->checkSetSelectionName(currentIndex);
0221     const auto checkSetSelectionName = askNewCheckSetSelectionName(currentCheckSetSelectionName);
0222     if (checkSetSelectionName.isEmpty()) {
0223         return;
0224     }
0225 
0226     m_checkSetSelectionListModel->setName(currentIndex, checkSetSelectionName);
0227 }
0228 
0229 void CheckSetManageWidget::addCheckSetSelection()
0230 {
0231     const auto checkSetSelectionName = askNewCheckSetSelectionName(QString());
0232     if (checkSetSelectionName.isEmpty()) {
0233         return;
0234     }
0235 
0236     const int checkSetSelectionIndex = m_checkSetSelectionListModel->addCheckSetSelection(checkSetSelectionName);
0237 
0238     m_ui.checkSetSelect->setCurrentIndex(checkSetSelectionIndex);
0239     m_ui.enabledChecks->setFocus(Qt::OtherFocusReason);
0240 }
0241 
0242 void CheckSetManageWidget::cloneSelectedCheckSetSelection()
0243 {
0244     const int currentIndex = m_ui.checkSetSelect->currentIndex();
0245     const auto currentCheckSetSelectionName = m_checkSetSelectionListModel->checkSetSelectionName(currentIndex);
0246     // pass original name as starting name, as the user might want to enter a variant of it
0247     const auto checkSetSelectionName = askNewCheckSetSelectionName(currentCheckSetSelectionName);
0248     if (checkSetSelectionName.isEmpty()) {
0249         return;
0250     }
0251 
0252     const int checkSetSelectionIndex = m_checkSetSelectionListModel->cloneCheckSetSelection(checkSetSelectionName, currentIndex);
0253 
0254     m_ui.checkSetSelect->setCurrentIndex(checkSetSelectionIndex);
0255     m_ui.enabledChecks->setFocus(Qt::OtherFocusReason);
0256 }
0257 
0258 void CheckSetManageWidget::removeSelectedCheckSetSelection()
0259 {
0260     const int selectedCheckSetSelectionIndex = m_ui.checkSetSelect->currentIndex();
0261 
0262     if (selectedCheckSetSelectionIndex == -1) {
0263         return;
0264     }
0265 
0266     m_checkSetSelectionListModel->removeCheckSetSelection(selectedCheckSetSelectionIndex);
0267 
0268     const int defaultCheckSetSelectionIndex = m_checkSetSelectionListModel->defaultCheckSetSelectionRow();
0269     m_ui.checkSetSelect->setCurrentIndex(defaultCheckSetSelectionIndex);
0270 }
0271 
0272 void CheckSetManageWidget::onDefaultCheckSetSelectionChanged(const QString& checkSetSelectionId)
0273 {
0274     const int defaultCheckSetSelectionIndex = m_checkSetSelectionListModel->row(checkSetSelectionId);
0275     const int selectedCheckSetSelectionIndex = m_ui.checkSetSelect->currentIndex();
0276     const bool isDefaultCheckSetSelection = (defaultCheckSetSelectionIndex == selectedCheckSetSelectionIndex);
0277 
0278     m_ui.setAsDefaultCheckSetSelectionButton->setEnabled(!isDefaultCheckSetSelection);
0279 }
0280 
0281 void CheckSetManageWidget::onSelectedCheckSetSelectionChanged(int selectedCheckSetSelectionIndex)
0282 {
0283     const bool isDefaultCheckSetSelection = (m_checkSetSelectionListModel->defaultCheckSetSelectionRow() == selectedCheckSetSelectionIndex);
0284     const bool isCheckSetSelectionSelected = (selectedCheckSetSelectionIndex != -1);
0285 
0286     m_ui.cloneCheckSetSelectionButton->setEnabled(isCheckSetSelectionSelected);
0287     m_ui.removeCheckSetSelectionButton->setEnabled(isCheckSetSelectionSelected);
0288     m_ui.setAsDefaultCheckSetSelectionButton->setEnabled(!isDefaultCheckSetSelection);
0289 
0290     m_ui.enabledChecks->blockSignals(true);
0291     const QString checks = m_checkSetSelectionListModel->checkSetSelectionAsString(selectedCheckSetSelectionIndex);
0292     m_ui.enabledChecks->setChecks(checks);
0293     m_ui.enabledChecks->setEnabled(isCheckSetSelectionSelected);
0294     m_ui.enabledChecks->blockSignals(false);
0295 }
0296 
0297 void CheckSetManageWidget::onEnabledChecksChanged(const QString& selection)
0298 {
0299     const int selectedCheckSetSelectionIndex = m_ui.checkSetSelect->currentIndex();
0300     m_checkSetSelectionListModel->setSelection(selectedCheckSetSelectionIndex, selection);
0301 }
0302 
0303 }
0304 
0305 #include "checksetmanagewidget.moc"
0306 #include "moc_checksetmanagewidget.cpp"