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
#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> // #include <qotherheader.h>
// // implement removed functions from 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 This is a convenience static function that returns the content of a file
selected by the user. selected by the user.
This function is used to access local files on Qt for WebAssembly, where the web Use this function to access local files on Qt for WebAssembly, if the web sandbox
sandbox places restrictions on how such access can happen. Its implementation will restricts file access. Its implementation enables displaying a native file dialog in
make the browser display a native file dialog, where the user makes the file selection the browser, where the user selects a file based on the \a nameFilter parameter.
based on the parameter \a nameFilter.
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 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 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 \snippet code/src_gui_dialogs_qfiledialog.cpp 15
\since 5.13 \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 #ifdef Q_OS_WASM
Q_UNUSED(parent);
auto openFileImpl = std::make_shared<std::function<void(void)>>(); auto openFileImpl = std::make_shared<std::function<void(void)>>();
QString fileName; QString fileName;
QByteArray fileContent; QByteArray fileContent;
@ -2322,9 +2324,10 @@ void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::funct
(*openFileImpl)(); (*openFileImpl)();
#else #else
QFileDialog *dialog = new QFileDialog(); QFileDialog *dialog = new QFileDialog(parent);
dialog->setFileMode(QFileDialog::ExistingFile); dialog->setFileMode(QFileDialog::ExistingFile);
dialog->setNameFilter(nameFilter); dialog->setNameFilter(nameFilter);
dialog->setAttribute(Qt::WA_DeleteOnClose);
auto fileSelected = [=](const QString &fileName) { auto fileSelected = [=](const QString &fileName) {
QByteArray fileContent; QByteArray fileContent;
@ -2337,7 +2340,6 @@ void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::funct
}; };
connect(dialog, &QFileDialog::fileSelected, dialog, fileSelected); connect(dialog, &QFileDialog::fileSelected, dialog, fileSelected);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show(); dialog->show();
#endif #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 a file name and location chosen by the user. \a fileNameHint can be provided to
suggest a file name to the user. suggest a file name to the user.
This function is used to save files to the local file system on Qt for WebAssembly, where Use this function to save content to local files on Qt for WebAssembly, if the web sandbox
the web sandbox places restrictions on how such access can happen. Its implementation will restricts file access. Its implementation enables displaying a native file dialog in the
make the browser display a native file dialog, where the user makes the file selection. 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. The function is asynchronous and returns immediately.
\snippet code/src_gui_dialogs_qfiledialog.cpp 16 \snippet code/src_gui_dialogs_qfiledialog.cpp 16
\since 5.14 \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 #ifdef Q_OS_WASM
Q_UNUSED(parent);
QWasmLocalFileAccess::saveFile(fileContent, fileNameHint.toStdString()); QWasmLocalFileAccess::saveFile(fileContent, fileNameHint.toStdString());
#else #else
QFileDialog *dialog = new QFileDialog(); QFileDialog *dialog = new QFileDialog(parent);
dialog->setAcceptMode(QFileDialog::AcceptSave); dialog->setAcceptMode(QFileDialog::AcceptSave);
dialog->setFileMode(QFileDialog::AnyFile); dialog->setFileMode(QFileDialog::AnyFile);
dialog->selectFile(fileNameHint); dialog->selectFile(fileNameHint);

View File

@ -212,9 +212,21 @@ public:
Options options = Options(), Options options = Options(),
const QStringList &supportedSchemes = QStringList()); 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, static void getOpenFileContent(const QString &nameFilter,
const std::function<void(const QString &, const QByteArray &)> &fileContentsReady); 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: protected:
QFileDialog(const QFileDialogArgs &args); QFileDialog(const QFileDialogArgs &args);