diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp index 9f9cd1f90d7..79bddadb0a0 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp +++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp @@ -28,6 +28,7 @@ #include "qbsbuildconfigurationwidget.h" #include "qbsbuildstep.h" #include "qbscleanstep.h" +#include "qbsinstallstep.h" #include "qbsproject.h" #include "qbsprojectmanagerconstants.h" #include "qbsprojectmanagersettings.h" @@ -37,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -213,24 +215,31 @@ public: StepProxy(const BuildStep *buildStep) : m_qbsBuildStep(qobject_cast(buildStep)) , m_qbsCleanStep(qobject_cast(buildStep)) + , m_qbsInstallStep(qobject_cast(buildStep)) { } QString command() const { if (m_qbsBuildStep) return QLatin1String("build"); + if (m_qbsInstallStep) + return QLatin1String("install"); return QLatin1String("clean"); } bool dryRun() const { if (m_qbsBuildStep) return false; + if (m_qbsInstallStep) + return m_qbsInstallStep->dryRun(); return m_qbsCleanStep->dryRun(); } bool keepGoing() const { if (m_qbsBuildStep) return m_qbsBuildStep->keepGoing(); + if (m_qbsInstallStep) + return m_qbsInstallStep->keepGoing(); return m_qbsCleanStep->keepGoing(); } @@ -242,9 +251,13 @@ public: return m_qbsBuildStep ? !m_qbsBuildStep->install() : false; } + bool noBuild() const { return m_qbsInstallStep; } + bool cleanInstallRoot() const { if (m_qbsBuildStep) return m_qbsBuildStep->cleanInstallRoot(); + if (m_qbsInstallStep) + return m_qbsInstallStep->removeFirst(); return false; } @@ -253,14 +266,22 @@ public: } Utils::FileName installRoot() const { - if (m_qbsBuildStep && m_qbsBuildStep->hasCustomInstallRoot()) - return m_qbsBuildStep->installRoot(); + const QbsBuildStep *bs = nullptr; + if (m_qbsBuildStep) { + bs = m_qbsBuildStep; + } else if (m_qbsInstallStep) { + bs = static_cast(m_qbsInstallStep->deployConfiguration() + ->target()->activeBuildConfiguration())->qbsStep(); + } + if (bs && bs->hasCustomInstallRoot()) + return bs->installRoot(); return Utils::FileName(); } private: const QbsBuildStep * const m_qbsBuildStep; const QbsCleanStep * const m_qbsCleanStep; + const QbsInstallStep * const m_qbsInstallStep; }; QString QbsBuildConfiguration::equivalentCommandLine(const BuildStep *buildStep) const @@ -290,6 +311,8 @@ QString QbsBuildConfiguration::equivalentCommandLine(const BuildStep *buildStep) "command-line"})); if (stepProxy.noInstall()) Utils::QtcProcess::addArg(&commandLine, QLatin1String("--no-install")); + if (stepProxy.noBuild()) + Utils::QtcProcess::addArg(&commandLine, QLatin1String("--no-build")); if (stepProxy.cleanInstallRoot()) Utils::QtcProcess::addArg(&commandLine, QLatin1String("--clean-install-root")); const int jobCount = stepProxy.jobCount(); @@ -307,6 +330,10 @@ QString QbsBuildConfiguration::equivalentCommandLine(const BuildStep *buildStep) if (!installRoot.isEmpty()) { Utils::QtcProcess::addArg(&commandLine, QLatin1String(Constants::QBS_INSTALL_ROOT_KEY) + QLatin1Char(':') + installRoot.toUserOutput()); + if (qobject_cast(buildStep)) { + Utils::QtcProcess::addArgs(&commandLine, QStringList({ QLatin1String("--installRoot"), + installRoot.toUserOutput() } )); + } } Utils::QtcProcess::addArg(&commandLine, QLatin1String("profile:") + profileName); diff --git a/src/plugins/qbsprojectmanager/qbsdeployconfigurationfactory.cpp b/src/plugins/qbsprojectmanager/qbsdeployconfigurationfactory.cpp index b91ece82db9..5435d5777ca 100644 --- a/src/plugins/qbsprojectmanager/qbsdeployconfigurationfactory.cpp +++ b/src/plugins/qbsprojectmanager/qbsdeployconfigurationfactory.cpp @@ -25,6 +25,7 @@ #include "qbsdeployconfigurationfactory.h" +#include "qbsinstallstep.h" #include "qbsproject.h" #include diff --git a/src/plugins/qbsprojectmanager/qbsinstallstep.cpp b/src/plugins/qbsprojectmanager/qbsinstallstep.cpp new file mode 100644 index 00000000000..840cf4eefd5 --- /dev/null +++ b/src/plugins/qbsprojectmanager/qbsinstallstep.cpp @@ -0,0 +1,376 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "qbsinstallstep.h" + +#include "qbsbuildconfiguration.h" +#include "qbsbuildstep.h" +#include "qbsproject.h" +#include "qbsprojectmanagerconstants.h" + +#include "ui_qbsinstallstepconfigwidget.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +// -------------------------------------------------------------------- +// Constants: +// -------------------------------------------------------------------- + +static const char QBS_REMOVE_FIRST[] = "Qbs.RemoveFirst"; +static const char QBS_DRY_RUN[] = "Qbs.DryRun"; +static const char QBS_KEEP_GOING[] = "Qbs.DryKeepGoing"; + +namespace QbsProjectManager { +namespace Internal { + +// -------------------------------------------------------------------- +// QbsInstallStep: +// -------------------------------------------------------------------- + +QbsInstallStep::QbsInstallStep(ProjectExplorer::BuildStepList *bsl) : + ProjectExplorer::BuildStep(bsl, Core::Id(Constants::QBS_INSTALLSTEP_ID)), + m_job(0), m_showCompilerOutput(true), m_parser(0) +{ + setDisplayName(tr("Qbs Install")); + ctor(); +} + +QbsInstallStep::QbsInstallStep(ProjectExplorer::BuildStepList *bsl, const QbsInstallStep *other) : + ProjectExplorer::BuildStep(bsl, Core::Id(Constants::QBS_INSTALLSTEP_ID)), + m_qbsInstallOptions(other->m_qbsInstallOptions), m_job(0), + m_showCompilerOutput(other->m_showCompilerOutput), m_parser(0) +{ + ctor(); +} + +QbsInstallStep::~QbsInstallStep() +{ + cancel(); + if (m_job) + m_job->deleteLater(); + m_job = 0; +} + +bool QbsInstallStep::init(QList &earlierSteps) +{ + Q_UNUSED(earlierSteps); + QTC_ASSERT(!static_cast(project())->isParsing() && !m_job, return false); + return true; +} + +void QbsInstallStep::run(QFutureInterface &fi) +{ + m_fi = &fi; + + QbsProject *pro = static_cast(project()); + m_job = pro->install(m_qbsInstallOptions); + + if (!m_job) { + reportRunResult(*m_fi, false); + return; + } + + m_progressBase = 0; + + connect(m_job, &qbs::AbstractJob::finished, this, &QbsInstallStep::installDone); + connect(m_job, &qbs::AbstractJob::taskStarted, + this, &QbsInstallStep::handleTaskStarted); + connect(m_job, &qbs::AbstractJob::taskProgress, + this, &QbsInstallStep::handleProgress); +} + +ProjectExplorer::BuildStepConfigWidget *QbsInstallStep::createConfigWidget() +{ + return new QbsInstallStepConfigWidget(this); +} + +bool QbsInstallStep::runInGuiThread() const +{ + return true; +} + +void QbsInstallStep::cancel() +{ + if (m_job) + m_job->cancel(); +} + +QString QbsInstallStep::installRoot() const +{ + const QbsBuildStep * const bs = buildConfig()->qbsStep(); + return bs ? bs->installRoot().toString() : QString(); +} + +bool QbsInstallStep::removeFirst() const +{ + return m_qbsInstallOptions.removeExistingInstallation(); +} + +bool QbsInstallStep::dryRun() const +{ + return m_qbsInstallOptions.dryRun(); +} + +bool QbsInstallStep::keepGoing() const +{ + return m_qbsInstallOptions.keepGoing(); +} + +void QbsInstallStep::ctor() +{ + const QbsBuildConfiguration * const bc = buildConfig(); + connect(bc, &QbsBuildConfiguration::qbsConfigurationChanged, + this, &QbsInstallStep::handleBuildConfigChanged); + if (bc->qbsStep()) { + connect(bc->qbsStep(), &QbsBuildStep::qbsBuildOptionsChanged, + this, &QbsInstallStep::handleBuildConfigChanged); + } +} + +const QbsBuildConfiguration *QbsInstallStep::buildConfig() const +{ + return static_cast( + deployConfiguration()->target()->activeBuildConfiguration()); +} + +bool QbsInstallStep::fromMap(const QVariantMap &map) +{ + if (!ProjectExplorer::BuildStep::fromMap(map)) + return false; + + m_qbsInstallOptions.setInstallRoot(installRoot()); + m_qbsInstallOptions.setRemoveExistingInstallation( + map.value(QLatin1String(QBS_REMOVE_FIRST), false).toBool()); + m_qbsInstallOptions.setDryRun(map.value(QLatin1String(QBS_DRY_RUN), false).toBool()); + m_qbsInstallOptions.setKeepGoing(map.value(QLatin1String(QBS_KEEP_GOING), false).toBool()); + + return true; +} + +QVariantMap QbsInstallStep::toMap() const +{ + QVariantMap map = ProjectExplorer::BuildStep::toMap(); + map.insert(QLatin1String(QBS_REMOVE_FIRST), m_qbsInstallOptions.removeExistingInstallation()); + map.insert(QLatin1String(QBS_DRY_RUN), m_qbsInstallOptions.dryRun()); + map.insert(QLatin1String(QBS_KEEP_GOING), m_qbsInstallOptions.keepGoing()); + return map; +} + +qbs::InstallOptions QbsInstallStep::installOptions() const +{ + return m_qbsInstallOptions; +} + +void QbsInstallStep::installDone(bool success) +{ + // Report errors: + foreach (const qbs::ErrorItem &item, m_job->error().items()) { + createTaskAndOutput(ProjectExplorer::Task::Error, item.description(), + item.codeLocation().filePath(), item.codeLocation().line()); + } + + QTC_ASSERT(m_fi, return); + reportRunResult(*m_fi, success); + m_fi = 0; // do not delete, it is not ours + m_job->deleteLater(); + m_job = 0; +} + +void QbsInstallStep::handleTaskStarted(const QString &desciption, int max) +{ + Q_UNUSED(desciption); + QTC_ASSERT(m_fi, return); + m_progressBase = m_fi->progressValue(); + m_fi->setProgressRange(0, m_progressBase + max); +} + +void QbsInstallStep::handleProgress(int value) +{ + QTC_ASSERT(m_fi, return); + m_fi->setProgressValue(m_progressBase + value); +} + +void QbsInstallStep::createTaskAndOutput(ProjectExplorer::Task::TaskType type, + const QString &message, const QString &file, int line) +{ + ProjectExplorer::Task task = ProjectExplorer::Task(type, message, + Utils::FileName::fromString(file), line, + ProjectExplorer::Constants::TASK_CATEGORY_COMPILE); + emit addTask(task, 1); + emit addOutput(message, OutputFormat::Stdout); +} + +void QbsInstallStep::setRemoveFirst(bool rf) +{ + if (m_qbsInstallOptions.removeExistingInstallation() == rf) + return; + m_qbsInstallOptions.setRemoveExistingInstallation(rf); + emit changed(); +} + +void QbsInstallStep::setDryRun(bool dr) +{ + if (m_qbsInstallOptions.dryRun() == dr) + return; + m_qbsInstallOptions.setDryRun(dr); + emit changed(); +} + +void QbsInstallStep::setKeepGoing(bool kg) +{ + if (m_qbsInstallOptions.keepGoing() == kg) + return; + m_qbsInstallOptions.setKeepGoing(kg); + emit changed(); +} + +void QbsInstallStep::handleBuildConfigChanged() +{ + m_qbsInstallOptions.setInstallRoot(installRoot()); + emit changed(); +} + +// -------------------------------------------------------------------- +// QbsInstallStepConfigWidget: +// -------------------------------------------------------------------- + +QbsInstallStepConfigWidget::QbsInstallStepConfigWidget(QbsInstallStep *step) : + m_step(step), m_ignoreChange(false) +{ + connect(m_step, &ProjectExplorer::ProjectConfiguration::displayNameChanged, + this, &QbsInstallStepConfigWidget::updateState); + connect(m_step, &QbsInstallStep::changed, + this, &QbsInstallStepConfigWidget::updateState); + + setContentsMargins(0, 0, 0, 0); + + QbsProject *project = static_cast(m_step->project()); + + m_ui = new Ui::QbsInstallStepConfigWidget; + m_ui->setupUi(this); + + connect(m_ui->removeFirstCheckBox, &QAbstractButton::toggled, + this, &QbsInstallStepConfigWidget::changeRemoveFirst); + connect(m_ui->dryRunCheckBox, &QAbstractButton::toggled, + this, &QbsInstallStepConfigWidget::changeDryRun); + connect(m_ui->keepGoingCheckBox, &QAbstractButton::toggled, + this, &QbsInstallStepConfigWidget::changeKeepGoing); + + connect(project, &QbsProject::projectParsingDone, + this, &QbsInstallStepConfigWidget::updateState); + + updateState(); +} + +QbsInstallStepConfigWidget::~QbsInstallStepConfigWidget() +{ + delete m_ui; +} + +QString QbsInstallStepConfigWidget::summaryText() const +{ + return m_summary; +} + +QString QbsInstallStepConfigWidget::displayName() const +{ + return m_step->displayName(); +} + +void QbsInstallStepConfigWidget::updateState() +{ + if (!m_ignoreChange) { + m_ui->installRootValueLabel->setText(m_step->installRoot()); + m_ui->removeFirstCheckBox->setChecked(m_step->removeFirst()); + m_ui->dryRunCheckBox->setChecked(m_step->dryRun()); + m_ui->keepGoingCheckBox->setChecked(m_step->keepGoing()); + } + + QString command = m_step->buildConfig()->equivalentCommandLine(m_step); + + m_ui->commandLineTextEdit->setPlainText(command); + + QString summary = tr("Qbs: %1").arg(command); + if (m_summary != summary) { + m_summary = summary; + emit updateSummary(); + } +} + +void QbsInstallStepConfigWidget::changeRemoveFirst(bool rf) +{ + m_step->setRemoveFirst(rf); +} + +void QbsInstallStepConfigWidget::changeDryRun(bool dr) +{ + m_step->setDryRun(dr); +} + +void QbsInstallStepConfigWidget::changeKeepGoing(bool kg) +{ + m_step->setKeepGoing(kg); +} + +// -------------------------------------------------------------------- +// QbsInstallStepFactory: +// -------------------------------------------------------------------- + +QbsInstallStepFactory::QbsInstallStepFactory(QObject *parent) : + ProjectExplorer::IBuildStepFactory(parent) +{ } + +QList QbsInstallStepFactory::availableSteps(ProjectExplorer::BuildStepList *parent) const +{ + if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_DEPLOY + && qobject_cast(parent->parent()) + && qobject_cast(parent->target()->project())) + return {{ Constants::QBS_INSTALLSTEP_ID, tr("Qbs Install") }}; + return {}; +} + +ProjectExplorer::BuildStep *QbsInstallStepFactory::create(ProjectExplorer::BuildStepList *parent, + const Core::Id id) +{ + Q_UNUSED(id); + return new QbsInstallStep(parent); +} + +ProjectExplorer::BuildStep *QbsInstallStepFactory::clone(ProjectExplorer::BuildStepList *parent, + ProjectExplorer::BuildStep *product) +{ + return new QbsInstallStep(parent, static_cast(product)); +} + +} // namespace Internal +} // namespace QbsProjectManager diff --git a/src/plugins/qbsprojectmanager/qbsinstallstep.h b/src/plugins/qbsprojectmanager/qbsinstallstep.h new file mode 100644 index 00000000000..ff1c5b9b1eb --- /dev/null +++ b/src/plugins/qbsprojectmanager/qbsinstallstep.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "qbsbuildconfiguration.h" + +#include +#include + +#include + +namespace QbsProjectManager { +namespace Internal { + +class QbsInstallStepConfigWidget; + +class QbsInstallStep : public ProjectExplorer::BuildStep +{ + Q_OBJECT + +public: + explicit QbsInstallStep(ProjectExplorer::BuildStepList *bsl); + QbsInstallStep(ProjectExplorer::BuildStepList *bsl, const QbsInstallStep *other); + ~QbsInstallStep() override; + + bool init(QList &earlierSteps) override; + + void run(QFutureInterface &fi) override; + + ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override; + + bool runInGuiThread() const override; + void cancel() override; + + bool fromMap(const QVariantMap &map) override; + QVariantMap toMap() const override; + + qbs::InstallOptions installOptions() const; + QString installRoot() const; + bool removeFirst() const; + bool dryRun() const; + bool keepGoing() const; + +signals: + void changed(); + +private: + void ctor(); + const QbsBuildConfiguration *buildConfig() const; + void installDone(bool success); + void handleTaskStarted(const QString &desciption, int max); + void handleProgress(int value); + + void createTaskAndOutput(ProjectExplorer::Task::TaskType type, + const QString &message, const QString &file, int line); + + void setRemoveFirst(bool rf); + void setDryRun(bool dr); + void setKeepGoing(bool kg); + void handleBuildConfigChanged(); + + qbs::InstallOptions m_qbsInstallOptions; + + QFutureInterface *m_fi; + qbs::InstallJob *m_job; + int m_progressBase; + bool m_showCompilerOutput; + ProjectExplorer::IOutputParser *m_parser; + + friend class QbsInstallStepConfigWidget; +}; + +namespace Ui { class QbsInstallStepConfigWidget; } + +class QbsInstallStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget +{ + Q_OBJECT +public: + QbsInstallStepConfigWidget(QbsInstallStep *step); + ~QbsInstallStepConfigWidget(); + QString summaryText() const; + QString displayName() const; + +private: + void updateState(); + + void changeRemoveFirst(bool rf); + void changeDryRun(bool dr); + void changeKeepGoing(bool kg); + +private: + Ui::QbsInstallStepConfigWidget *m_ui; + + QbsInstallStep *m_step; + QString m_summary; + bool m_ignoreChange; +}; + +class QbsInstallStepFactory : public ProjectExplorer::IBuildStepFactory +{ + Q_OBJECT + +public: + explicit QbsInstallStepFactory(QObject *parent = 0); + + QList + availableSteps(ProjectExplorer::BuildStepList *parent) const override; + + ProjectExplorer::BuildStep *create(ProjectExplorer::BuildStepList *parent, Core::Id id) override; + ProjectExplorer::BuildStep *clone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *product) override; +}; + +} // namespace Internal +} // namespace QbsProjectManager diff --git a/src/plugins/qbsprojectmanager/qbsinstallstepconfigwidget.ui b/src/plugins/qbsprojectmanager/qbsinstallstepconfigwidget.ui new file mode 100644 index 00000000000..69c51022039 --- /dev/null +++ b/src/plugins/qbsprojectmanager/qbsinstallstepconfigwidget.ui @@ -0,0 +1,118 @@ + + + QbsProjectManager::Internal::QbsInstallStepConfigWidget + + + + 0 + 0 + 474 + 146 + + + + + + + Install root: + + + + + + + Flags: + + + + + + + + + Dry run + + + + + + + Keep going + + + + + + + Remove first + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 0 + + + + Equivalent command line: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + 0 + 0 + + + + true + + + + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + + + dryRunCheckBox + keepGoingCheckBox + removeFirstCheckBox + commandLineTextEdit + + + + diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanager.pro b/src/plugins/qbsprojectmanager/qbsprojectmanager.pro index 465bad1d2ca..43562eceb2a 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanager.pro +++ b/src/plugins/qbsprojectmanager/qbsprojectmanager.pro @@ -27,6 +27,7 @@ HEADERS = \ qbscleanstep.h \ qbsdeployconfigurationfactory.h \ qbsinfopage.h \ + qbsinstallstep.h \ qbslogsink.h \ qbsnodes.h \ qbsnodetreebuilder.h \ @@ -51,6 +52,7 @@ SOURCES = \ qbscleanstep.cpp \ qbsdeployconfigurationfactory.cpp \ qbsinfopage.cpp \ + qbsinstallstep.cpp \ qbslogsink.cpp \ qbsnodes.cpp \ qbsnodetreebuilder.cpp \ @@ -69,6 +71,7 @@ FORMS = \ qbsbuildstepconfigwidget.ui \ qbscleanstepconfigwidget.ui \ qbsinfowidget.ui \ + qbsinstallstepconfigwidget.ui \ qbsprofilessettingswidget.ui RESOURCES += \ diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs index 120a3cae3bd..93753f46570 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs +++ b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs @@ -79,6 +79,9 @@ QtcPlugin { "qbsinfopage.cpp", "qbsinfopage.h", "qbsinfowidget.ui", + "qbsinstallstep.cpp", + "qbsinstallstep.h", + "qbsinstallstepconfigwidget.ui", "qbslogsink.cpp", "qbslogsink.h", "qbsnodes.cpp", diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp index 315b2d39638..fe7b3618e43 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp @@ -30,6 +30,7 @@ #include "qbscleanstep.h" #include "qbsdeployconfigurationfactory.h" #include "qbsinfopage.h" +#include "qbsinstallstep.h" #include "qbsnodes.h" #include "qbsprofilessettingspage.h" #include "qbsproject.h" @@ -98,6 +99,7 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString * addAutoReleasedObject(new QbsBuildConfigurationFactory); addAutoReleasedObject(new QbsBuildStepFactory); addAutoReleasedObject(new QbsCleanStepFactory); + addAutoReleasedObject(new QbsInstallStepFactory); addAutoReleasedObject(new QbsDeployConfigurationFactory); addAutoReleasedObject(new QbsRunConfigurationFactory); addAutoReleasedObject(new QbsProfilesSettingsPage); diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp index 6730963ab20..5d9ed553761 100644 --- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp +++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp @@ -26,6 +26,7 @@ #include "qbsrunconfiguration.h" #include "qbsdeployconfigurationfactory.h" +#include "qbsinstallstep.h" #include "qbsproject.h" #include @@ -110,6 +111,7 @@ const qbs::ProductData findProduct(const qbs::ProjectData &pro, const QString &u QbsRunConfiguration::QbsRunConfiguration(Target *parent, Core::Id id) : RunConfiguration(parent, id), m_uniqueProductName(uniqueProductNameFromId(id)), + m_currentInstallStep(0), m_currentBuildStepList(0) { auto * const envAspect = new LocalEnvironmentAspect(this, @@ -133,6 +135,7 @@ QbsRunConfiguration::QbsRunConfiguration(Target *parent, Core::Id id) : QbsRunConfiguration::QbsRunConfiguration(Target *parent, QbsRunConfiguration *source) : RunConfiguration(parent, source), m_uniqueProductName(source->m_uniqueProductName), + m_currentInstallStep(0), // no need to copy this, we will get if from the DC anyway. m_currentBuildStepList(0) // ditto { ctor(); @@ -186,6 +189,10 @@ QWidget *QbsRunConfiguration::createConfigurationWidget() void QbsRunConfiguration::installStepChanged() { + if (m_currentInstallStep) { + disconnect(m_currentInstallStep, &QbsInstallStep::changed, + this, &QbsRunConfiguration::targetInformationChanged); + } if (m_currentBuildStepList) { disconnect(m_currentBuildStepList, &BuildStepList::stepInserted, this, &QbsRunConfiguration::installStepChanged); @@ -197,10 +204,15 @@ void QbsRunConfiguration::installStepChanged() QbsDeployConfiguration *activeDc = qobject_cast(target()->activeDeployConfiguration()); m_currentBuildStepList = activeDc ? activeDc->stepList() : 0; - + if (m_currentInstallStep) { + connect(m_currentInstallStep, &QbsInstallStep::changed, + this, &QbsRunConfiguration::targetInformationChanged); + } if (m_currentBuildStepList) { connect(m_currentBuildStepList, &BuildStepList::stepInserted, this, &QbsRunConfiguration::installStepChanged); + connect(m_currentBuildStepList, &BuildStepList::aboutToRemoveStep, this, + &QbsRunConfiguration::installStepToBeRemoved); connect(m_currentBuildStepList, &BuildStepList::stepRemoved, this, &QbsRunConfiguration::installStepChanged); connect(m_currentBuildStepList, &BuildStepList::stepMoved, @@ -210,6 +222,18 @@ void QbsRunConfiguration::installStepChanged() emit targetInformationChanged(); } +void QbsRunConfiguration::installStepToBeRemoved(int pos) +{ + QTC_ASSERT(m_currentBuildStepList, return); + // TODO: Our logic is rather broken. Users can create as many qbs install steps as they want, + // but we ignore all but the first one. + if (m_currentBuildStepList->steps().at(pos) != m_currentInstallStep) + return; + disconnect(m_currentInstallStep, &QbsInstallStep::changed, + this, &QbsRunConfiguration::targetInformationChanged); + m_currentInstallStep = 0; +} + Runnable QbsRunConfiguration::runnable() const { StandardRunnable r; diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h index 92273e5f4ef..45b4c3b830b 100644 --- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h +++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h @@ -50,6 +50,7 @@ class QbsProject; namespace Internal { +class QbsInstallStep; class QbsRunConfigurationFactory; class QbsRunConfiguration : public ProjectExplorer::RunConfiguration @@ -86,6 +87,7 @@ protected: private: void installStepChanged(); + void installStepToBeRemoved(int pos); QString baseWorkingDirectory() const; QString defaultDisplayName(); @@ -95,8 +97,7 @@ private: QString m_uniqueProductName; - // Cached startup sub project information - + QbsInstallStep *m_currentInstallStep; // We do not take ownership! ProjectExplorer::BuildStepList *m_currentBuildStepList; // We do not take ownership! };