QbsRunConfiguration: Re-model based on RemoteLinux precedence

Task-number: QTCREATORBUG-19985
Change-Id: Ifd95187b72fed3565552ecd14f3353b7e7df0069
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
hjk
2018-02-21 12:30:09 +01:00
parent 7bbe5979a1
commit 9541aa7772
8 changed files with 199 additions and 255 deletions

View File

@@ -28,6 +28,7 @@
#include "projectexplorer_export.h"
#include <utils/algorithm.h>
#include <utils/environment.h>
#include <utils/fileutils.h>
#include <QList>
@@ -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<void(Utils::Environment &, bool)> 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<BuildTargetInfo> list;
};

View File

@@ -470,14 +470,20 @@ QString RunConfigurationFactory::decoratedTargetName(const QString targetName, T
QList<RunConfigurationCreationInfo>
RunConfigurationFactory::availableCreators(Target *parent) const
{
return Utils::transform(parent->applicationTargets().list, [parent, this](const BuildTargetInfo &ti) {
const QList<BuildTargetInfo> 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;
});
}

View File

@@ -302,6 +302,7 @@ public:
Core::Id id;
QString extra;
QString displayName;
QString buildKey;
CreationMode creationMode = AlwaysCreate;
bool useTerminal = false;
};

View File

@@ -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;
}

View File

@@ -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<ProjectConfiguration *>(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()

View File

@@ -141,8 +141,8 @@ private:
const QStringList &productNames, QString &error);
QHash<ProjectExplorer::Target *, qbs::Project> 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<Core::IDocument *> m_qbsDocuments;
QbsProjectParser *m_qbsProjectParser;

View File

@@ -26,42 +26,34 @@
#include "qbsrunconfiguration.h"
#include "qbsprojectmanagerconstants.h"
#include "qbsdeployconfigurationfactory.h"
#include "qbsinstallstep.h"
#include "qbsproject.h"
#include <coreplugin/messagemanager.h>
#include <coreplugin/variablechooser.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/buildstep.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/deployconfiguration.h>
#include <projectexplorer/localenvironmentaspect.h>
#include <projectexplorer/project.h>
#include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/target.h>
#include <projectexplorer/runconfigurationaspects.h>
#include <utils/algorithm.h>
#include <utils/qtcprocess.h>
#include <utils/pathchooser.h>
#include <utils/detailswidget.h>
#include <utils/stringutils.h>
#include <utils/persistentsettings.h>
#include <utils/utilsicons.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtoutputformatter.h>
#include <qtsupport/qtsupportconstants.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/algorithm.h>
#include <utils/detailswidget.h>
#include <utils/hostosinfo.h>
#include <utils/pathchooser.h>
#include <utils/persistentsettings.h>
#include <utils/stringutils.h>
#include <utils/utilsicons.h>
#include "api/runenvironment.h"
#include <QCheckBox>
#include <QDir>
#include <QFileInfo>
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QCheckBox>
#include <QToolButton>
#include <QComboBox>
#include <QDir>
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<QbsRunConfiguration *>(rc)->addToBaseEnvironment(env);
});
addExtraAspect(envAspect);
connect(static_cast<QbsProject *>(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<QbsProject *>(target->project());
connect(project, &Project::parsingFinished, this, [this](bool success) {
connect(project(), &Project::parsingFinished, this, [this](bool success) {
auto terminalAspect = extraAspect<TerminalAspect>();
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<WorkingDirectoryAspect>()->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<QbsDeployConfiguration *>(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<QbsProject *>(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<QbsProject *>(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<QbsProject *>(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<ArgumentsAspect>()->addToMainConfigurationWidget(this, toplayout);
m_rc->extraAspect<WorkingDirectoryAspect>()->addToMainConfigurationWidget(this, toplayout);
d->runConfiguration->extraAspect<ArgumentsAspect>()->addToMainConfigurationWidget(this, toplayout);
d->runConfiguration->extraAspect<WorkingDirectoryAspect>()->addToMainConfigurationWidget(this, toplayout);
d->runConfiguration->extraAspect<TerminalAspect>()->addToMainConfigurationWidget(this, toplayout);
m_rc->extraAspect<TerminalAspect>()->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<WorkingDirectoryAspect>();
aspect->pathChooser()->setBaseFileName(d->runConfiguration->target()->project()->projectDirectory());
WorkingDirectoryAspect *aspect = m_rc->extraAspect<WorkingDirectoryAspect>();
aspect->pathChooser()->setBaseFileName(m_rc->target()->project()->projectDirectory());
m_ignoreChange = false;
QString text = d->runConfiguration->executable();
d->executableLineLabel->setText(text.isEmpty() ? tr("<unknown>") : text);
}
void QbsRunConfigurationWidget::setExecutableLineText(const QString &text)
QbsRunConfigurationWidget::~QbsRunConfigurationWidget()
{
const QString newText = text.isEmpty() ? tr("<unknown>") : 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<QbsProject *>(parent->project());
QString product = buildTarget.left(buildTarget.indexOf(rcNameSeparator()));
return findProduct(project->qbsProjectData(), product).isValid();
}
QList<RunConfigurationCreationInfo>
QbsRunConfigurationFactory::availableCreators(Target *parent) const
{
QList<qbs::ProductData> products;
QbsProject *project = static_cast<QbsProject *>(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

View File

@@ -32,25 +32,19 @@
#include <QStringList>
#include <QWidget>
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<ProjectExplorer::RunConfigurationCreationInfo>
availableCreators(ProjectExplorer::Target *parent) const override;
};
} // namespace Internal