Meson: Inline mesonbuildsettingswidget file pair into buildconfiguration

Less code, leaner header.

Change-Id: Ibc018a60434f5dfeb67a7a77192c30e4cefeea96
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
hjk
2023-06-13 12:44:56 +02:00
parent b37b94f0e5
commit f489a3e4d5
6 changed files with 246 additions and 303 deletions

View File

@@ -18,8 +18,6 @@ add_qtc_plugin(MesonProjectManager
mesonactionsmanager.h
mesonbuildconfiguration.cpp
mesonbuildconfiguration.h
mesonbuildsettingswidget.cpp
mesonbuildsettingswidget.h
mesonbuildsystem.cpp
mesonbuildsystem.h
mesoninfo.h

View File

@@ -3,34 +3,73 @@
#include "mesonbuildconfiguration.h"
#include "mesonbuildsettingswidget.h"
#include "buildoptionsmodel.h"
#include "mesonbuildsystem.h"
#include "mesonpluginconstants.h"
#include "mesonpluginconstants.h"
#include "mesonprojectmanagertr.h"
#include "mesonwrapper.h"
#include "ninjabuildstep.h"
#include <coreplugin/find/itemviewfind.h>
#include <projectexplorer/buildaspects.h>
#include <projectexplorer/buildinfo.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/buildstep.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/namedwidget.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectconfiguration.h>
#include <projectexplorer/projectexplorer.h>
#include <utils/fileutils.h>
#include <utils/categorysortfiltermodel.h>
#include <utils/detailswidget.h>
#include <utils/headerviewstretcher.h>
#include <utils/itemviews.h>
#include <utils/layoutbuilder.h>
#include <utils/process.h>
#include <utils/progressindicator.h>
#include <utils/utilsicons.h>
#include <QDir>
#include <QLayout>
#include <QPushButton>
using namespace ProjectExplorer;
using namespace Utils;
namespace MesonProjectManager {
namespace Internal {
namespace MesonProjectManager::Internal {
MesonBuildConfiguration::MesonBuildConfiguration(ProjectExplorer::Target *target, Utils::Id id)
: ProjectExplorer::BuildConfiguration{target, id}
const QHash<QString, MesonBuildType> buildTypesByName = {
{"plain", MesonBuildType::plain},
{"debug", MesonBuildType::debug},
{"debugoptimized", MesonBuildType::debugoptimized},
{"release", MesonBuildType::release},
{"minsize", MesonBuildType::minsize},
{"custom", MesonBuildType::custom}
};
static MesonBuildType mesonBuildType(const QString &typeName)
{
return buildTypesByName.value(typeName, MesonBuildType::custom);
}
static FilePath shadowBuildDirectory(const FilePath &projectFilePath,
const Kit *k,
const QString &bcName,
BuildConfiguration::BuildType buildType)
{
if (projectFilePath.isEmpty())
return {};
const QString projectName = projectFilePath.parentDir().fileName();
return MesonBuildConfiguration::buildDirectoryFromTemplate(
Project::projectDirectory(projectFilePath), projectFilePath,
projectName, k, bcName, buildType, "meson");
}
MesonBuildConfiguration::MesonBuildConfiguration(ProjectExplorer::Target *target, Id id)
: BuildConfiguration(target, id)
{
appendInitialBuildStep(Constants::MESON_BUILD_STEP_ID);
appendInitialCleanStep(Constants::MESON_BUILD_STEP_ID);
@@ -52,19 +91,6 @@ MesonBuildConfiguration::~MesonBuildConfiguration()
delete m_buildSystem;
}
FilePath MesonBuildConfiguration::shadowBuildDirectory(const FilePath &projectFilePath,
const Kit *k,
const QString &bcName,
BuildConfiguration::BuildType buildType)
{
if (projectFilePath.isEmpty())
return {};
const QString projectName = projectFilePath.parentDir().fileName();
return buildDirectoryFromTemplate(Project::projectDirectory(projectFilePath), projectFilePath,
projectName, k, bcName, buildType, "meson");
}
ProjectExplorer::BuildSystem *MesonBuildConfiguration::buildSystem() const
{
return m_buildSystem;
@@ -89,6 +115,11 @@ void MesonBuildConfiguration::build(const QString &target)
mesonBuildStep->setBuildTarget(originalBuildTarget);
}
static QString mesonBuildTypeName(MesonBuildType type)
{
return buildTypesByName.key(type, "custom");
}
QStringList MesonBuildConfiguration::mesonConfigArgs()
{
return Utils::ProcessArgs::splitArgs(m_parameters, HostOsInfo::hostOs())
@@ -124,14 +155,196 @@ bool MesonBuildConfiguration::fromMap(const QVariantMap &map)
return res;
}
ProjectExplorer::NamedWidget *MesonBuildConfiguration::createConfigWidget()
class MesonBuildSettingsWidget : public NamedWidget
{
public:
explicit MesonBuildSettingsWidget(MesonBuildConfiguration *buildCfg)
: NamedWidget(Tr::tr("Meson")), m_progressIndicator(ProgressIndicatorSize::Large)
{
auto configureButton = new QPushButton(Tr::tr("Apply Configuration Changes"));
configureButton->setEnabled(false);
configureButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
auto wipeButton = new QPushButton(Tr::tr("Wipe Project"));
wipeButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
wipeButton->setIcon(Utils::Icons::WARNING.icon());
wipeButton->setToolTip(Tr::tr("Wipes build directory and reconfigures using previous command "
"line options.\nUseful if build directory is corrupted or when "
"rebuilding with a newer version of Meson."));
auto container = new DetailsWidget;
auto details = new QWidget;
container->setState(DetailsWidget::NoSummary);
container->setWidget(details);
auto parametersLineEdit = new QLineEdit;
auto optionsFilterLineEdit = new FancyLineEdit;
auto optionsTreeView = new TreeView;
optionsTreeView->setMinimumHeight(300);
optionsTreeView->setFrameShape(QFrame::NoFrame);
optionsTreeView->setSelectionBehavior(QAbstractItemView::SelectItems);
optionsTreeView->setUniformRowHeights(true);
optionsTreeView->setSortingEnabled(true);
using namespace Layouting;
Column {
noMargin,
Form {
Tr::tr("Parameters:"), parametersLineEdit, br,
buildCfg->buildDirectoryAspect(), br
},
optionsFilterLineEdit,
optionsTreeView,
}.attachTo(details);
Column {
noMargin,
container,
Row { configureButton, wipeButton, noMargin }
}.attachTo(this);
parametersLineEdit->setText(buildCfg->parameters());
optionsFilterLineEdit->setFiltering(true);
optionsTreeView->sortByColumn(0, Qt::AscendingOrder);
QFrame *findWrapper
= Core::ItemViewFind::createSearchableWrapper(optionsTreeView,
Core::ItemViewFind::LightColored);
findWrapper->setFrameStyle(QFrame::StyledPanel);
m_progressIndicator.attachToWidget(findWrapper);
m_progressIndicator.raise();
m_progressIndicator.hide();
details->layout()->addWidget(findWrapper);
m_showProgressTimer.setSingleShot(true);
m_showProgressTimer.setInterval(50); // don't show progress for < 50ms tasks
connect(&m_showProgressTimer, &QTimer::timeout, [this]() { m_progressIndicator.show(); });
connect(&m_optionsModel, &BuidOptionsModel::configurationChanged, this, [configureButton] {
configureButton->setEnabled(true);
});
m_optionsFilter.setSourceModel(&m_optionsModel);
m_optionsFilter.setSortRole(Qt::DisplayRole);
m_optionsFilter.setFilterKeyColumn(-1);
optionsTreeView->setModel(&m_optionsFilter);
optionsTreeView->setItemDelegate(new BuildOptionDelegate{optionsTreeView});
MesonBuildSystem *bs = static_cast<MesonBuildSystem *>(buildCfg->buildSystem());
connect(buildCfg->target(), &ProjectExplorer::Target::parsingFinished,
this, [this, bs, optionsTreeView](bool success) {
if (success) {
m_optionsModel.setConfiguration(bs->buildOptions());
} else {
m_optionsModel.clear();
}
optionsTreeView->expandAll();
optionsTreeView->resizeColumnToContents(0);
optionsTreeView->setEnabled(true);
m_showProgressTimer.stop();
m_progressIndicator.hide();
});
connect(bs, &MesonBuildSystem::parsingStarted, this, [this, optionsTreeView] {
if (!m_showProgressTimer.isActive()) {
optionsTreeView->setEnabled(false);
m_showProgressTimer.start();
}
});
connect(&m_optionsModel, &BuidOptionsModel::dataChanged, this, [bs, this] {
bs->setMesonConfigArgs(this->m_optionsModel.changesAsMesonArgs());
});
connect(&m_optionsFilter, &QAbstractItemModel::modelReset, this, [optionsTreeView] {
optionsTreeView->expandAll();
optionsTreeView->resizeColumnToContents(0);
});
connect(optionsFilterLineEdit, &QLineEdit::textChanged, &m_optionsFilter, [this](const QString &txt) {
m_optionsFilter.setFilterRegularExpression(
QRegularExpression(QRegularExpression::escape(txt),
QRegularExpression::CaseInsensitiveOption));
});
connect(optionsTreeView,
&Utils::TreeView::activated,
optionsTreeView,
[tree = optionsTreeView](const QModelIndex &idx) { tree->edit(idx); });
connect(configureButton, &QPushButton::clicked, [this, bs, configureButton, optionsTreeView] {
optionsTreeView->setEnabled(false);
configureButton->setEnabled(false);
m_showProgressTimer.start();
bs->configure();
});
connect(wipeButton, &QPushButton::clicked, [this, bs, configureButton, optionsTreeView] {
optionsTreeView->setEnabled(false);
configureButton->setEnabled(false);
m_showProgressTimer.start();
bs->wipe();
});
connect(parametersLineEdit, &QLineEdit::editingFinished, this, [ buildCfg, parametersLineEdit] {
buildCfg->setParameters(parametersLineEdit->text());
});
bs->triggerParsing();
}
private:
BuidOptionsModel m_optionsModel;
CategorySortFilterModel m_optionsFilter;
ProgressIndicator m_progressIndicator;
QTimer m_showProgressTimer;
};
NamedWidget *MesonBuildConfiguration::createConfigWidget()
{
return new MesonBuildSettingsWidget{this};
}
ProjectExplorer::BuildInfo createBuildInfo(MesonBuildType type)
static BuildConfiguration::BuildType buildType(MesonBuildType type)
{
ProjectExplorer::BuildInfo bInfo;
switch (type) {
case MesonBuildType::plain:
return BuildConfiguration::Unknown;
case MesonBuildType::debug:
return BuildConfiguration::Debug;
case MesonBuildType::debugoptimized:
return BuildConfiguration::Profile;
case MesonBuildType::release:
return BuildConfiguration::Release;
case MesonBuildType::minsize:
return BuildConfiguration::Release;
default:
return BuildConfiguration::Unknown;
}
}
static QString mesonBuildTypeDisplayName(MesonBuildType type)
{
switch (type) {
case MesonBuildType::plain:
return {"Plain"};
case MesonBuildType::debug:
return {"Debug"};
case MesonBuildType::debugoptimized:
return {"Debug With Optimizations"};
case MesonBuildType::release:
return {"Release"};
case MesonBuildType::minsize:
return {"Minimum Size"};
default:
return {"Custom"};
}
}
BuildInfo createBuildInfo(MesonBuildType type)
{
BuildInfo bInfo;
bInfo.typeName = mesonBuildTypeName(type);
bInfo.displayName = mesonBuildTypeDisplayName(type);
bInfo.buildType = buildType(type);
@@ -148,7 +361,7 @@ MesonBuildConfigurationFactory::MesonBuildConfigurationFactory()
QList<ProjectExplorer::BuildInfo> result;
Utils::FilePath path = forSetup
? ProjectExplorer::Project::projectDirectory(projectPath)
? Project::projectDirectory(projectPath)
: projectPath;
for (const auto &bType : {MesonBuildType::debug,
MesonBuildType::release,
@@ -156,16 +369,14 @@ MesonBuildConfigurationFactory::MesonBuildConfigurationFactory()
MesonBuildType::minsize}) {
auto bInfo = createBuildInfo(bType);
if (forSetup)
bInfo.buildDirectory
= MesonBuildConfiguration::shadowBuildDirectory(projectPath,
k,
bInfo.typeName,
bInfo.buildType);
bInfo.buildDirectory = shadowBuildDirectory(projectPath,
k,
bInfo.typeName,
bInfo.buildType);
result << bInfo;
}
return result;
});
}
} // namespace Internal
} // namespace MesonProjectManager
} // MesonProjectManager::Internal

View File

@@ -1,71 +1,15 @@
// Copyright (C) 2020 Alexis Jeandet.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/target.h>
namespace MesonProjectManager {
namespace Internal {
namespace MesonProjectManager::Internal {
enum class MesonBuildType { plain, debug, debugoptimized, release, minsize, custom };
const QHash<QString, MesonBuildType> buildTypesByName = {{"plain", MesonBuildType::plain},
{"debug", MesonBuildType::debug},
{"debugoptimized",
MesonBuildType::debugoptimized},
{"release", MesonBuildType::release},
{"minsize", MesonBuildType::minsize},
{"custom", MesonBuildType::custom}};
inline QString mesonBuildTypeName(MesonBuildType type)
{
return buildTypesByName.key(type, "custom");
}
inline QString mesonBuildTypeDisplayName(MesonBuildType type)
{
switch (type) {
case MesonBuildType::plain:
return {"Plain"};
case MesonBuildType::debug:
return {"Debug"};
case MesonBuildType::debugoptimized:
return {"Debug With Optimizations"};
case MesonBuildType::release:
return {"Release"};
case MesonBuildType::minsize:
return {"Minimum Size"};
default:
return {"Custom"};
}
}
inline MesonBuildType mesonBuildType(const QString &typeName)
{
return buildTypesByName.value(typeName, MesonBuildType::custom);
}
inline ProjectExplorer::BuildConfiguration::BuildType buildType(MesonBuildType type)
{
switch (type) {
case MesonBuildType::plain:
return ProjectExplorer::BuildConfiguration::Unknown;
case MesonBuildType::debug:
return ProjectExplorer::BuildConfiguration::Debug;
case MesonBuildType::debugoptimized:
return ProjectExplorer::BuildConfiguration::Profile;
case MesonBuildType::release:
return ProjectExplorer::BuildConfiguration::Release;
case MesonBuildType::minsize:
return ProjectExplorer::BuildConfiguration::Release;
default:
return ProjectExplorer::BuildConfiguration::Unknown;
}
}
class MesonBuildSystem;
class MesonTools;
class MesonBuildConfiguration final : public ProjectExplorer::BuildConfiguration
{
@@ -74,12 +18,6 @@ public:
MesonBuildConfiguration(ProjectExplorer::Target *target, Utils::Id id);
~MesonBuildConfiguration() final;
static Utils::FilePath shadowBuildDirectory(
const Utils::FilePath &projectFilePath,
const ProjectExplorer::Kit *k,
const QString &bcName,
ProjectExplorer::BuildConfiguration::BuildType buildType);
ProjectExplorer::BuildSystem *buildSystem() const final;
void build(const QString &target);
@@ -106,5 +44,4 @@ public:
MesonBuildConfigurationFactory();
};
} // namespace Internal
} // namespace MesonProjectManager
} // MesonProjectManager::Internal

View File

@@ -1,167 +0,0 @@
// Copyright (C) 2020 Alexis Jeandet.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "mesonbuildsettingswidget.h"
#include "mesonbuildconfiguration.h"
#include "mesonbuildsystem.h"
#include "mesonprojectmanagertr.h"
#include <coreplugin/find/itemviewfind.h>
#include <projectexplorer/buildaspects.h>
#include <projectexplorer/projectconfiguration.h>
#include <utils/detailswidget.h>
#include <utils/headerviewstretcher.h>
#include <utils/itemviews.h>
#include <utils/layoutbuilder.h>
#include <utils/utilsicons.h>
#include <QLayout>
#include <QPushButton>
using namespace Utils;
namespace MesonProjectManager::Internal {
MesonBuildSettingsWidget::MesonBuildSettingsWidget(MesonBuildConfiguration *buildCfg)
: ProjectExplorer::NamedWidget(Tr::tr("Meson"))
, m_progressIndicator(ProgressIndicatorSize::Large)
{
auto configureButton = new QPushButton(Tr::tr("Apply Configuration Changes"));
configureButton->setEnabled(false);
configureButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
auto wipeButton = new QPushButton(Tr::tr("Wipe Project"));
wipeButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
wipeButton->setIcon(Utils::Icons::WARNING.icon());
wipeButton->setToolTip(Tr::tr("Wipes build directory and reconfigures using previous command "
"line options.\nUseful if build directory is corrupted or when "
"rebuilding with a newer version of Meson."));
auto container = new DetailsWidget;
auto details = new QWidget;
container->setState(DetailsWidget::NoSummary);
container->setWidget(details);
auto parametersLineEdit = new QLineEdit;
auto optionsFilterLineEdit = new FancyLineEdit;
auto optionsTreeView = new TreeView;
optionsTreeView->setMinimumHeight(300);
optionsTreeView->setFrameShape(QFrame::NoFrame);
optionsTreeView->setSelectionBehavior(QAbstractItemView::SelectItems);
optionsTreeView->setUniformRowHeights(true);
optionsTreeView->setSortingEnabled(true);
using namespace Layouting;
Column {
noMargin,
Form {
Tr::tr("Parameters:"), parametersLineEdit, br,
buildCfg->buildDirectoryAspect(), br
},
optionsFilterLineEdit,
optionsTreeView,
}.attachTo(details);
Column {
noMargin,
container,
Row { configureButton, wipeButton, noMargin }
}.attachTo(this);
parametersLineEdit->setText(buildCfg->parameters());
optionsFilterLineEdit->setFiltering(true);
optionsTreeView->sortByColumn(0, Qt::AscendingOrder);
QFrame *findWrapper
= Core::ItemViewFind::createSearchableWrapper(optionsTreeView,
Core::ItemViewFind::LightColored);
findWrapper->setFrameStyle(QFrame::StyledPanel);
m_progressIndicator.attachToWidget(findWrapper);
m_progressIndicator.raise();
m_progressIndicator.hide();
details->layout()->addWidget(findWrapper);
m_showProgressTimer.setSingleShot(true);
m_showProgressTimer.setInterval(50); // don't show progress for < 50ms tasks
connect(&m_showProgressTimer, &QTimer::timeout, [this]() { m_progressIndicator.show(); });
connect(&m_optionsModel, &BuidOptionsModel::configurationChanged, this, [configureButton] {
configureButton->setEnabled(true);
});
m_optionsFilter.setSourceModel(&m_optionsModel);
m_optionsFilter.setSortRole(Qt::DisplayRole);
m_optionsFilter.setFilterKeyColumn(-1);
optionsTreeView->setModel(&m_optionsFilter);
optionsTreeView->setItemDelegate(new BuildOptionDelegate{optionsTreeView});
MesonBuildSystem *bs = static_cast<MesonBuildSystem *>(buildCfg->buildSystem());
connect(buildCfg->target(), &ProjectExplorer::Target::parsingFinished,
this, [this, bs, optionsTreeView](bool success) {
if (success) {
m_optionsModel.setConfiguration(bs->buildOptions());
} else {
m_optionsModel.clear();
}
optionsTreeView->expandAll();
optionsTreeView->resizeColumnToContents(0);
optionsTreeView->setEnabled(true);
m_showProgressTimer.stop();
m_progressIndicator.hide();
});
connect(bs, &MesonBuildSystem::parsingStarted, this, [this, optionsTreeView] {
if (!m_showProgressTimer.isActive()) {
optionsTreeView->setEnabled(false);
m_showProgressTimer.start();
}
});
connect(&m_optionsModel, &BuidOptionsModel::dataChanged, this, [bs, this] {
bs->setMesonConfigArgs(this->m_optionsModel.changesAsMesonArgs());
});
connect(&m_optionsFilter, &QAbstractItemModel::modelReset, this, [optionsTreeView] {
optionsTreeView->expandAll();
optionsTreeView->resizeColumnToContents(0);
});
connect(optionsFilterLineEdit, &QLineEdit::textChanged, &m_optionsFilter, [this](const QString &txt) {
m_optionsFilter.setFilterRegularExpression(
QRegularExpression(QRegularExpression::escape(txt),
QRegularExpression::CaseInsensitiveOption));
});
connect(optionsTreeView,
&Utils::TreeView::activated,
optionsTreeView,
[tree = optionsTreeView](const QModelIndex &idx) { tree->edit(idx); });
connect(configureButton, &QPushButton::clicked, [this, bs, configureButton, optionsTreeView] {
optionsTreeView->setEnabled(false);
configureButton->setEnabled(false);
m_showProgressTimer.start();
bs->configure();
});
connect(wipeButton, &QPushButton::clicked, [this, bs, configureButton, optionsTreeView] {
optionsTreeView->setEnabled(false);
configureButton->setEnabled(false);
m_showProgressTimer.start();
bs->wipe();
});
connect(parametersLineEdit, &QLineEdit::editingFinished, this, [ buildCfg, parametersLineEdit] {
buildCfg->setParameters(parametersLineEdit->text());
});
bs->triggerParsing();
}
MesonBuildSettingsWidget::~MesonBuildSettingsWidget() = default;
} // MesonProjectManager::Internal

View File

@@ -1,34 +0,0 @@
// Copyright (C) 2020 Alexis Jeandet.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include "buildoptionsmodel.h"
#include <projectexplorer/namedwidget.h>
#include <utils/categorysortfiltermodel.h>
#include <utils/progressindicator.h>
#include <QTimer>
namespace MesonProjectManager::Internal {
class MesonBuildConfiguration;
class MesonBuildSettingsWidget : public ProjectExplorer::NamedWidget
{
Q_OBJECT
public:
explicit MesonBuildSettingsWidget(MesonBuildConfiguration *buildCfg);
~MesonBuildSettingsWidget();
private:
BuidOptionsModel m_optionsModel;
Utils::CategorySortFilterModel m_optionsFilter;
Utils::ProgressIndicator m_progressIndicator;
QTimer m_showProgressTimer;
};
} // MesonProjectManager::Internal

View File

@@ -42,8 +42,6 @@ Project {
"mesonpluginconstants.h",
"mesonprojectplugin.cpp",
"mesonprojectplugin.h",
"mesonbuildsettingswidget.cpp",
"mesonbuildsettingswidget.h",
"arrayoptionlineedit.cpp",
"arrayoptionlineedit.h",
"buildoptionsmodel.cpp",