Commit 7835604c authored by Jan Grulich's avatar Jan Grulich

AppChooser portal: implement UpdateChoices()

parent 1d909d13
/*
* Copyright © 2016 Red Hat, Inc
* Copyright © 2016-2018 Red Hat, Inc
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
......@@ -26,7 +26,6 @@
Q_LOGGING_CATEGORY(XdgDesktopPortalKdeAppChooser, "xdp-kde-app-chooser")
AppChooserPortal::AppChooserPortal(QObject *parent)
: QDBusAbstractAdaptor(parent)
{
......@@ -37,11 +36,11 @@ AppChooserPortal::~AppChooserPortal()
}
uint AppChooserPortal::ChooseApplication(const QDBusObjectPath &handle,
const QString &app_id,
const QString &parent_window,
const QStringList &choices,
const QVariantMap &options,
QVariantMap &results)
const QString &app_id,
const QString &parent_window,
const QStringList &choices,
const QVariantMap &options,
QVariantMap &results)
{
qCDebug(XdgDesktopPortalKdeAppChooser) << "ChooseApplication called with parameters:";
qCDebug(XdgDesktopPortalKdeAppChooser) << " handle: " << handle.path();
......@@ -57,13 +56,27 @@ uint AppChooserPortal::ChooseApplication(const QDBusObjectPath &handle,
}
AppChooserDialog *appDialog = new AppChooserDialog(choices, latestChoice, options.value(QLatin1String("filename")).toString());
m_appChooserDialogs.insert(handle.path(), appDialog);
int result = appDialog->exec();
if (appDialog->exec()) {
if (result) {
results.insert(QLatin1String("choice"), appDialog->selectedApplication());
appDialog->deleteLater();
return 0;
}
m_appChooserDialogs.remove(handle.path());
appDialog->deleteLater();
return 1;
return !result;
}
void AppChooserPortal::UpdateChoices(const QDBusObjectPath &handle, const QStringList &choices)
{
qCDebug(XdgDesktopPortalKdeAppChooser) << "UpdateChoices called with parameters:";
qCDebug(XdgDesktopPortalKdeAppChooser) << " handle: " << handle.path();
qCDebug(XdgDesktopPortalKdeAppChooser) << " choices: " << choices;
if (m_appChooserDialogs.contains(handle.path())) {
m_appChooserDialogs.value(handle.path())->updateChoices(choices);
}
}
/*
* Copyright © 2016 Red Hat, Inc
* Copyright © 2016-2018 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -24,6 +24,8 @@
#include <QDBusAbstractAdaptor>
#include <QDBusObjectPath>
class AppChooserDialog;
class AppChooserPortal : public QDBusAbstractAdaptor
{
Q_OBJECT
......@@ -39,6 +41,11 @@ public Q_SLOTS:
const QStringList &choices,
const QVariantMap &options,
QVariantMap &results);
void UpdateChoices(const QDBusObjectPath &handle,
const QStringList &choices);
private:
QMap<QString, AppChooserDialog*> m_appChooserDialogs;
};
#endif // XDG_DESKTOP_PORTAL_KDE_APPCHOOSER_H
......
/*
* Copyright © 2017 Red Hat, Inc
* Copyright © 2017-2018 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -25,6 +25,7 @@
#include <QGridLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QLayoutItem>
#include <QLoggingCategory>
#include <KLocalizedString>
#include <QSettings>
......@@ -36,6 +37,8 @@ Q_LOGGING_CATEGORY(XdgDesktopPortalKdeAppChooserDialog, "xdp-kde-app-chooser-dia
AppChooserDialog::AppChooserDialog(const QStringList &choices, const QString &defaultApp, const QString &fileName, QDialog *parent, Qt::WindowFlags flags)
: QDialog(parent, flags)
, m_choices(choices)
, m_defaultApp(defaultApp)
{
setMinimumWidth(640);
......@@ -56,33 +59,100 @@ AppChooserDialog::AppChooserDialog(const QStringList &choices, const QString &de
vboxLayout->addWidget(label);
QGridLayout *gridLayout = new QGridLayout();
m_gridLayout = new QGridLayout();
addDialogItems();
vboxLayout->addLayout(m_gridLayout);
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel, this);
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
vboxLayout->addWidget(buttonBox, 0, Qt::AlignBottom | Qt::AlignRight);
setLayout(vboxLayout);
setWindowTitle(i18n("Open with"));
}
AppChooserDialog::~AppChooserDialog()
{
delete m_gridLayout;
}
void AppChooserDialog::updateChoices(const QStringList &choices)
{
bool changed = false;
// Check if we will be adding something
for (const QString &choice : choices) {
if (!m_choices.contains(choice)) {
changed = true;
m_choices << choice;
}
}
// Check if we will be removing something
for (const QString &choice : m_choices) {
if (!choices.contains(choice)) {
changed = true;
m_choices.removeAll(choice);
}
}
// If something changed, clear the layout and add the items again
if (changed) {
int rowCount = m_gridLayout->rowCount();
int columnCount = m_gridLayout->columnCount();
for (int i = 0; i < rowCount; ++i) {
for (int j = 0; j < columnCount; ++j) {
QLayoutItem *item = m_gridLayout->itemAtPosition(i, j);
if (item) {
QWidget *widget = item->widget();
if (widget) {
m_gridLayout->removeWidget(widget);
widget->deleteLater();
}
}
}
}
addDialogItems();
}
}
QString AppChooserDialog::selectedApplication() const
{
return m_selectedApplication;
}
void AppChooserDialog::addDialogItems()
{
int i = 0, j = 0;
foreach (const QString &choice, choices) {
const QString desktopFile = choice + QLatin1String(".desktop");
for (const QString &choice : m_choices) {
const QString desktopFile = choice + QStringLiteral(".desktop");
const QStringList desktopFilesLocations = QStandardPaths::locateAll(QStandardPaths::ApplicationsLocation, desktopFile, QStandardPaths::LocateFile);
foreach (const QString desktopFile, desktopFilesLocations) {
for (const QString &desktopFile : desktopFilesLocations) {
QString applicationIcon;
QString applicationName;
QSettings settings(desktopFile, QSettings::IniFormat);
settings.beginGroup(QLatin1String("Desktop Entry"));
if (settings.contains(QLatin1String("X-GNOME-FullName"))) {
applicationName = settings.value(QLatin1String("X-GNOME-FullName")).toString();
settings.beginGroup(QStringLiteral("Desktop Entry"));
if (settings.contains(QStringLiteral("X-GNOME-FullName"))) {
applicationName = settings.value(QStringLiteral("X-GNOME-FullName")).toString();
} else {
applicationName = settings.value(QLatin1String("Name")).toString();
applicationName = settings.value(QStringLiteral("Name")).toString();
}
applicationIcon = settings.value(QLatin1String("Icon")).toString();
applicationIcon = settings.value(QStringLiteral("Icon")).toString();
AppChooserDialogItem *item = new AppChooserDialogItem(applicationName, applicationIcon, choice);
gridLayout->addWidget(item, i, j++, Qt::AlignHCenter);
AppChooserDialogItem *item = new AppChooserDialogItem(applicationName, applicationIcon, choice, this);
m_gridLayout->addWidget(item, i, j++, Qt::AlignHCenter);
connect(item, &AppChooserDialogItem::doubleClicked, this, [this] (const QString &selectedApplication) {
m_selectedApplication = selectedApplication;
QDialog::accept();
});
if (choice == defaultApp) {
if (choice == m_defaultApp) {
item->setDown(true);
item->setChecked(true);
}
......@@ -93,23 +163,4 @@ AppChooserDialog::AppChooserDialog(const QStringList &choices, const QString &de
}
}
}
vboxLayout->addLayout(gridLayout);
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel, this);
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
vboxLayout->addWidget(buttonBox, 0, Qt::AlignBottom | Qt::AlignRight);
setLayout(vboxLayout);
setWindowTitle(i18n("Open with"));
}
AppChooserDialog::~AppChooserDialog()
{
}
QString AppChooserDialog::selectedApplication() const
{
return m_selectedApplication;
}
/*
* Copyright © 2016 Red Hat, Inc
* Copyright © 2016-2018 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -24,6 +24,9 @@
#include <QAbstractListModel>
#include <QDialog>
class AppChooserDialogItem;
class QGridLayout;
class AppChooserDialog : public QDialog
{
Q_OBJECT
......@@ -31,11 +34,17 @@ public:
AppChooserDialog(const QStringList &choices, const QString &defaultApp, const QString &fileName, QDialog *parent = nullptr, Qt::WindowFlags flags = {});
~AppChooserDialog();
void updateChoices(const QStringList &choices);
QString selectedApplication() const;
private:
QString m_selectedApplication;
void addDialogItems();
QStringList m_choices;
QString m_defaultApp;
QString m_selectedApplication;
QGridLayout *m_gridLayout;
};
#endif // XDG_DESKTOP_PORTAL_KDE_APPCHOOSER_DIALOG_H
......
......@@ -26,7 +26,7 @@
#include <QDebug>
AppChooserDialogItem::AppChooserDialogItem(const QString &applicationName, const QString &icon, const QString &applicationExec, QToolButton *parent)
AppChooserDialogItem::AppChooserDialogItem(const QString &applicationName, const QString &icon, const QString &applicationExec, QWidget *parent)
: QToolButton(parent)
, m_applicationName(applicationExec)
{
......
......@@ -29,7 +29,7 @@ class AppChooserDialogItem : public QToolButton
{
Q_OBJECT
public:
explicit AppChooserDialogItem(const QString &applicationName, const QString &icon, const QString &applicationExec, QToolButton *parent = nullptr);
explicit AppChooserDialogItem(const QString &applicationName, const QString &icon, const QString &applicationExec, QWidget *parent = nullptr);
~AppChooserDialogItem() override;
QString applicationName() const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment