Add parent arg to QFileDialog::getOpenFileContent and saveFileContent

This change updates getOpenFileContent to provide a parent when the
non-WASM fallback to a QFileDialog is created, which avoids issues
where this call is made inside another application. Specifically,
if a QDialog is created lacking a parent to the main window, it will
prevent interaction with that dialog. This patch addresses that problem
with window modality.

This change also updates saveFileContent to provide a parent for
the fallback mechanism, so that both static APIs that interact
with WASM/non-WASM dialogs have comparable behavior.

The new parent argument is updated in the documentation. Documentation
is clarified in terms of usage outside Qt for WebAssembly.

[ChangeLog][QtWidgets][QFileDialog] Adds an overload to the
static methods getOpenFileContent and saveFileContent with a
new parent argument which always no-ops in the WASM environment.

Fixes: QTBUG-118396
Pick-to: 6.6 6.5
Change-Id: Ic59aee386631172d4a29b42fe11e5af318474a1d
Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>
(cherry picked from commit 7c5cf8cae054954975a3e262f7fe3cd9897d67f4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Chris Von Bargen 2023-12-18 10:28:34 -05:00 committed by Qt Cherry-pick Bot
parent 433feb87c0
commit 253957b940
3 changed files with 52 additions and 16 deletions

View File

@ -78,7 +78,26 @@ QAction *QMenuBar::addAction(const QString &text, const QObject *receiver, const
}
#endif
#endif // QT_WIDGETS_REMOVED_SINCE(6, 3)
#if QT_WIDGETS_REMOVED_SINCE(6, 7)
#if QT_CONFIG(filedialog)
#include "qfiledialog.h"
void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::function<void(const QString &, const QByteArray &)> &fileOpenCompleted)
{
QFileDialog::getOpenFileContent(nameFilter, fileOpenCompleted, nullptr);
}
void QFileDialog::saveFileContent(const QByteArray &fileContent, const QString &fileNameHint)
{
saveFileContent(fileContent, fileNameHint, nullptr);
}
#endif
// #include <qotherheader.h>
// // implement removed functions from qotherheader.h
#endif // QT_WIDGETS_REMOVED_SINCE(6, 3)
#endif // QT_WIDGETS_REMOVED_SINCE(6, 7)

View File

@ -2276,12 +2276,13 @@ QList<QUrl> QFileDialog::getOpenFileUrls(QWidget *parent,
This is a convenience static function that returns the content of a file
selected by the user.
This function is used to access local files on Qt for WebAssembly, where the web
sandbox places restrictions on how such access can happen. Its implementation will
make the browser display a native file dialog, where the user makes the file selection
based on the parameter \a nameFilter.
Use this function to access local files on Qt for WebAssembly, if the web sandbox
restricts file access. Its implementation enables displaying a native file dialog in
the browser, where the user selects a file based on the \a nameFilter parameter.
It can also be used on other platforms, where it falls back to using QFileDialog.
\a parent is ignored on Qt for WebAssembly. Pass \a parent on other platforms, to make
the popup a child of another widget. If the platform doesn't support native file
dialogs, the function falls back to QFileDialog.
The function is asynchronous and returns immediately. The \a fileOpenCompleted
callback will be called when a file has been selected and its contents have been
@ -2290,9 +2291,10 @@ QList<QUrl> QFileDialog::getOpenFileUrls(QWidget *parent,
\snippet code/src_gui_dialogs_qfiledialog.cpp 15
\since 5.13
*/
void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::function<void(const QString &, const QByteArray &)> &fileOpenCompleted)
void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::function<void(const QString &, const QByteArray &)> &fileOpenCompleted, QWidget *parent)
{
#ifdef Q_OS_WASM
Q_UNUSED(parent);
auto openFileImpl = std::make_shared<std::function<void(void)>>();
QString fileName;
QByteArray fileContent;
@ -2322,9 +2324,10 @@ void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::funct
(*openFileImpl)();
#else
QFileDialog *dialog = new QFileDialog();
QFileDialog *dialog = new QFileDialog(parent);
dialog->setFileMode(QFileDialog::ExistingFile);
dialog->setNameFilter(nameFilter);
dialog->setAttribute(Qt::WA_DeleteOnClose);
auto fileSelected = [=](const QString &fileName) {
QByteArray fileContent;
@ -2337,7 +2340,6 @@ void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::funct
};
connect(dialog, &QFileDialog::fileSelected, dialog, fileSelected);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
#endif
}
@ -2347,23 +2349,26 @@ void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::funct
a file name and location chosen by the user. \a fileNameHint can be provided to
suggest a file name to the user.
This function is used to save files to the local file system on Qt for WebAssembly, where
the web sandbox places restrictions on how such access can happen. Its implementation will
make the browser display a native file dialog, where the user makes the file selection.
Use this function to save content to local files on Qt for WebAssembly, if the web sandbox
restricts file access. Its implementation enables displaying a native file dialog in the
browser, where the user specifies an output file based on the \a fileNameHint argument.
It can also be used on other platforms, where it falls back to using QFileDialog.
\a parent is ignored on Qt for WebAssembly. Pass \a parent on other platforms, to make
the popup a child of another widget. If the platform doesn't support native file
dialogs, the function falls back to QFileDialog.
The function is asynchronous and returns immediately.
\snippet code/src_gui_dialogs_qfiledialog.cpp 16
\since 5.14
*/
void QFileDialog::saveFileContent(const QByteArray &fileContent, const QString &fileNameHint)
void QFileDialog::saveFileContent(const QByteArray &fileContent, const QString &fileNameHint, QWidget *parent)
{
#ifdef Q_OS_WASM
Q_UNUSED(parent);
QWasmLocalFileAccess::saveFile(fileContent, fileNameHint.toStdString());
#else
QFileDialog *dialog = new QFileDialog();
QFileDialog *dialog = new QFileDialog(parent);
dialog->setAcceptMode(QFileDialog::AcceptSave);
dialog->setFileMode(QFileDialog::AnyFile);
dialog->selectFile(fileNameHint);

View File

@ -212,9 +212,21 @@ public:
Options options = Options(),
const QStringList &supportedSchemes = QStringList());
static void getOpenFileContent(const QString &nameFilter,
const std::function<void(const QString &, const QByteArray &)> &fileContentsReady,
QWidget *parent);
static void saveFileContent(const QByteArray &fileContent,
const QString &fileNameHint,
QWidget *parent = nullptr);
#if QT_WIDGETS_REMOVED_SINCE(6, 7)
static void getOpenFileContent(const QString &nameFilter,
const std::function<void(const QString &, const QByteArray &)> &fileContentsReady);
static void saveFileContent(const QByteArray &fileContent, const QString &fileNameHint = QString());
static void saveFileContent(const QByteArray &fileContent,
const QString &fileNameHint = QString());
#endif
protected:
QFileDialog(const QFileDialogArgs &args);