Utils: Use EnvironmentChange instead of Environment in several places

For path choosers this makes it easier to change the actual base retrospectively
based on the device for the file path entered by the user.

In other cases "end user code" only knows that something needs to
be added to PATH to get a proper environment. This here lets this
code to specify the change alone without bothering about the base
environment this might be applied to.

Change-Id: I726aaa2fd2feb0bee7158f601aac660b0ac6327b
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
hjk
2021-08-03 15:12:24 +02:00
parent 6405f9c436
commit 6418eb2dda
13 changed files with 59 additions and 42 deletions

View File

@@ -642,7 +642,7 @@ public:
QString m_placeHolderText; QString m_placeHolderText;
QString m_historyCompleterKey; QString m_historyCompleterKey;
PathChooser::Kind m_expectedKind = PathChooser::File; PathChooser::Kind m_expectedKind = PathChooser::File;
Environment m_environment; EnvironmentChange m_environmentChange;
QPointer<QLabel> m_labelDisplay; QPointer<QLabel> m_labelDisplay;
QPointer<FancyLineEdit> m_lineEditDisplay; QPointer<FancyLineEdit> m_lineEditDisplay;
QPointer<PathChooser> m_pathChooserDisplay; QPointer<PathChooser> m_pathChooserDisplay;
@@ -962,11 +962,11 @@ void StringAspect::setExpectedKind(const PathChooser::Kind expectedKind)
d->m_pathChooserDisplay->setExpectedKind(expectedKind); d->m_pathChooserDisplay->setExpectedKind(expectedKind);
} }
void StringAspect::setEnvironment(const Environment &env) void StringAspect::setEnvironmentChange(const EnvironmentChange &change)
{ {
d->m_environment = env; d->m_environmentChange = change;
if (d->m_pathChooserDisplay) if (d->m_pathChooserDisplay)
d->m_pathChooserDisplay->setEnvironment(env); d->m_pathChooserDisplay->setEnvironmentChange(change);
} }
void StringAspect::setBaseFileName(const FilePath &baseFileName) void StringAspect::setBaseFileName(const FilePath &baseFileName)
@@ -1064,7 +1064,7 @@ void StringAspect::addToLayout(LayoutBuilder &builder)
d->m_pathChooserDisplay->setHistoryCompleter(d->m_historyCompleterKey); d->m_pathChooserDisplay->setHistoryCompleter(d->m_historyCompleterKey);
if (d->m_validator) if (d->m_validator)
d->m_pathChooserDisplay->setValidationFunction(d->m_validator); d->m_pathChooserDisplay->setValidationFunction(d->m_validator);
d->m_pathChooserDisplay->setEnvironment(d->m_environment); d->m_pathChooserDisplay->setEnvironmentChange(d->m_environmentChange);
d->m_pathChooserDisplay->setBaseDirectory(d->m_baseFileName); d->m_pathChooserDisplay->setBaseDirectory(d->m_baseFileName);
d->m_pathChooserDisplay->setOpenTerminalHandler(d->m_openTerminal); d->m_pathChooserDisplay->setOpenTerminalHandler(d->m_openTerminal);
d->m_pathChooserDisplay->setFilePath(FilePath::fromString(displayedString)); d->m_pathChooserDisplay->setFilePath(FilePath::fromString(displayedString));

View File

@@ -298,7 +298,7 @@ public:
void setPlaceHolderText(const QString &placeHolderText); void setPlaceHolderText(const QString &placeHolderText);
void setHistoryCompleter(const QString &historyCompleterKey); void setHistoryCompleter(const QString &historyCompleterKey);
void setExpectedKind(const Utils::PathChooser::Kind expectedKind); void setExpectedKind(const Utils::PathChooser::Kind expectedKind);
void setEnvironment(const Utils::Environment &env); void setEnvironmentChange(const Utils::EnvironmentChange &change);
void setBaseFileName(const Utils::FilePath &baseFileName); void setBaseFileName(const Utils::FilePath &baseFileName);
void setUndoRedoEnabled(bool readOnly); void setUndoRedoEnabled(bool readOnly);
void setAcceptRichText(bool acceptRichText); void setAcceptRichText(bool acceptRichText);

View File

@@ -413,13 +413,17 @@ void EnvironmentChange::addUnsetValue(const QString &key)
m_changeItems.append([key](Environment &env) { env.unset(key); }); m_changeItems.append([key](Environment &env) { env.unset(key); });
} }
void EnvironmentChange::addPrependToPath(const QString &value) void EnvironmentChange::addPrependToPath(const QStringList &values)
{ {
for (int i = values.size(); --i >= 0; ) {
const QString value = values.at(i);
m_changeItems.append([value](Environment &env) { env.prependOrSetPath(value); }); m_changeItems.append([value](Environment &env) { env.prependOrSetPath(value); });
} }
}
void EnvironmentChange::addAppendToPath(const QString &value) void EnvironmentChange::addAppendToPath(const QStringList &values)
{ {
for (const QString &value : values)
m_changeItems.append([value](Environment &env) { env.appendOrSetPath(value); }); m_changeItems.append([value](Environment &env) { env.appendOrSetPath(value); });
} }
@@ -428,6 +432,13 @@ void EnvironmentChange::addModify(const NameValueItems &items)
m_changeItems.append([items](Environment &env) { env.modify(items); }); m_changeItems.append([items](Environment &env) { env.modify(items); });
} }
EnvironmentChange EnvironmentChange::fromFixedEnvironment(const Environment &fixedEnv)
{
EnvironmentChange change;
change.m_changeItems.append([fixedEnv](Environment &env) { env = fixedEnv; });
return change;
}
void EnvironmentChange::applyToEnvironment(Environment &env) const void EnvironmentChange::applyToEnvironment(Environment &env) const
{ {
for (const Item &item : m_changeItems) for (const Item &item : m_changeItems)

View File

@@ -93,12 +93,14 @@ public:
EnvironmentChange() = default; EnvironmentChange() = default;
static EnvironmentChange fromFixedEnvironment(const Environment &fixedEnv);
void applyToEnvironment(Environment &) const; void applyToEnvironment(Environment &) const;
void addSetValue(const QString &key, const QString &value); void addSetValue(const QString &key, const QString &value);
void addUnsetValue(const QString &key); void addUnsetValue(const QString &key);
void addPrependToPath(const QString &value); void addPrependToPath(const QStringList &values);
void addAppendToPath(const QString &value); void addAppendToPath(const QStringList &values);
void addModify(const NameValueItems &items); void addModify(const NameValueItems &items);
void addChange(const Item &item) { m_changeItems.append(item); } void addChange(const Item &item) { m_changeItems.append(item); }

View File

@@ -47,6 +47,7 @@ class tst_fileutils; // This becomes a friend of Utils::FilePath for testing pri
namespace Utils { namespace Utils {
class Environment; class Environment;
class EnvironmentChange;
class QTCREATOR_UTILS_EXPORT FilePath class QTCREATOR_UTILS_EXPORT FilePath
{ {

View File

@@ -191,7 +191,7 @@ public:
FilePath m_initialBrowsePathOverride; FilePath m_initialBrowsePathOverride;
QString m_defaultValue; QString m_defaultValue;
FilePath m_baseDirectory; FilePath m_baseDirectory;
Environment m_environment; EnvironmentChange m_environmentChange;
BinaryVersionToolTipEventFilter *m_binaryVersionToolTipEventFilter = nullptr; BinaryVersionToolTipEventFilter *m_binaryVersionToolTipEventFilter = nullptr;
QList<QAbstractButton *> m_buttons; QList<QAbstractButton *> m_buttons;
MacroExpander *m_macroExpander = globalMacroExpander(); MacroExpander *m_macroExpander = globalMacroExpander();
@@ -209,18 +209,22 @@ FilePath PathChooserPrivate::expandedPath(const QString &input) const
if (input.isEmpty()) if (input.isEmpty())
return {}; return {};
QString expandedInput = m_environment.expandVariables(input); FilePath path = FilePath::fromUserInput(input);
if (m_macroExpander)
expandedInput = m_macroExpander->expand(expandedInput); Environment env = path.deviceEnvironment();
m_environmentChange.applyToEnvironment(env);
path = env.expandVariables(path);
if (m_macroExpander)
path = m_macroExpander->expand(path);
const FilePath path = FilePath::fromUserInput(expandedInput);
if (path.isEmpty()) if (path.isEmpty())
return path; return path;
switch (m_acceptingKind) { switch (m_acceptingKind) {
case PathChooser::Command: case PathChooser::Command:
case PathChooser::ExistingCommand: { case PathChooser::ExistingCommand: {
FilePaths searchPaths = m_environment.path(); FilePaths searchPaths = env.path();
searchPaths.append(m_baseDirectory); searchPaths.append(m_baseDirectory);
const FilePath expanded = path.searchOnDevice(searchPaths); const FilePath expanded = path.searchOnDevice(searchPaths);
return expanded.isEmpty() ? path : expanded; return expanded.isEmpty() ? path : expanded;
@@ -277,7 +281,6 @@ PathChooser::PathChooser(QWidget *parent) :
setLayout(d->m_hLayout); setLayout(d->m_hLayout);
setFocusProxy(d->m_lineEdit); setFocusProxy(d->m_lineEdit);
setFocusPolicy(d->m_lineEdit->focusPolicy()); setFocusPolicy(d->m_lineEdit->focusPolicy());
setEnvironment(Environment::systemEnvironment());
d->m_lineEdit->setValidationFunction(defaultValidationFunction()); d->m_lineEdit->setValidationFunction(defaultValidationFunction());
} }
@@ -328,10 +331,10 @@ FilePath PathChooser::baseDirectory() const
return d->m_baseDirectory; return d->m_baseDirectory;
} }
void PathChooser::setEnvironment(const Environment &env) void PathChooser::setEnvironmentChange(const EnvironmentChange &env)
{ {
QString oldExpand = filePath().toString(); QString oldExpand = filePath().toString();
d->m_environment = env; d->m_environmentChange = env;
if (filePath().toString() != oldExpand) { if (filePath().toString() != oldExpand) {
triggerChanged(); triggerChanged();
emit rawPathChanged(rawPath()); emit rawPathChanged(rawPath());

View File

@@ -41,6 +41,7 @@ namespace Utils {
class FancyLineEdit; class FancyLineEdit;
class MacroExpander; class MacroExpander;
class Environment; class Environment;
class EnvironmentChange;
class PathChooserPrivate; class PathChooserPrivate;
class QTCREATOR_UTILS_EXPORT PathChooser : public QWidget class QTCREATOR_UTILS_EXPORT PathChooser : public QWidget
@@ -99,7 +100,7 @@ public:
FilePath baseDirectory() const; FilePath baseDirectory() const;
void setBaseDirectory(const FilePath &base); void setBaseDirectory(const FilePath &base);
void setEnvironment(const Environment &env); void setEnvironmentChange(const EnvironmentChange &change);
/** Returns the suggested label title when used in a form layout. */ /** Returns the suggested label title when used in a form layout. */
static QString label(); static QString label();

View File

@@ -317,10 +317,9 @@ void SystemSettingsWidget::resetFileBrowser()
void SystemSettingsWidget::updatePath() void SystemSettingsWidget::updatePath()
{ {
Environment env = Environment::systemEnvironment(); EnvironmentChange change;
QStringList toAdd = VcsManager::additionalToolsPath(); change.addAppendToPath(VcsManager::additionalToolsPath());
env.appendOrSetPath(toAdd.join(HostOsInfo::pathListSeparator())); m_ui.patchChooser->setEnvironmentChange(change);
m_ui.patchChooser->setEnvironment(env);
} }
void SystemSettingsWidget::updateEnvironmentChangesLabel() void SystemSettingsWidget::updateEnvironmentChangesLabel()

View File

@@ -213,12 +213,12 @@ BuildConfiguration::BuildConfiguration(Target *target, Utils::Id id)
d->m_buildDirectoryAspect = addAspect<BuildDirectoryAspect>(this); d->m_buildDirectoryAspect = addAspect<BuildDirectoryAspect>(this);
d->m_buildDirectoryAspect->setBaseFileName(target->project()->projectDirectory()); d->m_buildDirectoryAspect->setBaseFileName(target->project()->projectDirectory());
d->m_buildDirectoryAspect->setEnvironment(environment()); d->m_buildDirectoryAspect->setEnvironmentChange(EnvironmentChange::fromFixedEnvironment(environment()));
d->m_buildDirectoryAspect->setMacroExpanderProvider([this] { return macroExpander(); }); d->m_buildDirectoryAspect->setMacroExpanderProvider([this] { return macroExpander(); });
connect(d->m_buildDirectoryAspect, &StringAspect::changed, connect(d->m_buildDirectoryAspect, &StringAspect::changed,
this, &BuildConfiguration::emitBuildDirectoryChanged); this, &BuildConfiguration::emitBuildDirectoryChanged);
connect(this, &BuildConfiguration::environmentChanged, this, [this] { connect(this, &BuildConfiguration::environmentChanged, this, [this] {
d->m_buildDirectoryAspect->setEnvironment(environment()); d->m_buildDirectoryAspect->setEnvironmentChange(EnvironmentChange::fromFixedEnvironment(environment()));
emit this->target()->buildEnvironmentChanged(this); emit this->target()->buildEnvironmentChanged(this);
}); });

View File

@@ -73,14 +73,15 @@ CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *targe
exeAspect->setDisplayStyle(StringAspect::PathChooserDisplay); exeAspect->setDisplayStyle(StringAspect::PathChooserDisplay);
exeAspect->setHistoryCompleter("Qt.CustomExecutable.History"); exeAspect->setHistoryCompleter("Qt.CustomExecutable.History");
exeAspect->setExpectedKind(PathChooser::ExistingCommand); exeAspect->setExpectedKind(PathChooser::ExistingCommand);
exeAspect->setEnvironment(envAspect->environment()); exeAspect->setEnvironmentChange(EnvironmentChange::fromFixedEnvironment(envAspect->environment()));
addAspect<ArgumentsAspect>(); addAspect<ArgumentsAspect>();
addAspect<WorkingDirectoryAspect>(); addAspect<WorkingDirectoryAspect>();
addAspect<TerminalAspect>(); addAspect<TerminalAspect>();
connect(envAspect, &EnvironmentAspect::environmentChanged, connect(envAspect, &EnvironmentAspect::environmentChanged, this, [exeAspect, envAspect] {
this, [exeAspect, envAspect] { exeAspect->setEnvironment(envAspect->environment()); }); exeAspect->setEnvironmentChange(EnvironmentChange::fromFixedEnvironment(envAspect->environment()));
});
setDefaultDisplayName(defaultDisplayName()); setDefaultDisplayName(defaultDisplayName());
} }

View File

@@ -195,9 +195,9 @@ void WorkingDirectoryAspect::addToLayout(LayoutBuilder &builder)
if (m_envAspect) { if (m_envAspect) {
connect(m_envAspect, &EnvironmentAspect::environmentChanged, m_chooser.data(), [this] { connect(m_envAspect, &EnvironmentAspect::environmentChanged, m_chooser.data(), [this] {
m_chooser->setEnvironment(m_envAspect->environment()); m_chooser->setEnvironmentChange(EnvironmentChange::fromFixedEnvironment(m_envAspect->environment()));
}); });
m_chooser->setEnvironment(m_envAspect->environment()); m_chooser->setEnvironmentChange(EnvironmentChange::fromFixedEnvironment(m_envAspect->environment()));
} }
builder.addItems({tr("Working directory:"), m_chooser.data(), m_resetButton.data()}); builder.addItems({tr("Working directory:"), m_chooser.data(), m_resetButton.data()});
@@ -566,13 +566,13 @@ void ExecutableAspect::setExpectedKind(const PathChooser::Kind expectedKind)
of paths is chosen as PathChooser::Command or PathChooser::ExistingCommand of paths is chosen as PathChooser::Command or PathChooser::ExistingCommand
to \a env. to \a env.
\sa Utils::StringAspect::setEnvironment() \sa Utils::StringAspect::setEnvironmentChange()
*/ */
void ExecutableAspect::setEnvironment(const Environment &env) void ExecutableAspect::setEnvironmentChange(const EnvironmentChange &change)
{ {
m_executable.setEnvironment(env); m_executable.setEnvironmentChange(change);
if (m_alternativeExecutable) if (m_alternativeExecutable)
m_alternativeExecutable->setEnvironment(env); m_alternativeExecutable->setEnvironmentChange(change);
} }
/*! /*!

View File

@@ -174,7 +174,7 @@ public:
void setExecutablePathStyle(Utils::OsType osType); void setExecutablePathStyle(Utils::OsType osType);
void setHistoryCompleter(const QString &historyCompleterKey); void setHistoryCompleter(const QString &historyCompleterKey);
void setExpectedKind(const Utils::PathChooser::Kind expectedKind); void setExpectedKind(const Utils::PathChooser::Kind expectedKind);
void setEnvironment(const Utils::Environment &env); void setEnvironmentChange(const Utils::EnvironmentChange &change);
void setDisplayStyle(Utils::StringAspect::DisplayStyle style); void setDisplayStyle(Utils::StringAspect::DisplayStyle style);
protected: protected:

View File

@@ -155,10 +155,9 @@ CommonSettingsWidget::CommonSettingsWidget(CommonOptionsPage *page)
void CommonSettingsWidget::updatePath() void CommonSettingsWidget::updatePath()
{ {
Environment env = Environment::systemEnvironment(); EnvironmentChange change;
QStringList toAdd = Core::VcsManager::additionalToolsPath(); change.addAppendToPath(Core::VcsManager::additionalToolsPath());
env.appendOrSetPath(toAdd.join(HostOsInfo::pathListSeparator())); m_page->settings().sshPasswordPrompt.setEnvironmentChange(change);
m_page->settings().sshPasswordPrompt.setEnvironment(env);
} }
void CommonSettingsWidget::apply() void CommonSettingsWidget::apply()