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.7 6.6 6.5
Change-Id: I8dbf41ba403d09419a2d66130bdad59e66c9d1cf
Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
This commit is contained in:
Oliver Eftevaag 2023-12-13 13:31:11 +01:00
parent 93b3c7d7fe
commit 8e734b2fc0
8 changed files with 64 additions and 5 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -47,6 +47,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);

View File

@ -90,6 +90,7 @@ private slots:
void selectNewFileViaTextField_data();
void selectNewFileViaTextField();
void selectExistingFileShouldWarnUserWhenFileModeEqualsSaveFile();
void fileNameTextFieldOnlyChangesWhenSelectingFiles();
private:
enum DelegateOrderPolicy
@ -1565,6 +1566,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<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)
#include "tst_qquickfiledialogimpl.moc"