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 <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2021-07-22 15:11:41 +02:00
parent 67b082b51b
commit b6dd53d4ed
4 changed files with 38 additions and 0 deletions

View File

@@ -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<void ()> &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);

View File

@@ -34,6 +34,7 @@
#include <utils/fileutils.h>
#include <utils/infolabel.h>
#include <utils/layoutbuilder.h>
#include <utils/pathchooser.h>
#include <QLayout>
@@ -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)

View File

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

View File

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