From a976130b7113c2afb6761ec30fe7ed70cfd39a6a Mon Sep 17 00:00:00 2001 From: Oliver Eftevaag Date: Wed, 13 Dec 2023 13:31:11 +0100 Subject: [PATCH] Only update the filename text field when the user selects a file Apparently, it's normal for file dialogs to not update the text field that represents the filename of the currently selected file, if the selected file is a directory. To achieve that behavior, I'm removing the binding on the text property, and instead call setText() to update the text field when either the user selects another file in the file dialog list view, or when the selectedFile is changed externally. But only if the selectedFile is an actual real file, and not a directory. Fixes: QTBUG-119917 Change-Id: I8dbf41ba403d09419a2d66130bdad59e66c9d1cf Reviewed-by: Santhosh Kumar (cherry picked from commit 8e734b2fc027dc53fca1f344d1ab234a0756ea89) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit ddee70ac8cebbba4e1f394d3d8b7149ef0436bc0) (cherry picked from commit 000e0ec5169fd055cc6d49af9842185f0e5b5b2c) --- .../qml/+Fusion/FileDialog.qml | 1 - .../qml/+Imagine/FileDialog.qml | 1 - .../qml/+Material/FileDialog.qml | 1 - .../qml/+Universal/FileDialog.qml | 1 - .../quickdialogsquickimpl/qml/FileDialog.qml | 1 - .../qquickfiledialogimpl.cpp | 14 ++++++ .../qquickfiledialogimpl_p_p.h | 1 + .../tst_qquickfiledialogimpl.cpp | 49 +++++++++++++++++++ 8 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/+Fusion/FileDialog.qml b/src/quickdialogs/quickdialogsquickimpl/qml/+Fusion/FileDialog.qml index 9c8a6de231..a388fee95c 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/+Fusion/FileDialog.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/+Fusion/FileDialog.qml @@ -167,7 +167,6 @@ FileDialogImpl { TextField { id: fileNameTextField objectName: "fileNameTextField" - text: control.fileName visible: false Layout.fillWidth: true diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/+Imagine/FileDialog.qml b/src/quickdialogs/quickdialogsquickimpl/qml/+Imagine/FileDialog.qml index 54b4f39e54..63e96c5ef6 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/+Imagine/FileDialog.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/+Imagine/FileDialog.qml @@ -158,7 +158,6 @@ FileDialogImpl { TextField { id: fileNameTextField objectName: "fileNameTextField" - text: control.fileName visible: false Layout.fillWidth: true diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/+Material/FileDialog.qml b/src/quickdialogs/quickdialogsquickimpl/qml/+Material/FileDialog.qml index 4c2b0b0331..0f4062c431 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/+Material/FileDialog.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/+Material/FileDialog.qml @@ -139,7 +139,6 @@ FileDialogImpl { TextField { id: fileNameTextField objectName: "fileNameTextField" - text: control.fileName visible: false Layout.topMargin: 12 diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/+Universal/FileDialog.qml b/src/quickdialogs/quickdialogsquickimpl/qml/+Universal/FileDialog.qml index 1cad9fe33a..cfb52f694f 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/+Universal/FileDialog.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/+Universal/FileDialog.qml @@ -143,7 +143,6 @@ FileDialogImpl { TextField { id: fileNameTextField objectName: "fileNameTextField" - text: control.fileName visible: false Layout.fillWidth: true diff --git a/src/quickdialogs/quickdialogsquickimpl/qml/FileDialog.qml b/src/quickdialogs/quickdialogsquickimpl/qml/FileDialog.qml index 6faebe8145..7a7e6ee8b8 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qml/FileDialog.qml +++ b/src/quickdialogs/quickdialogsquickimpl/qml/FileDialog.qml @@ -155,7 +155,6 @@ FileDialogImpl { TextField { id: fileNameTextField objectName: "fileNameTextField" - text: control.fileName visible: false Layout.fillWidth: true diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickfiledialogimpl.cpp b/src/quickdialogs/quickdialogsquickimpl/qquickfiledialogimpl.cpp index d190d3dd73..29bf832fa9 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qquickfiledialogimpl.cpp +++ b/src/quickdialogs/quickdialogsquickimpl/qquickfiledialogimpl.cpp @@ -137,12 +137,24 @@ void QQuickFileDialogImplPrivate::updateSelectedFile(const QString &oldFolderPat qCDebug(lcUpdateSelectedFile).nospace() << "updateSelectedFile is setting selectedFile to " << newSelectedFileUrl << ", newSelectedFileIndex is " << newSelectedFileIndex; q->setSelectedFile(newSelectedFileUrl); + updateFileNameTextEdit(); // If the index is -1, there are no files in the directory, and so fileDialogListView's // currentIndex will already be -1. if (newSelectedFileIndex != -1) tryUpdateFileDialogListViewCurrentIndex(newSelectedFileIndex); } +void QQuickFileDialogImplPrivate::updateFileNameTextEdit() +{ + QQuickFileDialogImplAttached *attached = attachedOrWarn(); + if (Q_UNLIKELY(!attached)) + return; + + const QFileInfo fileInfo(selectedFile.toLocalFile()); + if (fileInfo.isFile()) + attached->fileNameTextField()->setText(fileInfo.fileName()); +} + QDir::SortFlags QQuickFileDialogImplPrivate::fileListSortFlags() { QDir::SortFlags sortFlags = QDir::IgnoreCase; @@ -353,6 +365,7 @@ void QQuickFileDialogImpl::setInitialCurrentFolderAndSelectedFile(const QUrl &fi qCDebug(lcSelectedFile) << "setting initial currentFolder to" << fileDirUrl << "and selectedFile to" << file; setCurrentFolder(fileDirUrl, QQuickFileDialogImpl::SetReason::Internal); setSelectedFile(file); + d->updateFileNameTextEdit(); d->setCurrentIndexToInitiallySelectedFile = true; // If the currentFolder didn't change, the FolderListModel won't change and @@ -590,6 +603,7 @@ void QQuickFileDialogImplAttachedPrivate::fileDialogListViewCurrentIndexChanged( auto fileDialogImplPrivate = QQuickFileDialogImplPrivate::get(fileDialogImpl); if (moveReason != QQuickItemViewPrivate::Other) { fileDialogImpl->setSelectedFile(fileDialogDelegate->file()); + fileDialogImplPrivate->updateFileNameTextEdit(); } else if (fileDialogImplPrivate->setCurrentIndexToInitiallySelectedFile) { // When setting selectedFile before opening the FileDialog, // we need to ensure that the currentIndex is correct, because the initial change diff --git a/src/quickdialogs/quickdialogsquickimpl/qquickfiledialogimpl_p_p.h b/src/quickdialogs/quickdialogsquickimpl/qquickfiledialogimpl_p_p.h index 9ec1accbcd..67a51125df 100644 --- a/src/quickdialogs/quickdialogsquickimpl/qquickfiledialogimpl_p_p.h +++ b/src/quickdialogs/quickdialogsquickimpl/qquickfiledialogimpl_p_p.h @@ -45,6 +45,7 @@ public: void updateEnabled(); void updateSelectedFile(const QString &oldFolderPath); + void updateFileNameTextEdit(); static QDir::SortFlags fileListSortFlags(); static QFileInfoList fileList(const QDir &dir); void setFileDialogListViewCurrentIndex(int newCurrentIndex); diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp b/tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp index d65856d331..9766411066 100644 --- a/tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp @@ -90,6 +90,7 @@ private slots: void selectNewFileViaTextField_data(); void selectNewFileViaTextField(); void selectExistingFileShouldWarnUserWhenFileModeEqualsSaveFile(); + void fileNameTextFieldOnlyChangesWhenSelectingFiles(); private: enum DelegateOrderPolicy @@ -1548,6 +1549,54 @@ void tst_QQuickFileDialogImpl::selectExistingFileShouldWarnUserWhenFileModeEqual QCOMPARE(acceptedSpy.count(), 3); } +void tst_QQuickFileDialogImpl::fileNameTextFieldOnlyChangesWhenSelectingFiles() +{ + const auto tempSubFile1Url = QUrl::fromLocalFile(tempSubFile1->fileName()); + const auto tempSubDirUrl = QUrl::fromLocalFile(tempSubDir.path()); + const auto tempFile11Url = QUrl::fromLocalFile(tempFile1->fileName()); + + const QVariantMap initialProperties = { + { "tempFile1Url", QVariant::fromValue(tempSubFile1Url) }, + { "fileMode", QVariant::fromValue(QQuickFileDialog::SaveFile) } + }; + FileDialogTestHelper dialogHelper(this, "setSelectedFile.qml", {}, initialProperties); + + OPEN_QUICK_DIALOG(); + QQuickTest::qWaitForPolish(dialogHelper.window()); + + QQuickTextField *fileNameTextField = + dialogHelper.quickDialog->findChild("fileNameTextField"); + QVERIFY(fileNameTextField); + + auto getSelectedFileInfo = [&dialogHelper]() { + return QFileInfo(dialogHelper.dialog->selectedFile().toLocalFile()); + }; + + QVERIFY(getSelectedFileInfo().isFile()); + QCOMPARE(fileNameTextField->text(), tempSubFile1Url.fileName()); + QCOMPARE(dialogHelper.dialog->selectedFile(), tempSubFile1Url); + + auto *breadcrumbBar = dialogHelper.quickDialog->findChild(); + QVERIFY(breadcrumbBar); + + // Pressing the up button causes tempSubDir to be selected + QVERIFY(clickButton(breadcrumbBar->upButton())); + + QVERIFY(getSelectedFileInfo().isDir()); + QCOMPARE(fileNameTextField->text(), tempSubFile1Url.fileName()); + QCOMPARE(dialogHelper.dialog->selectedFile(), tempSubDirUrl); + + // Change the selected file from the outside + dialogHelper.dialog->close(); + dialogHelper.dialog->setSelectedFile(tempFile11Url); + dialogHelper.openDialog(); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + QVERIFY(getSelectedFileInfo().isFile()); + QCOMPARE(fileNameTextField->text(), tempFile11Url.fileName()); + QCOMPARE(dialogHelper.dialog->selectedFile(), tempFile11Url); +} + QTEST_MAIN(tst_QQuickFileDialogImpl) #include "tst_qquickfiledialogimpl.moc"