QbsProjectManager: Fix working directory handling.

Commit 2dbc5b1032 introduced usage of WorkingDirectoryAspect into the
qbs run configurations for Desktop targets. However, the design of that
class was not suitable for the way our working directory logic works:
There typically is a user-provided value and, as a fallback if the user
does not provide anything, a default value managed by (build system
specific) code. The WorkingDirectoryAspect class could not differentiate
between these two values and so the value stayed forever at the initial
default if the user did not override it, instead of adapting to the
location of the executable.
This patch makes the necessary changes to the WorkingDirectoryAspect
class so that it matches the actual use case.

Task-number: QTCREATORBUG-14891
Change-Id: I7555d0a9cb4b04b75c9215a988278db32eb1ca10
Reviewed-by: Jake Petroules <jake.petroules@petroules.com>
This commit is contained in:
Christian Kandeler
2015-08-20 18:02:07 +02:00
parent d0655e5cf2
commit 5f3b9dd89c
4 changed files with 39 additions and 37 deletions

View File

@@ -135,8 +135,8 @@ void TerminalAspect::setRunMode(ApplicationLauncher::Mode runMode)
\class ProjectExplorer::WorkingDirectoryAspect \class ProjectExplorer::WorkingDirectoryAspect
*/ */
WorkingDirectoryAspect::WorkingDirectoryAspect(RunConfiguration *runConfig, const QString &key, const QString &dir) WorkingDirectoryAspect::WorkingDirectoryAspect(RunConfiguration *runConfig, const QString &key)
: IRunConfigurationAspect(runConfig), m_workingDirectory(dir), m_chooser(0), m_key(key) : IRunConfigurationAspect(runConfig), m_chooser(0), m_key(key)
{ {
setDisplayName(tr("Working Directory")); setDisplayName(tr("Working Directory"));
setId("WorkingDirectoryAspect"); setId("WorkingDirectoryAspect");
@@ -149,7 +149,10 @@ WorkingDirectoryAspect *WorkingDirectoryAspect::create(RunConfiguration *runConf
WorkingDirectoryAspect *WorkingDirectoryAspect::clone(RunConfiguration *runConfig) const WorkingDirectoryAspect *WorkingDirectoryAspect::clone(RunConfiguration *runConfig) const
{ {
return new WorkingDirectoryAspect(runConfig, m_key, m_workingDirectory); auto * const aspect = new WorkingDirectoryAspect(runConfig, m_key);
aspect->m_defaultWorkingDirectory = m_defaultWorkingDirectory;
aspect->m_workingDirectory = m_workingDirectory;
return aspect;
} }
void WorkingDirectoryAspect::addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout) void WorkingDirectoryAspect::addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout)
@@ -159,8 +162,10 @@ void WorkingDirectoryAspect::addToMainConfigurationWidget(QWidget *parent, QForm
m_chooser->setHistoryCompleter(m_key); m_chooser->setHistoryCompleter(m_key);
m_chooser->setExpectedKind(Utils::PathChooser::Directory); m_chooser->setExpectedKind(Utils::PathChooser::Directory);
m_chooser->setPromptDialogTitle(tr("Select Working Directory")); m_chooser->setPromptDialogTitle(tr("Select Working Directory"));
connect(m_chooser.data(), &PathChooser::pathChanged, m_chooser->lineEdit()->setPlaceholderText(m_defaultWorkingDirectory);
this, &WorkingDirectoryAspect::setWorkingDirectory); m_chooser->setPath(m_workingDirectory);
connect(m_chooser.data(), &PathChooser::pathChanged, this,
[this]() { m_workingDirectory = m_chooser->rawPath(); });
auto resetButton = new QToolButton(parent); auto resetButton = new QToolButton(parent);
resetButton->setToolTip(tr("Reset to Default")); resetButton->setToolTip(tr("Reset to Default"));
@@ -187,25 +192,39 @@ void WorkingDirectoryAspect::updateEnvironment()
m_chooser->setEnvironment(envAspect->environment()); m_chooser->setEnvironment(envAspect->environment());
} }
QString WorkingDirectoryAspect::keyForDefaultWd() const
{
return m_key + QLatin1String(".default");
}
void WorkingDirectoryAspect::resetPath() void WorkingDirectoryAspect::resetPath()
{ {
QTC_ASSERT(m_chooser, return);
m_chooser->setPath(QString()); m_chooser->setPath(QString());
} }
void WorkingDirectoryAspect::fromMap(const QVariantMap &map) void WorkingDirectoryAspect::fromMap(const QVariantMap &map)
{ {
m_workingDirectory = map.value(m_key).toString(); m_workingDirectory = map.value(m_key).toString();
m_defaultWorkingDirectory = map.value(keyForDefaultWd()).toString();
} }
void WorkingDirectoryAspect::toMap(QVariantMap &data) const void WorkingDirectoryAspect::toMap(QVariantMap &data) const
{ {
data.insert(m_key, m_workingDirectory); data.insert(m_key, m_workingDirectory);
data.insert(keyForDefaultWd(), m_defaultWorkingDirectory);
} }
QString WorkingDirectoryAspect::workingDirectory() const QString WorkingDirectoryAspect::workingDirectory() const
{ {
return runConfiguration()->macroExpander()->expandProcessArgs(m_workingDirectory); QTC_ASSERT(m_chooser, return m_defaultWorkingDirectory);
return m_workingDirectory.isEmpty()
? m_defaultWorkingDirectory
: runConfiguration()->macroExpander()->expandProcessArgs(m_chooser->path());
}
QString WorkingDirectoryAspect::defaultWorkingDirectory() const
{
return m_defaultWorkingDirectory;
} }
QString WorkingDirectoryAspect::unexpandedWorkingDirectory() const QString WorkingDirectoryAspect::unexpandedWorkingDirectory() const
@@ -213,9 +232,11 @@ QString WorkingDirectoryAspect::unexpandedWorkingDirectory() const
return m_workingDirectory; return m_workingDirectory;
} }
void WorkingDirectoryAspect::setWorkingDirectory(const QString &workingDirectory) void WorkingDirectoryAspect::setDefaultWorkingDirectory(const QString &defaultWorkingDir)
{ {
m_workingDirectory = workingDirectory; m_defaultWorkingDirectory = defaultWorkingDir;
if (m_chooser)
m_chooser->lineEdit()->setPlaceholderText(m_defaultWorkingDirectory);
} }
PathChooser *WorkingDirectoryAspect::pathChooser() const PathChooser *WorkingDirectoryAspect::pathChooser() const

View File

@@ -85,7 +85,7 @@ class PROJECTEXPLORER_EXPORT WorkingDirectoryAspect : public IRunConfigurationAs
Q_OBJECT Q_OBJECT
public: public:
explicit WorkingDirectoryAspect(RunConfiguration *runConfig, const QString &key, const QString &dir = QString()); explicit WorkingDirectoryAspect(RunConfiguration *runConfig, const QString &key);
WorkingDirectoryAspect *create(RunConfiguration *runConfig) const override; WorkingDirectoryAspect *create(RunConfiguration *runConfig) const override;
WorkingDirectoryAspect *clone(RunConfiguration *runConfig) const override; WorkingDirectoryAspect *clone(RunConfiguration *runConfig) const override;
@@ -93,8 +93,9 @@ public:
void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout); void addToMainConfigurationWidget(QWidget *parent, QFormLayout *layout);
QString workingDirectory() const; QString workingDirectory() const;
QString defaultWorkingDirectory() const;
QString unexpandedWorkingDirectory() const; QString unexpandedWorkingDirectory() const;
void setWorkingDirectory(const QString &workingDirectory); void setDefaultWorkingDirectory(const QString &defaultWorkingDir);
Utils::PathChooser *pathChooser() const; Utils::PathChooser *pathChooser() const;
private: private:
@@ -103,8 +104,10 @@ private:
void resetPath(); void resetPath();
void updateEnvironment(); void updateEnvironment();
QString keyForDefaultWd() const;
QString m_workingDirectory; QString m_workingDirectory;
QString m_defaultWorkingDirectory;
QPointer<Utils::PathChooser> m_chooser; QPointer<Utils::PathChooser> m_chooser;
QString m_key; QString m_key;
}; };

View File

@@ -246,21 +246,13 @@ bool QbsRunConfiguration::isConsoleApplication() const
QString QbsRunConfiguration::workingDirectory() const QString QbsRunConfiguration::workingDirectory() const
{ {
EnvironmentAspect *aspect = extraAspect<EnvironmentAspect>(); const auto *wdAspect = extraAspect<WorkingDirectoryAspect>();
QTC_ASSERT(aspect, return baseWorkingDirectory()); QTC_ASSERT(wdAspect, return baseWorkingDirectory());
return QDir::cleanPath(aspect->environment().expandVariables( return wdAspect->workingDirectory();
macroExpander()->expand(baseWorkingDirectory())));
} }
QString QbsRunConfiguration::baseWorkingDirectory() const QString QbsRunConfiguration::baseWorkingDirectory() const
{ {
WorkingDirectoryAspect *aspect = extraAspect<WorkingDirectoryAspect>();
// if the user overrode us, then return his working directory
QString wd = aspect->unexpandedWorkingDirectory();
if (!wd.isEmpty())
return wd;
// else what the pro file reader tells us
const QString exe = executable(); const QString exe = executable();
if (!exe.isEmpty()) if (!exe.isEmpty())
return QFileInfo(executable()).absolutePath(); return QFileInfo(executable()).absolutePath();
@@ -272,18 +264,6 @@ QString QbsRunConfiguration::commandLineArguments() const
return extraAspect<ArgumentsAspect>()->arguments(); return extraAspect<ArgumentsAspect>()->arguments();
} }
void QbsRunConfiguration::setBaseWorkingDirectory(const QString &wd)
{
WorkingDirectoryAspect *aspect = extraAspect<WorkingDirectoryAspect>();
const QString &oldWorkingDirectory = workingDirectory();
aspect->setWorkingDirectory(wd);
const QString &newWorkingDirectory = workingDirectory();
if (oldWorkingDirectory != newWorkingDirectory)
emit baseWorkingDirectoryChanged(newWorkingDirectory);
}
void QbsRunConfiguration::setRunMode(ApplicationLauncher::Mode runMode) void QbsRunConfiguration::setRunMode(ApplicationLauncher::Mode runMode)
{ {
extraAspect<TerminalAspect>()->setRunMode(runMode); extraAspect<TerminalAspect>()->setRunMode(runMode);
@@ -413,7 +393,7 @@ void QbsRunConfigurationWidget::targetInformationHasChanged()
setExecutableLineText(m_rc->executable()); setExecutableLineText(m_rc->executable());
WorkingDirectoryAspect *aspect = m_rc->extraAspect<WorkingDirectoryAspect>(); WorkingDirectoryAspect *aspect = m_rc->extraAspect<WorkingDirectoryAspect>();
aspect->pathChooser()->setPath(m_rc->baseWorkingDirectory()); aspect->setDefaultWorkingDirectory(m_rc->baseWorkingDirectory());
aspect->pathChooser()->setBaseFileName(m_rc->target()->project()->projectDirectory()); aspect->pathChooser()->setBaseFileName(m_rc->target()->project()->projectDirectory());
m_ignoreChange = false; m_ignoreChange = false;
} }

View File

@@ -92,7 +92,6 @@ public:
bool isConsoleApplication() const; bool isConsoleApplication() const;
signals: signals:
void baseWorkingDirectoryChanged(const QString&);
void targetInformationChanged(); void targetInformationChanged();
void usingDyldImageSuffixChanged(bool); void usingDyldImageSuffixChanged(bool);
@@ -104,7 +103,6 @@ private slots:
void installStepToBeRemoved(int pos); void installStepToBeRemoved(int pos);
private: private:
void setBaseWorkingDirectory(const QString &workingDirectory);
QString baseWorkingDirectory() const; QString baseWorkingDirectory() const;
QString defaultDisplayName(); QString defaultDisplayName();
qbs::InstallOptions installOptions() const; qbs::InstallOptions installOptions() const;