From ecd3027d385fd0f41cf7d970fc9273965e04ffc3 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 11 Apr 2013 10:23:01 +0200 Subject: [PATCH] Strip any trailing spaces from the filename before trying to open it On Windows, trailing spaces in a filename are silently ignored, so we need to strip it before trying to open a file with it. Otherwise it ends up being stripped later and in a case like " ." it will end up causing Qt to think that a folder exists when it does not. [ChangeLog][Platform Specific Changes][Windows][QtWidgets][QFileDialog] Handled the case of having trailing spaces in a filename correctly so if the filename ends up being empty that the parent path is used instead. Change-Id: I6500cc3a44746bf4a65e73bcfb63265a0a97c8a3 Reviewed-by: Stephen Kelly Reviewed-by: Marc Mutz --- src/widgets/dialogs/qfilesystemmodel.cpp | 13 +++++++-- .../dialogs/qfiledialog/tst_qfiledialog.cpp | 28 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index bda448bde3b..0b0f6865644 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -401,9 +401,18 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS for (int i = 0; i < pathElements.count(); ++i) { QString element = pathElements.at(i); #ifdef Q_OS_WIN - // On Windows, "filename......." and "filename" are equivalent Task #133928 - while (element.endsWith(QLatin1Char('.'))) + // On Windows, "filename " and "filename" are equivalent and + // "filename . " and "filename" are equivalent + // "filename......." and "filename" are equivalent Task #133928 + // whereas "filename .txt" is still "filename .txt" + // If after stripping the characters there is nothing left then we + // just return the parent directory as it is assumed that the path + // is referring to the parent + while (element.endsWith(QLatin1Char('.')) || element.endsWith(QLatin1Char(' '))) element.chop(1); + // Only filenames that can't possibly exist will be end up being empty + if (element.isEmpty()) + return parent; #endif bool alreadyExisted = parent->children.contains(element); diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index 8bad4bb176d..54a3a85e871 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -148,6 +148,7 @@ private slots: void enableChooseButton(); void hooks(); void widgetlessNativeDialog(); + void trailingDotsAndSpaces(); #ifdef Q_OS_UNIX #ifdef QT_BUILD_INTERNAL void tildeExpansion_data(); @@ -1413,6 +1414,33 @@ void tst_QFiledialog::widgetlessNativeDialog() QVERIFY(!button); } +void tst_QFiledialog::trailingDotsAndSpaces() +{ +#ifndef Q_OS_WIN + QSKIP("This is only tested on Windows"); +#endif + QNonNativeFileDialog fd; + fd.setViewMode(QFileDialog::List); + fd.setFileMode(QFileDialog::ExistingFile); + fd.setOptions(QFileDialog::DontUseNativeDialog); + fd.show(); + QLineEdit *lineEdit = fd.findChild("fileNameEdit"); + QVERIFY(lineEdit); + QListView *list = fd.findChild("listView"); + QVERIFY(list); + QTest::qWait(1000); + int currentChildrenCount = list->model()->rowCount(list->rootIndex()); + QTest::keyClick(lineEdit, Qt::Key_Space); + QTest::keyClick(lineEdit, Qt::Key_Period); + QTest::qWait(1000); + QVERIFY(currentChildrenCount == list->model()->rowCount(list->rootIndex())); + lineEdit->clear(); + QTest::keyClick(lineEdit, Qt::Key_Period); + QTest::keyClick(lineEdit, Qt::Key_Space); + QTest::qWait(1000); + QVERIFY(currentChildrenCount == list->model()->rowCount(list->rootIndex())); +} + #ifdef Q_OS_UNIX #ifdef QT_BUILD_INTERNAL void tst_QFiledialog::tildeExpansion_data()