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

0001 /*
0002     SPDX-FileCopyrightText: 2012 Miha Čančula <miha@noughmad.eu>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "templateoptionspage.h"
0008 
0009 #include "templateclassassistant.h"
0010 #include "debug.h"
0011 
0012 #include <language/codegen/sourcefiletemplate.h>
0013 
0014 #include <KLocalizedString>
0015 
0016 #include <QLineEdit>
0017 #include <QSpinBox>
0018 #include <QGroupBox>
0019 #include <QVBoxLayout>
0020 #include <QFormLayout>
0021 #include <QLabel>
0022 #include <QCheckBox>
0023 #include <QComboBox>
0024 
0025 using namespace KDevelop;
0026 
0027 class KDevelop::TemplateOptionsPagePrivate
0028 {
0029 public:
0030     QVector<SourceFileTemplate::ConfigOption> entries;
0031     QHash<QString, QWidget*> controls;
0032     QHash<QString, QByteArray> typeProperties;
0033     QWidget *firstEditWidget;
0034     QList<QWidget*> groupBoxes;
0035 };
0036 
0037 TemplateOptionsPage::TemplateOptionsPage(QWidget* parent)
0038 : QWidget(parent)
0039 , d(new TemplateOptionsPagePrivate)
0040 {
0041     d->firstEditWidget = nullptr;
0042 
0043     d->typeProperties.insert(QStringLiteral("String"), "text");
0044     d->typeProperties.insert(QStringLiteral("Enum"), "currentText");
0045     d->typeProperties.insert(QStringLiteral("Int"), "value");
0046     d->typeProperties.insert(QStringLiteral("Bool"), "checked");
0047 }
0048 
0049 TemplateOptionsPage::~TemplateOptionsPage()
0050 {
0051     delete d;
0052 }
0053 
0054 void TemplateOptionsPage::load(const SourceFileTemplate& fileTemplate, TemplateRenderer* renderer)
0055 {
0056     // TODO: keep any old changed values, as it comes by surprise to have them lost
0057     // when going back and forward
0058 
0059     // clear anything as there is on reentering the page
0060     d->entries.clear();
0061     d->controls.clear();
0062     // clear any old option group boxes & the base layout
0063     d->firstEditWidget = nullptr;
0064     qDeleteAll(d->groupBoxes);
0065     d->groupBoxes.clear();
0066     delete layout();
0067 
0068     auto* layout = new QVBoxLayout();
0069     layout->setContentsMargins(0, 0, 0, 0);
0070 
0071     const auto customOptions = fileTemplate.customOptions(renderer);
0072     d->groupBoxes.reserve(customOptions.size());
0073     d->entries.reserve(customOptions.size());
0074     for (const auto& optionGroup : customOptions) {
0075         auto* box = new QGroupBox(this);
0076         d->groupBoxes.append(box);
0077 
0078         box->setTitle(optionGroup.name);
0079 
0080         auto* formLayout = new QFormLayout;
0081 
0082         d->entries << optionGroup.options;
0083         for (const auto& entry : optionGroup.options) {
0084             QWidget* control = nullptr;
0085             const QString type = entry.type;
0086             if (type == QLatin1String("String"))
0087             {
0088                 control = new QLineEdit(entry.value.toString(), box);
0089             }
0090             else if (type == QLatin1String("Enum"))
0091             {
0092                 auto input = new QComboBox(box);
0093                 input->addItems(entry.values);
0094                 input->setCurrentText(entry.value.toString());
0095                 control = input;
0096             }
0097             else if (type == QLatin1String("Int"))
0098             {
0099                 auto input = new QSpinBox(box);
0100                 input->setValue(entry.value.toInt());
0101                 if (!entry.minValue.isEmpty())
0102                 {
0103                     input->setMinimum(entry.minValue.toInt());
0104                 }
0105                 if (!entry.maxValue.isEmpty())
0106                 {
0107                     input->setMaximum(entry.maxValue.toInt());
0108                 }
0109                 control = input;
0110             }
0111             else if (type == QLatin1String("Bool"))
0112             {
0113                 bool checked = (QString::compare(entry.value.toString(), QStringLiteral("true"), Qt::CaseInsensitive) == 0);
0114                 auto* checkBox = new QCheckBox(box);
0115                 checkBox->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
0116                 control = checkBox;
0117             }
0118             else
0119             {
0120                 qCDebug(PLUGIN_FILETEMPLATES) << "Unrecognized option type" << entry.type;
0121             }
0122             if (control)
0123             {
0124                 const QString entryLabelText = i18nc("@label", "%1:", entry.label);
0125                 auto* label = new QLabel(entryLabelText, box);
0126                 if (!entry.context.isEmpty()) {
0127                     label->setToolTip(entry.context);
0128                     control->setToolTip(entry.context);
0129                 }
0130                 formLayout->addRow(label, control);
0131                 d->controls.insert(entry.name, control);
0132                 if (d->firstEditWidget == nullptr) {
0133                     d->firstEditWidget = control;
0134                 }
0135             }
0136         }
0137 
0138         box->setLayout(formLayout);
0139         layout->addWidget(box);
0140     }
0141 
0142     layout->addStretch();
0143 
0144     setLayout(layout);
0145 }
0146 
0147 QVariantHash TemplateOptionsPage::templateOptions() const
0148 {
0149     QVariantHash values;
0150 
0151     for (const SourceFileTemplate::ConfigOption& entry : qAsConst(d->entries)) {
0152         Q_ASSERT(d->controls.contains(entry.name));
0153         Q_ASSERT(d->typeProperties.contains(entry.type));
0154 
0155         values.insert(entry.name, d->controls[entry.name]->property(d->typeProperties[entry.type].constData()));
0156     }
0157 
0158     qCDebug(PLUGIN_FILETEMPLATES) << values.size() << d->entries.size();
0159 
0160     return values;
0161 }
0162 
0163 void TemplateOptionsPage::setFocusToFirstEditWidget()
0164 {
0165     if (d->firstEditWidget) {
0166         d->firstEditWidget->setFocus();
0167     }
0168 }
0169 
0170 #include "moc_templateoptionspage.cpp"