diff --git a/plugins/meson/rewriter/mesonrewriterjob.cpp b/plugins/meson/rewriter/mesonrewriterjob.cpp index e70fdfb79e..60e207880e 100644 --- a/plugins/meson/rewriter/mesonrewriterjob.cpp +++ b/plugins/meson/rewriter/mesonrewriterjob.cpp @@ -1,124 +1,124 @@ /* This file is part of KDevelop Copyright 2019 Daniel Mensinger This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "mesonrewriterjob.h" #include "mesonconfig.h" #include "interfaces/iproject.h" #include "util/path.h" #include #include #include #include #include #include #include "debug.h" using namespace KDevelop; MesonRewriterJob::MesonRewriterJob(IProject* project, QVector const& actions, QObject* parent) : KJob(parent) , m_project(project) , m_actions(actions) { connect(&m_futureWatcher, &QFutureWatcher::finished, this, &MesonRewriterJob::finished); } QString MesonRewriterJob::execute() { QJsonArray command; for (auto& i : m_actions) { command.append(i->command()); } QTemporaryFile tempFile; tempFile.setAutoRemove(false); if (!tempFile.open()) { - return i18n("Failed to create a temorary file"); + return i18n("Failed to create a temporary file."); } QJsonDocument doc(command); tempFile.write(doc.toJson()); tempFile.flush(); Meson::BuildDir buildDir = Meson::currentBuildDir(m_project); KProcess proc(this); proc.setWorkingDirectory(m_project->path().toLocalFile()); proc.setOutputChannelMode(KProcess::SeparateChannels); proc.setProgram(buildDir.mesonExecutable.toLocalFile()); proc << QStringLiteral("rewrite") << QStringLiteral("command") << tempFile.fileName(); int ret = proc.execute(); if (ret != 0) { return i18n("%1 returned %2", proc.program().join(QChar::fromLatin1(' ')), ret); } auto rawData = proc.readAllStandardError(); if (rawData.isEmpty()) { return QString(); } QJsonParseError error; QJsonDocument result = QJsonDocument::fromJson(rawData, &error); if (error.error) { return i18n("JSON parser error: %1", error.errorString()); } if (!result.isObject()) { return i18n("The rewriter output of '%1' is not an object", proc.program().join(QChar::fromLatin1(' '))); } for (auto& i : m_actions) { i->parseResult(result.object()); } return QString(); } void MesonRewriterJob::finished() { QString result = m_futureWatcher.result(); if (!result.isEmpty()) { qCWarning(KDEV_Meson) << "REWRITER " << result; setError(true); setErrorText(result); emitResult(); return; } qCDebug(KDEV_Meson) << "REWRITER: Meson rewriter job finished"; emitResult(); } bool MesonRewriterJob::doKill() { if (m_futureWatcher.isRunning()) { m_futureWatcher.cancel(); } return true; } void MesonRewriterJob::start() { auto future = QtConcurrent::run(this, &MesonRewriterJob::execute); m_futureWatcher.setFuture(future); } diff --git a/plugins/meson/settings/mesonoptionbaseview.cpp b/plugins/meson/settings/mesonoptionbaseview.cpp index 10cd7538fa..31f695b66b 100644 --- a/plugins/meson/settings/mesonoptionbaseview.cpp +++ b/plugins/meson/settings/mesonoptionbaseview.cpp @@ -1,310 +1,312 @@ /* This file is part of KDevelop Copyright 2019 Daniel Mensinger This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "mesonoptionbaseview.h" #include "mesonlisteditor.h" #include "ui_mesonoptionbaseview.h" #include #include #include #include #include #include #include #include #include using namespace std; // Helper class for RAII signal blocking class SignalBlocker { public: SignalBlocker(QWidget* widget) : m_widget(widget) { if (m_widget) { m_widget->blockSignals(true); } } ~SignalBlocker() { if (m_widget) { m_widget->blockSignals(false); } } private: QWidget* m_widget = nullptr; }; MesonOptionBaseView::MesonOptionBaseView(MesonOptionPtr option, QWidget* parent) : QWidget(parent) { Q_ASSERT(option); m_ui = new Ui::MesonOptionBaseView; m_ui->setupUi(this); m_ui->l_name->setText(option->name() + QStringLiteral(":")); m_ui->l_name->setToolTip(option->description()); setToolTip(option->description()); } MesonOptionBaseView::~MesonOptionBaseView() { if (m_ui) { delete m_ui; } } // Base class functions int MesonOptionBaseView::nameWidth() { + // Make the name a bit (by 25) wider than it actually is to create a margin. Maybe do + // something smarter in the future (TODO) return m_ui->l_name->fontMetrics().boundingRect(m_ui->l_name->text()).width() + 25; } void MesonOptionBaseView::setMinNameWidth(int width) { m_ui->l_name->setMinimumWidth(width); } void MesonOptionBaseView::setInputWidget(QWidget* input) { QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(input->sizePolicy().hasHeightForWidth()); input->setSizePolicy(sizePolicy); input->setToolTip(option()->description()); m_ui->layout->insertWidget(1, input); updateInput(); setChanged(false); } void MesonOptionBaseView::reset() { option()->reset(); updateInput(); setChanged(false); } void MesonOptionBaseView::setChanged(bool changed) { KColorScheme scheme(QPalette::Normal); KColorScheme::ForegroundRole role; if (changed) { m_ui->l_name->setStyleSheet(QStringLiteral("font-weight: bold")); m_ui->b_reset->setDisabled(false); role = KColorScheme::NeutralText; } else { m_ui->l_name->setStyleSheet(QString()); m_ui->b_reset->setDisabled(true); role = KColorScheme::NormalText; } QPalette pal = m_ui->l_name->palette(); pal.setColor(QPalette::Foreground, scheme.foreground(role).color()); m_ui->l_name->setPalette(pal); emit configChanged(); } std::shared_ptr MesonOptionBaseView::fromOption(MesonOptionPtr option, QWidget* parent) { std::shared_ptr opt = nullptr; switch (option->type()) { case MesonOptionBase::ARRAY: opt = make_shared(option, parent); break; case MesonOptionBase::BOOLEAN: opt = make_shared(option, parent); break; case MesonOptionBase::COMBO: opt = make_shared(option, parent); break; case MesonOptionBase::INTEGER: opt = make_shared(option, parent); break; case MesonOptionBase::STRING: opt = make_shared(option, parent); break; } return opt; } // Derived class constructors MesonOptionArrayView::MesonOptionArrayView(MesonOptionPtr option, QWidget* parent) : MesonOptionBaseView(option, parent) , m_option(dynamic_pointer_cast(option)) { Q_ASSERT(m_option); m_input = new QPushButton(this); connect(m_input, &QPushButton::clicked, this, [this]() { MesonListEditor editor(m_option->rawValue(), this); if (editor.exec() == QDialog::Accepted) { m_option->setValue(editor.content()); m_input->setText(m_option->value()); setChanged(m_option->isUpdated()); } }); setInputWidget(m_input); } MesonOptionBoolView::MesonOptionBoolView(MesonOptionPtr option, QWidget* parent) : MesonOptionBaseView(option, parent) , m_option(dynamic_pointer_cast(option)) { Q_ASSERT(m_option); m_input = new QCheckBox(this); connect(m_input, &QCheckBox::stateChanged, this, &MesonOptionBoolView::updated); setInputWidget(m_input); } MesonOptionComboView::MesonOptionComboView(MesonOptionPtr option, QWidget* parent) : MesonOptionBaseView(option, parent) , m_option(dynamic_pointer_cast(option)) { Q_ASSERT(m_option); m_input = new QComboBox(this); m_input->clear(); m_input->addItems(m_option->choices()); m_input->setEditable(false); connect(m_input, QOverload::of(&QComboBox::currentIndexChanged), this, &MesonOptionComboView::updated); setInputWidget(m_input); } MesonOptionIntegerView::MesonOptionIntegerView(MesonOptionPtr option, QWidget* parent) : MesonOptionBaseView(option, parent) , m_option(dynamic_pointer_cast(option)) { Q_ASSERT(m_option); m_input = new QSpinBox(this); m_input->setMinimum(INT32_MIN); m_input->setMaximum(INT32_MAX); connect(m_input, QOverload::of(&QSpinBox::valueChanged), this, &MesonOptionIntegerView::updated); setInputWidget(m_input); } MesonOptionStringView::MesonOptionStringView(MesonOptionPtr option, QWidget* parent) : MesonOptionBaseView(option, parent) , m_option(dynamic_pointer_cast(option)) { Q_ASSERT(m_option); m_input = new QLineEdit(this); connect(m_input, &QLineEdit::textChanged, this, &MesonOptionStringView::updated); setInputWidget(m_input); } // Option getters MesonOptionBase* MesonOptionArrayView::option() { return m_option.get(); } MesonOptionBase* MesonOptionBoolView::option() { return m_option.get(); } MesonOptionBase* MesonOptionComboView::option() { return m_option.get(); } MesonOptionBase* MesonOptionIntegerView::option() { return m_option.get(); } MesonOptionBase* MesonOptionStringView::option() { return m_option.get(); } // Updaters for the input widget void MesonOptionArrayView::updateInput() { SignalBlocker block(m_input); m_input->setText(m_option->value()); } void MesonOptionBoolView::updateInput() { SignalBlocker block(m_input); m_input->setCheckState(m_option->rawValue() ? Qt::Checked : Qt::Unchecked); } void MesonOptionComboView::updateInput() { SignalBlocker block(m_input); m_input->setCurrentText(m_option->rawValue()); } void MesonOptionIntegerView::updateInput() { SignalBlocker block(m_input); m_input->setValue(m_option->rawValue()); } void MesonOptionStringView::updateInput() { SignalBlocker block(m_input); m_input->setText(m_option->rawValue()); } // Slots to update the option value void MesonOptionBoolView::updated() { m_option->setValue(m_input->isChecked()); setChanged(m_option->isUpdated()); } void MesonOptionComboView::updated() { m_option->setValue(m_input->currentText()); setChanged(m_option->isUpdated()); } void MesonOptionIntegerView::updated() { m_option->setValue(m_input->value()); setChanged(m_option->isUpdated()); } void MesonOptionStringView::updated() { m_option->setValue(m_input->text()); setChanged(m_option->isUpdated()); } diff --git a/plugins/meson/settings/mesonrewriterinput.cpp b/plugins/meson/settings/mesonrewriterinput.cpp index 1d4b74ad51..d6dd54f3f5 100644 --- a/plugins/meson/settings/mesonrewriterinput.cpp +++ b/plugins/meson/settings/mesonrewriterinput.cpp @@ -1,211 +1,213 @@ /* This file is part of KDevelop Copyright 2019 Daniel Mensinger This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "mesonrewriterinput.h" #include "mesonoptionbaseview.h" #include "rewriter/mesonkwargsinfo.h" #include "rewriter/mesonkwargsmodify.h" #include "ui_mesonrewriterinput.h" #include "ui_mesonrewriteroptioncontainer.h" #include #include #include MesonRewriterInputBase::MesonRewriterInputBase(QString const& name, QString const& kwarg, QWidget* parent) : QWidget(parent) , m_name(name) , m_kwarg(kwarg) { m_ui = new Ui::MesonRewriterInputBase; m_ui->setupUi(this); m_ui->l_name->setText(m_name + QStringLiteral(":")); connect(this, &MesonRewriterInputBase::configChanged, this, &MesonRewriterInputBase::updateUi); } MesonRewriterInputBase::~MesonRewriterInputBase() {} int MesonRewriterInputBase::nameWidth() { + // Make the name a bit (by 25) wider than it actually is to create a margin. Maybe do + // something smarter in the future (TODO) return m_ui->l_name->fontMetrics().boundingRect(m_ui->l_name->text()).width() + 25; } void MesonRewriterInputBase::setMinNameWidth(int width) { m_ui->l_name->setMinimumWidth(width); } void MesonRewriterInputBase::setInputWidget(QWidget* input) { QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(input->sizePolicy().hasHeightForWidth()); input->setSizePolicy(sizePolicy); m_ui->layout->insertWidget(1, input); updateUi(); } void MesonRewriterInputBase::updateUi() { KColorScheme scheme(QPalette::Normal); KColorScheme::ForegroundRole role; if (hasChanged()) { m_ui->l_name->setStyleSheet(QStringLiteral("font-weight: bold")); m_ui->b_reset->setDisabled(false || !m_enabled); role = KColorScheme::NeutralText; } else { m_ui->l_name->setStyleSheet(QString()); m_ui->b_reset->setDisabled(true); role = KColorScheme::NormalText; } role = m_enabled ? role : KColorScheme::InactiveText; QPalette pal = m_ui->l_name->palette(); pal.setColor(QPalette::Foreground, scheme.foreground(role).color()); m_ui->l_name->setPalette(pal); m_ui->l_name->setDisabled(!m_enabled); inputWidget()->setDisabled(!m_enabled); m_ui->b_add->setHidden(m_enabled); m_ui->b_delete->setHidden(!m_enabled); } void MesonRewriterInputBase::reset() { doReset(); emit configChanged(); } void MesonRewriterInputBase::remove() { m_enabled = false; reset(); } void MesonRewriterInputBase::add() { m_enabled = true; reset(); } void MesonRewriterInputBase::resetFromAction(MesonKWARGSInfo* action) { resetValue(action->get(m_kwarg)); m_default_enabled = m_enabled = action->hasKWARG(m_kwarg); if (m_enabled) { add(); } else { remove(); } } void MesonRewriterInputBase::writeToAction(MesonKWARGSModify* action) { action->set(m_kwarg, value()); } bool MesonRewriterInputBase::hasChanged() const { return hasValueChanged() || (m_default_enabled != m_enabled); } bool MesonRewriterInputBase::isEnabled() const { return m_enabled; } // String input class MesonRewriterInputString::MesonRewriterInputString(QString const& name, QString const& kwarg, QWidget* parent) : MesonRewriterInputBase(name, kwarg, parent) { m_lineEdit = new QLineEdit(this); connect(m_lineEdit, &QLineEdit::textChanged, this, [=]() { emit configChanged(); }); setInputWidget(m_lineEdit); } MesonRewriterInputString::~MesonRewriterInputString() {} MesonRewriterInputBase::Type MesonRewriterInputString::type() const { return STRING; } bool MesonRewriterInputString::hasValueChanged() const { return m_lineEdit->text() != m_initialValue; } QWidget* MesonRewriterInputString::inputWidget() { return m_lineEdit; } void MesonRewriterInputString::doReset() { m_lineEdit->setText(m_initialValue); } void MesonRewriterInputString::resetValue(QJsonValue const& val) { m_initialValue = val.toString(); } QJsonValue MesonRewriterInputString::value() { return QJsonValue(m_lineEdit->text()); } // Options container MesonRewriterOptionContainer::MesonRewriterOptionContainer(MesonOptViewPtr optView, QWidget* parent) : QWidget(parent) , m_optView(optView) { m_ui = new Ui::MesonRewriterOptionContainer; m_ui->setupUi(this); m_ui->h_layout->insertWidget(0, m_optView.get()); connect(optView.get(), &MesonOptionBaseView::configChanged, this, [this]() { emit configChanged(); }); } void MesonRewriterOptionContainer::deleteMe() { m_markedForDeletion = true; emit configChanged(); } bool MesonRewriterOptionContainer::shouldDelete() const { return m_markedForDeletion; } bool MesonRewriterOptionContainer::hasChanged() const { return m_optView->option()->isUpdated(); } MesonOptViewPtr MesonRewriterOptionContainer::view() { return m_optView; }