[kcmkwin] Add requestConfigure to effects model

Summary:
The main motivation for adding this method is to avoid code duplication.
Both virtual desktops kcm and desktop effects kcm have their own logic
to create configuration dialogs for effects.

On the bright side, if we add support for declarative effect kcms, we
will need to change only this method.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D18704
This commit is contained in:
Vlad Zagorodniy 2019-02-03 17:18:42 +02:00
parent 2211a951e7
commit 1faa861bd5
4 changed files with 91 additions and 126 deletions

View file

@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <kwin_effects_interface.h>
#include <KAboutData>
#include <KCModule>
#include <KLocalizedString>
#include <KPackage/PackageLoader>
#include <KPluginLoader>
@ -36,6 +37,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QDBusInterface>
#include <QDBusMessage>
#include <QDBusPendingCall>
#include <QDialog>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QVBoxLayout>
namespace KWin
{
@ -536,6 +541,78 @@ QModelIndex EffectModel::findByPluginId(const QString &pluginId) const
return index(std::distance(m_effectsList.constBegin(), it), 0);
}
static KCModule *findBinaryConfig(const QString &pluginId, QObject *parent)
{
return KPluginTrader::createInstanceFromQuery<KCModule>(
QStringLiteral("kwin/effects/configs/"),
QString(),
QStringLiteral("'%1' in [X-KDE-ParentComponents]").arg(pluginId),
parent
);
}
static KCModule *findScriptedConfig(const QString &pluginId, QObject *parent)
{
const auto offers = KPluginTrader::self()->query(
QStringLiteral("kwin/effects/configs/"),
QString(),
QStringLiteral("[X-KDE-Library] == 'kcm_kwin4_genericscripted'")
);
if (offers.isEmpty()) {
return nullptr;
}
const KPluginInfo &generic = offers.first();
KPluginLoader loader(generic.libraryPath());
KPluginFactory *factory = loader.factory();
if (!factory) {
return nullptr;
}
return factory->create<KCModule>(pluginId, parent);
}
void EffectModel::requestConfigure(const QModelIndex &index, QWindow *transientParent)
{
if (!index.isValid()) {
return;
}
QPointer<QDialog> dialog = new QDialog();
KCModule *module = index.data(ScriptedRole).toBool()
? findScriptedConfig(index.data(ServiceNameRole).toString(), dialog)
: findBinaryConfig(index.data(ServiceNameRole).toString(), dialog);
if (!module) {
delete dialog;
return;
}
dialog->setWindowTitle(index.data(NameRole).toString());
dialog->winId();
dialog->windowHandle()->setTransientParent(transientParent);
auto buttons = new QDialogButtonBox(
QDialogButtonBox::Ok |
QDialogButtonBox::Cancel |
QDialogButtonBox::RestoreDefaults,
dialog
);
connect(buttons, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
connect(buttons->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked,
module, &KCModule::defaults);
auto layout = new QVBoxLayout(dialog);
layout->addWidget(module);
layout->addWidget(buttons);
dialog->exec();
delete dialog;
}
bool EffectModel::shouldStore(const EffectData &data) const
{
Q_UNUSED(data)

View file

@ -29,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QAbstractItemModel>
#include <QString>
#include <QUrl>
#include <QWindow>
namespace KWin
{
@ -187,6 +188,14 @@ public:
**/
QModelIndex findByPluginId(const QString &pluginId) const;
/**
* Shows a configuration dialog for a given effect.
*
* @param index An effect represented by the given index.
* @param transientParent The transient parent of the configuration dialog.
**/
void requestConfigure(const QModelIndex &index, QWindow *transientParent);
protected:
enum class Kind {
BuiltIn,

View file

@ -22,16 +22,8 @@
#include <KAboutApplicationDialog>
#include <KAboutData>
#include <KCModule>
#include <KConfigGroup>
#include <KLocalizedString>
#include <KPluginFactory>
#include <KPluginTrader>
#include <QDialog>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QVBoxLayout>
K_PLUGIN_FACTORY_WITH_JSON(VirtualDesktopsFactory, "kcm_kwin_virtualdesktops.json", registerPlugin<KWin::VirtualDesktops>();)
@ -198,50 +190,7 @@ void VirtualDesktops::configureAnimation()
return;
}
const QString name = index.data(AnimationsModel::NameRole).toString();
const QString serviceName = index.data(AnimationsModel::ServiceNameRole).toString();
QPointer<QDialog> configDialog = new QDialog();
KCModule *kcm = KPluginTrader::createInstanceFromQuery<KCModule>(
QStringLiteral("kwin/effects/configs/"),
QString(),
QStringLiteral("'%1' in [X-KDE-ParentComponents]").arg(serviceName),
configDialog
);
if (!kcm) {
delete configDialog;
return;
}
configDialog->setWindowTitle(name);
configDialog->setLayout(new QVBoxLayout);
auto buttons = new QDialogButtonBox(
QDialogButtonBox::Ok |
QDialogButtonBox::Cancel |
QDialogButtonBox::RestoreDefaults,
configDialog
);
QObject::connect(buttons, &QDialogButtonBox::accepted, configDialog, &QDialog::accept);
QObject::connect(buttons, &QDialogButtonBox::rejected, configDialog, &QDialog::reject);
QObject::connect(buttons->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, kcm, &KCModule::defaults);
auto showWidget = new QWidget(configDialog);
auto layout = new QVBoxLayout;
showWidget->setLayout(layout);
layout->addWidget(kcm);
configDialog->layout()->addWidget(showWidget);
configDialog->layout()->addWidget(buttons);
if (configDialog->exec() == QDialog::Accepted) {
kcm->save();
} else if (!configDialog.isNull()) {
kcm->load();
}
delete configDialog;
m_animationsModel->requestConfigure(index, nullptr);
}
void VirtualDesktops::showAboutAnimation()

View file

@ -20,16 +20,10 @@
#include "effectsfilterproxymodel.h"
#include <KAboutData>
#include <KCModule>
#include <KLocalizedString>
#include <KNS3/DownloadDialog>
#include <KPluginFactory>
#include <KPluginTrader>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QQuickWindow>
#include <QVBoxLayout>
#include <QWindow>
K_PLUGIN_FACTORY_WITH_JSON(DesktopEffectsKCMFactory,
@ -106,80 +100,16 @@ void DesktopEffectsKCM::openGHNS(QQuickItem *context)
delete dialog;
}
static KCModule *findBinaryConfig(const QString &pluginId, QObject *parent)
{
return KPluginTrader::createInstanceFromQuery<KCModule>(
QStringLiteral("kwin/effects/configs/"),
QString(),
QStringLiteral("'%1' in [X-KDE-ParentComponents]").arg(pluginId),
parent
);
}
static KCModule *findScriptedConfig(const QString &pluginId, QObject *parent)
{
const auto offers = KPluginTrader::self()->query(
QStringLiteral("kwin/effects/configs/"),
QString(),
QStringLiteral("[X-KDE-Library] == 'kcm_kwin4_genericscripted'")
);
if (offers.isEmpty()) {
return nullptr;
}
const KPluginInfo &generic = offers.first();
KPluginLoader loader(generic.libraryPath());
KPluginFactory *factory = loader.factory();
if (!factory) {
return nullptr;
}
return factory->create<KCModule>(pluginId, parent);
}
void DesktopEffectsKCM::configure(const QString &pluginId, QQuickItem *context)
{
const QModelIndex idx = m_model->findByPluginId(pluginId);
if (!idx.isValid()) {
return;
}
QPointer<QDialog> dialog = new QDialog();
KCModule *module = idx.data(EffectModel::ScriptedRole).toBool()
? findScriptedConfig(pluginId, dialog)
: findBinaryConfig(pluginId, dialog);
if (!module) {
delete dialog;
return;
}
dialog->setWindowTitle(idx.data(EffectModel::NameRole).toString());
dialog->winId();
auto buttons = new QDialogButtonBox(
QDialogButtonBox::Ok |
QDialogButtonBox::Cancel |
QDialogButtonBox::RestoreDefaults,
dialog
);
connect(buttons, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
connect(buttons->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked,
module, &KCModule::defaults);
auto layout = new QVBoxLayout(dialog);
layout->addWidget(module);
layout->addWidget(buttons);
const QModelIndex index = m_model->findByPluginId(pluginId);
QWindow *transientParent = nullptr;
if (context && context->window()) {
dialog->windowHandle()->setTransientParent(context->window());
transientParent = context->window();
}
dialog->exec();
delete dialog;
m_model->requestConfigure(index, transientParent);
}
void DesktopEffectsKCM::updateNeedsSave()