6#include <private/qgenericunixservices_p.h>
7#include <private/qguiapplication_p.h>
8#include <qpa/qplatformintegration.h>
10#include <QDBusConnection>
11#include <QDBusMessage>
12#include <QDBusPendingCall>
13#include <QDBusPendingCallWatcher>
14#include <QDBusPendingReply>
15#include <QDBusMetaType>
22#include <QMimeDatabase>
23#include <QRandomGenerator>
25#include <QRegularExpression>
34 arg << filterCondition.type << filterCondition.pattern;
46 filterCondition.pattern = filterPattern;
65 arg >>
name >> filterConditions;
67 filter.filterConditions = filterConditions;
106 if (
d->nativeFileDialog) {
119void QXdgDesktopPortalFileDialog::initializeDialog()
123 if (
d->nativeFileDialog)
124 d->nativeFileDialog->setOptions(
options());
127 d->multipleFiles =
true;
130 d->directoryMode =
true;
141 if (!
options()->nameFilters().isEmpty())
147 if (!
options()->initiallySelectedMimeTypeFilter().isEmpty())
150 if (!
options()->initiallySelectedNameFilter().isEmpty())
156void QXdgDesktopPortalFileDialog::openPortal(Qt::WindowFlags windowFlags,
Qt::WindowModality windowModality,
QWindow *parent)
161 "/org/freedesktop/portal/desktop"_L1,
162 "org.freedesktop.portal.FileChooser"_L1,
163 d->saveFile ?
"SaveFile"_L1 :
"OpenFile"_L1);
165 if (!
d->acceptLabel.isEmpty())
166 options.insert(
"accept_label"_L1,
d->acceptLabel);
169 options.insert(
"multiple"_L1,
d->multipleFiles);
170 options.insert(
"directory"_L1,
d->directoryMode);
172 if (!
d->directory.isEmpty())
175 if (
d->saveFile && !
d->selectedFiles.isEmpty()) {
179 QFileInfo selectedFileInfo(
d->selectedFiles.constFirst());
180 if (selectedFileInfo.exists())
181 options.insert(
"current_file"_L1,
183 options.insert(
"current_name"_L1, selectedFileInfo.fileName());
187 qDBusRegisterMetaType<FilterCondition>();
188 qDBusRegisterMetaType<FilterConditionList>();
189 qDBusRegisterMetaType<Filter>();
190 qDBusRegisterMetaType<FilterList>();
193 auto selectedFilterIndex = filterList.size() - 1;
195 d->userVisibleToNameFilter.clear();
197 if (!
d->mimeTypesFilters.isEmpty()) {
198 for (
const QString &mimeTypefilter :
d->mimeTypesFilters) {
203 FilterCondition filterCondition;
205 filterCondition.pattern = mimeTypefilter;
209 filterConditions << filterCondition;
214 filter.filterConditions = filterConditions;
216 if (
filter.name.isEmpty())
217 filter.name = mimeTypefilter;
221 if (!
d->selectedMimeTypeFilter.isEmpty() &&
d->selectedMimeTypeFilter == mimeTypefilter)
222 selectedFilterIndex = filterList.size() - 1;
224 }
else if (!
d->nameFilters.isEmpty()) {
225 for (
const QString &nameFilter :
d->nameFilters) {
230 if (
match.hasMatch()) {
234 if (filterStrings.isEmpty()) {
235 qWarning() <<
"Filter " << userVisibleName <<
" is empty and will be ignored.";
240 for (
const QString &filterString : filterStrings) {
241 FilterCondition filterCondition;
243 filterCondition.pattern = filterString;
244 filterConditions << filterCondition;
248 filter.name = userVisibleName;
249 filter.filterConditions = filterConditions;
253 d->userVisibleToNameFilter.insert(userVisibleName, nameFilter);
255 if (!
d->selectedNameFilter.isEmpty() &&
d->selectedNameFilter == nameFilter)
256 selectedFilterIndex = filterList.size() - 1;
261 if (!filterList.isEmpty())
264 if (selectedFilterIndex != -1)
274 if (
parent && unixServices)
286 d->failedToOpen =
reply.isError();
287 if (
d->failedToOpen) {
288 if (d->nativeFileDialog) {
289 d->nativeFileDialog->show(windowFlags, windowModality, parent);
290 if (d->loop.isRunning())
291 d->nativeFileDialog->exec();
297 reply.value().path(),
298 "org.freedesktop.portal.Request"_L1,
316 if (
d->nativeFileDialog) {
317 d->nativeFileDialog->setOptions(
options());
328 if (
d->nativeFileDialog && useNativeFileDialog())
329 return d->nativeFileDialog->directory();
338 if (
d->nativeFileDialog) {
339 d->nativeFileDialog->setOptions(
options());
340 d->nativeFileDialog->selectFile(filename);
343 d->selectedFiles << filename.
path();
350 if (
d->nativeFileDialog && useNativeFileDialog())
351 return d->nativeFileDialog->selectedFiles();
364 if (
d->nativeFileDialog) {
365 d->nativeFileDialog->setOptions(
options());
366 d->nativeFileDialog->setFilter();
373 if (
d->nativeFileDialog) {
374 d->nativeFileDialog->setOptions(
options());
375 d->nativeFileDialog->selectMimeTypeFilter(
filter);
382 return d->selectedMimeTypeFilter;
389 if (
d->nativeFileDialog) {
390 d->nativeFileDialog->setOptions(
options());
391 d->nativeFileDialog->selectNameFilter(
filter);
398 return d->selectedNameFilter;
405 if (
d->nativeFileDialog && useNativeFileDialog()) {
406 d->nativeFileDialog->exec();
418 if (
d->nativeFileDialog)
419 d->nativeFileDialog->hide();
428 if (
d->nativeFileDialog && useNativeFileDialog(
OpenFallback))
429 return d->nativeFileDialog->show(windowFlags, windowModality,
parent);
431 openPortal(windowFlags, windowModality,
parent);
446 if (!selectedFilter.filterConditions.empty() && selectedFilter.filterConditions[0].type ==
MimeType) {
448 d->selectedMimeTypeFilter = selectedFilter.filterConditions[0].pattern;
449 d->selectedNameFilter.clear();
451 d->selectedNameFilter =
d->userVisibleToNameFilter.value(selectedFilter.name);
452 d->selectedMimeTypeFilter.clear();
468 if (
d->fileChooserPortalVersion < 3) {
480#include "moc_qxdgdesktopportalfiledialog_p.cpp"
static QDBusConnection sessionBus()
Returns a QDBusConnection object opened with the session bus.
static QDBusMessage createMethodCall(const QString &destination, const QString &path, const QString &interface, const QString &method)
Constructs a new DBus message representing a method call.
void finished(QDBusPendingCallWatcher *self=nullptr)
This signal is emitted when the pending call has finished and its reply is available.
QStringList mimeTypeFilters() const
QString initiallySelectedNameFilter() const
QString labelText(DialogLabel label) const
QStringList nameFilters() const
QString windowTitle() const
QString initiallySelectedMimeTypeFilter() const
static QByteArray encodeName(const QString &fileName)
Converts fileName to an 8-bit encoding that you can use in native APIs.
virtual QString portalWindowIdentifier(QWindow *window)
static QPlatformIntegration * platformIntegration()
T value(qsizetype i) const
QObject * parent() const
Returns a pointer to the parent object.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
static Q_DECL_CONST_FUNCTION QRandomGenerator * global()
\threadsafe
\inmodule QtCore \reentrant
\inmodule QtCore \reentrant
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString path(ComponentFormattingOptions options=FullyDecoded) const
Returns the path of the URL.
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
QStringList selectedFiles
QMap< QString, QString > userVisibleToNameFilter
uint fileChooserPortalVersion
QString selectedMimeTypeFilter
std::unique_ptr< QPlatformFileDialogHelper > nativeFileDialog
QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
QString selectedNameFilter
QStringList mimeTypesFilters
QString selectedNameFilter() const override
void selectNameFilter(const QString &filter) override
QString selectedMimeTypeFilter() const override
QList< FilterCondition > FilterConditionList
void setFilter() override
bool defaultNameFilterDisables() const override
bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override
void selectMimeTypeFilter(const QString &filter) override
~QXdgDesktopPortalFileDialog()
void setDirectory(const QUrl &directory) override
void selectFile(const QUrl &filename) override
QUrl directory() const override
QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog=nullptr, uint fileChooserPortalVersion=0)
QList< QUrl > selectedFiles() const override
QList< Filter > FilterList
Combined button and popup list for selecting options.
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLuint GLsizei const GLchar * message
#define QStringLiteral(str)
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
static QString windowTitle(HWND hwnd)
QDBusArgument & operator<<(QDBusArgument &arg, const QXdgDesktopPortalFileDialog::FilterCondition &filterCondition)
const QDBusArgument & operator>>(const QDBusArgument &arg, QXdgDesktopPortalFileDialog::FilterCondition &filterCondition)
QFutureWatcher< int > watcher
QStringList mimeTypeFilters({"image/jpeg", "image/png", "application/octet-stream" })
[12]
bool contains(const AT &t) const noexcept