diff --git a/src/plugins/projectexplorer/buildtargetinfo.h b/src/plugins/projectexplorer/buildtargetinfo.h index c41cbea69fb..06416ea899e 100644 --- a/src/plugins/projectexplorer/buildtargetinfo.h +++ b/src/plugins/projectexplorer/buildtargetinfo.h @@ -28,6 +28,7 @@ #include "projectexplorer_export.h" #include +#include #include #include @@ -40,28 +41,32 @@ class PROJECTEXPLORER_EXPORT BuildTargetInfo public: BuildTargetInfo() = default; BuildTargetInfo(const QString &targetName, const Utils::FileName &targetFilePath, - const Utils::FileName &projectFilePath) : + const Utils::FileName &projectFilePath, bool isQtcRunnable = true) : targetName(targetName), targetFilePath(targetFilePath), - projectFilePath(projectFilePath) + projectFilePath(projectFilePath), + isQtcRunnable(isQtcRunnable) { } QString targetName; QString displayName; + QString buildKey; // Used to identify this BuildTargetInfo object in its list. Utils::FileName targetFilePath; Utils::FileName projectFilePath; - - bool isAutoRunnable = true; + bool isQtcRunnable = true; bool usesTerminal = false; - bool isValid() const { return !targetName.isEmpty(); } + std::function runEnvModifier; }; inline bool operator==(const BuildTargetInfo &ti1, const BuildTargetInfo &ti2) { - return ti1.targetName == ti2.targetName && ti1.targetFilePath == ti2.targetFilePath - && ti1.projectFilePath == ti2.projectFilePath; + return ti1.targetName == ti2.targetName + && ti1.displayName == ti2.displayName + && ti1.buildKey == ti2.buildKey + && ti1.targetFilePath == ti2.targetFilePath + && ti1.projectFilePath == ti2.projectFilePath; } inline bool operator!=(const BuildTargetInfo &ti1, const BuildTargetInfo &ti2) @@ -71,7 +76,7 @@ inline bool operator!=(const BuildTargetInfo &ti1, const BuildTargetInfo &ti2) inline uint qHash(const BuildTargetInfo &ti) { - return qHash(ti.targetName); + return qHash(ti.targetName) ^ qHash(ti.displayName) ^ qHash(ti.buildKey); } class PROJECTEXPLORER_EXPORT BuildTargetInfoList @@ -104,6 +109,12 @@ public: }).targetFilePath; } + BuildTargetInfo buildTargetInfo(const QString &buildKey) { + return Utils::findOrDefault(list, [&buildKey](const BuildTargetInfo &ti) { + return ti.buildKey == buildKey; + }); + } + QList list; }; diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 9f1b26b3f3e..eabfb002c50 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -470,14 +470,20 @@ QString RunConfigurationFactory::decoratedTargetName(const QString targetName, T QList RunConfigurationFactory::availableCreators(Target *parent) const { - return Utils::transform(parent->applicationTargets().list, [parent, this](const BuildTargetInfo &ti) { + const QList buildTargets = parent->applicationTargets().list; + const bool hasAnyQtcRunnable = Utils::anyOf(buildTargets, + Utils::equal(&BuildTargetInfo::isQtcRunnable, true)); + return Utils::transform(buildTargets, [&](const BuildTargetInfo &ti) { QString displayName = ti.displayName; if (displayName.isEmpty()) displayName = decoratedTargetName(ti.targetName, parent); - return RunConfigurationCreationInfo(this, m_runConfigBaseId, ti.targetName, displayName, - ti.isAutoRunnable ? RunConfigurationCreationInfo::AlwaysCreate - : RunConfigurationCreationInfo::ManualCreationOnly, - ti.usesTerminal); + RunConfigurationCreationInfo rci(this, m_runConfigBaseId, ti.targetName, displayName); + rci.creationMode = ti.isQtcRunnable || !hasAnyQtcRunnable + ? RunConfigurationCreationInfo::AlwaysCreate + : RunConfigurationCreationInfo::ManualCreationOnly; + rci.useTerminal = ti.usesTerminal; + rci.buildKey = ti.buildKey; + return rci; }); } diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index a6576aaf96e..81edca33d3f 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -302,6 +302,7 @@ public: Core::Id id; QString extra; QString displayName; + QString buildKey; CreationMode creationMode = AlwaysCreate; bool useTerminal = false; }; diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp index 77c02a75e9b..c275720a9d2 100644 --- a/src/plugins/projectexplorer/target.cpp +++ b/src/plugins/projectexplorer/target.cpp @@ -563,7 +563,8 @@ void Target::updateDefaultRunConfigurations() foreach (RunConfiguration *rc, existingConfigured) { bool present = false; for (const RunConfigurationCreationInfo &item : creators) { - if (item.id == rc->id() && item.extra == rc->extraId()) { + QString rcExtraId = rc->extraId(); + if (item.id == rc->id() && (item.extra == rcExtraId || item.buildKey == rcExtraId)) { existing.append(item); present = true; } diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 68e97c5d59c..c028926c28e 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -94,6 +94,8 @@ static const char CONFIG_SYSTEM_INCLUDEPATHS[] = "systemIncludePaths"; static const char CONFIG_FRAMEWORKPATHS[] = "frameworkPaths"; static const char CONFIG_SYSTEM_FRAMEWORKPATHS[] = "systemFrameworkPaths"; +static QString rcNameSeparator() { return QLatin1String("---Qbs.RC.NameSeparator---"); } + class OpTimer { public: @@ -135,10 +137,18 @@ QbsProject::QbsProject(const FileName &fileName) : rebuildProjectTree(); connect(this, &Project::activeTargetChanged, this, &QbsProject::changeActiveTarget); - connect(this, &Project::addedTarget, - this, [this](Target *t) { m_qbsProjects.insert(t, qbs::Project()); }); - connect(this, &Project::removedTarget, - this, [this](Target *t) {m_qbsProjects.remove(t); }); + connect(this, &Project::addedTarget, this, [this](Target *t) { + m_qbsProjects.insert(t, qbs::Project()); + }); + connect(this, &Project::removedTarget, this, [this](Target *t) { + const auto it = m_qbsProjects.find(t); + QTC_ASSERT(it != m_qbsProjects.end(), return); + if (it.value() == m_qbsProject) { + m_qbsProject = qbs::Project(); + m_projectData = qbs::ProjectData(); + } + m_qbsProjects.erase(it); + }); auto delayedParsing = [this]() { if (static_cast(sender())->isActive()) delayParsing(); @@ -1104,20 +1114,52 @@ void QbsProject::updateApplicationTargets() foreach (const qbs::ProductData &productData, m_projectData.allProducts()) { if (!productData.isEnabled() || !productData.isRunnable()) continue; - const QString displayName = productData.fullDisplayName(); - QString taName; + const bool isQtcRunnable = productData.properties().value("qtcRunnable").toBool(); + const bool usesTerminal = productData.properties().value("consoleApplication").toBool(); + const QString projectFile = productData.location().filePath(); + QString targetFile; foreach (const qbs::ArtifactData &ta, productData.targetArtifacts()) { QTC_ASSERT(ta.isValid(), continue); if (ta.isExecutable()) { - taName = ta.filePath(); + targetFile = ta.filePath(); break; } } - applications.list - << BuildTargetInfo(displayName, FileName::fromString(taName), - FileName::fromString(productData.location().filePath())); + BuildTargetInfo bti; + bti.targetName = productData.fullDisplayName(); + bti.buildKey = QbsProject::uniqueProductName(productData) + + rcNameSeparator() + + productData.fullDisplayName(); + bti.targetFilePath = FileName::fromString(targetFile); + bti.projectFilePath = FileName::fromString(projectFile); + bti.isQtcRunnable = isQtcRunnable; // Fixed up below. + bti.usesTerminal = usesTerminal; + bti.displayName = productData.fullDisplayName(); + bti.runEnvModifier = [targetFile, productData, this](Utils::Environment &env, bool usingLibraryPaths) { + QProcessEnvironment procEnv = env.toProcessEnvironment(); + procEnv.insert(QLatin1String("QBS_RUN_FILE_PATH"), targetFile); + QStringList setupRunEnvConfig; + if (!usingLibraryPaths) + setupRunEnvConfig << QLatin1String("ignore-lib-dependencies"); + qbs::RunEnvironment qbsRunEnv = qbsProject().getRunEnvironment(productData, + qbs::InstallOptions(), procEnv, setupRunEnvConfig, QbsManager::settings()); + qbs::ErrorInfo error; + procEnv = qbsRunEnv.runEnvironment(&error); + if (error.hasError()) { + Core::MessageManager::write(tr("Error retrieving run environment: %1") + .arg(error.toString())); + } + if (!procEnv.isEmpty()) { + env = Utils::Environment(); + foreach (const QString &key, procEnv.keys()) + env.set(key, procEnv.value(key)); + } + }; + + applications.list.append(bti); } - activeTarget()->setApplicationTargets(applications); + if (activeTarget()) + activeTarget()->setApplicationTargets(applications); } void QbsProject::updateDeploymentInfo() @@ -1129,7 +1171,8 @@ void QbsProject::updateDeploymentInfo() f.isExecutable() ? DeployableFile::TypeExecutable : DeployableFile::TypeNormal); } } - activeTarget()->setDeploymentData(deploymentData); + if (activeTarget()) + activeTarget()->setDeploymentData(deploymentData); } void QbsProject::updateBuildTargetData() diff --git a/src/plugins/qbsprojectmanager/qbsproject.h b/src/plugins/qbsprojectmanager/qbsproject.h index f545bf84baf..a30c33e30f6 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.h +++ b/src/plugins/qbsprojectmanager/qbsproject.h @@ -141,8 +141,8 @@ private: const QStringList &productNames, QString &error); QHash m_qbsProjects; - qbs::Project m_qbsProject; - qbs::ProjectData m_projectData; + qbs::Project m_qbsProject; // for activeTarget() + qbs::ProjectData m_projectData; // Cached m_qbsProject.projectData() QSet m_qbsDocuments; QbsProjectParser *m_qbsProjectParser; diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp index 9c064fdd40e..d8423e9faf1 100644 --- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp +++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp @@ -26,42 +26,34 @@ #include "qbsrunconfiguration.h" #include "qbsprojectmanagerconstants.h" -#include "qbsdeployconfigurationfactory.h" -#include "qbsinstallstep.h" -#include "qbsproject.h" #include #include + #include -#include -#include #include #include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include + +#include #include #include -#include + +#include +#include #include +#include +#include +#include +#include -#include "api/runenvironment.h" - +#include +#include #include #include #include -#include -#include -#include -#include -#include using namespace ProjectExplorer; using namespace Utils; @@ -75,15 +67,6 @@ static QString rcNameSeparator() { return QLatin1String("---Qbs.RC.NameSeparator static QString usingLibraryPathsKey() { return QString("Qbs.RunConfiguration.UsingLibraryPaths"); } -const qbs::ProductData findProduct(const qbs::ProjectData &pro, const QString &uniqeName) -{ - foreach (const qbs::ProductData &product, pro.allProducts()) { - if (QbsProject::uniqueProductName(product) == uniqeName) - return product; - } - return qbs::ProductData(); -} - // -------------------------------------------------------------------- // QbsRunConfiguration: // -------------------------------------------------------------------- @@ -96,22 +79,22 @@ QbsRunConfiguration::QbsRunConfiguration(Target *target) static_cast(rc)->addToBaseEnvironment(env); }); addExtraAspect(envAspect); - connect(static_cast(target->project()), &Project::parsingFinished, this, + + connect(project(), &Project::parsingFinished, this, [envAspect]() { envAspect->buildEnvironmentHasChanged(); }); addExtraAspect(new ArgumentsAspect(this, "Qbs.RunConfiguration.CommandLineArguments")); addExtraAspect(new WorkingDirectoryAspect(this, "Qbs.RunConfiguration.WorkingDirectory")); addExtraAspect(new TerminalAspect(this, "Qbs.RunConfiguration.UseTerminal", isConsoleApplication())); - QbsProject *project = static_cast(target->project()); - connect(project, &Project::parsingFinished, this, [this](bool success) { + connect(project(), &Project::parsingFinished, this, [this](bool success) { auto terminalAspect = extraAspect(); if (success && !terminalAspect->isUserSet()) terminalAspect->setUseTerminal(isConsoleApplication()); }); connect(BuildManager::instance(), &BuildManager::buildStateChanged, this, - [this, project](Project *p) { - if (p == project && !BuildManager::isBuilding(p)) { + [this](Project *p) { + if (p == project() && !BuildManager::isBuilding(p)) { const QString defaultWorkingDir = baseWorkingDirectory(); if (!defaultWorkingDir.isEmpty()) { extraAspect()->setDefaultWorkingDirectory( @@ -122,8 +105,17 @@ QbsRunConfiguration::QbsRunConfiguration(Target *target) } ); - connect(target, &Target::activeDeployConfigurationChanged, - this, &QbsRunConfiguration::installStepChanged); + connect(target, &Target::deploymentDataChanged, + this, &QbsRunConfiguration::handleBuildSystemDataUpdated); + connect(target, &Target::applicationTargetsChanged, + this, &QbsRunConfiguration::handleBuildSystemDataUpdated); + // Handles device changes, etc. + connect(target, &Target::kitChanged, + this, &QbsRunConfiguration::handleBuildSystemDataUpdated); +} + +QbsRunConfiguration::~QbsRunConfiguration() +{ } QVariantMap QbsRunConfiguration::toMap() const @@ -138,16 +130,14 @@ bool QbsRunConfiguration::fromMap(const QVariantMap &map) if (!RunConfiguration::fromMap(map)) return false; - QString extraId = ProjectExplorer::idFromMap(map).suffixAfter(id()); - if (!extraId.isEmpty()) { - const int sepPos = extraId.indexOf(rcNameSeparator()); - m_uniqueProductName = extraId.left(sepPos); - m_productDisplayName = sepPos == -1 ? QString() : extraId.mid(sepPos + rcNameSeparator().size()); - } + m_buildKey = ProjectExplorer::idFromMap(map).suffixAfter(id()); + m_usingLibraryPaths = map.value(usingLibraryPathsKey(), true).toBool(); + + const int sepPos = m_buildKey.indexOf(rcNameSeparator()); + m_productDisplayName = sepPos == -1 ? QString() : m_buildKey.mid(sepPos + rcNameSeparator().size()); + m_uniqueProductName = m_buildKey.left(sepPos); setDefaultDisplayName(defaultDisplayName()); - m_usingLibraryPaths = map.value(usingLibraryPathsKey(), true).toBool(); - installStepChanged(); return true; } @@ -157,59 +147,22 @@ QString QbsRunConfiguration::extraId() const return m_uniqueProductName + rcNameSeparator() + m_productDisplayName; } +void QbsRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &rci) +{ + m_buildKey = rci.buildKey; + + const int sepPos = m_buildKey.indexOf(rcNameSeparator()); + m_productDisplayName = sepPos == -1 ? QString() : m_buildKey.mid(sepPos + rcNameSeparator().size()); + m_uniqueProductName = m_buildKey.left(sepPos); + + setDefaultDisplayName(defaultDisplayName()); +} QWidget *QbsRunConfiguration::createConfigurationWidget() { return new QbsRunConfigurationWidget(this); } -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); - disconnect(m_currentBuildStepList, &BuildStepList::stepRemoved, - this, &QbsRunConfiguration::installStepChanged); - disconnect(m_currentBuildStepList, &BuildStepList::stepMoved, - this, &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, - this, &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; @@ -223,20 +176,14 @@ Runnable QbsRunConfiguration::runnable() const QString QbsRunConfiguration::executable() const { - QbsProject *pro = static_cast(target()->project()); - const qbs::ProductData product = findProduct(pro->qbsProjectData(), uniqueProductName()); - - if (!product.isValid() || !pro->qbsProject().isValid()) - return QString(); - - return product.targetExecutable(); + BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(m_buildKey); + return bti.targetFilePath.toString(); } bool QbsRunConfiguration::isConsoleApplication() const { - QbsProject *pro = static_cast(target()->project()); - const qbs::ProductData product = findProduct(pro->qbsProjectData(), uniqueProductName()); - return product.properties().value(QLatin1String("consoleApplication"), false).toBool(); + BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(m_buildKey); + return bti.usesTerminal; } void QbsRunConfiguration::setUsingLibraryPaths(bool useLibPaths) @@ -255,35 +202,14 @@ QString QbsRunConfiguration::baseWorkingDirectory() const void QbsRunConfiguration::addToBaseEnvironment(Utils::Environment &env) const { - QbsProject *project = static_cast(target()->project()); - if (project && project->qbsProject().isValid()) { - const qbs::ProductData product = findProduct(project->qbsProjectData(), uniqueProductName()); - if (product.isValid()) { - QProcessEnvironment procEnv = env.toProcessEnvironment(); - procEnv.insert(QLatin1String("QBS_RUN_FILE_PATH"), executable()); - QStringList setupRunEnvConfig; - if (!m_usingLibraryPaths) - setupRunEnvConfig << QLatin1String("ignore-lib-dependencies"); - qbs::RunEnvironment qbsRunEnv = project->qbsProject().getRunEnvironment(product, - qbs::InstallOptions(), procEnv, setupRunEnvConfig, QbsManager::settings()); - qbs::ErrorInfo error; - procEnv = qbsRunEnv.runEnvironment(&error); - if (error.hasError()) { - Core::MessageManager::write(tr("Error retrieving run environment: %1") - .arg(error.toString())); - } - if (!procEnv.isEmpty()) { - env = Utils::Environment(); - foreach (const QString &key, procEnv.keys()) - env.set(key, procEnv.value(key)); - } - } - } + BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(m_buildKey); + if (bti.runEnvModifier) + bti.runEnvModifier(env, m_usingLibraryPaths); } QString QbsRunConfiguration::buildSystemTarget() const { - return m_productDisplayName; + return m_buildKey; } QString QbsRunConfiguration::uniqueProductName() const @@ -304,64 +230,78 @@ Utils::OutputFormatter *QbsRunConfiguration::createOutputFormatter() const return new QtSupport::QtOutputFormatter(target()->project()); } +void QbsRunConfiguration::handleBuildSystemDataUpdated() +{ + emit targetInformationChanged(); + emit enabledChanged(); +} + // -------------------------------------------------------------------- // QbsRunConfigurationWidget: // -------------------------------------------------------------------- -QbsRunConfigurationWidget::QbsRunConfigurationWidget(QbsRunConfiguration *rc) - : m_rc(rc) +class QbsRunConfigurationWidgetPrivate { - auto vboxTopLayout = new QVBoxLayout(this); - vboxTopLayout->setMargin(0); +public: + QbsRunConfiguration *runConfiguration = nullptr; + QLabel *executableLineLabel = nullptr; +}; + +QbsRunConfigurationWidget::QbsRunConfigurationWidget(QbsRunConfiguration *rc) + : d(new QbsRunConfigurationWidgetPrivate) +{ + d->runConfiguration = rc; + + auto mainLayout = new QVBoxLayout(this); + mainLayout->setMargin(0); auto detailsContainer = new Utils::DetailsWidget(this); detailsContainer->setState(Utils::DetailsWidget::NoSummary); - vboxTopLayout->addWidget(detailsContainer); + + mainLayout->addWidget(detailsContainer); auto detailsWidget = new QWidget(detailsContainer); detailsContainer->setWidget(detailsWidget); auto toplayout = new QFormLayout(detailsWidget); toplayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); toplayout->setMargin(0); - m_executableLineLabel = new QLabel(this); - m_executableLineLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - setExecutableLineText(); - toplayout->addRow(tr("Executable:"), m_executableLineLabel); + d->executableLineLabel = new QLabel(this); + d->executableLineLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); + toplayout->addRow(tr("Executable:"), d->executableLineLabel); - m_rc->extraAspect()->addToMainConfigurationWidget(this, toplayout); - m_rc->extraAspect()->addToMainConfigurationWidget(this, toplayout); + d->runConfiguration->extraAspect()->addToMainConfigurationWidget(this, toplayout); + d->runConfiguration->extraAspect()->addToMainConfigurationWidget(this, toplayout); + d->runConfiguration->extraAspect()->addToMainConfigurationWidget(this, toplayout); - m_rc->extraAspect()->addToMainConfigurationWidget(this, toplayout); - m_usingLibPathsCheckBox = new QCheckBox(tr("Add library paths to run environment")); - m_usingLibPathsCheckBox->setChecked(m_rc->usingLibraryPaths()); - connect(m_usingLibPathsCheckBox, &QCheckBox::toggled, m_rc, - &QbsRunConfiguration::setUsingLibraryPaths); - toplayout->addRow(QString(), m_usingLibPathsCheckBox); + auto usingLibPathsCheckBox = new QCheckBox(tr("Add library paths to run environment")); + usingLibPathsCheckBox->setChecked(d->runConfiguration->usingLibraryPaths()); + connect(usingLibPathsCheckBox, &QCheckBox::toggled, + d->runConfiguration, &QbsRunConfiguration::setUsingLibraryPaths); + toplayout->addRow(QString(), usingLibPathsCheckBox); - connect(m_rc, &QbsRunConfiguration::targetInformationChanged, + connect(d->runConfiguration, &QbsRunConfiguration::targetInformationChanged, this, &QbsRunConfigurationWidget::targetInformationHasChanged, Qt::QueuedConnection); - connect(m_rc, &RunConfiguration::enabledChanged, + connect(d->runConfiguration, &RunConfiguration::enabledChanged, this, &QbsRunConfigurationWidget::targetInformationHasChanged); - targetInformationHasChanged(); Core::VariableChooser::addSupportForChildWidgets(this, rc->macroExpander()); + + targetInformationHasChanged(); } void QbsRunConfigurationWidget::targetInformationHasChanged() { - m_ignoreChange = true; - setExecutableLineText(m_rc->executable()); + WorkingDirectoryAspect *aspect = d->runConfiguration->extraAspect(); + aspect->pathChooser()->setBaseFileName(d->runConfiguration->target()->project()->projectDirectory()); - WorkingDirectoryAspect *aspect = m_rc->extraAspect(); - aspect->pathChooser()->setBaseFileName(m_rc->target()->project()->projectDirectory()); - m_ignoreChange = false; + QString text = d->runConfiguration->executable(); + d->executableLineLabel->setText(text.isEmpty() ? tr("") : text); } -void QbsRunConfigurationWidget::setExecutableLineText(const QString &text) +QbsRunConfigurationWidget::~QbsRunConfigurationWidget() { - const QString newText = text.isEmpty() ? tr("") : text; - m_executableLineLabel->setText(newText); + delete d; } // -------------------------------------------------------------------- @@ -375,46 +315,5 @@ QbsRunConfigurationFactory::QbsRunConfigurationFactory() addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); } -bool QbsRunConfigurationFactory::canCreateHelper(Target *parent, const QString &buildTarget) const -{ - QbsProject *project = static_cast(parent->project()); - QString product = buildTarget.left(buildTarget.indexOf(rcNameSeparator())); - return findProduct(project->qbsProjectData(), product).isValid(); -} - -QList -QbsRunConfigurationFactory::availableCreators(Target *parent) const -{ - QList products; - - QbsProject *project = static_cast(parent->project()); - if (!project || !project->qbsProject().isValid()) - return {}; - - foreach (const qbs::ProductData &product, project->qbsProjectData().allProducts()) { - if (product.isRunnable() && product.isEnabled()) - products << product; - } - - const auto isQtcRunnable = [](const qbs::ProductData &product) { - return product.properties().value("qtcRunnable").toBool(); - }; - const bool hasAnyQtcRunnable = Utils::anyOf(products, isQtcRunnable); - - return Utils::transform(products, [&](const qbs::ProductData &product) { - const QString displayName = product.fullDisplayName(); - const QString targetName = QbsProject::uniqueProductName(product) + rcNameSeparator() + displayName; - return RunConfigurationCreationInfo { - this, - runConfigurationBaseId(), - targetName, - displayName, - (hasAnyQtcRunnable && !isQtcRunnable(product)) - ? RunConfigurationCreationInfo::ManualCreationOnly - : RunConfigurationCreationInfo::AlwaysCreate - }; - }); -} - } // namespace Internal } // namespace QbsProjectManager diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h index 161bdde0b38..283aae0b360 100644 --- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h +++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h @@ -32,25 +32,19 @@ #include #include -namespace qbs { class InstallOptions; } - -namespace ProjectExplorer { class BuildStepList; } - namespace QbsProjectManager { namespace Internal { -class QbsInstallStep; - class QbsRunConfiguration : public ProjectExplorer::RunConfiguration { Q_OBJECT // to change the display name and arguments and set the userenvironmentchanges friend class QbsRunConfigurationWidget; - friend class ProjectExplorer::RunConfigurationFactory; public: explicit QbsRunConfiguration(ProjectExplorer::Target *target); + ~QbsRunConfiguration(); QWidget *createConfigurationWidget() override; @@ -72,22 +66,23 @@ signals: void usingDyldImageSuffixChanged(bool); private: - QVariantMap toMap() const final; + QVariantMap toMap() const; bool fromMap(const QVariantMap &map) final; QString extraId() const final; + void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &rci); - void installStepChanged(); - void installStepToBeRemoved(int pos); QString baseWorkingDirectory() const; QString defaultDisplayName(); + void handleBuildSystemDataUpdated(); - void updateTarget(); - - QbsInstallStep *m_currentInstallStep = nullptr; // We do not take ownership! - ProjectExplorer::BuildStepList *m_currentBuildStepList = nullptr; // We do not take ownership! - QString m_uniqueProductName; - QString m_productDisplayName; bool m_usingLibraryPaths = true; + + QString m_buildKey; + + // m_buildKey consists of the two below initially, but + // m_productDisplayName main be changed for clones etc. + QString m_productDisplayName; + QString m_uniqueProductName; }; class QbsRunConfigurationWidget : public QWidget @@ -95,31 +90,19 @@ class QbsRunConfigurationWidget : public QWidget Q_OBJECT public: - QbsRunConfigurationWidget(QbsRunConfiguration *rc); + explicit QbsRunConfigurationWidget(QbsRunConfiguration *rc); + ~QbsRunConfigurationWidget(); private: - void runConfigurationEnabledChange(); void targetInformationHasChanged(); - void setExecutableLineText(const QString &text = QString()); - QbsRunConfiguration *m_rc; - QLabel *m_executableLineLabel; - QCheckBox *m_usingLibPathsCheckBox; - bool m_ignoreChange = false; - bool m_isShown = false; + class QbsRunConfigurationWidgetPrivate * const d; }; class QbsRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory { - Q_OBJECT - public: QbsRunConfigurationFactory(); - - bool canCreateHelper(ProjectExplorer::Target *parent, const QString &suffix) const override; - - QList - availableCreators(ProjectExplorer::Target *parent) const override; }; } // namespace Internal