diff --git a/plugins/meson/CMakeLists.txt b/plugins/meson/CMakeLists.txt
index afa76ddf42..792fb3f80b 100644
--- a/plugins/meson/CMakeLists.txt
+++ b/plugins/meson/CMakeLists.txt
@@ -1,69 +1,67 @@
add_definitions(-DTRANSLATION_DOMAIN=\"kdevmesonmanager\")
set(mesonbuilder_SRCS
mesonbuilder.cpp
mesonconfig.cpp
mesonjob.cpp
mesonjobprune.cpp
mesonmanager.cpp
mintro/mesonintrospectjob.cpp
mintro/mesonoptions.cpp
mintro/mesonprojectinfo.cpp
mintro/mesontargets.cpp
mintro/mesontests.cpp
rewriter/mesonactionbase.cpp
rewriter/mesondefaultopts.cpp
rewriter/mesonkwargsinfo.cpp
rewriter/mesonkwargsmodify.cpp
rewriter/mesonrewriterjob.cpp
settings/mesonadvancedsettings.cpp
settings/mesonconfigpage.cpp
settings/mesonlisteditor.cpp
settings/mesonnewbuilddir.cpp
settings/mesonoptionbaseview.cpp
settings/mesonoptionsview.cpp
settings/mesonrewriterinput.cpp
settings/mesonrewriterpage.cpp
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
ki18n_wrap_ui(mesonbuilder_SRCS
settings/mesonadvancedsettings.ui
settings/mesonconfigpage.ui
settings/mesonlisteditor.ui
settings/mesonnewbuilddir.ui
settings/mesonoptionbaseview.ui
settings/mesonoptionsview.ui
settings/mesonrewriterinput.ui
settings/mesonrewriteroptioncontainer.ui
settings/mesonrewriterpage.ui
)
ecm_qt_declare_logging_category(mesonbuilder_SRCS
HEADER debug.h
IDENTIFIER KDEV_Meson
CATEGORY_NAME "kdevelop.plugins.meson"
)
kdevplatform_add_plugin(kdevmesonmanager
JSON kdevmesonmanager.json
SOURCES ${mesonbuilder_SRCS})
-add_subdirectory(icons)
-
target_link_libraries(kdevmesonmanager
Qt5::Concurrent
KDev::Interfaces
KDev::Language
KDev::Project
KDev::Util
KDev::OutputView
)
set_target_properties(kdevmesonmanager PROPERTIES
CXX_STANDARD 14
CXX_STANDARD_REQUIRED YES
)
diff --git a/plugins/meson/icons/128-apps-meson.png b/plugins/meson/icons/128-apps-meson.png
deleted file mode 100644
index f09f8fd3c4..0000000000
Binary files a/plugins/meson/icons/128-apps-meson.png and /dev/null differ
diff --git a/plugins/meson/icons/16-apps-meson.png b/plugins/meson/icons/16-apps-meson.png
deleted file mode 100644
index 00f73111ce..0000000000
Binary files a/plugins/meson/icons/16-apps-meson.png and /dev/null differ
diff --git a/plugins/meson/icons/256-apps-meson.png b/plugins/meson/icons/256-apps-meson.png
deleted file mode 100644
index 03868d680e..0000000000
Binary files a/plugins/meson/icons/256-apps-meson.png and /dev/null differ
diff --git a/plugins/meson/icons/32-apps-meson.png b/plugins/meson/icons/32-apps-meson.png
deleted file mode 100644
index 9e188071c9..0000000000
Binary files a/plugins/meson/icons/32-apps-meson.png and /dev/null differ
diff --git a/plugins/meson/icons/64-apps-meson.png b/plugins/meson/icons/64-apps-meson.png
deleted file mode 100644
index a80d901deb..0000000000
Binary files a/plugins/meson/icons/64-apps-meson.png and /dev/null differ
diff --git a/plugins/meson/icons/CMakeLists.txt b/plugins/meson/icons/CMakeLists.txt
deleted file mode 100644
index 4dd530f40a..0000000000
--- a/plugins/meson/icons/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-ecm_install_icons(ICONS
- 256-apps-meson.png
- 128-apps-meson.png
- 64-apps-meson.png
- 32-apps-meson.png
- 16-apps-meson.png
- DESTINATION ${KDE_INSTALL_ICONDIR})
-
diff --git a/plugins/meson/icons/meson_logo.svg b/plugins/meson/icons/meson_logo.svg
deleted file mode 100644
index b8dd59371b..0000000000
--- a/plugins/meson/icons/meson_logo.svg
+++ /dev/null
@@ -1,96 +0,0 @@
-
-
-
-
diff --git a/plugins/meson/kdevmesonmanager.json b/plugins/meson/kdevmesonmanager.json
index 5affaeeeab..57dcfe117f 100644
--- a/plugins/meson/kdevmesonmanager.json
+++ b/plugins/meson/kdevmesonmanager.json
@@ -1,60 +1,60 @@
{
"KPlugin": {
"Category": "Project Management",
"Description": "Imports and edits Meson projects",
"Description[ca@valencia]": "Importa i edita projectes del Meson",
"Description[ca]": "Importa i edita projectes del Meson",
"Description[cs]": "Importuje a upravuje vlastní projekty Meson",
"Description[de]": "Import und Bearbeitung von benutzerdefinierten Meson-Projekten",
"Description[en_GB]": "Imports and edits Meson projects",
"Description[es]": "Importa y edita proyectos Meson",
"Description[fr]": "Importe et édite des projets Meson",
"Description[gl]": "Importa e edita proxectos Meson",
"Description[it]": "Importa e modifica i progetti Meson",
"Description[nl]": "Importeert en bewerkt Meson-projecten",
"Description[pl]": "Importuje i edytuje projekty Meson",
"Description[pt]": "Importa e edita os projectos do Meson",
"Description[pt_BR]": "Importa e edita os projetos do Meson",
"Description[sv]": "Importerar och redigerar Meson-projekt",
"Description[uk]": "Імпортує і дає змогу редагувати проєкти Meson",
"Description[x-test]": "xxImports and edits Meson projectsxx",
"Description[zh_CN]": "倒入并编辑 Meson 工程",
- "Icon": "meson",
+ "Icon": "run-build",
"Id": "KDevMesonManager",
"Name": "Meson Project Manager",
"Name[ca@valencia]": "Gestor de projectes Meson",
"Name[ca]": "Gestor de projectes Meson",
"Name[cs]": "Správce projektů Meson",
"Name[de]": "Meson-Projektverwaltung",
"Name[en_GB]": "Meson Project Manager",
"Name[es]": "Gestor de proyectos Meson",
"Name[fr]": "Gestionnaire de projet Meson",
"Name[gl]": "Xestor de proxectos Meson",
"Name[it]": "Gestore progetto Meson",
"Name[nl]": "Meson projectbeheerder",
"Name[pl]": "Zarządzanie projektem Meson",
"Name[pt]": "Gestor de Projectos do Meson",
"Name[pt_BR]": "Gerenciador de projetos do Meson",
"Name[sv]": "Meson projekthanterare",
"Name[uk]": "Керування проєктами Meson",
"Name[x-test]": "xxMeson Project Managerxx",
"Name[zh_CN]": "Meson 工程管理器",
"ServiceTypes": [
"KDevelop/Plugin"
]
},
"X-KDevelop-Category": "Project",
"X-KDevelop-FileManager": "Meson",
"X-KDevelop-IRequired": [
"org.kdevelop.IProjectBuilder"
],
"X-KDevelop-Interfaces": [
"org.kdevelop.IBuildSystemManager",
"org.kdevelop.IProjectFileManager"
],
"X-KDevelop-Mode": "NoGUI",
"X-KDevelop-ProjectFilesFilter": [
"meson.build"
],
"X-KDevelop-ProjectFilesFilterDescription": "Meson Project Files"
}
diff --git a/plugins/meson/settings/mesonconfigpage.cpp b/plugins/meson/settings/mesonconfigpage.cpp
index 0752516172..db9bad059f 100644
--- a/plugins/meson/settings/mesonconfigpage.cpp
+++ b/plugins/meson/settings/mesonconfigpage.cpp
@@ -1,356 +1,356 @@
/* This file is part of KDevelop
Copyright 2018 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 "mesonconfigpage.h"
#include "mesonbuilder.h"
#include "mesonjob.h"
#include "mesonmanager.h"
#include "mesonnewbuilddir.h"
#include "mintro/mesonintrospectjob.h"
#include "ui_mesonconfigpage.h"
#include
#include
#include
#include
#include
#include
using namespace KDevelop;
MesonConfigPage::MesonConfigPage(IPlugin* plugin, IProject* project, QWidget* parent)
: ConfigPage(plugin, nullptr, parent)
, m_project(project)
{
Q_ASSERT(project); // Catch errors early
MesonManager* mgr = dynamic_cast(m_project->buildSystemManager());
Q_ASSERT(mgr); // This dialog only works with the MesonManager
m_ui = new Ui::MesonConfigPage;
m_ui->setupUi(this);
m_ui->advanced->setSupportedBackends(mgr->supportedMesonBackends());
m_config = Meson::getMesonConfig(m_project);
if (m_config.buildDirs.isEmpty()) {
m_config.currentIndex = -1;
reset();
return;
} else if (m_config.currentIndex < 0 || m_config.currentIndex >= m_config.buildDirs.size()) {
m_config.currentIndex = 0;
}
QStringList buildPathList;
for (auto& i : m_config.buildDirs) {
buildPathList << i.buildDir.toLocalFile();
}
m_ui->i_buildDirs->blockSignals(true);
m_ui->i_buildDirs->clear();
m_ui->i_buildDirs->addItems(buildPathList);
m_ui->i_buildDirs->setCurrentIndex(m_config.currentIndex);
m_ui->i_buildDirs->blockSignals(false);
reset();
}
void MesonConfigPage::writeConfig()
{
qCDebug(KDEV_Meson) << "Writing config to file";
if (m_config.currentIndex >= 0) {
m_config.buildDirs[m_config.currentIndex] = m_current;
}
if (m_config.buildDirs.isEmpty()) {
m_config.currentIndex = -1;
} else if (m_config.currentIndex < 0 || m_config.currentIndex >= m_config.buildDirs.size()) {
m_config.currentIndex = 0;
}
Meson::writeMesonConfig(m_project, m_config);
}
void MesonConfigPage::apply()
{
qCDebug(KDEV_Meson) << "Applying meson config for build dir " << m_current.buildDir;
readUI();
writeConfig();
if (m_config.currentIndex >= 0 && m_configChanged) {
QList joblist;
auto options = m_ui->options->options();
if (!options) {
qCWarning(KDEV_Meson) << "Options is nullptr. Can not update meson config";
return;
}
QStringList mesonArgs = options->getMesonArgs();
if (mesonArgs.empty()) {
qCDebug(KDEV_Meson) << "Config has not changed --> nothing has to be updated";
return;
}
// Check if a configuration is required
auto status = MesonBuilder::evaluateBuildDirectory(m_current.buildDir, m_current.mesonBackend);
if (status != MesonBuilder::MESON_CONFIGURED) {
joblist << new MesonJob(m_current, m_project, MesonJob::CONFIGURE, mesonArgs, nullptr);
}
joblist << new MesonJob(m_current, m_project, MesonJob::SET_CONFIG, mesonArgs, nullptr);
joblist << m_ui->options->repopulateFromBuildDir(m_project, m_current);
KJob* job = new ExecuteCompositeJob(nullptr, joblist);
connect(job, &KJob::result, this, [this]() {
setDisabled(false);
updateUI();
});
setDisabled(true);
m_configChanged = false;
job->start();
}
}
void MesonConfigPage::defaults()
{
qCDebug(KDEV_Meson) << "Restoring build dir " << m_current.buildDir << " to it's default values";
MesonManager* mgr = dynamic_cast(m_project->buildSystemManager());
Q_ASSERT(mgr);
m_current.mesonArgs.clear();
m_current.mesonBackend = mgr->defaultMesonBackend();
m_current.mesonExecutable = mgr->findMeson();
m_ui->options->resetAll();
updateUI();
}
void MesonConfigPage::reset()
{
if (m_config.buildDirs.isEmpty()) {
m_config.currentIndex = -1;
m_ui->i_buildDirs->clear();
setWidgetsDisabled(true);
m_ui->b_addDir->setDisabled(false); // Allow adding a new build dir when there are none
return;
} else if (m_config.currentIndex < 0 || m_config.currentIndex >= m_config.buildDirs.size()) {
m_config.currentIndex = 0;
m_ui->i_buildDirs->blockSignals(true);
m_ui->i_buildDirs->setCurrentIndex(m_config.currentIndex);
m_ui->i_buildDirs->blockSignals(false);
}
setWidgetsDisabled(false);
qCDebug(KDEV_Meson) << "Resetting changes for build dir " << m_current.buildDir;
m_current = m_config.buildDirs[m_config.currentIndex];
m_ui->options->repopulateFromBuildDir(m_project, m_current)->start();
updateUI();
}
void MesonConfigPage::checkStatus()
{
// Get the config build dir status
auto status = MesonBuilder::evaluateBuildDirectory(m_current.buildDir, m_current.mesonBackend);
auto setStatus = [this](const QString& msg, int color) -> void {
KColorScheme scheme(QPalette::Normal);
KColorScheme::ForegroundRole role;
switch (color) {
case 0:
role = KColorScheme::PositiveText;
break;
case 1:
role = KColorScheme::NeutralText;
break;
case 2:
default:
role = KColorScheme::NegativeText;
break;
}
QPalette pal = m_ui->l_status->palette();
pal.setColor(QPalette::Foreground, scheme.foreground(role).color());
m_ui->l_status->setPalette(pal);
m_ui->l_status->setText(i18n("Status: %1", msg));
};
switch (status) {
case MesonBuilder::DOES_NOT_EXIST:
setStatus(i18n("The current build directory does not exist"), 1);
break;
case MesonBuilder::CLEAN:
setStatus(i18n("The current build directory is empty"), 1);
break;
case MesonBuilder::MESON_CONFIGURED:
setStatus(i18n("Build directory configured"), 0);
break;
case MesonBuilder::MESON_FAILED_CONFIGURATION:
setStatus(i18n("This meson build directory is not fully configured"), 1);
break;
case MesonBuilder::INVALID_BUILD_DIR:
setStatus(i18n("The current build directory is invalid"), 2);
break;
case MesonBuilder::DIR_NOT_EMPTY:
setStatus(i18n("This directory does not seem to be a meson build directory"), 2);
break;
case MesonBuilder::EMPTY_STRING:
setStatus(i18n("Invalid build directory configuration (empty build directory string)"), 2);
break;
case MesonBuilder::___UNDEFINED___:
setStatus(i18n("Something went very wrong. This is a bug"), 2);
break;
}
KColorScheme scheme(QPalette::Normal);
KColorScheme::ForegroundRole role;
int numChanged = 0;
auto options = m_ui->options->options();
if (options) {
numChanged = options->numChanged();
}
if (numChanged == 0) {
role = KColorScheme::NormalText;
m_ui->l_changed->setText(i18n("No changes"));
} else {
role = KColorScheme::NeutralText;
m_ui->l_changed->setText(i18n("%1 options changed", numChanged));
}
QPalette pal = m_ui->l_changed->palette();
pal.setColor(QPalette::Foreground, scheme.foreground(role).color());
m_ui->l_changed->setPalette(pal);
}
void MesonConfigPage::updateUI()
{
auto aConf = m_ui->advanced->getConfig();
aConf.args = m_current.mesonArgs;
aConf.backend = m_current.mesonBackend;
aConf.meson = m_current.mesonExecutable;
m_ui->advanced->setConfig(aConf);
checkStatus();
}
void MesonConfigPage::readUI()
{
qCDebug(KDEV_Meson) << "Reading current build configuration from the UI " << m_current.buildDir.toLocalFile();
auto aConf = m_ui->advanced->getConfig();
m_current.mesonArgs = aConf.args;
m_current.mesonBackend = aConf.backend;
m_current.mesonExecutable = aConf.meson;
}
void MesonConfigPage::setWidgetsDisabled(bool disabled)
{
m_ui->advanced->setDisabled(disabled);
m_ui->i_buildDirs->setDisabled(disabled);
m_ui->b_addDir->setDisabled(disabled);
m_ui->b_rmDir->setDisabled(disabled);
m_ui->options->setDisabled(disabled);
}
void MesonConfigPage::addBuildDir()
{
qCDebug(KDEV_Meson) << "Adding build directory";
MesonManager* mgr = dynamic_cast(m_project->buildSystemManager());
MesonBuilder* bld = dynamic_cast(mgr->builder());
Q_ASSERT(mgr);
Q_ASSERT(bld);
MesonNewBuildDir newBD(m_project);
if (!newBD.exec() || !newBD.isConfigValid()) {
qCDebug(KDEV_Meson) << "Failed to create a new build directory";
return;
}
m_current = newBD.currentConfig();
m_current.canonicalizePaths();
m_config.currentIndex = m_config.addBuildDir(m_current);
m_ui->i_buildDirs->blockSignals(true);
m_ui->i_buildDirs->addItem(m_current.buildDir.toLocalFile());
m_ui->i_buildDirs->setCurrentIndex(m_config.currentIndex);
m_ui->i_buildDirs->blockSignals(false);
setWidgetsDisabled(true);
writeConfig();
KJob* job = bld->configure(m_project, m_current, newBD.mesonArgs());
connect(job, &KJob::result, this, [this]() { reset(); });
job->start();
}
void MesonConfigPage::removeBuildDir()
{
qCDebug(KDEV_Meson) << "Removing current build directory";
m_ui->i_buildDirs->blockSignals(true);
m_ui->i_buildDirs->removeItem(m_config.currentIndex);
m_config.removeBuildDir(m_config.currentIndex);
if (m_config.buildDirs.isEmpty()) {
m_config.currentIndex = -1;
} else if (m_config.currentIndex < 0 || m_config.currentIndex >= m_config.buildDirs.size()) {
m_config.currentIndex = 0;
}
m_ui->i_buildDirs->setCurrentIndex(m_config.currentIndex);
m_ui->i_buildDirs->blockSignals(false);
reset();
writeConfig();
}
void MesonConfigPage::changeBuildDirIndex(int index)
{
if (index == m_config.currentIndex || m_config.buildDirs.isEmpty()) {
return;
}
if (index < 0 || index >= m_config.buildDirs.size()) {
qCWarning(KDEV_Meson) << "Invalid build dir index " << index;
return;
}
qCDebug(KDEV_Meson) << "Changing build directory to index " << index;
m_config.currentIndex = index;
reset();
writeConfig();
}
void MesonConfigPage::emitChanged()
{
m_configChanged = true;
checkStatus();
emit changed();
}
QString MesonConfigPage::name() const
{
return i18n("Meson");
}
QString MesonConfigPage::fullName() const
{
return i18n("Meson project configuration");
}
QIcon MesonConfigPage::icon() const
{
- return QIcon::fromTheme(QStringLiteral("meson"));
+ return QIcon::fromTheme(QStringLiteral("run-build"));
}
diff --git a/plugins/meson/settings/mesonrewriterpage.cpp b/plugins/meson/settings/mesonrewriterpage.cpp
index 9c77c516af..2963812fd8 100644
--- a/plugins/meson/settings/mesonrewriterpage.cpp
+++ b/plugins/meson/settings/mesonrewriterpage.cpp
@@ -1,462 +1,462 @@
/* 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 "mesonrewriterpage.h"
#include "mesonconfig.h"
#include "mesonmanager.h"
#include "mesonoptionbaseview.h"
#include "mesonrewriterinput.h"
#include "mintro/mesonintrospectjob.h"
#include "mintro/mesonprojectinfo.h"
#include "rewriter/mesondefaultopts.h"
#include "rewriter/mesonkwargsinfo.h"
#include "rewriter/mesonkwargsmodify.h"
#include "rewriter/mesonrewriterjob.h"
#include "ui_mesonrewriterpage.h"
#include
#include
#include
#include
#include
#include
#include
#include
using namespace KDevelop;
using namespace std;
class JobDeleter
{
public:
explicit JobDeleter(QList jobs)
: m_jobs(jobs)
{
}
~JobDeleter()
{
for (KJob* i : m_jobs) {
delete i;
}
}
private:
QList m_jobs;
};
MesonRewriterPage::MesonRewriterPage(IPlugin* plugin, IProject* project, QWidget* parent)
: ConfigPage(plugin, nullptr, parent)
, m_project(project)
{
Q_ASSERT(m_project);
m_ui = new Ui::MesonRewriterPage;
m_ui->setupUi(this);
m_projectKwargs = constructPojectInputs();
// Initialize widgets
for (auto* i : m_projectKwargs) {
m_ui->c_project->addWidget(i);
connect(i, &MesonRewriterInputBase::configChanged, this, &MesonRewriterPage::emitChanged);
}
recalculateLengths();
reset();
}
#define STRING_INPUT(name, id) new MesonRewriterInputString(QStringLiteral(name), QStringLiteral(id), this)
QVector MesonRewriterPage::constructPojectInputs()
{
return {
STRING_INPUT("Version", "version"),
STRING_INPUT("License", "license"),
STRING_INPUT("Meson version", "meson_version"),
STRING_INPUT("Subprojects directory", "subproject_dir"),
};
}
MesonOptContainerPtr MesonRewriterPage::constructDefaultOpt(const QString& name, const QString& value)
{
if (!m_opts) {
return nullptr;
}
for (auto& i : m_opts->options()) {
if (i->name() != name) {
continue;
}
if (!value.isNull()) {
i->setFromString(value);
}
auto optView = MesonOptionBaseView::fromOption(i, this);
if (!optView) {
continue;
}
auto opt = std::make_shared(optView, this);
if (!opt) {
continue;
}
connect(opt.get(), &MesonRewriterOptionContainer::configChanged, this, &MesonRewriterPage::emitChanged);
return opt;
}
return nullptr;
}
void MesonRewriterPage::setWidgetsDisabled(bool disabled)
{
m_ui->c_tabs->setDisabled(disabled);
}
void MesonRewriterPage::recalculateLengths()
{
// Calculate the maximum name width to align all widgets
vector lengths;
int maxWidth = 50;
lengths.reserve(m_projectKwargs.size() + m_defaultOpts.size());
auto input_op = [](MesonRewriterInputBase* x) -> int { return x->nameWidth(); };
auto optCont_op = [](MesonOptContainerPtr x) -> int { return x->view()->nameWidth(); };
transform(begin(m_projectKwargs), end(m_projectKwargs), back_inserter(lengths), input_op);
transform(begin(m_defaultOpts), end(m_defaultOpts), back_inserter(lengths), optCont_op);
maxWidth = accumulate(begin(lengths), end(lengths), maxWidth, [](int a, int b) -> int { return max(a, b); });
// Set widgets width
for (auto* i : m_projectKwargs) {
i->setMinNameWidth(maxWidth);
}
for (auto& i : m_defaultOpts) {
i->view()->setMinNameWidth(maxWidth);
}
m_ui->l_dispProject->setMinimumWidth(maxWidth);
}
void MesonRewriterPage::checkStatus()
{
// Get the config build dir status
auto setStatus = [this](const QString& msg, int color) -> void {
KColorScheme scheme(QPalette::Normal);
KColorScheme::ForegroundRole role;
switch (color) {
case 0:
role = KColorScheme::PositiveText;
setDisabled(false);
break;
case 1:
role = KColorScheme::NeutralText;
setDisabled(true);
break;
case 2:
default:
role = KColorScheme::NegativeText;
setDisabled(true);
break;
}
QPalette pal = m_ui->l_status->palette();
pal.setColor(QPalette::Foreground, scheme.foreground(role).color());
m_ui->l_status->setPalette(pal);
m_ui->l_status->setText(i18n("Status: %1", msg));
};
switch (m_state) {
case START:
setStatus(i18n("Initializing GUI"), 1);
break;
case LOADING:
setStatus(i18n("Loading project data..."), 1);
break;
case WRITING:
setStatus(i18n("Writing project data..."), 1);
break;
case READY:
setStatus(i18n("Initializing GUI"), 0);
break;
case ERROR:
setStatus(i18n("Loading meson rewriter data failed"), 2);
break;
}
// Remove old default options
m_defaultOpts.erase(remove_if(begin(m_defaultOpts), end(m_defaultOpts), [](auto x) { return x->shouldDelete(); }),
end(m_defaultOpts));
KColorScheme scheme(QPalette::Normal);
KColorScheme::ForegroundRole role;
int numChanged = 0;
numChanged += count_if(begin(m_projectKwargs), end(m_projectKwargs), [](auto* x) { return x->hasChanged(); });
numChanged += count_if(begin(m_defaultOpts), end(m_defaultOpts), [](auto x) { return x->hasChanged(); });
if (numChanged == 0) {
role = KColorScheme::NormalText;
m_ui->l_changed->setText(i18n("No changes"));
} else {
role = KColorScheme::NeutralText;
m_ui->l_changed->setText(i18n("%1 options changed", numChanged));
}
QPalette pal = m_ui->l_changed->palette();
pal.setColor(QPalette::Foreground, scheme.foreground(role).color());
m_ui->l_changed->setPalette(pal);
}
void MesonRewriterPage::setStatus(MesonRewriterPage::State s)
{
m_state = s;
checkStatus();
}
void MesonRewriterPage::apply()
{
qCDebug(KDEV_Meson) << "REWRITER GUI: APPLY";
auto projectSet = make_shared(MesonKWARGSProjectModify::SET);
auto projectDel = make_shared(MesonKWARGSProjectModify::DELETE);
auto defOptsSet = make_shared(MesonRewriterDefaultOpts::SET);
auto defOptsDel = make_shared(MesonRewriterDefaultOpts::DELETE);
auto writer = [](MesonRewriterInputBase* widget, MesonKWARGSModifyPtr set, MesonKWARGSModifyPtr del) {
if (!widget->hasChanged()) {
return;
}
if (widget->isEnabled()) {
widget->writeToAction(set.get());
} else {
widget->writeToAction(del.get());
}
};
for_each(begin(m_projectKwargs), end(m_projectKwargs), [&](auto* w) { writer(w, projectSet, projectDel); });
QStringList deletedOptions = m_initialDefaultOpts;
for (auto& i : m_defaultOpts) {
auto opt = i->view()->option();
// Detect deleted options by removing all current present options from the initial option list
deletedOptions.removeAll(opt->name());
if (opt->isUpdated() || !m_initialDefaultOpts.contains(opt->name())) {
defOptsSet->set(opt->name(), opt->value());
}
}
for (auto i : deletedOptions) {
defOptsDel->set(i, QString());
}
QVector actions = { projectSet, projectDel, defOptsSet, defOptsDel };
KJob* rewriterJob = new MesonRewriterJob(m_project, actions, this);
// Reload the GUI once the data has been written
connect(rewriterJob, &KJob::result, this, &MesonRewriterPage::reset);
setStatus(WRITING);
rewriterJob->start();
}
void MesonRewriterPage::reset()
{
qCDebug(KDEV_Meson) << "REWRITER GUI: RESET";
Meson::BuildDir buildDir = Meson::currentBuildDir(m_project);
if (!buildDir.isValid()) {
setStatus(ERROR);
return;
}
auto projectInfo = std::make_shared();
QVector actions = { projectInfo };
QVector types = { MesonIntrospectJob::PROJECTINFO, MesonIntrospectJob::BUILDOPTIONS };
MesonIntrospectJob::Mode mode = MesonIntrospectJob::MESON_FILE;
auto introspectJob = new MesonIntrospectJob(m_project, buildDir, types, mode, this);
auto rewriterJob = new MesonRewriterJob(m_project, actions, this);
QList jobs = { introspectJob, rewriterJob };
// Don't automatically delete jobs beause they are used in the lambda below
for (KJob* i : jobs) {
i->setAutoDelete(false);
}
KJob* job = new ExecuteCompositeJob(this, jobs);
connect(job, &KJob::result, this, [=]() -> void {
JobDeleter deleter(jobs); // Make sure to free all jobs with RAII
auto prInfo = introspectJob->projectInfo();
m_opts = introspectJob->buildOptions();
if (!prInfo || !m_opts) {
setStatus(ERROR);
return;
}
m_ui->l_project->setText(QStringLiteral("") + prInfo->name()
+ QStringLiteral("
"));
auto setter = [](MesonRewriterInputBase* w, MesonKWARGSInfoPtr i) { w->resetFromAction(i.get()); };
for_each(begin(m_projectKwargs), end(m_projectKwargs), [=](auto* x) { setter(x, projectInfo); });
// Updated the default options
m_defaultOpts.clear();
m_initialDefaultOpts.clear();
if (projectInfo->hasKWARG(QStringLiteral("default_options"))) {
auto rawValues = projectInfo->getArray(QStringLiteral("default_options"));
auto options = m_opts->options();
for (auto i : rawValues) {
int idx = i.indexOf(QLatin1Char('='));
if (idx < 0) {
continue;
}
QString name = i.left(idx);
QString val = i.mid(idx + 1);
auto opt = constructDefaultOpt(name, val);
if (!opt) {
continue;
}
m_defaultOpts += opt;
m_initialDefaultOpts += name;
m_ui->c_defOpts->addWidget(opt.get());
}
}
recalculateLengths();
setStatus(READY);
return;
});
setStatus(LOADING);
job->start();
}
void MesonRewriterPage::newOption()
{
// Sort by section
QStringList core;
QStringList backend;
QStringList base;
QStringList compiler;
QStringList directory;
QStringList user;
QStringList test;
for (auto& i : m_opts->options()) {
switch (i->section()) {
case MesonOptionBase::CORE:
core += i->name();
break;
case MesonOptionBase::BACKEND:
backend += i->name();
break;
case MesonOptionBase::BASE:
base += i->name();
break;
case MesonOptionBase::COMPILER:
compiler += i->name();
break;
case MesonOptionBase::DIRECTORY:
directory += i->name();
break;
case MesonOptionBase::USER:
user += i->name();
break;
case MesonOptionBase::TEST:
test += i->name();
break;
}
}
QStringList total = core + backend + base + compiler + directory + user + test;
// Remove already existing options
for (auto& i : m_defaultOpts) {
total.removeAll(i->view()->option()->name());
}
QInputDialog dialog(this);
dialog.setOption(QInputDialog::UseListViewForComboBoxItems, true);
dialog.setInputMode(QInputDialog::TextInput);
dialog.setWindowTitle(i18n("Select meson option to add"));
dialog.setLabelText(i18n("Select one new meson option to add"));
dialog.setComboBoxItems(total);
if (dialog.exec() != QDialog::Accepted) {
return;
}
auto opt = constructDefaultOpt(dialog.textValue(), QString());
if (!opt) {
return;
}
m_defaultOpts += opt;
m_ui->c_defOpts->addWidget(opt.get());
recalculateLengths();
}
void MesonRewriterPage::defaults()
{
reset();
}
void MesonRewriterPage::emitChanged()
{
m_configChanged = true;
checkStatus();
emit changed();
}
QString MesonRewriterPage::name() const
{
return i18n("Project");
}
QString MesonRewriterPage::fullName() const
{
return i18n("Meson project settings");
}
QIcon MesonRewriterPage::icon() const
{
- return QIcon::fromTheme(QStringLiteral("meson"));
+ return QIcon::fromTheme(QStringLiteral("run-build"));
}