From 4bbf76a344bf1ce84297bb16ab15f23ea4f18378 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 30 Jul 2020 14:54:10 +0200 Subject: [PATCH] ProjectExplorer: Allow to add custom output parsers programatically This enables plugins to add custom parsers to the global pool. Fixes: QTCREATORBUG-24403 Change-Id: Id600c12fc66876879a5a2975139d72f87c4f2e30 Reviewed-by: hjk --- src/plugins/projectexplorer/customparser.cpp | 57 ++++++++++--------- src/plugins/projectexplorer/customparser.h | 42 +++++++------- .../projectexplorer/customtoolchain.cpp | 15 +++-- src/plugins/projectexplorer/customtoolchain.h | 2 +- .../projectexplorer/projectexplorer.cpp | 21 ++++++- src/plugins/projectexplorer/projectexplorer.h | 8 ++- 6 files changed, 83 insertions(+), 62 deletions(-) diff --git a/src/plugins/projectexplorer/customparser.cpp b/src/plugins/projectexplorer/customparser.cpp index aaa97f703a9..7fbd9ffb588 100644 --- a/src/plugins/projectexplorer/customparser.cpp +++ b/src/plugins/projectexplorer/customparser.cpp @@ -59,7 +59,6 @@ const char channelKey[] = "Channel"; const char exampleKey[] = "Example"; namespace ProjectExplorer { -namespace Internal { bool CustomParserExpression::operator ==(const CustomParserExpression &other) const { @@ -177,6 +176,33 @@ void CustomParserSettings::fromMap(const QVariantMap &map) warning.fromMap(map.value(warningKey).toMap()); } +CustomParsersAspect::CustomParsersAspect(Target *target) +{ + Q_UNUSED(target) + setId("CustomOutputParsers"); + setSettingsKey("CustomOutputParsers"); + setDisplayName(tr("Custom Output Parsers")); + setConfigWidgetCreator([this] { + const auto widget = new Internal::CustomParsersSelectionWidget; + widget->setSelectedParsers(m_parsers); + connect(widget, &Internal::CustomParsersSelectionWidget::selectionChanged, + this, [this, widget] { m_parsers = widget->selectedParsers(); }); + return widget; + }); +} + +void CustomParsersAspect::fromMap(const QVariantMap &map) +{ + m_parsers = transform(map.value(settingsKey()).toList(), &Utils::Id::fromSetting); +} + +void CustomParsersAspect::toMap(QVariantMap &map) const +{ + map.insert(settingsKey(), transform(m_parsers, &Utils::Id::toSetting)); +} + +namespace Internal { + CustomParser::CustomParser(const CustomParserSettings &settings) { setObjectName("CustomParser"); @@ -192,8 +218,8 @@ void CustomParser::setSettings(const CustomParserSettings &settings) CustomParser *CustomParser::createFromId(Utils::Id id) { - const Internal::CustomParserSettings parser = findOrDefault(ProjectExplorerPlugin::customParsers(), - [id](const Internal::CustomParserSettings &p) { return p.id == id; }); + const CustomParserSettings parser = findOrDefault(ProjectExplorerPlugin::customParsers(), + [id](const CustomParserSettings &p) { return p.id == id; }); if (parser.id.isValid()) return new CustomParser(parser); return nullptr; @@ -347,31 +373,6 @@ void CustomParsersSelectionWidget::updateSummary() setSummaryText(tr("There are %n custom parsers active", nullptr, parsers.count())); } -CustomParsersAspect::CustomParsersAspect(Target *target) -{ - Q_UNUSED(target) - setId("CustomOutputParsers"); - setSettingsKey("CustomOutputParsers"); - setDisplayName(tr("Custom Output Parsers")); - setConfigWidgetCreator([this] { - const auto widget = new CustomParsersSelectionWidget; - widget->setSelectedParsers(m_parsers); - connect(widget, &CustomParsersSelectionWidget::selectionChanged, - this, [this, widget] { m_parsers = widget->selectedParsers(); }); - return widget; - }); -} - -void CustomParsersAspect::fromMap(const QVariantMap &map) -{ - m_parsers = transform(map.value(settingsKey()).toList(), &Utils::Id::fromSetting); -} - -void CustomParsersAspect::toMap(QVariantMap &map) const -{ - map.insert(settingsKey(), transform(m_parsers, &Utils::Id::toSetting)); -} - } // namespace Internal // Unit tests: diff --git a/src/plugins/projectexplorer/customparser.h b/src/plugins/projectexplorer/customparser.h index 0d431487e19..c1e01780225 100644 --- a/src/plugins/projectexplorer/customparser.h +++ b/src/plugins/projectexplorer/customparser.h @@ -37,9 +37,7 @@ namespace ProjectExplorer { class Target; -namespace Internal { - -class CustomParserExpression +class PROJECTEXPLORER_EXPORT CustomParserExpression { public: enum CustomParserChannel { @@ -80,7 +78,7 @@ private: int m_messageCap = 3; }; -class CustomParserSettings +class PROJECTEXPLORER_EXPORT CustomParserSettings { public: bool operator ==(const CustomParserSettings &other) const; @@ -95,6 +93,24 @@ public: CustomParserExpression warning; }; +class PROJECTEXPLORER_EXPORT CustomParsersAspect : public ProjectConfigurationAspect +{ + Q_OBJECT +public: + CustomParsersAspect(Target *target); + + void setParsers(const QList &parsers) { m_parsers = parsers; } + const QList parsers() const { return m_parsers; } + +private: + void fromMap(const QVariantMap &map) override; + void toMap(QVariantMap &map) const override; + + QList m_parsers; +}; + +namespace Internal { + class CustomParser : public ProjectExplorer::OutputTaskParser { public: @@ -132,23 +148,7 @@ private: void updateSummary(); }; -class CustomParsersAspect : public ProjectConfigurationAspect -{ - Q_OBJECT -public: - CustomParsersAspect(Target *target); - - void setParsers(const QList &parsers) { m_parsers = parsers; } - const QList parsers() const { return m_parsers; } - -private: - void fromMap(const QVariantMap &map) override; - void toMap(QVariantMap &map) const override; - - QList m_parsers; -}; - } // namespace Internal } // namespace ProjectExplorer -Q_DECLARE_METATYPE(ProjectExplorer::Internal::CustomParserExpression::CustomParserChannel); +Q_DECLARE_METATYPE(ProjectExplorer::CustomParserExpression::CustomParserChannel); diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp index 07468c3392f..e18becd9793 100644 --- a/src/plugins/projectexplorer/customtoolchain.cpp +++ b/src/plugins/projectexplorer/customtoolchain.cpp @@ -77,10 +77,10 @@ CustomToolChain::CustomToolChain() : setTypeDisplayName(tr("Custom")); } -Internal::CustomParserSettings CustomToolChain::customParserSettings() const +CustomParserSettings CustomToolChain::customParserSettings() const { return findOrDefault(ProjectExplorerPlugin::customParsers(), - [this](const Internal::CustomParserSettings &s) { + [this](const CustomParserSettings &s) { return s.id == outputParserId(); }); } @@ -310,7 +310,7 @@ bool CustomToolChain::fromMap(const QVariantMap &data) // Restore Pre-4.13 settings. if (outputParserId() == Internal::CustomParser::id()) { - Internal::CustomParserSettings customParserSettings; + CustomParserSettings customParserSettings; customParserSettings.error.setPattern( data.value("ProjectExplorer.CustomToolChain.ErrorPattern").toString()); customParserSettings.error.setFileNameCap( @@ -320,7 +320,7 @@ bool CustomToolChain::fromMap(const QVariantMap &data) customParserSettings.error.setMessageCap( data.value("ProjectExplorer.CustomToolChain.ErrorMessageCap").toInt()); customParserSettings.error.setChannel( - static_cast( + static_cast( data.value("ProjectExplorer.CustomToolChain.ErrorChannel").toInt())); customParserSettings.error.setExample( data.value("ProjectExplorer.CustomToolChain.ErrorExample").toString()); @@ -333,7 +333,7 @@ bool CustomToolChain::fromMap(const QVariantMap &data) customParserSettings.warning.setMessageCap( data.value("ProjectExplorer.CustomToolChain.WarningMessageCap").toInt()); customParserSettings.warning.setChannel( - static_cast( + static_cast( data.value("ProjectExplorer.CustomToolChain.WarningChannel").toInt())); customParserSettings.warning.setExample( data.value("ProjectExplorer.CustomToolChain.WarningExample").toString()); @@ -343,8 +343,7 @@ bool CustomToolChain::fromMap(const QVariantMap &data) customParserSettings.id = Utils::Id::fromString(QUuid::createUuid().toString()); setOutputParserId(customParserSettings.id); customParserSettings.displayName = tr("Parser for toolchain %1").arg(displayName()); - QList settings - = ProjectExplorerPlugin::customParsers(); + QList settings = ProjectExplorerPlugin::customParsers(); settings << customParserSettings; ProjectExplorerPlugin::setCustomParsers(settings); } @@ -476,7 +475,7 @@ CustomToolChainConfigWidget::CustomToolChainConfigWidget(CustomToolChain *tc) : const QList parsers = CustomToolChain::parsers(); for (const auto &parser : parsers) m_errorParserComboBox->addItem(parser.displayName, parser.parserId.toString()); - for (const Internal::CustomParserSettings &s : ProjectExplorerPlugin::customParsers()) + for (const CustomParserSettings &s : ProjectExplorerPlugin::customParsers()) m_errorParserComboBox->addItem(s.displayName, s.id.toString()); auto parserLayoutWidget = new QWidget; diff --git a/src/plugins/projectexplorer/customtoolchain.h b/src/plugins/projectexplorer/customtoolchain.h index fafa9f58c77..bd1ccd367f0 100644 --- a/src/plugins/projectexplorer/customtoolchain.h +++ b/src/plugins/projectexplorer/customtoolchain.h @@ -112,7 +112,7 @@ public: private: CustomToolChain(); - Internal::CustomParserSettings customParserSettings() const; + CustomParserSettings customParserSettings() const; Utils::FilePath m_compilerCommand; Utils::FilePath m_makeCommand; diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 67fb64b92ee..22ba895cc2f 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -555,7 +555,7 @@ public: MiniProjectTargetSelector * m_targetSelector; ProjectExplorerSettings m_projectExplorerSettings; BuildPropertiesSettings m_buildPropertiesSettings; - QList m_customParsers; + QList m_customParsers; bool m_shouldHaveRunConfiguration = false; bool m_shuttingDown = false; Utils::Id m_runMode = Constants::NO_RUN_MODE; @@ -3897,6 +3897,25 @@ void ProjectExplorerPlugin::setCustomParsers(const QList & } } +void ProjectExplorerPlugin::addCustomParser(const CustomParserSettings &settings) +{ + QTC_ASSERT(settings.id.isValid(), return); + QTC_ASSERT(!contains(dd->m_customParsers, [&settings](const CustomParserSettings &s) { + return s.id == settings.id; + }), return); + + dd->m_customParsers << settings; + emit m_instance->customParsersChanged(); +} + +void ProjectExplorerPlugin::removeCustomParser(Id id) +{ + erase(dd->m_customParsers, [id](const CustomParserSettings &s) { + return s.id == id; + }); + emit m_instance->customParsersChanged(); +} + const QList ProjectExplorerPlugin::customParsers() { return dd->m_customParsers; diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index a8eef60e439..1255beb08ec 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -49,6 +49,7 @@ class FilePath; namespace ProjectExplorer { class BuildPropertiesSettings; +class CustomParserSettings; class RunControl; class RunConfiguration; class Project; @@ -58,7 +59,6 @@ class FileNode; namespace Internal { class AppOutputSettings; -class CustomParserSettings; class MiniProjectTargetSelector; class ProjectExplorerSettings; } @@ -141,8 +141,10 @@ public: static const BuildPropertiesSettings &buildPropertiesSettings(); static void showQtSettings(); - static void setCustomParsers(const QList &settings); - static const QList customParsers(); + static void setCustomParsers(const QList &settings); + static void addCustomParser(const CustomParserSettings &settings); + static void removeCustomParser(Utils::Id id); + static const QList customParsers(); static void startRunControl(RunControl *runControl); static void showOutputPaneForRunControl(RunControl *runControl);