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
Pick-to: 6.5
Change-Id: I8dbf41ba403d09419a2d66130bdad59e66c9d1cf
Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
(cherry picked from commit 8e734b2fc0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit ddee70ac8c)
This commit is contained in:
Oliver Eftevaag 2023-12-13 13:31:11 +01:00 committed by Qt Cherry-pick Bot
parent 3ed6f08973
commit 000e0ec516
8 changed files with 64 additions and 5 deletions

View File

@ -167,7 +167,6 @@ FileDialogImpl {
TextField { TextField {
id: fileNameTextField id: fileNameTextField
objectName: "fileNameTextField" objectName: "fileNameTextField"
text: control.fileName
visible: false visible: false
Layout.fillWidth: true Layout.fillWidth: true

View File

@ -158,7 +158,6 @@ FileDialogImpl {
TextField { TextField {
id: fileNameTextField id: fileNameTextField
objectName: "fileNameTextField" objectName: "fileNameTextField"
text: control.fileName
visible: false visible: false
Layout.fillWidth: true Layout.fillWidth: true

View File

@ -139,7 +139,6 @@ FileDialogImpl {
TextField { TextField {
id: fileNameTextField id: fileNameTextField
objectName: "fileNameTextField" objectName: "fileNameTextField"
text: control.fileName
visible: false visible: false
Layout.topMargin: 12 Layout.topMargin: 12

View File

@ -143,7 +143,6 @@ FileDialogImpl {
TextField { TextField {
id: fileNameTextField id: fileNameTextField
objectName: "fileNameTextField" objectName: "fileNameTextField"
text: control.fileName
visible: false visible: false
Layout.fillWidth: true Layout.fillWidth: true

View File

@ -155,7 +155,6 @@ FileDialogImpl {
TextField { TextField {
id: fileNameTextField id: fileNameTextField
objectName: "fileNameTextField" objectName: "fileNameTextField"
text: control.fileName
visible: false visible: false
Layout.fillWidth: true Layout.fillWidth: true

View File

@ -137,12 +137,24 @@ void QQuickFileDialogImplPrivate::updateSelectedFile(const QString &oldFolderPat
qCDebug(lcUpdateSelectedFile).nospace() << "updateSelectedFile is setting selectedFile to " << newSelectedFileUrl qCDebug(lcUpdateSelectedFile).nospace() << "updateSelectedFile is setting selectedFile to " << newSelectedFileUrl
<< ", newSelectedFileIndex is " << newSelectedFileIndex; << ", newSelectedFileIndex is " << newSelectedFileIndex;
q->setSelectedFile(newSelectedFileUrl); q->setSelectedFile(newSelectedFileUrl);
updateFileNameTextEdit();
// If the index is -1, there are no files in the directory, and so fileDialogListView's // If the index is -1, there are no files in the directory, and so fileDialogListView's
// currentIndex will already be -1. // currentIndex will already be -1.
if (newSelectedFileIndex != -1) if (newSelectedFileIndex != -1)
tryUpdateFileDialogListViewCurrentIndex(newSelectedFileIndex); 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 QQuickFileDialogImplPrivate::fileListSortFlags()
{ {
QDir::SortFlags sortFlags = QDir::IgnoreCase; 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; qCDebug(lcSelectedFile) << "setting initial currentFolder to" << fileDirUrl << "and selectedFile to" << file;
setCurrentFolder(fileDirUrl, QQuickFileDialogImpl::SetReason::Internal); setCurrentFolder(fileDirUrl, QQuickFileDialogImpl::SetReason::Internal);
setSelectedFile(file); setSelectedFile(file);
d->updateFileNameTextEdit();
d->setCurrentIndexToInitiallySelectedFile = true; d->setCurrentIndexToInitiallySelectedFile = true;
// If the currentFolder didn't change, the FolderListModel won't change and // If the currentFolder didn't change, the FolderListModel won't change and
@ -590,6 +603,7 @@ void QQuickFileDialogImplAttachedPrivate::fileDialogListViewCurrentIndexChanged(
auto fileDialogImplPrivate = QQuickFileDialogImplPrivate::get(fileDialogImpl); auto fileDialogImplPrivate = QQuickFileDialogImplPrivate::get(fileDialogImpl);
if (moveReason != QQuickItemViewPrivate::Other) { if (moveReason != QQuickItemViewPrivate::Other) {
fileDialogImpl->setSelectedFile(fileDialogDelegate->file()); fileDialogImpl->setSelectedFile(fileDialogDelegate->file());
fileDialogImplPrivate->updateFileNameTextEdit();
} else if (fileDialogImplPrivate->setCurrentIndexToInitiallySelectedFile) { } else if (fileDialogImplPrivate->setCurrentIndexToInitiallySelectedFile) {
// When setting selectedFile before opening the FileDialog, // When setting selectedFile before opening the FileDialog,
// we need to ensure that the currentIndex is correct, because the initial change // we need to ensure that the currentIndex is correct, because the initial change

View File

@ -45,6 +45,7 @@ public:
void updateEnabled(); void updateEnabled();
void updateSelectedFile(const QString &oldFolderPath); void updateSelectedFile(const QString &oldFolderPath);
void updateFileNameTextEdit();
static QDir::SortFlags fileListSortFlags(); static QDir::SortFlags fileListSortFlags();
static QFileInfoList fileList(const QDir &dir); static QFileInfoList fileList(const QDir &dir);
void setFileDialogListViewCurrentIndex(int newCurrentIndex); void setFileDialogListViewCurrentIndex(int newCurrentIndex);

View File

@ -90,6 +90,7 @@ private slots:
void selectNewFileViaTextField_data(); void selectNewFileViaTextField_data();
void selectNewFileViaTextField(); void selectNewFileViaTextField();
void selectExistingFileShouldWarnUserWhenFileModeEqualsSaveFile(); void selectExistingFileShouldWarnUserWhenFileModeEqualsSaveFile();
void fileNameTextFieldOnlyChangesWhenSelectingFiles();
private: private:
enum DelegateOrderPolicy enum DelegateOrderPolicy
@ -1565,6 +1566,54 @@ void tst_QQuickFileDialogImpl::selectExistingFileShouldWarnUserWhenFileModeEqual
QCOMPARE(acceptedSpy.count(), 3); 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<QQuickTextField *>("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<QQuickFolderBreadcrumbBar *>();
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) QTEST_MAIN(tst_QQuickFileDialogImpl)
#include "tst_qquickfiledialogimpl.moc" #include "tst_qquickfiledialogimpl.moc"