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;
|
||||
for (const auto &filter : filterList) {
|
||||
|
||||
emscripten::val::global("console").call<void>("log", filter.toStdString());
|
||||
|
||||
const auto type = Type::fromQt(filter);
|
||||
if (type && type->accept()) {
|
||||
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),
|
||||
[](const Type::Accept::MimeType::Extension &extension) {
|
||||
return extension.value().toString();
|
||||
});
|
||||
}
|
||||
}
|
||||
for (const QString &tran : transformed) {
|
||||
emscripten::val::global("console").call<void>("log", tran.toStdString());
|
||||
}
|
||||
return transformed.join(QStringLiteral(",")).toStdString();
|
||||
}
|
||||
|
||||
@ -39,13 +28,12 @@ std::optional<emscripten::val> qtFilterListToTypes(const QStringList &filterList
|
||||
{
|
||||
using namespace qstdweb;
|
||||
using namespace emscripten;
|
||||
|
||||
auto types = emscripten::val::array();
|
||||
|
||||
for (const auto &fileFilter : filterList) {
|
||||
auto type = Type::fromQt(fileFilter);
|
||||
if (type) {
|
||||
auto jsType = val::object();
|
||||
auto jsType = emscripten::val::object();
|
||||
jsType.set("description", type->description().toString().toStdString());
|
||||
if (type->accept()) {
|
||||
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)
|
||||
{
|
||||
auto options = emscripten::val::object();
|
||||
if (auto typeList = qtFilterListToTypes(filterList)) {
|
||||
if (auto typeList = qtFilterListToTypes(filterList); typeList) {
|
||||
options.set("types", std::move(*typeList));
|
||||
options.set("excludeAcceptAllOption", true);
|
||||
}
|
||||
|
@ -135,66 +135,18 @@ void readFiles(const qstdweb::FileList &fileList,
|
||||
(*readFile)(0);
|
||||
}
|
||||
|
||||
QStringList acceptListFromQtFormat(const std::string &qtAcceptList)
|
||||
QStringList makeFilterList(const std::string &qtAcceptList)
|
||||
{
|
||||
// copy of qt_make_filter_list() from qfiledialog.cpp
|
||||
auto make_filter_list = [](const QString &filter) -> QStringList
|
||||
{
|
||||
if (filter.isEmpty())
|
||||
return QStringList();
|
||||
auto filter = QString::fromStdString(qtAcceptList);
|
||||
if (filter.isEmpty())
|
||||
return QStringList();
|
||||
QString sep(";;");
|
||||
if (!filter.contains(sep) && filter.contains(u'\n'))
|
||||
sep = u'\n';
|
||||
|
||||
QString sep(";;");
|
||||
if (!filter.contains(sep) && filter.contains(u'\n'))
|
||||
sep = u'\n';
|
||||
|
||||
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;
|
||||
return filter.split(sep);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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<void()> &fileDataReady)
|
||||
{
|
||||
FileDialog::showOpen(acceptListFromQtFormat(accept), fileSelectMode, {
|
||||
FileDialog::showOpen(makeFilterList(accept), fileSelectMode, {
|
||||
.thenFunc = [=](emscripten::val result) {
|
||||
auto files = qstdweb::FileList(result);
|
||||
fileDialogClosed(files.length());
|
||||
|
Loading…
x
Reference in New Issue
Block a user