Add support for FileChooser flatpak portal
Adds support for FileChooser Flatpak portal. To support them we just do specific DBus calls, which are then caught and forwarded by xdg-desktop- portal daemon/service. This is needed for Qt applications running in sandbox. [ChangeLog][Platform Specific Changes][Linux] Added support for flatpak portals. Flatpak is a software utility for software deployment and package management. It provides a sandbox environment in which users can run applications in isolation from the rest of the system. To communicate with the system flatpak uses portals, which are designed to be a bridge between sandboxed applications and desktop/system running on user's computer. Flatpak runs this service (called xdg-desktop-portal) automatically. It exports the portals via DBus and they are visible by default to all applications running under Flatpak. Change-Id: I4de1402434ba7cbcc805eab51c30f84f8ba0c5c5 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
91aa782f01
commit
84731fbb2b
@ -53,6 +53,7 @@
|
||||
#include <qpa/qplatformdrag.h>
|
||||
|
||||
#include <QtCore/QAbstractEventDispatcher>
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/private/qcoreapplication_p.h>
|
||||
#include <QtCore/private/qabstracteventdispatcher_p.h>
|
||||
@ -244,6 +245,15 @@ static inline void clearFontUnlocked()
|
||||
QGuiApplicationPrivate::app_font = 0;
|
||||
}
|
||||
|
||||
static bool checkRunningUnderFlatpak()
|
||||
{
|
||||
#if QT_CONFIG(dbus)
|
||||
return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, QLatin1String("flatpak-info")).isEmpty();
|
||||
#else
|
||||
return false;
|
||||
#endif // QT_CONFIG(dbus)
|
||||
}
|
||||
|
||||
// Using aggregate initialization instead of ctor so we can have a POD global static
|
||||
#define Q_WINDOW_GEOMETRY_SPECIFICATION_INITIALIZER { Qt::TopLeftCorner, -1, -1, -1, -1 }
|
||||
|
||||
@ -1179,16 +1189,21 @@ static void init_platform(const QString &pluginArgument, const QString &platform
|
||||
if (!platformThemeName.isEmpty())
|
||||
themeNames.append(platformThemeName);
|
||||
|
||||
// 2) Ask the platform integration for a list of theme names
|
||||
// 2) Special case - check whether we are in sandbox to use flatpak platform theme for portals support
|
||||
if (checkRunningUnderFlatpak()) {
|
||||
themeNames.append(QStringLiteral("flatpak"));
|
||||
}
|
||||
|
||||
// 3) Ask the platform integration for a list of theme names
|
||||
themeNames += QGuiApplicationPrivate::platform_integration->themeNames();
|
||||
// 3) Look for a theme plugin.
|
||||
// 4) Look for a theme plugin.
|
||||
for (const QString &themeName : qAsConst(themeNames)) {
|
||||
QGuiApplicationPrivate::platform_theme = QPlatformThemeFactory::create(themeName, platformPluginPath);
|
||||
if (QGuiApplicationPrivate::platform_theme)
|
||||
break;
|
||||
}
|
||||
|
||||
// 4) If no theme plugin was found ask the platform integration to
|
||||
// 5) If no theme plugin was found ask the platform integration to
|
||||
// create a theme
|
||||
if (!QGuiApplicationPrivate::platform_theme) {
|
||||
for (const QString &themeName : qAsConst(themeNames)) {
|
||||
@ -1199,7 +1214,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform
|
||||
// No error message; not having a theme plugin is allowed.
|
||||
}
|
||||
|
||||
// 5) Fall back on the built-in "null" platform theme.
|
||||
// 6) Fall back on the built-in "null" platform theme.
|
||||
if (!QGuiApplicationPrivate::platform_theme)
|
||||
QGuiApplicationPrivate::platform_theme = new QPlatformTheme;
|
||||
|
||||
|
3
src/plugins/platformthemes/flatpak/flatpak.json
Normal file
3
src/plugins/platformthemes/flatpak/flatpak.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"Keys": [ "flatpak" ]
|
||||
}
|
17
src/plugins/platformthemes/flatpak/flatpak.pro
Normal file
17
src/plugins/platformthemes/flatpak/flatpak.pro
Normal file
@ -0,0 +1,17 @@
|
||||
TARGET = qflatpak
|
||||
|
||||
PLUGIN_TYPE = platformthemes
|
||||
PLUGIN_EXTENDS = -
|
||||
PLUGIN_CLASS_NAME = QFlatpakThemePlugin
|
||||
load(qt_plugin)
|
||||
|
||||
QT += core-private dbus gui-private theme_support-private
|
||||
|
||||
HEADERS += \
|
||||
qflatpaktheme.h \
|
||||
qflatpakfiledialog_p.h
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
qflatpaktheme.cpp \
|
||||
qflatpakfiledialog.cpp
|
65
src/plugins/platformthemes/flatpak/main.cpp
Normal file
65
src/plugins/platformthemes/flatpak/main.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 Red Hat, Inc
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <qpa/qplatformthemeplugin.h>
|
||||
#include "qflatpaktheme.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QFlatpakThemePlugin : public QPlatformThemePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID QPlatformThemeFactoryInterface_iid FILE "flatpak.json")
|
||||
|
||||
public:
|
||||
QPlatformTheme *create(const QString &key, const QStringList ¶ms) override;
|
||||
};
|
||||
|
||||
QPlatformTheme *QFlatpakThemePlugin::create(const QString &key, const QStringList ¶ms)
|
||||
{
|
||||
Q_UNUSED(params);
|
||||
if (!key.compare(QLatin1String("flatpak"), Qt::CaseInsensitive))
|
||||
return new QFlatpakTheme;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "main.moc"
|
347
src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp
Normal file
347
src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp
Normal file
@ -0,0 +1,347 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 Red Hat, Inc
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qflatpakfiledialog_p.h"
|
||||
|
||||
#include <QtCore/qeventloop.h>
|
||||
|
||||
#include <QtDBus/QtDBus>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusPendingCall>
|
||||
#include <QDBusPendingCallWatcher>
|
||||
#include <QDBusPendingReply>
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QMimeType>
|
||||
#include <QMimeDatabase>
|
||||
#include <QWindow>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QDBusArgument &operator <<(QDBusArgument &arg, const QFlatpakFileDialog::FilterCondition &filterCondition)
|
||||
{
|
||||
arg.beginStructure();
|
||||
arg << filterCondition.type << filterCondition.pattern;
|
||||
arg.endStructure();
|
||||
return arg;
|
||||
}
|
||||
|
||||
const QDBusArgument &operator >>(const QDBusArgument &arg, QFlatpakFileDialog::FilterCondition &filterCondition)
|
||||
{
|
||||
uint type;
|
||||
QString filterPattern;
|
||||
arg.beginStructure();
|
||||
arg >> type >> filterPattern;
|
||||
filterCondition.type = (QFlatpakFileDialog::ConditionType)type;
|
||||
filterCondition.pattern = filterPattern;
|
||||
arg.endStructure();
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
QDBusArgument &operator <<(QDBusArgument &arg, const QFlatpakFileDialog::Filter filter)
|
||||
{
|
||||
arg.beginStructure();
|
||||
arg << filter.name << filter.filterConditions;
|
||||
arg.endStructure();
|
||||
return arg;
|
||||
}
|
||||
|
||||
const QDBusArgument &operator >>(const QDBusArgument &arg, QFlatpakFileDialog::Filter &filter)
|
||||
{
|
||||
QString name;
|
||||
QFlatpakFileDialog::FilterConditionList filterConditions;
|
||||
arg.beginStructure();
|
||||
arg >> name >> filterConditions;
|
||||
filter.name = name;
|
||||
filter.filterConditions = filterConditions;
|
||||
arg.endStructure();
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
class QFlatpakFileDialogPrivate
|
||||
{
|
||||
public:
|
||||
WId winId = 0;
|
||||
bool modal = false;
|
||||
bool multipleFiles = false;
|
||||
bool saveFile = false;
|
||||
QString acceptLabel;
|
||||
QString directory;
|
||||
QString title;
|
||||
QStringList nameFilters;
|
||||
QStringList mimeTypesFilters;
|
||||
QStringList selectedFiles;
|
||||
};
|
||||
|
||||
QFlatpakFileDialog::QFlatpakFileDialog()
|
||||
: QPlatformFileDialogHelper()
|
||||
, d_ptr(new QFlatpakFileDialogPrivate)
|
||||
{
|
||||
}
|
||||
|
||||
QFlatpakFileDialog::~QFlatpakFileDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void QFlatpakFileDialog::initializeDialog()
|
||||
{
|
||||
Q_D(QFlatpakFileDialog);
|
||||
|
||||
if (options()->fileMode() == QFileDialogOptions::ExistingFiles)
|
||||
d->multipleFiles = true;
|
||||
|
||||
if (options()->isLabelExplicitlySet(QFileDialogOptions::Accept))
|
||||
d->acceptLabel = options()->labelText(QFileDialogOptions::Accept);
|
||||
|
||||
if (!options()->windowTitle().isEmpty())
|
||||
d->title = options()->windowTitle();
|
||||
|
||||
if (options()->acceptMode() == QFileDialogOptions::AcceptSave)
|
||||
d->saveFile = true;
|
||||
|
||||
if (!options()->nameFilters().isEmpty())
|
||||
d->nameFilters = options()->nameFilters();
|
||||
|
||||
if (!options()->mimeTypeFilters().isEmpty())
|
||||
d->mimeTypesFilters = options()->mimeTypeFilters();
|
||||
|
||||
setDirectory(options()->initialDirectory());
|
||||
}
|
||||
|
||||
bool QFlatpakFileDialog::defaultNameFilterDisables() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void QFlatpakFileDialog::setDirectory(const QUrl &directory)
|
||||
{
|
||||
Q_D(QFlatpakFileDialog);
|
||||
|
||||
d->directory = directory.path();
|
||||
}
|
||||
|
||||
QUrl QFlatpakFileDialog::directory() const
|
||||
{
|
||||
Q_D(const QFlatpakFileDialog);
|
||||
|
||||
return d->directory;
|
||||
}
|
||||
|
||||
void QFlatpakFileDialog::selectFile(const QUrl &filename)
|
||||
{
|
||||
Q_D(QFlatpakFileDialog);
|
||||
|
||||
d->selectedFiles << filename.path();
|
||||
}
|
||||
|
||||
QList<QUrl> QFlatpakFileDialog::selectedFiles() const
|
||||
{
|
||||
Q_D(const QFlatpakFileDialog);
|
||||
|
||||
QList<QUrl> files;
|
||||
for (const QString &file : d->selectedFiles) {
|
||||
files << QUrl(file);
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
void QFlatpakFileDialog::setFilter()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void QFlatpakFileDialog::selectNameFilter(const QString &filter)
|
||||
{
|
||||
Q_UNUSED(filter);
|
||||
// TODO
|
||||
}
|
||||
|
||||
QString QFlatpakFileDialog::selectedNameFilter() const
|
||||
{
|
||||
// TODO
|
||||
return QString();
|
||||
}
|
||||
|
||||
void QFlatpakFileDialog::exec()
|
||||
{
|
||||
Q_D(const QFlatpakFileDialog);
|
||||
|
||||
QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.portal.Desktop"),
|
||||
QLatin1String("/org/freedesktop/portal/desktop"),
|
||||
QLatin1String("org.freedesktop.portal.FileChooser"),
|
||||
d->saveFile ? QLatin1String("SaveFile") : QLatin1String("OpenFile"));
|
||||
QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId);
|
||||
|
||||
QVariantMap options;
|
||||
if (!d->acceptLabel.isEmpty())
|
||||
options.insert(QLatin1String("accept_label"), d->acceptLabel);
|
||||
|
||||
options.insert(QLatin1String("modal"), d->modal);
|
||||
options.insert(QLatin1String("multiple"), d->multipleFiles);
|
||||
|
||||
if (d->saveFile) {
|
||||
if (!d->directory.isEmpty())
|
||||
options.insert(QLatin1String("current_folder"), d->directory.toLatin1());
|
||||
|
||||
if (!d->selectedFiles.isEmpty())
|
||||
options.insert(QLatin1String("current_file"), d->selectedFiles.first().toLatin1());
|
||||
}
|
||||
|
||||
// Insert filters
|
||||
qDBusRegisterMetaType<FilterCondition>();
|
||||
qDBusRegisterMetaType<FilterConditionList>();
|
||||
qDBusRegisterMetaType<Filter>();
|
||||
qDBusRegisterMetaType<FilterList>();
|
||||
|
||||
FilterList filterList;
|
||||
|
||||
if (!d->mimeTypesFilters.isEmpty()) {
|
||||
for (const QString &mimeTypefilter : d->mimeTypesFilters) {
|
||||
QMimeDatabase mimeDatabase;
|
||||
QMimeType mimeType = mimeDatabase.mimeTypeForName(mimeTypefilter);
|
||||
|
||||
// Creates e.g. (1, "image/png")
|
||||
FilterCondition filterCondition;
|
||||
filterCondition.type = MimeType;
|
||||
filterCondition.pattern = mimeTypefilter;
|
||||
|
||||
// Creates e.g. [((1, "image/png"))]
|
||||
FilterConditionList filterConditions;
|
||||
filterConditions << filterCondition;
|
||||
|
||||
// Creates e.g. [("Images", [((1, "image/png"))])]
|
||||
Filter filter;
|
||||
filter.name = mimeType.comment();
|
||||
filter.filterConditions = filterConditions;
|
||||
|
||||
filterList << filter;
|
||||
}
|
||||
} else if (!d->nameFilters.isEmpty()) {
|
||||
for (const QString &filter : d->nameFilters) {
|
||||
// Do parsing:
|
||||
// Supported format is ("Images (*.png *.jpg)")
|
||||
QRegularExpression regexp(QPlatformFileDialogHelper::filterRegExp);
|
||||
QRegularExpressionMatch match = regexp.match(filter);
|
||||
if (match.hasMatch()) {
|
||||
QString userVisibleName = match.captured(0);
|
||||
QStringList filterStrings = match.captured(1).split(QLatin1String(" "));
|
||||
|
||||
FilterConditionList filterConditions;
|
||||
for (const QString &filterString : filterStrings) {
|
||||
FilterCondition filterCondition;
|
||||
filterCondition.type = GlobalPattern;
|
||||
filterCondition.pattern = filterString;
|
||||
filterConditions << filterCondition;
|
||||
}
|
||||
|
||||
Filter filter;
|
||||
filter.name = userVisibleName;
|
||||
filter.filterConditions = filterConditions;
|
||||
|
||||
filterList << filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!filterList.isEmpty())
|
||||
options.insert(QLatin1String("filters"), QVariant::fromValue(filterList));
|
||||
|
||||
// TODO choices a(ssa(ss)s)
|
||||
// List of serialized combo boxes to add to the file chooser.
|
||||
|
||||
message << parentWindowId << d->title << options;
|
||||
|
||||
QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this] (QDBusPendingCallWatcher *watcher) {
|
||||
QDBusPendingReply<QDBusObjectPath> reply = *watcher;
|
||||
if (reply.isError()) {
|
||||
Q_EMIT reject();
|
||||
} else {
|
||||
QDBusConnection::sessionBus().connect(nullptr,
|
||||
reply.value().path(),
|
||||
QLatin1String("org.freedesktop.portal.Request"),
|
||||
QLatin1String("Response"),
|
||||
this,
|
||||
SLOT(gotResponse(uint,QVariantMap)));
|
||||
}
|
||||
});
|
||||
|
||||
// HACK we have to avoid returning until we emit that the dialog was accepted or rejected
|
||||
QEventLoop loop;
|
||||
loop.connect(this, SIGNAL(accept()), SLOT(quit()));
|
||||
loop.connect(this, SIGNAL(reject()), SLOT(quit()));
|
||||
loop.exec();
|
||||
}
|
||||
|
||||
void QFlatpakFileDialog::hide()
|
||||
{
|
||||
}
|
||||
|
||||
bool QFlatpakFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
|
||||
{
|
||||
Q_D(QFlatpakFileDialog);
|
||||
Q_UNUSED(windowFlags);
|
||||
|
||||
initializeDialog();
|
||||
|
||||
d->modal = windowModality != Qt::NonModal;
|
||||
d->winId = parent ? parent->winId() : 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QFlatpakFileDialog::gotResponse(uint response, const QVariantMap &results)
|
||||
{
|
||||
Q_D(QFlatpakFileDialog);
|
||||
|
||||
if (!response) {
|
||||
if (results.contains(QLatin1String("uris")))
|
||||
d->selectedFiles = results.value(QLatin1String("uris")).toStringList();
|
||||
|
||||
Q_EMIT accept();
|
||||
} else {
|
||||
Q_EMIT reject();
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
105
src/plugins/platformthemes/flatpak/qflatpakfiledialog_p.h
Normal file
105
src/plugins/platformthemes/flatpak/qflatpakfiledialog_p.h
Normal file
@ -0,0 +1,105 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 Red Hat, Inc
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#ifndef QFLATPAKFILEDIALOG_P_H
|
||||
#define QFLATPAKFILEDIALOG_P_H
|
||||
|
||||
#include <qpa/qplatformdialoghelper.h>
|
||||
#include <QVector>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QFlatpakFileDialogPrivate;
|
||||
|
||||
class QFlatpakFileDialog : public QPlatformFileDialogHelper
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(QFlatpakFileDialog)
|
||||
public:
|
||||
enum ConditionType {
|
||||
GlobalPattern = 0,
|
||||
MimeType = 1
|
||||
};
|
||||
// Filters a(sa(us))
|
||||
// Example: [('Images', [(0, '*.ico'), (1, 'image/png')]), ('Text', [(0, '*.txt')])]
|
||||
struct FilterCondition {
|
||||
ConditionType type;
|
||||
QString pattern; // E.g. '*ico' or 'image/png'
|
||||
};
|
||||
typedef QVector<FilterCondition> FilterConditionList;
|
||||
|
||||
struct Filter {
|
||||
QString name; // E.g. 'Images' or 'Text
|
||||
FilterConditionList filterConditions;; // E.g. [(0, '*.ico'), (1, 'image/png')] or [(0, '*.txt')]
|
||||
};
|
||||
typedef QVector<Filter> FilterList;
|
||||
|
||||
QFlatpakFileDialog();
|
||||
~QFlatpakFileDialog();
|
||||
|
||||
bool defaultNameFilterDisables() const override;
|
||||
QUrl directory() const override;
|
||||
void setDirectory(const QUrl &directory) override;
|
||||
void selectFile(const QUrl &filename) override;
|
||||
QList<QUrl> selectedFiles() const override;
|
||||
void setFilter() override;
|
||||
void selectNameFilter(const QString &filter) override;
|
||||
QString selectedNameFilter() const override;
|
||||
|
||||
void exec() override;
|
||||
bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override;
|
||||
void hide() override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void gotResponse(uint response, const QVariantMap &results);
|
||||
|
||||
private:
|
||||
void initializeDialog();
|
||||
|
||||
QScopedPointer<QFlatpakFileDialogPrivate> d_ptr;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
Q_DECLARE_METATYPE(QFlatpakFileDialog::FilterCondition);
|
||||
Q_DECLARE_METATYPE(QFlatpakFileDialog::FilterConditionList);
|
||||
Q_DECLARE_METATYPE(QFlatpakFileDialog::Filter);
|
||||
Q_DECLARE_METATYPE(QFlatpakFileDialog::FilterList);
|
||||
|
||||
#endif // QFLATPAKFILEDIALOG_P_H
|
||||
|
254
src/plugins/platformthemes/flatpak/qflatpaktheme.cpp
Normal file
254
src/plugins/platformthemes/flatpak/qflatpaktheme.cpp
Normal file
@ -0,0 +1,254 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qflatpaktheme.h"
|
||||
#include "qflatpakfiledialog_p.h"
|
||||
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <qpa/qplatformtheme_p.h>
|
||||
#include <qpa/qplatformthemefactory_p.h>
|
||||
#include <qpa/qplatformintegration.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QFlatpakThemePrivate : public QPlatformThemePrivate
|
||||
{
|
||||
public:
|
||||
QFlatpakThemePrivate()
|
||||
: QPlatformThemePrivate()
|
||||
{ }
|
||||
|
||||
~QFlatpakThemePrivate()
|
||||
{
|
||||
delete baseTheme;
|
||||
}
|
||||
|
||||
QPlatformTheme *baseTheme;
|
||||
};
|
||||
|
||||
QFlatpakTheme::QFlatpakTheme()
|
||||
: d_ptr(new QFlatpakThemePrivate)
|
||||
{
|
||||
Q_D(QFlatpakTheme);
|
||||
|
||||
QStringList themeNames;
|
||||
themeNames += QGuiApplicationPrivate::platform_integration->themeNames();
|
||||
// 1) Look for a theme plugin.
|
||||
for (const QString &themeName : qAsConst(themeNames)) {
|
||||
d->baseTheme = QPlatformThemeFactory::create(themeName, nullptr);
|
||||
if (d->baseTheme)
|
||||
break;
|
||||
}
|
||||
|
||||
// 2) If no theme plugin was found ask the platform integration to
|
||||
// create a theme
|
||||
if (!d->baseTheme) {
|
||||
for (const QString &themeName : qAsConst(themeNames)) {
|
||||
d->baseTheme = QGuiApplicationPrivate::platform_integration->createPlatformTheme(themeName);
|
||||
if (d->baseTheme)
|
||||
break;
|
||||
}
|
||||
// No error message; not having a theme plugin is allowed.
|
||||
}
|
||||
|
||||
// 3) Fall back on the built-in "null" platform theme.
|
||||
if (!d->baseTheme)
|
||||
d->baseTheme = new QPlatformTheme;
|
||||
}
|
||||
|
||||
QPlatformMenuItem* QFlatpakTheme::createPlatformMenuItem() const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->createPlatformMenuItem();
|
||||
|
||||
return QPlatformTheme::createPlatformMenuItem();
|
||||
}
|
||||
|
||||
QPlatformMenu* QFlatpakTheme::createPlatformMenu() const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->createPlatformMenu();
|
||||
|
||||
return QPlatformTheme::createPlatformMenu();
|
||||
}
|
||||
|
||||
QPlatformMenuBar* QFlatpakTheme::createPlatformMenuBar() const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->createPlatformMenuBar();
|
||||
|
||||
return QFlatpakTheme::createPlatformMenuBar();
|
||||
}
|
||||
|
||||
void QFlatpakTheme::showPlatformMenuBar()
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->showPlatformMenuBar();
|
||||
|
||||
return QFlatpakTheme::showPlatformMenuBar();
|
||||
}
|
||||
|
||||
bool QFlatpakTheme::usePlatformNativeDialog(DialogType type) const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (type == FileDialog)
|
||||
return true;
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->usePlatformNativeDialog(type);
|
||||
|
||||
return QFlatpakTheme::usePlatformNativeDialog(type);
|
||||
}
|
||||
|
||||
QPlatformDialogHelper* QFlatpakTheme::createPlatformDialogHelper(DialogType type) const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (type == FileDialog)
|
||||
return new QFlatpakFileDialog;
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->createPlatformDialogHelper(type);
|
||||
|
||||
return QFlatpakTheme::createPlatformDialogHelper(type);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_SYSTEMTRAYICON
|
||||
QPlatformSystemTrayIcon* QFlatpakTheme::createPlatformSystemTrayIcon() const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->createPlatformSystemTrayIcon();
|
||||
|
||||
return QPlatformTheme::createPlatformSystemTrayIcon();
|
||||
}
|
||||
#endif
|
||||
|
||||
const QPalette *QFlatpakTheme::palette(Palette type) const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->palette(type);
|
||||
|
||||
return QPlatformTheme::palette(type);
|
||||
}
|
||||
|
||||
const QFont* QFlatpakTheme::font(Font type) const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->font(type);
|
||||
|
||||
return QPlatformTheme::font(type);
|
||||
}
|
||||
|
||||
QVariant QFlatpakTheme::themeHint(ThemeHint hint) const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->themeHint(hint);
|
||||
|
||||
return QPlatformTheme::themeHint(hint);
|
||||
}
|
||||
|
||||
QPixmap QFlatpakTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->standardPixmap(sp, size);
|
||||
|
||||
return QPlatformTheme::standardPixmap(sp, size);
|
||||
}
|
||||
|
||||
QIcon QFlatpakTheme::fileIcon(const QFileInfo &fileInfo,
|
||||
QPlatformTheme::IconOptions iconOptions) const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->fileIcon(fileInfo, iconOptions);
|
||||
|
||||
return QPlatformTheme::fileIcon(fileInfo, iconOptions);
|
||||
}
|
||||
|
||||
QIconEngine * QFlatpakTheme::createIconEngine(const QString &iconName) const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->createIconEngine(iconName);
|
||||
|
||||
return QPlatformTheme::createIconEngine(iconName);
|
||||
}
|
||||
|
||||
QList<QKeySequence> QFlatpakTheme::keyBindings(QKeySequence::StandardKey key) const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->keyBindings(key);
|
||||
|
||||
return QPlatformTheme::keyBindings(key);
|
||||
}
|
||||
|
||||
QString QFlatpakTheme::standardButtonText(int button) const
|
||||
{
|
||||
Q_D(const QFlatpakTheme);
|
||||
|
||||
if (d->baseTheme)
|
||||
return d->baseTheme->standardButtonText(button);
|
||||
|
||||
return QPlatformTheme::standardButtonText(button);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
90
src/plugins/platformthemes/flatpak/qflatpaktheme.h
Normal file
90
src/plugins/platformthemes/flatpak/qflatpaktheme.h
Normal file
@ -0,0 +1,90 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QFLATPAKTHEME_H
|
||||
#define QFLATPAKTHEME_H
|
||||
|
||||
#include <qpa/qplatformtheme.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QFlatpakThemePrivate;
|
||||
|
||||
class QFlatpakTheme : public QPlatformTheme
|
||||
{
|
||||
Q_DECLARE_PRIVATE(QFlatpakTheme)
|
||||
public:
|
||||
QFlatpakTheme();
|
||||
|
||||
QPlatformMenuItem *createPlatformMenuItem() const override;
|
||||
QPlatformMenu *createPlatformMenu() const override;
|
||||
QPlatformMenuBar *createPlatformMenuBar() const override;
|
||||
void showPlatformMenuBar() override;
|
||||
|
||||
bool usePlatformNativeDialog(DialogType type) const override;
|
||||
QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override;
|
||||
|
||||
#ifndef QT_NO_SYSTEMTRAYICON
|
||||
QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const override;
|
||||
#endif
|
||||
|
||||
const QPalette *palette(Palette type = SystemPalette) const override;
|
||||
|
||||
const QFont *font(Font type = SystemFont) const override;
|
||||
|
||||
QVariant themeHint(ThemeHint hint) const override;
|
||||
|
||||
QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override;
|
||||
QIcon fileIcon(const QFileInfo &fileInfo,
|
||||
QPlatformTheme::IconOptions iconOptions = 0) const;
|
||||
|
||||
QIconEngine *createIconEngine(const QString &iconName) const override;
|
||||
|
||||
QList<QKeySequence> keyBindings(QKeySequence::StandardKey key) const override;
|
||||
|
||||
QString standardButtonText(int button) const override;
|
||||
|
||||
private:
|
||||
QScopedPointer<QFlatpakThemePrivate> d_ptr;
|
||||
Q_DISABLE_COPY(QFlatpakTheme)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QFLATPAKTHEME_H
|
@ -1,4 +1,6 @@
|
||||
TEMPLATE = subdirs
|
||||
QT_FOR_CONFIG += widgets-private
|
||||
|
||||
qtConfig(dbus): SUBDIRS += flatpak
|
||||
|
||||
qtHaveModule(widgets):qtConfig(gtk3): SUBDIRS += gtk3
|
||||
|
Loading…
Reference in New Issue
Block a user