Qbs: Rework RunConfiguration

Use new ExecutableAspect, simplify working directory and
'use terminal' access.

Change-Id: I1daca3a30a4a46f3e1ad0019a49d28279cbc885f
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
hjk
2018-03-23 09:33:26 +01:00
parent 96b5fa208f
commit fbb7f380e2
2 changed files with 42 additions and 119 deletions

View File

@@ -29,32 +29,18 @@
#include "qbsprojectmanagerconstants.h" #include "qbsprojectmanagerconstants.h"
#include "qbsproject.h" #include "qbsproject.h"
#include <coreplugin/messagemanager.h>
#include <coreplugin/variablechooser.h> #include <coreplugin/variablechooser.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/deployconfiguration.h>
#include <projectexplorer/localenvironmentaspect.h> #include <projectexplorer/localenvironmentaspect.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/runconfigurationaspects.h> #include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtoutputformatter.h> #include <qtsupport/qtoutputformatter.h>
#include <qtsupport/qtsupportconstants.h>
#include <utils/algorithm.h>
#include <utils/hostosinfo.h>
#include <utils/pathchooser.h>
#include <utils/persistentsettings.h>
#include <utils/stringutils.h>
#include <utils/utilsicons.h>
#include <QCheckBox> #include <QCheckBox>
#include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QFormLayout> #include <QFormLayout>
#include <QLabel>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
@@ -75,57 +61,27 @@ static QString usingLibraryPathsKey() { return QString("Qbs.RunConfiguration.Usi
class QbsRunConfigurationWidget : public QWidget class QbsRunConfigurationWidget : public QWidget
{ {
public: public:
explicit QbsRunConfigurationWidget(QbsRunConfiguration *rc); explicit QbsRunConfigurationWidget(QbsRunConfiguration *rc)
{
private:
void targetInformationHasChanged();
QbsRunConfiguration *m_runConfiguration = nullptr;
QLabel *m_executableLineLabel = nullptr;
};
QbsRunConfigurationWidget::QbsRunConfigurationWidget(QbsRunConfiguration *rc)
{
m_runConfiguration = rc;
auto toplayout = new QFormLayout(this); auto toplayout = new QFormLayout(this);
toplayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); toplayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
toplayout->setMargin(0); toplayout->setMargin(0);
m_executableLineLabel = new QLabel(this); rc->extraAspect<ExecutableAspect>()->addToMainConfigurationWidget(this, toplayout);
m_executableLineLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); rc->extraAspect<ArgumentsAspect>()->addToMainConfigurationWidget(this, toplayout);
toplayout->addRow(QbsRunConfiguration::tr("Executable:"), m_executableLineLabel); rc->extraAspect<WorkingDirectoryAspect>()->addToMainConfigurationWidget(this, toplayout);
rc->extraAspect<TerminalAspect>()->addToMainConfigurationWidget(this, toplayout);
m_runConfiguration->extraAspect<ArgumentsAspect>()->addToMainConfigurationWidget(this, toplayout);
m_runConfiguration->extraAspect<WorkingDirectoryAspect>()->addToMainConfigurationWidget(this, toplayout);
m_runConfiguration->extraAspect<TerminalAspect>()->addToMainConfigurationWidget(this, toplayout);
auto usingLibPathsCheckBox = new QCheckBox; auto usingLibPathsCheckBox = new QCheckBox;
usingLibPathsCheckBox->setText(QbsRunConfiguration::tr("Add library paths to run environment")); usingLibPathsCheckBox->setText(QbsRunConfiguration::tr("Add library paths to run environment"));
usingLibPathsCheckBox->setChecked(m_runConfiguration->usingLibraryPaths()); usingLibPathsCheckBox->setChecked(rc->usingLibraryPaths());
connect(usingLibPathsCheckBox, &QCheckBox::toggled, connect(usingLibPathsCheckBox, &QCheckBox::toggled,
m_runConfiguration, &QbsRunConfiguration::setUsingLibraryPaths); rc, &QbsRunConfiguration::setUsingLibraryPaths);
toplayout->addRow(QString(), usingLibPathsCheckBox); toplayout->addRow(QString(), usingLibPathsCheckBox);
connect(m_runConfiguration, &QbsRunConfiguration::targetInformationChanged,
this, &QbsRunConfigurationWidget::targetInformationHasChanged, Qt::QueuedConnection);
connect(m_runConfiguration, &RunConfiguration::enabledChanged,
this, &QbsRunConfigurationWidget::targetInformationHasChanged);
Core::VariableChooser::addSupportForChildWidgets(this, rc->macroExpander()); Core::VariableChooser::addSupportForChildWidgets(this, rc->macroExpander());
}
targetInformationHasChanged(); };
}
void QbsRunConfigurationWidget::targetInformationHasChanged()
{
WorkingDirectoryAspect *aspect = m_runConfiguration->extraAspect<WorkingDirectoryAspect>();
aspect->pathChooser()->setBaseFileName(m_runConfiguration->target()->project()->projectDirectory());
QString text = m_runConfiguration->executable();
m_executableLineLabel->setText(text.isEmpty() ? QbsRunConfiguration::tr("<unknown>") : text);
}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// QbsRunConfiguration: // QbsRunConfiguration:
@@ -140,30 +96,13 @@ QbsRunConfiguration::QbsRunConfiguration(Target *target)
}); });
addExtraAspect(envAspect); addExtraAspect(envAspect);
connect(project(), &Project::parsingFinished, this, addExtraAspect(new ExecutableAspect(this));
[envAspect]() { envAspect->buildEnvironmentHasChanged(); });
addExtraAspect(new ArgumentsAspect(this, "Qbs.RunConfiguration.CommandLineArguments")); addExtraAspect(new ArgumentsAspect(this, "Qbs.RunConfiguration.CommandLineArguments"));
addExtraAspect(new WorkingDirectoryAspect(this, "Qbs.RunConfiguration.WorkingDirectory")); addExtraAspect(new WorkingDirectoryAspect(this, "Qbs.RunConfiguration.WorkingDirectory"));
addExtraAspect(new TerminalAspect(this, "Qbs.RunConfiguration.UseTerminal"));
addExtraAspect(new TerminalAspect(this, "Qbs.RunConfiguration.UseTerminal", isConsoleApplication())); connect(project(), &Project::parsingFinished, this,
[envAspect]() { envAspect->buildEnvironmentHasChanged(); });
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 *p) {
if (p == project() && !BuildManager::isBuilding(p)) {
const QString defaultWorkingDir = baseWorkingDirectory();
if (!defaultWorkingDir.isEmpty()) {
extraAspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(
Utils::FileName::fromString(defaultWorkingDir));
}
emit enabledChanged();
}
}
);
connect(target, &Target::deploymentDataChanged, connect(target, &Target::deploymentDataChanged,
this, &QbsRunConfiguration::handleBuildSystemDataUpdated); this, &QbsRunConfiguration::handleBuildSystemDataUpdated);
@@ -172,10 +111,9 @@ QbsRunConfiguration::QbsRunConfiguration(Target *target)
// Handles device changes, etc. // Handles device changes, etc.
connect(target, &Target::kitChanged, connect(target, &Target::kitChanged,
this, &QbsRunConfiguration::handleBuildSystemDataUpdated); this, &QbsRunConfiguration::handleBuildSystemDataUpdated);
}
QbsRunConfiguration::~QbsRunConfiguration() connect(target->project(), &Project::parsingFinished,
{ this, &QbsRunConfiguration::handleBuildSystemDataUpdated);
} }
QVariantMap QbsRunConfiguration::toMap() const QVariantMap QbsRunConfiguration::toMap() const
@@ -217,7 +155,7 @@ QWidget *QbsRunConfiguration::createConfigurationWidget()
Runnable QbsRunConfiguration::runnable() const Runnable QbsRunConfiguration::runnable() const
{ {
StandardRunnable r; StandardRunnable r;
r.executable = executable(); r.executable = extraAspect<ExecutableAspect>()->executable().toString();
r.workingDirectory = extraAspect<WorkingDirectoryAspect>()->workingDirectory().toString(); r.workingDirectory = extraAspect<WorkingDirectoryAspect>()->workingDirectory().toString();
r.commandLineArguments = extraAspect<ArgumentsAspect>()->arguments(); r.commandLineArguments = extraAspect<ArgumentsAspect>()->arguments();
r.runMode = extraAspect<TerminalAspect>()->runMode(); r.runMode = extraAspect<TerminalAspect>()->runMode();
@@ -225,32 +163,12 @@ Runnable QbsRunConfiguration::runnable() const
return r; return r;
} }
QString QbsRunConfiguration::executable() const
{
BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(m_buildKey);
return bti.targetFilePath.toString();
}
bool QbsRunConfiguration::isConsoleApplication() const
{
BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(m_buildKey);
return bti.usesTerminal;
}
void QbsRunConfiguration::setUsingLibraryPaths(bool useLibPaths) void QbsRunConfiguration::setUsingLibraryPaths(bool useLibPaths)
{ {
m_usingLibraryPaths = useLibPaths; m_usingLibraryPaths = useLibPaths;
extraAspect<LocalEnvironmentAspect>()->environmentChanged(); extraAspect<LocalEnvironmentAspect>()->environmentChanged();
} }
QString QbsRunConfiguration::baseWorkingDirectory() const
{
const QString exe = executable();
if (!exe.isEmpty())
return QFileInfo(exe).absolutePath();
return QString();
}
void QbsRunConfiguration::addToBaseEnvironment(Utils::Environment &env) const void QbsRunConfiguration::addToBaseEnvironment(Utils::Environment &env) const
{ {
BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(m_buildKey); BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(m_buildKey);
@@ -278,7 +196,23 @@ Utils::OutputFormatter *QbsRunConfiguration::createOutputFormatter() const
void QbsRunConfiguration::handleBuildSystemDataUpdated() void QbsRunConfiguration::handleBuildSystemDataUpdated()
{ {
emit targetInformationChanged(); BuildTargetInfo bti = target()->applicationTargets().buildTargetInfo(m_buildKey);
FileName executable = bti.targetFilePath;
auto terminalAspect = extraAspect<TerminalAspect>();
if (!terminalAspect->isUserSet())
terminalAspect->setUseTerminal(bti.usesTerminal);
extraAspect<ExecutableAspect>()->setExecutable(executable);
if (!executable.isEmpty()) {
QString defaultWorkingDir = QFileInfo(executable.toString()).absolutePath();
if (!defaultWorkingDir.isEmpty()) {
auto wdAspect = extraAspect<WorkingDirectoryAspect>();
wdAspect->setDefaultWorkingDirectory(FileName::fromString(defaultWorkingDir));
}
}
emit enabledChanged(); emit enabledChanged();
} }

View File

@@ -44,26 +44,17 @@ class QbsRunConfiguration : public ProjectExplorer::RunConfiguration
public: public:
explicit QbsRunConfiguration(ProjectExplorer::Target *target); explicit QbsRunConfiguration(ProjectExplorer::Target *target);
~QbsRunConfiguration();
QWidget *createConfigurationWidget() final; QWidget *createConfigurationWidget() final;
ProjectExplorer::Runnable runnable() const final; ProjectExplorer::Runnable runnable() const final;
QString executable() const;
Utils::OutputFormatter *createOutputFormatter() const final; Utils::OutputFormatter *createOutputFormatter() const final;
void addToBaseEnvironment(Utils::Environment &env) const; void addToBaseEnvironment(Utils::Environment &env) const;
QString buildSystemTarget() const final; QString buildSystemTarget() const final;
bool isConsoleApplication() const;
bool usingLibraryPaths() const { return m_usingLibraryPaths; } bool usingLibraryPaths() const { return m_usingLibraryPaths; }
void setUsingLibraryPaths(bool useLibPaths); void setUsingLibraryPaths(bool useLibPaths);
signals:
void targetInformationChanged();
void usingDyldImageSuffixChanged(bool);
private: private:
QVariantMap toMap() const final; QVariantMap toMap() const final;
bool fromMap(const QVariantMap &map) final; bool fromMap(const QVariantMap &map) final;
@@ -71,12 +62,10 @@ private:
void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &rci) final; void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &rci) final;
bool canRunForNode(const ProjectExplorer::Node *node) const final; bool canRunForNode(const ProjectExplorer::Node *node) const final;
QString baseWorkingDirectory() const;
QString defaultDisplayName(); QString defaultDisplayName();
void handleBuildSystemDataUpdated(); void handleBuildSystemDataUpdated();
bool m_usingLibraryPaths = true; bool m_usingLibraryPaths = true;
QString m_buildKey; QString m_buildKey;
}; };