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] 35fca7fae8
Fixes: QTBUG-85658
Pick-to: 5.15
Change-Id: I8651c1a8942dfd358895b7826730729c4d22e680
Reviewed-by: Jan Grulich <jgrulich@redhat.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
parent
ecc72bc63d
commit
3e09c28101
|
|
@ -116,6 +116,10 @@ public:
|
|||
QString title;
|
||||
QStringList nameFilters;
|
||||
QStringList mimeTypesFilters;
|
||||
// maps user-visible name for portal to full name filter
|
||||
QMap<QString, QString> 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 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<Filter>(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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue