From 9f6a0300a5ab5996a97b27bc8ada55f41e3ca517 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 28 Apr 2014 16:16:34 +0200 Subject: Observe case insensitive file systems in QFileDialog::selectFile(). When stripping the root path from a file name that cannot be found in the model, use case sensitive comparison depending on file system. Task-number: QTBUG-38162 Change-Id: I28e28973fca2da35a5768fdd00cc258b9669a15a Reviewed-by: Shawn Rutledge --- src/widgets/dialogs/qfiledialog.cpp | 60 ++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index ecbd9480ff..bb8cdec896 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -71,6 +71,7 @@ extern bool qt_priv_ptr_valid; #endif #if defined(Q_OS_UNIX) #include +#include // for pathconf() on OS X #elif defined(Q_OS_WIN) # include #endif @@ -1018,6 +1019,44 @@ QUrl QFileDialog::directoryUrl() const return QUrl::fromLocalFile(directory().absolutePath()); } +// FIXME Qt 5.4: Use upcoming QVolumeInfo class to determine this information? +static inline bool isCaseSensitiveFileSystem(const QString &path) +{ + Q_UNUSED(path) +#if defined(Q_OS_WIN) + // Return case insensitive unconditionally, even if someone has a case sensitive + // file system mounted, wrongly capitalized drive letters will cause mismatches. + return false; +#elif defined(Q_OS_OSX) + return pathconf(QFile::encodeName(path).constData(), _PC_CASE_SENSITIVE); +#else + return true; +#endif +} + +// Determine the file name to be set on the line edit from the path +// passed to selectFile() in mode QFileDialog::AcceptSave. +static inline QString fileFromPath(const QString &rootPath, QString path) +{ + if (!QFileInfo(path).isAbsolute()) + return path; + if (path.startsWith(rootPath, isCaseSensitiveFileSystem(rootPath) ? Qt::CaseSensitive : Qt::CaseInsensitive)) + path.remove(0, rootPath.size()); + + if (path.isEmpty()) + return path; + + if (path.at(0) == QDir::separator() +#ifdef Q_OS_WIN + //On Windows both cases can happen + || path.at(0) == QLatin1Char('/') +#endif + ) { + path.remove(0, 1); + } + return path; +} + /*! Selects the given \a filename in the file dialog. @@ -1049,28 +1088,9 @@ void QFileDialog::selectFile(const QString &filename) } QModelIndex index = d->model->index(filename); - QString file; - if (!index.isValid()) { - // save as dialog where we want to input a default value - QString text = filename; - if (QFileInfo(filename).isAbsolute()) { - QString current = d->rootPath(); - text.remove(current); - if (text.at(0) == QDir::separator() -#ifdef Q_OS_WIN - //On Windows both cases can happen - || text.at(0) == QLatin1Char('/') -#endif - ) - text = text.remove(0,1); - } - file = text; - } else { - file = index.data().toString(); - } d->qFileDialogUi->listView->selectionModel()->clear(); if (!isVisible() || !d->lineEdit()->hasFocus()) - d->lineEdit()->setText(file); + d->lineEdit()->setText(index.isValid() ? index.data().toString() : fileFromPath(d->rootPath(), filename)); } /*! -- cgit v1.2.3