wasm: Fix QFileDialog file filter
File filter was not properly processed when using LocalFileAPI. The QtFormat->AcceptList conversion was happening twice, resulting in erronous types. This prevented dialog from appearing on Chrome. Additionally remove unused debug code. Fixes: QTBUG-115087 Change-Id: Ie6770e2f1d2aa7c3ad19f9ab105dbec8102d45fc Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> (cherry picked from commit 62caae95784a2e70d46194622e96e0e6bdf13c28) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
e32b3aeb64
commit
8240f9437e
@ -12,26 +12,15 @@ std::string qtFilterListToFileInputAccept(const QStringList &filterList)
|
|||||||
{
|
{
|
||||||
QStringList transformed;
|
QStringList transformed;
|
||||||
for (const auto &filter : filterList) {
|
for (const auto &filter : filterList) {
|
||||||
|
|
||||||
emscripten::val::global("console").call<void>("log", filter.toStdString());
|
|
||||||
|
|
||||||
const auto type = Type::fromQt(filter);
|
const auto type = Type::fromQt(filter);
|
||||||
if (type && type->accept()) {
|
if (type && type->accept()) {
|
||||||
const auto &extensions = type->accept()->mimeType().extensions();
|
const auto &extensions = type->accept()->mimeType().extensions();
|
||||||
for (const auto &ext : extensions) {
|
|
||||||
emscripten::val::global("console").call<void>("log",
|
|
||||||
ext.value().toString().toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::transform(extensions.begin(), extensions.end(), std::back_inserter(transformed),
|
std::transform(extensions.begin(), extensions.end(), std::back_inserter(transformed),
|
||||||
[](const Type::Accept::MimeType::Extension &extension) {
|
[](const Type::Accept::MimeType::Extension &extension) {
|
||||||
return extension.value().toString();
|
return extension.value().toString();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const QString &tran : transformed) {
|
|
||||||
emscripten::val::global("console").call<void>("log", tran.toStdString());
|
|
||||||
}
|
|
||||||
return transformed.join(QStringLiteral(",")).toStdString();
|
return transformed.join(QStringLiteral(",")).toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,13 +28,12 @@ std::optional<emscripten::val> qtFilterListToTypes(const QStringList &filterList
|
|||||||
{
|
{
|
||||||
using namespace qstdweb;
|
using namespace qstdweb;
|
||||||
using namespace emscripten;
|
using namespace emscripten;
|
||||||
|
|
||||||
auto types = emscripten::val::array();
|
auto types = emscripten::val::array();
|
||||||
|
|
||||||
for (const auto &fileFilter : filterList) {
|
for (const auto &fileFilter : filterList) {
|
||||||
auto type = Type::fromQt(fileFilter);
|
auto type = Type::fromQt(fileFilter);
|
||||||
if (type) {
|
if (type) {
|
||||||
auto jsType = val::object();
|
auto jsType = emscripten::val::object();
|
||||||
jsType.set("description", type->description().toString().toStdString());
|
jsType.set("description", type->description().toString().toStdString());
|
||||||
if (type->accept()) {
|
if (type->accept()) {
|
||||||
jsType.set("accept", ([&mimeType = type->accept()->mimeType()]() {
|
jsType.set("accept", ([&mimeType = type->accept()->mimeType()]() {
|
||||||
@ -190,7 +178,7 @@ Type::Accept::MimeType::Extension::fromQt(QStringView qtRepresentation)
|
|||||||
emscripten::val makeOpenFileOptions(const QStringList &filterList, bool acceptMultiple)
|
emscripten::val makeOpenFileOptions(const QStringList &filterList, bool acceptMultiple)
|
||||||
{
|
{
|
||||||
auto options = emscripten::val::object();
|
auto options = emscripten::val::object();
|
||||||
if (auto typeList = qtFilterListToTypes(filterList)) {
|
if (auto typeList = qtFilterListToTypes(filterList); typeList) {
|
||||||
options.set("types", std::move(*typeList));
|
options.set("types", std::move(*typeList));
|
||||||
options.set("excludeAcceptAllOption", true);
|
options.set("excludeAcceptAllOption", true);
|
||||||
}
|
}
|
||||||
|
@ -135,66 +135,18 @@ void readFiles(const qstdweb::FileList &fileList,
|
|||||||
(*readFile)(0);
|
(*readFile)(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList acceptListFromQtFormat(const std::string &qtAcceptList)
|
QStringList makeFilterList(const std::string &qtAcceptList)
|
||||||
{
|
{
|
||||||
// copy of qt_make_filter_list() from qfiledialog.cpp
|
// copy of qt_make_filter_list() from qfiledialog.cpp
|
||||||
auto make_filter_list = [](const QString &filter) -> QStringList
|
auto filter = QString::fromStdString(qtAcceptList);
|
||||||
{
|
|
||||||
if (filter.isEmpty())
|
if (filter.isEmpty())
|
||||||
return QStringList();
|
return QStringList();
|
||||||
|
|
||||||
QString sep(";;");
|
QString sep(";;");
|
||||||
if (!filter.contains(sep) && filter.contains(u'\n'))
|
if (!filter.contains(sep) && filter.contains(u'\n'))
|
||||||
sep = u'\n';
|
sep = u'\n';
|
||||||
|
|
||||||
return filter.split(sep);
|
return filter.split(sep);
|
||||||
};
|
|
||||||
|
|
||||||
const QStringList fileFilter = make_filter_list(QString::fromStdString(qtAcceptList));
|
|
||||||
QStringList transformed;
|
|
||||||
for (const auto &element : fileFilter) {
|
|
||||||
// Accepts either a string in format:
|
|
||||||
// GROUP3
|
|
||||||
// or in this format:
|
|
||||||
// GROUP1 (GROUP2)
|
|
||||||
// Group 1 is treated as the description, whereas group 2 or 3 are treated as the filter
|
|
||||||
// list.
|
|
||||||
static QRegularExpression regex(
|
|
||||||
QString(QStringLiteral("(?:([^(]*)\\(([^()]+)\\)[^)]*)|([^()]+)")));
|
|
||||||
static QRegularExpression wordCharacterRegex(QString(QStringLiteral("\\w")));
|
|
||||||
const auto match = regex.match(element);
|
|
||||||
|
|
||||||
if (!match.hasMatch())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
constexpr size_t FilterListFromParensIndex = 2;
|
|
||||||
constexpr size_t PlainFilterListIndex = 3;
|
|
||||||
QString filterList = match.captured(match.hasCaptured(FilterListFromParensIndex)
|
|
||||||
? FilterListFromParensIndex
|
|
||||||
: PlainFilterListIndex);
|
|
||||||
for (auto singleExtension : filterList.split(QStringLiteral(" "), Qt::SkipEmptyParts)) {
|
|
||||||
// Checks for a filter that matches everything:
|
|
||||||
// Any number of asterisks or any number of asterisks with a '.' between them.
|
|
||||||
// The web filter does not support wildcards.
|
|
||||||
static QRegularExpression qtAcceptAllRegex(QRegularExpression::anchoredPattern(
|
|
||||||
QString(QStringLiteral("[*]+|[*]+\\.[*]+"))));
|
|
||||||
if (qtAcceptAllRegex.match(singleExtension).hasMatch())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Checks for correctness. The web filter only allows filename extensions and does not
|
|
||||||
// filter the actual filenames, therefore we check whether the filter provided only
|
|
||||||
// filters for the extension.
|
|
||||||
static QRegularExpression qtFilenameMatcherRegex(QRegularExpression::anchoredPattern(
|
|
||||||
QString(QStringLiteral("(\\*?)(\\.[^*]+)"))));
|
|
||||||
|
|
||||||
auto extensionMatch = qtFilenameMatcherRegex.match(singleExtension);
|
|
||||||
if (extensionMatch.hasMatch())
|
|
||||||
transformed.append(extensionMatch.captured(2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return transformed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void downloadDataAsFile(const char *content, size_t size, const std::string &fileNameHint)
|
void downloadDataAsFile(const char *content, size_t size, const std::string &fileNameHint)
|
||||||
@ -225,7 +177,7 @@ void openFiles(const std::string &accept, FileSelectMode fileSelectMode,
|
|||||||
const std::function<char *(uint64_t size, const std::string& name)> &acceptFile,
|
const std::function<char *(uint64_t size, const std::string& name)> &acceptFile,
|
||||||
const std::function<void()> &fileDataReady)
|
const std::function<void()> &fileDataReady)
|
||||||
{
|
{
|
||||||
FileDialog::showOpen(acceptListFromQtFormat(accept), fileSelectMode, {
|
FileDialog::showOpen(makeFilterList(accept), fileSelectMode, {
|
||||||
.thenFunc = [=](emscripten::val result) {
|
.thenFunc = [=](emscripten::val result) {
|
||||||
auto files = qstdweb::FileList(result);
|
auto files = qstdweb::FileList(result);
|
||||||
fileDialogClosed(files.length());
|
fileDialogClosed(files.length());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user