diff --git a/src/plugins/mesonprojectmanager/CMakeLists.txt b/src/plugins/mesonprojectmanager/CMakeLists.txt index d56f77c20e4..2f0d61ad59a 100644 --- a/src/plugins/mesonprojectmanager/CMakeLists.txt +++ b/src/plugins/mesonprojectmanager/CMakeLists.txt @@ -18,8 +18,6 @@ add_qtc_plugin(MesonProjectManager mesonactionsmanager.h mesonbuildconfiguration.cpp mesonbuildconfiguration.h - mesonbuildsettingswidget.cpp - mesonbuildsettingswidget.h mesonbuildsystem.cpp mesonbuildsystem.h mesoninfo.h diff --git a/src/plugins/mesonprojectmanager/mesonbuildconfiguration.cpp b/src/plugins/mesonprojectmanager/mesonbuildconfiguration.cpp index 514c529212a..b71d28b1072 100644 --- a/src/plugins/mesonprojectmanager/mesonbuildconfiguration.cpp +++ b/src/plugins/mesonprojectmanager/mesonbuildconfiguration.cpp @@ -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 + +#include #include #include #include #include #include +#include #include +#include #include -#include +#include +#include +#include +#include +#include #include +#include +#include -#include +#include +#include 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 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(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 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 diff --git a/src/plugins/mesonprojectmanager/mesonbuildconfiguration.h b/src/plugins/mesonprojectmanager/mesonbuildconfiguration.h index a4059091892..d262c837810 100644 --- a/src/plugins/mesonprojectmanager/mesonbuildconfiguration.h +++ b/src/plugins/mesonprojectmanager/mesonbuildconfiguration.h @@ -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 -#include -namespace MesonProjectManager { -namespace Internal { +namespace MesonProjectManager::Internal { enum class MesonBuildType { plain, debug, debugoptimized, release, minsize, custom }; -const QHash 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 diff --git a/src/plugins/mesonprojectmanager/mesonbuildsettingswidget.cpp b/src/plugins/mesonprojectmanager/mesonbuildsettingswidget.cpp deleted file mode 100644 index 26389d38883..00000000000 --- a/src/plugins/mesonprojectmanager/mesonbuildsettingswidget.cpp +++ /dev/null @@ -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 - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -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(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 diff --git a/src/plugins/mesonprojectmanager/mesonbuildsettingswidget.h b/src/plugins/mesonprojectmanager/mesonbuildsettingswidget.h deleted file mode 100644 index 8c3f89d9518..00000000000 --- a/src/plugins/mesonprojectmanager/mesonbuildsettingswidget.h +++ /dev/null @@ -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 - -#include -#include - -#include - -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 diff --git a/src/plugins/mesonprojectmanager/mesonprojectmanager.qbs b/src/plugins/mesonprojectmanager/mesonprojectmanager.qbs index 552029cf639..db81d16f1a7 100644 --- a/src/plugins/mesonprojectmanager/mesonprojectmanager.qbs +++ b/src/plugins/mesonprojectmanager/mesonprojectmanager.qbs @@ -42,8 +42,6 @@ Project { "mesonpluginconstants.h", "mesonprojectplugin.cpp", "mesonprojectplugin.h", - "mesonbuildsettingswidget.cpp", - "mesonbuildsettingswidget.h", "arrayoptionlineedit.cpp", "arrayoptionlineedit.h", "buildoptionsmodel.cpp",