Use KPluginTrader to find the effect configuration and show it

The model data contains a new role ConfigurableRole. This is used to
decide whether the configure button is available.

The value for the role is set by searching for a KPlugin which has the
effect's service name as X-KDE-ParentComponents. All available configs
are expected to be in kf5/kwin/effects/configs/ and are located through
the KPluginTrader thus binary effect configs need to provide json meta
data.

REVIEW: 116855
This commit is contained in:
Martin Gräßlin 2014-03-17 13:13:17 +01:00
parent e5ef7602ba
commit ca725b437f
5 changed files with 36 additions and 41 deletions

View file

@ -20,9 +20,8 @@
#include "effectconfig.h"
#include <KCModuleProxy>
#include <KPluginInfo>
#include <KServiceTypeTrader>
#include <KCModule>
#include <KPluginTrader>
#include <KNS3/DownloadDialog>
@ -41,48 +40,33 @@ EffectConfig::EffectConfig(QObject *parent)
{
}
bool EffectConfig::effectUiConfigExists(const QString &serviceName)
{
//Our effect UI config is something like showfps_config.desktop
QString tmp = serviceName;
const QString effectConfig = tmp.remove("kwin4_effect_") + "_config.desktop";
QString effectConfigFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kde5/services/kwin/" + effectConfig , QStandardPaths::LocateFile);
return !effectConfigFile.isEmpty();
}
void EffectConfig::openConfig(const QString &effectName)
void EffectConfig::openConfig(const QString &serviceName)
{
//setup the UI
QDialog dialog;
QVBoxLayout layout;
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
// create the KCModule through the plugintrader
KCModule *kcm = KPluginTrader::createInstanceFromQuery<KCModule>(QStringLiteral("kf5/kwin/effects/configs/"), QString(),
QStringLiteral("[X-KDE-ParentComponents] == '%1'").arg(serviceName),
&dialog);
if (!kcm) {
return;
}
connect(&dialog, &QDialog::accepted, kcm, &KCModule::save);
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog);
buttons->setCenterButtons(true);
//Here we connect our buttons with the dialog
connect(buttons, SIGNAL(QDialogButtonBox::accepted), &dialog, SLOT(QDialog::accept));
connect(buttons, SIGNAL(rejected()), &dialog, SLOT(reject()));
connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
KService::List offers = KServiceTypeTrader::self()->query("KWin/Effect");
for(KService::Ptr service : offers) {
const QString effectPluginPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kde5/services/"+ service->entryPath(), QStandardPaths::LocateFile);
KPluginInfo plugin(effectPluginPath);
if (plugin.name() == effectName) {
QString effectConfig = effectName.toLower().remove(" ") + "_config";
KCModuleProxy *proxy = new KCModuleProxy(effectConfig);
//setup the Layout of our UI
layout.addWidget(proxy);
layout.addWidget(buttons);
dialog.setLayout(&layout);
//open the dialog
if (dialog.exec() == QDialog::Accepted) {
proxy->save();
}
}
}
QVBoxLayout *layout = new QVBoxLayout(&dialog);
layout->addWidget(kcm);
layout->addWidget(buttons);
dialog.exec();
}
void EffectConfig::openGHNS()

View file

@ -36,7 +36,6 @@ public:
explicit EffectConfig(QObject *parent = 0);
QString serviceName(const QString &serviceName);
Q_INVOKABLE bool effectUiConfigExists(const QString &effectName);
Q_INVOKABLE void openConfig(const QString &effectName);
Q_INVOKABLE void openGHNS();

View file

@ -28,6 +28,7 @@
#include <KServiceTypeTrader>
#include <KSharedConfig>
#include <KCModuleProxy>
#include <KPluginTrader>
#include <QAbstractItemModel>
#include <QDBusConnection>
@ -67,6 +68,7 @@ QHash< int, QByteArray > EffectModel::roleNames() const
roleNames[VideoRole] = "VideoRole";
roleNames[SupportedRole] = "SupportedRole";
roleNames[ExclusiveRole] = "ExclusiveRole";
roleNames[ConfigurableRole] = "ConfigurableRole";
return roleNames;
}
@ -135,6 +137,8 @@ QVariant EffectModel::data(const QModelIndex &index, int role) const
return m_effectsList.at(index.row()).exclusiveGroup;
case InternalRole:
return m_effectsList.at(index.row()).internal;
case ConfigurableRole:
return m_effectsList.at(index.row()).configurable;
default:
return QVariant();
}
@ -184,6 +188,7 @@ void EffectModel::loadEffects()
m_effectsChanged.clear();
m_effectsList.clear();
KService::List offers = KServiceTypeTrader::self()->query("KWin/Effect");
const KPluginInfo::List configs = KPluginTrader::self()->query(QStringLiteral("kf5/kwin/effects/configs/"));
for(KService::Ptr service : offers) {
const QString effectPluginPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kde5/services/"+ service->entryPath(), QStandardPaths::LocateFile);
KPluginInfo plugin(effectPluginPath);
@ -203,6 +208,11 @@ void EffectModel::loadEffects()
effect.exclusiveGroup = service->property(QStringLiteral("X-KWin-Exclusive-Category"), QVariant::String).toString();
effect.internal = service->property(QStringLiteral("X-KWin-Internal"), QVariant::Bool).toBool();
auto it = std::find_if(configs.begin(), configs.end(), [&plugin](const KPluginInfo &info) {
return info.property(QStringLiteral("X-KDE-ParentComponents")).toString() == plugin.pluginName();
});
effect.configurable = it != configs.end();
m_effectsList << effect;
}

View file

@ -49,6 +49,7 @@ struct EffectData {
bool supported;
QString exclusiveGroup;
bool internal;
bool configurable;
};
class EffectModel : public QAbstractItemModel
@ -71,7 +72,8 @@ public:
VideoRole,
SupportedRole,
ExclusiveRole,
InternalRole
InternalRole,
ConfigurableRole
};
explicit EffectModel(QObject *parent = 0);

View file

@ -126,11 +126,11 @@ Rectangle {
}
Button {
id: configureButton
visible: effectConfig.effectUiConfigExists(model.ServiceNameRole)
visible: ConfigurableRole
enabled: effectStatusCheckBox.checked
iconName: "configure"
onClicked: {
effectConfig.openConfig(model.NameRole);
effectConfig.openConfig(model.ServiceNameRole);
}
}