From b6dd53d4ed754171050bfce94325c55e033df5a7 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 22 Jul 2021 15:11:41 +0200 Subject: [PATCH] ProjectExplorer: Prevent build directory on non-existing drive A drive that is not actually there is apparently different enough from a "normal" non-writable location to seriously throw off some build tools, so spend some effort in preventing this. Fixes: QTCREATORBUG-25633 Change-Id: I5a15b0b2a3a882a08f50866c23e4d45c93fd78c9 Reviewed-by: hjk --- src/libs/utils/aspects.cpp | 4 +++ src/plugins/projectexplorer/buildaspects.cpp | 29 +++++++++++++++++++ src/plugins/projectexplorer/buildaspects.h | 2 ++ .../projectexplorer/buildconfiguration.cpp | 3 ++ 4 files changed, 38 insertions(+) diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index 23b57a8e0e5..1be9b1b92d5 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -1010,6 +1010,8 @@ void StringAspect::setValidationFunction(const FancyLineEdit::ValidationFunction d->m_validator = validator; if (d->m_lineEditDisplay) d->m_lineEditDisplay->setValidationFunction(d->m_validator); + else if (d->m_pathChooserDisplay) + d->m_pathChooserDisplay->setValidationFunction(d->m_validator); } void StringAspect::setOpenTerminalHandler(const std::function &openTerminal) @@ -1060,6 +1062,8 @@ void StringAspect::addToLayout(LayoutBuilder &builder) d->m_pathChooserDisplay->setExpectedKind(d->m_expectedKind); if (!d->m_historyCompleterKey.isEmpty()) d->m_pathChooserDisplay->setHistoryCompleter(d->m_historyCompleterKey); + if (d->m_validator) + d->m_pathChooserDisplay->setValidationFunction(d->m_validator); d->m_pathChooserDisplay->setEnvironment(d->m_environment); d->m_pathChooserDisplay->setBaseDirectory(d->m_baseFileName); d->m_pathChooserDisplay->setOpenTerminalHandler(d->m_openTerminal); diff --git a/src/plugins/projectexplorer/buildaspects.cpp b/src/plugins/projectexplorer/buildaspects.cpp index 4e88f810c50..9275daa0762 100644 --- a/src/plugins/projectexplorer/buildaspects.cpp +++ b/src/plugins/projectexplorer/buildaspects.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -56,6 +57,12 @@ BuildDirectoryAspect::BuildDirectoryAspect(const BuildConfiguration *bc) : d(new setLabelText(tr("Build directory:")); setDisplayStyle(PathChooserDisplay); setExpectedKind(Utils::PathChooser::Directory); + setValidationFunction([this](FancyLineEdit *edit, QString *error) { + const FilePath fixedDir = fixupDir(FilePath::fromString(edit->text())); + if (!fixedDir.isEmpty()) + edit->setText(fixedDir.toUserOutput()); + return pathChooser() ? pathChooser()->defaultValidationFunction()(edit, error) : true; + }); setOpenTerminalHandler([this, bc] { Core::FileUtils::openTerminal(value(), bc->environment()); }); @@ -123,6 +130,28 @@ void BuildDirectoryAspect::addToLayout(LayoutBuilder &builder) } } +FilePath BuildDirectoryAspect::fixupDir(const FilePath &dir) +{ + if (dir.needsDevice() || !HostOsInfo::isWindowsHost()) + return {}; + const QString dirString = dir.toString().toLower(); + if (dirString.length() < 2) + return {}; + if (!dirString.at(0).isLetter()) + return {}; + const QStringList drives = Utils::transform(QDir::drives(), [](const QFileInfo &fi) { + return fi.absoluteFilePath().toLower().chopped(1); + }); + if (!Utils::contains(drives, [&dirString](const QString &drive) { + return dirString.startsWith(drive); + }) && !drives.isEmpty()) { + QString newDir = dirString; + newDir.replace(0, 2, drives.first()); + return FilePath::fromString(newDir); + } + return {}; +} + void BuildDirectoryAspect::updateProblemLabel() { if (!d->problemLabel) diff --git a/src/plugins/projectexplorer/buildaspects.h b/src/plugins/projectexplorer/buildaspects.h index 978fcd2e616..45e7f1e9666 100644 --- a/src/plugins/projectexplorer/buildaspects.h +++ b/src/plugins/projectexplorer/buildaspects.h @@ -47,6 +47,8 @@ public: void addToLayout(Utils::LayoutBuilder &builder) override; + static Utils::FilePath fixupDir(const Utils::FilePath &dir); + private: void toMap(QVariantMap &map) const override; void fromMap(const QVariantMap &map) override; diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp index 6067d75f167..034ff4fcbfc 100644 --- a/src/plugins/projectexplorer/buildconfiguration.cpp +++ b/src/plugins/projectexplorer/buildconfiguration.cpp @@ -257,6 +257,9 @@ void BuildConfiguration::setBuildDirectory(const FilePath &dir) if (dir == d->m_buildDirectoryAspect->filePath()) return; d->m_buildDirectoryAspect->setFilePath(dir); + const FilePath fixedDir = BuildDirectoryAspect::fixupDir(buildDirectory()); + if (!fixedDir.isEmpty()) + d->m_buildDirectoryAspect->setFilePath(fixedDir); emitBuildDirectoryChanged(); }