Replace currentFile(s) with selectedFile(s)

selectedFile can represent the currently-selected file (if the platform
supports it), and so we can free up "currentFolder" for FolderDialog
now that it means the folder that is being displayed, rather than the
folder that is currently selected.

[ChangeLog][QtQuickDialogs] FileDialog's currentFile and currentFiles
properties have been deprecated. The selectedFile and selectedFiles
properties now refer to the currently selected file(s), as well
as the final selection.

Fixes: QTBUG-98562
Task-number: QTBUG-87798
Change-Id: Ic66481332338f21169a9f63617cf4db4be83265d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 13399bd54d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Mitch Curtis 2021-11-24 14:57:40 +01:00 committed by Qt Cherry-pick Bot
parent 0d0499dfc9
commit a318e6f354
10 changed files with 94 additions and 135 deletions

View File

@ -56,11 +56,16 @@ QQuickPlatformTheme::QQuickPlatformTheme(QObject *parent) :
QVariant QQuickPlatformTheme::themeHint(QPlatformTheme::ThemeHint themeHint) const QVariant QQuickPlatformTheme::themeHint(QPlatformTheme::ThemeHint themeHint) const
{ {
if (themeHint == QPlatformTheme::ShowDirectoriesFirst) { // Allow tests to force some theme hint values, otherwise they get very messy and difficult to understand.
// Allow tests to force this value, otherwise they get very messy and difficult to understand. switch (themeHint) {
case QPlatformTheme::ShowDirectoriesFirst: {
const QVariant showDirsFirst = qEnvironmentVariable("QT_QUICK_DIALOGS_SHOW_DIRS_FIRST"); const QVariant showDirsFirst = qEnvironmentVariable("QT_QUICK_DIALOGS_SHOW_DIRS_FIRST");
if (showDirsFirst.isValid() && showDirsFirst.canConvert<bool>()) if (showDirsFirst.isValid() && showDirsFirst.canConvert<bool>())
return showDirsFirst; return showDirsFirst;
break;
}
default:
break;
} }
return QGuiApplicationPrivate::platformTheme()->themeHint(themeHint); return QGuiApplicationPrivate::platformTheme()->themeHint(themeHint);
} }

View File

@ -159,18 +159,16 @@ void QQuickFileDialog::setFileMode(FileMode mode)
\qmlproperty url QtQuick.Dialogs::FileDialog::selectedFile \qmlproperty url QtQuick.Dialogs::FileDialog::selectedFile
\readonly \readonly
This property holds the final accepted file. This property holds the last file that was selected in the dialog.
If there are multiple selected files, this property refers to the first If there are multiple selected files, this property refers to the first
file. file.
Unlike the \l currentFile property, the \c selectedFile property is not The value of this property is updated each time the user selects a file in
updated while the user is selecting files in the dialog, but only after the the dialog, and when the dialog is accepted. Handle the
final selection has been made. That is, when the user has clicked \l {Dialog::}{accepted()} signal to get the final selection.
\uicontrol OK to accept a file. Alternatively, the
\l {Dialog::}{accepted()} signal can be handled to get the final selection.
\sa selectedFiles, currentFile, {Dialog::}{accepted()}, currentFolder \sa selectedFiles, {Dialog::}{accepted()}, currentFolder
*/ */
QUrl QQuickFileDialog::selectedFile() const QUrl QQuickFileDialog::selectedFile() const
{ {
@ -180,15 +178,13 @@ QUrl QQuickFileDialog::selectedFile() const
/*! /*!
\qmlproperty list<url> QtQuick.Dialogs::FileDialog::selectedFiles \qmlproperty list<url> QtQuick.Dialogs::FileDialog::selectedFiles
This property holds the final accepted files. This property holds the last files that were selected in the dialog.
Unlike the \l currentFiles property, the \c selectedFiles property is not The value of this property is updated each time the user selects files in
updated while the user is selecting files in the dialog, but only after the the dialog, and when the dialog is accepted. Handle the
final selection has been made. That is, when the user has clicked \l {Dialog::}{accepted()} signal to get the final selection.
\uicontrol OK to accept files. Alternatively, the \l {Dialog::}{accepted()}
signal can be handled to get the final selection.
\sa currentFiles, {Dialog::}{accepted()}, currentFolder \sa {Dialog::}{accepted()}, currentFolder
*/ */
QList<QUrl> QQuickFileDialog::selectedFiles() const QList<QUrl> QQuickFileDialog::selectedFiles() const
{ {
@ -202,57 +198,48 @@ void QQuickFileDialog::setSelectedFiles(const QList<QUrl> &selectedFiles)
bool firstChanged = m_selectedFiles.value(0) != selectedFiles.value(0); bool firstChanged = m_selectedFiles.value(0) != selectedFiles.value(0);
m_selectedFiles = selectedFiles; m_selectedFiles = selectedFiles;
if (firstChanged) if (firstChanged) {
emit selectedFileChanged(); emit selectedFileChanged();
emit currentFileChanged();
}
emit selectedFilesChanged(); emit selectedFilesChanged();
emit currentFilesChanged();
} }
/*! /*!
\qmlproperty url QtQuick.Dialogs::FileDialog::currentFile \qmlproperty url QtQuick.Dialogs::FileDialog::currentFile
\deprecated [6.3] Use \l selectedFile instead.
This property holds the currently selected file in the dialog. This property holds the currently selected file in the dialog.
Unlike the \l selectedFile property, the \c currentFile property is updated
while the user is selecting files in the dialog, even before the final
selection has been made.
\sa selectedFile, currentFiles, currentFolder \sa selectedFile, currentFiles, currentFolder
*/ */
QUrl QQuickFileDialog::currentFile() const QUrl QQuickFileDialog::currentFile() const
{ {
return currentFiles().value(0); return selectedFile();
} }
void QQuickFileDialog::setCurrentFile(const QUrl &file) void QQuickFileDialog::setCurrentFile(const QUrl &file)
{ {
setCurrentFiles(QList<QUrl>() << file); setSelectedFiles(QList<QUrl>() << file);
} }
/*! /*!
\qmlproperty list<url> QtQuick.Dialogs::FileDialog::currentFiles \qmlproperty list<url> QtQuick.Dialogs::FileDialog::currentFiles
\deprecated [6.3] Use \l selectedFiles instead.
This property holds the currently selected files in the dialog. This property holds the currently selected files in the dialog.
Unlike the \l selectedFiles property, the \c currentFiles property is
updated while the user is selecting files in the dialog, even before the
final selection has been made.
\sa selectedFiles, currentFile, currentFolder \sa selectedFiles, currentFile, currentFolder
*/ */
QList<QUrl> QQuickFileDialog::currentFiles() const QList<QUrl> QQuickFileDialog::currentFiles() const
{ {
if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(handle())) return selectedFiles();
return fileDialog->selectedFiles();
return m_options->initiallySelectedFiles();
} }
void QQuickFileDialog::setCurrentFiles(const QList<QUrl> &currentFiles) void QQuickFileDialog::setCurrentFiles(const QList<QUrl> &currentFiles)
{ {
if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(handle())) { setSelectedFiles(currentFiles);
for (const QUrl &file : currentFiles)
fileDialog->selectFile(file);
}
m_options->setInitiallySelectedFiles(currentFiles);
} }
/*! /*!
@ -541,10 +528,13 @@ bool QQuickFileDialog::useNativeDialog() const
void QQuickFileDialog::onCreate(QPlatformDialogHelper *dialog) void QQuickFileDialog::onCreate(QPlatformDialogHelper *dialog)
{ {
if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(dialog)) { if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(dialog)) {
connect(fileDialog, &QPlatformFileDialogHelper::currentChanged, this, &QQuickFileDialog::currentFileChanged); connect(fileDialog, &QPlatformFileDialogHelper::currentChanged, this, [=](){ setSelectedFiles(fileDialog->selectedFiles()); });
connect(fileDialog, &QPlatformFileDialogHelper::currentChanged, this, &QQuickFileDialog::currentFilesChanged);
connect(fileDialog, &QPlatformFileDialogHelper::directoryEntered, this, &QQuickFileDialog::currentFolderChanged); connect(fileDialog, &QPlatformFileDialogHelper::directoryEntered, this, &QQuickFileDialog::currentFolderChanged);
fileDialog->setOptions(m_options); fileDialog->setOptions(m_options);
// Need to call this manually once on creation because QPlatformFileDialogHelper::currentChanged
// has already been emitted by this point (because of QQuickFileDialogImplPrivate::updateSelectedFile).
setSelectedFiles(fileDialog->selectedFiles());
} }
} }
@ -580,15 +570,6 @@ void QQuickFileDialog::onHide(QPlatformDialogHelper *dialog)
} }
} }
void QQuickFileDialog::accept()
{
if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(handle())) {
// Take the currently selected files and make them the final set of files.
setSelectedFiles(fileDialog->selectedFiles());
}
QQuickAbstractDialog::accept();
}
QUrl QQuickFileDialog::addDefaultSuffix(const QUrl &file) const QUrl QQuickFileDialog::addDefaultSuffix(const QUrl &file) const
{ {
QUrl url = file; QUrl url = file;

View File

@ -146,7 +146,6 @@ protected:
void onCreate(QPlatformDialogHelper *dialog) override; void onCreate(QPlatformDialogHelper *dialog) override;
void onShow(QPlatformDialogHelper *dialog) override; void onShow(QPlatformDialogHelper *dialog) override;
void onHide(QPlatformDialogHelper *dialog) override; void onHide(QPlatformDialogHelper *dialog) override;
void accept() override;
private: private:
QUrl addDefaultSuffix(const QUrl &file) const; QUrl addDefaultSuffix(const QUrl &file) const;

View File

@ -84,7 +84,7 @@ void QQuickFileDialogDelegatePrivate::highlightFile()
if (converted) { if (converted) {
attached->view()->setCurrentIndex(index); attached->view()->setCurrentIndex(index);
if (fileDialog) if (fileDialog)
fileDialog->setCurrentFile(file); fileDialog->setSelectedFile(file);
else if (folderDialog) else if (folderDialog)
folderDialog->setSelectedFolder(file); folderDialog->setSelectedFolder(file);
} }

View File

@ -52,6 +52,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcCurrentFolder, "qt.quick.dialogs.quickfiledialogimpl.currentFolder") Q_LOGGING_CATEGORY(lcCurrentFolder, "qt.quick.dialogs.quickfiledialogimpl.currentFolder")
Q_LOGGING_CATEGORY(lcUpdateSelectedFile, "qt.quick.dialogs.quickfiledialogimpl.updateSelectedFile")
Q_LOGGING_CATEGORY(lcOptions, "qt.quick.dialogs.quickfiledialogimpl.options") Q_LOGGING_CATEGORY(lcOptions, "qt.quick.dialogs.quickfiledialogimpl.options")
Q_LOGGING_CATEGORY(lcNameFilters, "qt.quick.dialogs.quickfiledialogimpl.namefilters") Q_LOGGING_CATEGORY(lcNameFilters, "qt.quick.dialogs.quickfiledialogimpl.namefilters")
Q_LOGGING_CATEGORY(lcAttachedNameFilters, "qt.quick.dialogs.quickfiledialogimplattached.namefilters") Q_LOGGING_CATEGORY(lcAttachedNameFilters, "qt.quick.dialogs.quickfiledialogimplattached.namefilters")
@ -83,7 +84,7 @@ void QQuickFileDialogImplPrivate::updateEnabled()
return; return;
} }
openButton->setEnabled(!currentFile.isEmpty() && attached->breadcrumbBar() openButton->setEnabled(!selectedFile.isEmpty() && attached->breadcrumbBar()
&& !attached->breadcrumbBar()->textField()->isVisible()); && !attached->breadcrumbBar()->textField()->isVisible());
} }
@ -94,22 +95,22 @@ void QQuickFileDialogImplPrivate::updateEnabled()
\a oldFolderPath is the previous value of \c folder. \a oldFolderPath is the previous value of \c folder.
*/ */
void QQuickFileDialogImplPrivate::updateCurrentFile(const QString &oldFolderPath) void QQuickFileDialogImplPrivate::updateSelectedFile(const QString &oldFolderPath)
{ {
Q_Q(QQuickFileDialogImpl); Q_Q(QQuickFileDialogImpl);
QQuickFileDialogImplAttached *attached = attachedOrWarn(); QQuickFileDialogImplAttached *attached = attachedOrWarn();
if (!attached || !attached->fileDialogListView()) if (!attached || !attached->fileDialogListView())
return; return;
QString newCurrentFilePath; QString newSelectedFilePath;
int newCurrentFileIndex = 0; int newSelectedFileIndex = 0;
const QString newFolderPath = QQmlFile::urlToLocalFileOrQrc(currentFolder); const QString newFolderPath = QQmlFile::urlToLocalFileOrQrc(currentFolder);
if (!oldFolderPath.isEmpty() && !newFolderPath.isEmpty()) { if (!oldFolderPath.isEmpty() && !newFolderPath.isEmpty()) {
// If the user went up a directory (or several), we should set // If the user went up a directory (or several), we should set
// currentFile to be the directory that we were in (or // selectedFile to be the directory that we were in (or
// its closest ancestor that is a child of the new directory). // its closest ancestor that is a child of the new directory).
// E.g. if oldFolderPath is /foo/bar/baz/abc/xyz, and newFolderPath is /foo/bar, // E.g. if oldFolderPath is /foo/bar/baz/abc/xyz, and newFolderPath is /foo/bar,
// then we want to set currentFile to be /foo/bar/baz. // then we want to set selectedFile to be /foo/bar/baz.
const int indexOfFolder = oldFolderPath.indexOf(newFolderPath); const int indexOfFolder = oldFolderPath.indexOf(newFolderPath);
if (indexOfFolder != -1) { if (indexOfFolder != -1) {
// [folder] // [folder]
@ -117,24 +118,24 @@ void QQuickFileDialogImplPrivate::updateCurrentFile(const QString &oldFolderPath
// /foo/bar/baz/abc/xyz // /foo/bar/baz/abc/xyz
// [rel...Paths] // [rel...Paths]
QStringList relativePaths = oldFolderPath.mid(indexOfFolder + newFolderPath.size()).split(QLatin1Char('/'), Qt::SkipEmptyParts); QStringList relativePaths = oldFolderPath.mid(indexOfFolder + newFolderPath.size()).split(QLatin1Char('/'), Qt::SkipEmptyParts);
newCurrentFilePath = newFolderPath + QLatin1Char('/') + relativePaths.first(); newSelectedFilePath = newFolderPath + QLatin1Char('/') + relativePaths.first();
// Now find the index of that directory so that we can set the ListView's currentIndex to it. // Now find the index of that directory so that we can set the ListView's currentIndex to it.
const QDir newFolderDir(newFolderPath); const QDir newFolderDir(newFolderPath);
// Just to be safe... // Just to be safe...
if (!newFolderDir.exists()) { if (!newFolderDir.exists()) {
qmlWarning(q) << "Directory" << newCurrentFilePath << "doesn't exist; can't get a file entry list for it"; qmlWarning(q) << "Directory" << newSelectedFilePath << "doesn't exist; can't get a file entry list for it";
return; return;
} }
const QFileInfoList dirs = newFolderDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::DirsFirst); const QFileInfoList dirs = newFolderDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::DirsFirst);
const QFileInfo newCurrentFileInfo(newCurrentFilePath); const QFileInfo newSelectedFileInfo(newSelectedFilePath);
// The directory can contain files, but since we put dirs first, that should never affect the indices. // The directory can contain files, but since we put dirs first, that should never affect the indices.
newCurrentFileIndex = dirs.indexOf(newCurrentFileInfo); newSelectedFileIndex = dirs.indexOf(newSelectedFileInfo);
} }
} }
if (newCurrentFilePath.isEmpty()) { if (newSelectedFilePath.isEmpty()) {
// When entering into a directory that isn't a parent of the old one, the first // When entering into a directory that isn't a parent of the old one, the first
// file delegate should be selected. // file delegate should be selected.
// TODO: is there a cheaper way to do this? QDirIterator doesn't support sorting, // TODO: is there a cheaper way to do this? QDirIterator doesn't support sorting,
@ -145,13 +146,15 @@ void QQuickFileDialogImplPrivate::updateCurrentFile(const QString &oldFolderPath
if (newFolderDir.exists()) { if (newFolderDir.exists()) {
const QFileInfoList files = newFolderDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::DirsFirst); const QFileInfoList files = newFolderDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::DirsFirst);
if (!files.isEmpty()) if (!files.isEmpty())
newCurrentFilePath = files.first().absoluteFilePath(); newSelectedFilePath = files.first().absoluteFilePath();
} }
} }
if (!newCurrentFilePath.isEmpty()) { const QUrl newSelectedFileUrl = QUrl::fromLocalFile(newSelectedFilePath);
q->setCurrentFile(QUrl::fromLocalFile(newCurrentFilePath)); qCDebug(lcUpdateSelectedFile) << "updateSelectedFile is setting selectedFile to" << newSelectedFileUrl;
attached->fileDialogListView()->setCurrentIndex(newCurrentFileIndex); q->setSelectedFile(newSelectedFileUrl);
if (!newSelectedFilePath.isEmpty()) {
attached->fileDialogListView()->setCurrentIndex(newSelectedFileIndex);
if (QQuickItem *currentItem = attached->fileDialogListView()->currentItem()) if (QQuickItem *currentItem = attached->fileDialogListView()->currentItem())
currentItem->forceActiveFocus(); currentItem->forceActiveFocus();
} }
@ -165,19 +168,19 @@ void QQuickFileDialogImplPrivate::handleAccept()
void QQuickFileDialogImplPrivate::handleClick(QQuickAbstractButton *button) void QQuickFileDialogImplPrivate::handleClick(QQuickAbstractButton *button)
{ {
Q_Q(QQuickFileDialogImpl); Q_Q(QQuickFileDialogImpl);
if (buttonRole(button) == QPlatformDialogHelper::AcceptRole && currentFile.isValid()) { if (buttonRole(button) == QPlatformDialogHelper::AcceptRole && selectedFile.isValid()) {
// The "Open" button was clicked, so we need to set the file to the current file, if any. // The "Open" button was clicked, so we need to set the file to the current file, if any.
const QFileInfo fileInfo(currentFile.toLocalFile()); const QFileInfo fileInfo(selectedFile.toLocalFile());
if (fileInfo.isDir()) { if (fileInfo.isDir()) {
// If it's a directory, navigate to it. // If it's a directory, navigate to it.
q->setCurrentFolder(currentFile); q->setCurrentFolder(selectedFile);
// Don't call accept(), because selecting a folder != accepting the dialog. // Don't call accept(), because selecting a folder != accepting the dialog.
} else { } else {
// Otherwise it's a file, so select it and close the dialog. // Otherwise it's a file, so select it and close the dialog.
q->setSelectedFile(currentFile); q->setSelectedFile(selectedFile);
q->accept(); q->accept();
QQuickDialogPrivate::handleClick(button); QQuickDialogPrivate::handleClick(button);
emit q->fileSelected(currentFile); emit q->fileSelected(selectedFile);
} }
} }
} }
@ -209,8 +212,7 @@ void QQuickFileDialogImpl::setCurrentFolder(const QUrl &currentFolder)
d->currentFolder = currentFolder; d->currentFolder = currentFolder;
// Since the directory changed, the old file can no longer be selected. // Since the directory changed, the old file can no longer be selected.
setCurrentFile(QUrl()); d->updateSelectedFile(oldFolderPath);
d->updateCurrentFile(oldFolderPath);
emit currentFolderChanged(d->currentFolder); emit currentFolderChanged(d->currentFolder);
} }
@ -227,24 +229,8 @@ void QQuickFileDialogImpl::setSelectedFile(const QUrl &selectedFile)
return; return;
d->selectedFile = selectedFile; d->selectedFile = selectedFile;
emit selectedFileChanged();
}
QUrl QQuickFileDialogImpl::currentFile() const
{
Q_D(const QQuickFileDialogImpl);
return d->currentFile;
}
void QQuickFileDialogImpl::setCurrentFile(const QUrl &currentFile)
{
Q_D(QQuickFileDialogImpl);
if (currentFile == d->currentFile)
return;
d->currentFile = currentFile;
d->updateEnabled(); d->updateEnabled();
emit currentFileChanged(d->currentFile); emit selectedFileChanged(d->selectedFile);
} }
QSharedPointer<QFileDialogOptions> QQuickFileDialogImpl::options() const QSharedPointer<QFileDialogOptions> QQuickFileDialogImpl::options() const
@ -432,7 +418,7 @@ void QQuickFileDialogImplAttachedPrivate::fileDialogListViewCurrentIndexChanged(
if (!fileDialogDelegate) if (!fileDialogDelegate)
return; return;
fileDialogImpl->setCurrentFile(fileDialogDelegate->file()); fileDialogImpl->setSelectedFile(fileDialogDelegate->file());
} }
QQuickFileDialogImplAttached::QQuickFileDialogImplAttached(QObject *parent) QQuickFileDialogImplAttached::QQuickFileDialogImplAttached(QObject *parent)

View File

@ -72,7 +72,6 @@ class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFileDialogImpl : public QQui
Q_OBJECT Q_OBJECT
Q_PROPERTY(QUrl currentFolder READ currentFolder WRITE setCurrentFolder NOTIFY currentFolderChanged FINAL) Q_PROPERTY(QUrl currentFolder READ currentFolder WRITE setCurrentFolder NOTIFY currentFolderChanged FINAL)
Q_PROPERTY(QUrl selectedFile READ selectedFile WRITE setSelectedFile NOTIFY selectedFileChanged FINAL) Q_PROPERTY(QUrl selectedFile READ selectedFile WRITE setSelectedFile NOTIFY selectedFileChanged FINAL)
Q_PROPERTY(QUrl currentFile READ currentFile WRITE setCurrentFile NOTIFY currentFileChanged FINAL)
Q_PROPERTY(QStringList nameFilters READ nameFilters NOTIFY nameFiltersChanged FINAL) Q_PROPERTY(QStringList nameFilters READ nameFilters NOTIFY nameFiltersChanged FINAL)
Q_PROPERTY(QQuickFileNameFilter *selectedNameFilter READ selectedNameFilter CONSTANT) Q_PROPERTY(QQuickFileNameFilter *selectedNameFilter READ selectedNameFilter CONSTANT)
QML_NAMED_ELEMENT(FileDialogImpl) QML_NAMED_ELEMENT(FileDialogImpl)
@ -92,9 +91,6 @@ public:
QUrl selectedFile() const; QUrl selectedFile() const;
void setSelectedFile(const QUrl &file); void setSelectedFile(const QUrl &file);
QUrl currentFile() const;
void setCurrentFile(const QUrl &currentFile);
QSharedPointer<QFileDialogOptions> options() const; QSharedPointer<QFileDialogOptions> options() const;
void setOptions(const QSharedPointer<QFileDialogOptions> &options); void setOptions(const QSharedPointer<QFileDialogOptions> &options);
@ -111,8 +107,7 @@ public Q_SLOTS:
Q_SIGNALS: Q_SIGNALS:
void currentFolderChanged(const QUrl &folderUrl); void currentFolderChanged(const QUrl &folderUrl);
void selectedFileChanged(); void selectedFileChanged(const QUrl &selectedFileUrl);
void currentFileChanged(const QUrl &currentFileUrl);
void nameFiltersChanged(); void nameFiltersChanged();
void fileSelected(const QUrl &fileUrl); void fileSelected(const QUrl &fileUrl);
void filterSelected(const QString &filter); void filterSelected(const QString &filter);

View File

@ -78,7 +78,7 @@ public:
void setNameFilters(const QStringList &filters); void setNameFilters(const QStringList &filters);
void updateEnabled(); void updateEnabled();
void updateCurrentFile(const QString &oldFolderPath); void updateSelectedFile(const QString &oldFolderPath);
void handleAccept() override; void handleAccept() override;
void handleClick(QQuickAbstractButton *button) override; void handleClick(QQuickAbstractButton *button) override;
@ -86,7 +86,6 @@ public:
QSharedPointer<QFileDialogOptions> options; QSharedPointer<QFileDialogOptions> options;
QUrl currentFolder; QUrl currentFolder;
QUrl selectedFile; QUrl selectedFile;
QUrl currentFile;
QStringList nameFilters; QStringList nameFilters;
mutable QQuickFileNameFilter *selectedNameFilter = nullptr; mutable QQuickFileNameFilter *selectedNameFilter = nullptr;
QString acceptLabel; QString acceptLabel;

View File

@ -319,13 +319,8 @@ void QQuickFolderBreadcrumbBarPrivate::textFieldAccepted()
setDialogFolder(fileUrl); setDialogFolder(fileUrl);
} else if (!enteredPathIsDir && (enteredPathExists || !mustExist)) { } else if (!enteredPathIsDir && (enteredPathExists || !mustExist)) {
qCDebug(lcTextInput) << "path entered is a file; setting file and calling accept()"; qCDebug(lcTextInput) << "path entered is a file; setting file and calling accept()";
// It's important that we set the currentFile here, as that's what
// QQuickPlatformFileDialog::selectedFiles() needs to return, and
// QQuickFileDialog::accept() sets its file property based on
// selectedFiles().
if (isFileDialog()) { if (isFileDialog()) {
auto fileDialog = asFileDialog(); auto fileDialog = asFileDialog();
fileDialog->setCurrentFile(fileUrl);
fileDialog->setSelectedFile(fileUrl); fileDialog->setSelectedFile(fileUrl);
fileDialog->accept(); fileDialog->accept();
} else { } else {

View File

@ -103,7 +103,7 @@ QQuickPlatformFileDialog::QQuickPlatformFileDialog(QObject *parent)
// urls += QUrl::fromLocalFile(file); // urls += QUrl::fromLocalFile(file);
// emit filesSelected(urls); // emit filesSelected(urls);
// }); // });
connect(m_dialog, &QQuickFileDialogImpl::currentFileChanged, this, &QQuickPlatformFileDialog::currentChanged); connect(m_dialog, &QQuickFileDialogImpl::selectedFileChanged, this, &QQuickPlatformFileDialog::currentChanged);
connect(m_dialog, &QQuickFileDialogImpl::currentFolderChanged, this, &QQuickPlatformFileDialog::directoryEntered); connect(m_dialog, &QQuickFileDialogImpl::currentFolderChanged, this, &QQuickPlatformFileDialog::directoryEntered);
connect(m_dialog, &QQuickFileDialogImpl::filterSelected, this, &QQuickPlatformFileDialog::filterSelected); connect(m_dialog, &QQuickFileDialogImpl::filterSelected, this, &QQuickPlatformFileDialog::filterSelected);
@ -150,7 +150,7 @@ void QQuickPlatformFileDialog::selectFile(const QUrl &file)
QList<QUrl> QQuickPlatformFileDialog::selectedFiles() const QList<QUrl> QQuickPlatformFileDialog::selectedFiles() const
{ {
// TODO: support for multiple selected files // TODO: support for multiple selected files
return { m_dialog->currentFile() }; return { m_dialog->selectedFile() };
} }
void QQuickPlatformFileDialog::setFilter() void QQuickPlatformFileDialog::setFilter()

View File

@ -203,11 +203,11 @@ void tst_QQuickFileDialogImpl::defaults()
QQuickFileDialogImpl *quickDialog = window->findChild<QQuickFileDialogImpl*>(); QQuickFileDialogImpl *quickDialog = window->findChild<QQuickFileDialogImpl*>();
QTRY_VERIFY(quickDialog->isOpened()); QTRY_VERIFY(quickDialog->isOpened());
QVERIFY(quickDialog); QVERIFY(quickDialog);
COMPARE_URL(quickDialog->selectedFile(), QUrl());
COMPARE_URL(quickDialog->currentFolder(), QUrl::fromLocalFile(QDir().absolutePath())); COMPARE_URL(quickDialog->currentFolder(), QUrl::fromLocalFile(QDir().absolutePath()));
COMPARE_URL(dialog->currentFile(), QUrl::fromLocalFile(tempSubDir.path())); COMPARE_URL(dialog->selectedFile(), QUrl::fromLocalFile(tempSubDir.path()));
COMPARE_URLS(dialog->currentFiles(), { QUrl::fromLocalFile(tempSubDir.path()) }); COMPARE_URLS(dialog->selectedFiles(), { QUrl::fromLocalFile(tempSubDir.path()) });
COMPARE_URL(quickDialog->currentFile(), QUrl::fromLocalFile(tempSubDir.path())); COMPARE_URL(dialog->currentFile(), dialog->selectedFile());
COMPARE_URLS(dialog->currentFiles(), dialog->selectedFiles());
QCOMPARE(quickDialog->title(), QString()); QCOMPARE(quickDialog->title(), QString());
} }
@ -221,12 +221,10 @@ void tst_QQuickFileDialogImpl::chooseFileViaStandardButtons()
QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
// Select the delegate by clicking once. // Select the delegate by clicking once.
QSignalSpy dialogFileChangedSpy(dialogHelper.dialog, SIGNAL(selectedFileChanged())); QSignalSpy dialogSelectedFileChangedSpy(dialogHelper.dialog, SIGNAL(selectedFileChanged()));
QVERIFY(dialogFileChangedSpy.isValid()); QVERIFY(dialogSelectedFileChangedSpy.isValid());
QSignalSpy dialogCurrentFileChangedSpy(dialogHelper.dialog, SIGNAL(currentFileChanged())); QSignalSpy dialogCurrentFileChangedSpy(dialogHelper.dialog, SIGNAL(currentFileChanged()));
QVERIFY(dialogCurrentFileChangedSpy.isValid()); QVERIFY(dialogCurrentFileChangedSpy.isValid());
QSignalSpy quickDialogCurrentFileChangedSpy(dialogHelper.quickDialog, SIGNAL(currentFileChanged(const QUrl &)));
QVERIFY(quickDialogCurrentFileChangedSpy.isValid());
auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView");
QVERIFY(fileDialogListView); QVERIFY(fileDialogListView);
@ -234,13 +232,12 @@ void tst_QQuickFileDialogImpl::chooseFileViaStandardButtons()
QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 2, delegate)); QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 2, delegate));
COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempFile2->fileName())); COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempFile2->fileName()));
QVERIFY(clickButton(delegate)); QVERIFY(clickButton(delegate));
COMPARE_URL(dialogHelper.quickDialog->currentFile(), QUrl::fromLocalFile(tempFile2->fileName())); COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName()));
COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile2->fileName())); COMPARE_URL(dialogHelper.quickDialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName()));
COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); COMPARE_URL(dialogHelper.dialog->currentFile(), dialogHelper.dialog->selectedFile());
// Only currentFile-related signals should be emitted. COMPARE_URLS(dialogHelper.dialog->currentFiles(), { dialogHelper.dialog->selectedFile() });
QCOMPARE(dialogFileChangedSpy.count(), 0); QCOMPARE(dialogSelectedFileChangedSpy.count(), 1);
QCOMPARE(dialogCurrentFileChangedSpy.count(), 1); QCOMPARE(dialogCurrentFileChangedSpy.count(), 1);
QCOMPARE(quickDialogCurrentFileChangedSpy.count(), 1);
// Click the "Open" button. // Click the "Open" button.
QVERIFY(dialogHelper.quickDialog->footer()); QVERIFY(dialogHelper.quickDialog->footer());
@ -251,8 +248,9 @@ void tst_QQuickFileDialogImpl::chooseFileViaStandardButtons()
QVERIFY(clickButton(openButton)); QVERIFY(clickButton(openButton));
COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName()));
COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) });
QCOMPARE(dialogFileChangedSpy.count(), 1);
COMPARE_URL(dialogHelper.quickDialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); COMPARE_URL(dialogHelper.quickDialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName()));
QCOMPARE(dialogSelectedFileChangedSpy.count(), 1);
QCOMPARE(dialogCurrentFileChangedSpy.count(), 1);
QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); QTRY_VERIFY(!dialogHelper.quickDialog->isVisible());
QVERIFY(!dialogHelper.dialog->isVisible()); QVERIFY(!dialogHelper.dialog->isVisible());
} }
@ -407,13 +405,12 @@ void tst_QQuickFileDialogImpl::changeFolderViaStandardButtons()
QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, delegate)); QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, delegate));
COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempSubDir.path())); COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempSubDir.path()));
QVERIFY(clickButton(delegate)); QVERIFY(clickButton(delegate));
// The selectedFile and currentFolder shouldn't change yet. // The selectedFile should change, but not currentFolder.
COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl()); COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempSubDir.path()));
COMPARE_URLS(dialogHelper.dialog->selectedFiles(), {}); COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempSubDir.path()) });
COMPARE_URL(dialogHelper.dialog->currentFile(), dialogHelper.dialog->selectedFile());
COMPARE_URLS(dialogHelper.dialog->currentFiles(), dialogHelper.dialog->selectedFiles());
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path())); COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path()));
// The currentFile should, though.
COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempSubDir.path()));
COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempSubDir.path()) });
// Click the "Open" button. The dialog should navigate to that directory, but still be open. // Click the "Open" button. The dialog should navigate to that directory, but still be open.
QVERIFY(dialogHelper.quickDialog->footer()); QVERIFY(dialogHelper.quickDialog->footer());
@ -422,7 +419,7 @@ void tst_QQuickFileDialogImpl::changeFolderViaStandardButtons()
QQuickAbstractButton* openButton = findDialogButton(dialogButtonBox, "Open"); QQuickAbstractButton* openButton = findDialogButton(dialogButtonBox, "Open");
QVERIFY(openButton); QVERIFY(openButton);
QVERIFY(clickButton(openButton)); QVERIFY(clickButton(openButton));
COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl()); COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempSubSubDir.path()));
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path()));
QVERIFY(dialogHelper.dialog->isVisible()); QVERIFY(dialogHelper.dialog->isVisible());
@ -448,13 +445,15 @@ void tst_QQuickFileDialogImpl::changeFolderViaDoubleClick()
COMPARE_URL(subDirDelegate->file(), QUrl::fromLocalFile(tempSubDir.path())); COMPARE_URL(subDirDelegate->file(), QUrl::fromLocalFile(tempSubDir.path()));
QVERIFY(doubleClickButton(subDirDelegate)); QVERIFY(doubleClickButton(subDirDelegate));
// The first file in the directory should be selected, which is "sub-sub-dir". // The first file in the directory should be selected, which is "sub-sub-dir".
COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempSubSubDir.path())); COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempSubSubDir.path()));
COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempSubSubDir.path()) }); COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempSubSubDir.path()) });
COMPARE_URL(dialogHelper.dialog->currentFile(), dialogHelper.dialog->selectedFile());
COMPARE_URLS(dialogHelper.dialog->currentFiles(), { dialogHelper.dialog->selectedFiles() });
QQuickFileDialogDelegate *subSubDirDelegate = nullptr; QQuickFileDialogDelegate *subSubDirDelegate = nullptr;
QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subSubDirDelegate)); QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subSubDirDelegate));
QCOMPARE(subSubDirDelegate->isHighlighted(), true); QCOMPARE(subSubDirDelegate->isHighlighted(), true);
COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl()); COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempSubSubDir.path()));
COMPARE_URLS(dialogHelper.dialog->selectedFiles(), {}); COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempSubSubDir.path()) });
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path()));
// Since we only chose a folder, the dialog should still be open. // Since we only chose a folder, the dialog should still be open.
QVERIFY(dialogHelper.dialog->isVisible()); QVERIFY(dialogHelper.dialog->isVisible());
@ -489,14 +488,14 @@ void tst_QQuickFileDialogImpl::chooseFolderViaTextEdit()
// Hit enter to accept. // Hit enter to accept.
QTest::keyClick(dialogHelper.window(), Qt::Key_Return); QTest::keyClick(dialogHelper.window(), Qt::Key_Return);
// The first file in the directory should be selected, which is "sub-sub-dir". // The first file in the directory should be selected, which is "sub-sub-dir".
COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempSubSubDir.path())); COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempSubSubDir.path()));
auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView");
QVERIFY(fileDialogListView); QVERIFY(fileDialogListView);
QQuickFileDialogDelegate *subSubDirDelegate = nullptr; QQuickFileDialogDelegate *subSubDirDelegate = nullptr;
QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subSubDirDelegate)); QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subSubDirDelegate));
QCOMPARE(subSubDirDelegate->isHighlighted(), true); QCOMPARE(subSubDirDelegate->isHighlighted(), true);
COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl()); COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempSubSubDir.path()));
COMPARE_URLS(dialogHelper.dialog->selectedFiles(), {}); COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempSubSubDir.path()) });
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path()));
QTRY_VERIFY(dialogHelper.dialog->isVisible()); QTRY_VERIFY(dialogHelper.dialog->isVisible());
@ -590,15 +589,15 @@ void tst_QQuickFileDialogImpl::chooseFileAndThenFolderViaTextEdit()
// Hit enter to accept. // Hit enter to accept.
QTest::keyClick(dialogHelper.window(), Qt::Key_Return); QTest::keyClick(dialogHelper.window(), Qt::Key_Return);
// The first file in the directory should be selected, which is "sub-sub-dir". // The first file in the directory should be selected, which is "sub-sub-dir".
COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempSubSubDir.path())); COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempSubSubDir.path()));
auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView");
QVERIFY(fileDialogListView); QVERIFY(fileDialogListView);
QQuickFileDialogDelegate *subSubDirDelegate = nullptr; QQuickFileDialogDelegate *subSubDirDelegate = nullptr;
QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subSubDirDelegate)); QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subSubDirDelegate));
QCOMPARE(subSubDirDelegate->isHighlighted(), true); QCOMPARE(subSubDirDelegate->isHighlighted(), true);
// We just changed directories, so the actual selected file shouldn't change. // We just changed directories, so the actual selected file shouldn't change.
COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempSubSubDir.path()));
COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempSubSubDir.path()) });
COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path()));
QTRY_VERIFY(dialogHelper.dialog->isVisible()); QTRY_VERIFY(dialogHelper.dialog->isVisible());