From 3e09c28101d1af1dd90a4b515d7edbe5a3737f97 Mon Sep 17 00:00:00 2001 From: Michael Weghorn Date: Sat, 18 Jul 2020 15:07:05 +0200 Subject: Filechooser portal: Implement "current_filter" This adds supports for setting and retrieving the selected MIME and name filter for 'QXdgDesktopPortalFileDialog'. For preselecting a filter [1]: > current_filter (sa(us)) > > Request that this filter be set by default at dialog creation. If > the filters list is nonempty, it should match a filter in the list > to set the default filter from the list. Alternatively, it may be > specified when the list is empty to apply the filter > unconditionally. The "current_filter" return value was added in xdg-desktop-portal commit [2]. [1] https://flatpak.github.io/xdg-desktop-portal/portal-docs.html#gdbus-org.freedesktop.portal.FileChooser [2] https://github.com/flatpak/xdg-desktop-portal/commit/35fca7fae881bdaba1bebccf7775eba84407a488 Fixes: QTBUG-85658 Pick-to: 5.15 Change-Id: I8651c1a8942dfd358895b7826730729c4d22e680 Reviewed-by: Jan Grulich Reviewed-by: Thiago Macieira --- .../qxdgdesktopportalfiledialog.cpp | 61 ++++++++++++++++++++-- .../qxdgdesktopportalfiledialog_p.h | 2 + 2 files changed, 58 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp index 4b37367ad0..fc386935d4 100644 --- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp +++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp @@ -116,6 +116,10 @@ public: QString title; QStringList nameFilters; QStringList mimeTypesFilters; + // maps user-visible name for portal to full name filter + QMap userVisibleToNameFilter; + QString selectedMimeTypeFilter; + QString selectedNameFilter; QStringList selectedFiles; QPlatformFileDialogHelper *nativeFileDialog = nullptr; }; @@ -164,12 +168,18 @@ void QXdgDesktopPortalFileDialog::initializeDialog() if (!options()->mimeTypeFilters().isEmpty()) d->mimeTypesFilters = options()->mimeTypeFilters(); + if (!options()->initiallySelectedMimeTypeFilter().isEmpty()) + d->selectedMimeTypeFilter = options()->initiallySelectedMimeTypeFilter(); + + if (!options()->initiallySelectedNameFilter().isEmpty()) + d->selectedNameFilter = options()->initiallySelectedNameFilter(); + setDirectory(options()->initialDirectory()); } void QXdgDesktopPortalFileDialog::openPortal() { - Q_D(const QXdgDesktopPortalFileDialog); + Q_D(QXdgDesktopPortalFileDialog); QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.portal.Desktop"), QLatin1String("/org/freedesktop/portal/desktop"), @@ -200,6 +210,9 @@ void QXdgDesktopPortalFileDialog::openPortal() qDBusRegisterMetaType(); FilterList filterList; + Filter* selectedFilter = nullptr; + + d->userVisibleToNameFilter.clear(); if (!d->mimeTypesFilters.isEmpty()) { for (const QString &mimeTypefilter : d->mimeTypesFilters) { @@ -221,13 +234,16 @@ void QXdgDesktopPortalFileDialog::openPortal() filter.filterConditions = filterConditions; filterList << filter; + + if (!d->selectedMimeTypeFilter.isEmpty() && d->selectedMimeTypeFilter == mimeTypefilter) + selectedFilter = &filter; } } else if (!d->nameFilters.isEmpty()) { - for (const QString &filter : d->nameFilters) { + for (const QString &nameFilter : d->nameFilters) { // Do parsing: // Supported format is ("Images (*.png *.jpg)") QRegularExpression regexp(QPlatformFileDialogHelper::filterRegExp); - QRegularExpressionMatch match = regexp.match(filter); + QRegularExpressionMatch match = regexp.match(nameFilter); if (match.hasMatch()) { QString userVisibleName = match.captured(1); QStringList filterStrings = match.captured(2).split(QLatin1Char(' '), Qt::SkipEmptyParts); @@ -245,6 +261,11 @@ void QXdgDesktopPortalFileDialog::openPortal() filter.filterConditions = filterConditions; filterList << filter; + + d->userVisibleToNameFilter.insert(userVisibleName, nameFilter); + + if (!d->selectedNameFilter.isEmpty() && d->selectedNameFilter == nameFilter) + selectedFilter = &filter; } } } @@ -252,6 +273,10 @@ void QXdgDesktopPortalFileDialog::openPortal() if (!filterList.isEmpty()) options.insert(QLatin1String("filters"), QVariant::fromValue(filterList)); + if (selectedFilter) { + options.insert(QLatin1String("current_filter"), QVariant::fromValue(*selectedFilter)); + } + options.insert(QLatin1String("handle_token"), QStringLiteral("qt%1").arg(QRandomGenerator::global()->generate())); // TODO choices a(ssa(ss)s) @@ -339,6 +364,21 @@ void QXdgDesktopPortalFileDialog::setFilter() } } +void QXdgDesktopPortalFileDialog::selectMimeTypeFilter(const QString &filter) +{ + Q_D(QXdgDesktopPortalFileDialog); + if (d->nativeFileDialog) { + d->nativeFileDialog->setOptions(options()); + d->nativeFileDialog->selectMimeTypeFilter(filter); + } +} + +QString QXdgDesktopPortalFileDialog::selectedMimeTypeFilter() const +{ + Q_D(const QXdgDesktopPortalFileDialog); + return d->selectedMimeTypeFilter; +} + void QXdgDesktopPortalFileDialog::selectNameFilter(const QString &filter) { Q_D(QXdgDesktopPortalFileDialog); @@ -351,8 +391,8 @@ void QXdgDesktopPortalFileDialog::selectNameFilter(const QString &filter) QString QXdgDesktopPortalFileDialog::selectedNameFilter() const { - // TODO - return QString(); + Q_D(const QXdgDesktopPortalFileDialog); + return d->selectedNameFilter; } void QXdgDesktopPortalFileDialog::exec() @@ -404,6 +444,17 @@ void QXdgDesktopPortalFileDialog::gotResponse(uint response, const QVariantMap & if (results.contains(QLatin1String("uris"))) d->selectedFiles = results.value(QLatin1String("uris")).toStringList(); + if (results.contains(QLatin1String("current_filter"))) { + const Filter selectedFilter = qdbus_cast(results.value(QStringLiteral("current_filter"))); + if (!selectedFilter.filterConditions.empty() && selectedFilter.filterConditions[0].type == MimeType) { + // s.a. QXdgDesktopPortalFileDialog::openPortal which basically does the inverse + d->selectedMimeTypeFilter = selectedFilter.filterConditions[0].pattern; + d->selectedNameFilter.clear(); + } else { + d->selectedNameFilter = d->userVisibleToNameFilter.value(selectedFilter.name); + d->selectedMimeTypeFilter.clear(); + } + } Q_EMIT accept(); } else { Q_EMIT reject(); diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h index b21a9f7d84..ce1a0720bb 100644 --- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h +++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h @@ -80,6 +80,8 @@ public: void setFilter() override; void selectNameFilter(const QString &filter) override; QString selectedNameFilter() const override; + void selectMimeTypeFilter(const QString &filter) override; + QString selectedMimeTypeFilter() const override; void exec() override; bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override; -- cgit v1.2.3