/* * SPDX-FileCopyrightText: 2016-2018 Red Hat Inc * * SPDX-License-Identifier: LGPL-2.0-or-later * * SPDX-FileCopyrightText: 2016-2018 Jan Grulich * SPDX-FileCopyrightText: 2022 Harald Sitter */ #include "filechooser.h" #include "filechooser_debug.h" #include "utils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "documents_interface.h" #include "fuse_interface.h" #include "request.h" #include // Keep in sync with qflatpakfiledialog from flatpak-platform-plugin Q_DECLARE_METATYPE(FileChooserPortal::Filter) Q_DECLARE_METATYPE(FileChooserPortal::Filters) Q_DECLARE_METATYPE(FileChooserPortal::FilterList) Q_DECLARE_METATYPE(FileChooserPortal::FilterListList) // used for options - choices Q_DECLARE_METATYPE(FileChooserPortal::Choice) Q_DECLARE_METATYPE(FileChooserPortal::Choices) Q_DECLARE_METATYPE(FileChooserPortal::Option) Q_DECLARE_METATYPE(FileChooserPortal::OptionList) QDBusArgument &operator<<(QDBusArgument &arg, const FileChooserPortal::Filter &filter) { arg.beginStructure(); arg << filter.type << filter.filterString; arg.endStructure(); return arg; } const QDBusArgument &operator>>(const QDBusArgument &arg, FileChooserPortal::Filter &filter) { uint type; QString filterString; arg.beginStructure(); arg >> type >> filterString; filter.type = type; filter.filterString = filterString; arg.endStructure(); return arg; } QDBusArgument &operator<<(QDBusArgument &arg, const FileChooserPortal::FilterList &filterList) { arg.beginStructure(); arg << filterList.userVisibleName << filterList.filters; arg.endStructure(); return arg; } const QDBusArgument &operator>>(const QDBusArgument &arg, FileChooserPortal::FilterList &filterList) { QString userVisibleName; FileChooserPortal::Filters filters; arg.beginStructure(); arg >> userVisibleName >> filters; filterList.userVisibleName = userVisibleName; filterList.filters = filters; arg.endStructure(); return arg; } QDBusArgument &operator<<(QDBusArgument &arg, const FileChooserPortal::Choice &choice) { arg.beginStructure(); arg << choice.id << choice.value; arg.endStructure(); return arg; } const QDBusArgument &operator>>(const QDBusArgument &arg, FileChooserPortal::Choice &choice) { QString id; QString value; arg.beginStructure(); arg >> id >> value; choice.id = id; choice.value = value; arg.endStructure(); return arg; } QDBusArgument &operator<<(QDBusArgument &arg, const FileChooserPortal::Option &option) { arg.beginStructure(); arg << option.id << option.label << option.choices << option.initialChoiceId; arg.endStructure(); return arg; } const QDBusArgument &operator>>(const QDBusArgument &arg, FileChooserPortal::Option &option) { QString id; QString label; FileChooserPortal::Choices choices; QString initialChoiceId; arg.beginStructure(); arg >> id >> label >> choices >> initialChoiceId; option.id = id; option.label = label; option.choices = choices; option.initialChoiceId = initialChoiceId; arg.endStructure(); return arg; } static bool isKIOFuseAvailable() { static bool available = QDBusConnection::sessionBus().interface() && QDBusConnection::sessionBus().interface()->activatableServiceNames().value().contains("org.kde.KIOFuse"); return available; } // The portal might send us null terminated strings, make sure to strip the extranous \0 in favor of the implicit \0. // QByteArrays are implicitly terminated already. static QString decodeFileName(const QByteArray &name) { QByteArray decodedName = name; while (decodedName.endsWith('\0')) { decodedName.chop(1); } return QFile::decodeName(decodedName); } FileDialog::FileDialog(QDialog *parent, Qt::WindowFlags flags) : QDialog(parent, flags) , m_fileWidget(new KFileWidget(QUrl(), this)) , m_configGroup(KSharedConfig::openConfig()->group("FileDialogSize")) { setLayout(new QVBoxLayout); layout()->setContentsMargins({}); layout()->addWidget(m_fileWidget); m_fileWidget->okButton()->show(); m_fileWidget->cancelButton()->show(); // accept connect(m_fileWidget->okButton(), &QAbstractButton::clicked, m_fileWidget, &KFileWidget::slotOk); connect(m_fileWidget, &KFileWidget::accepted, m_fileWidget, &KFileWidget::accept); connect(m_fileWidget, &KFileWidget::accepted, this, &QDialog::accept); // reject connect(m_fileWidget->cancelButton(), &QAbstractButton::clicked, this, &QDialog::reject); connect(this, &QDialog::rejected, m_fileWidget, &KFileWidget::slotCancel); // restore window size if (m_configGroup.exists()) { winId(); // ensure there's a window created KWindowConfig::restoreWindowSize(windowHandle(), m_configGroup); resize(windowHandle()->size()); } } FileDialog::~FileDialog() { // save window size KWindowConfig::saveWindowSize(windowHandle(), m_configGroup); } FileChooserPortal::FileChooserPortal(QObject *parent) : QDBusAbstractAdaptor(parent) { qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType