From 493196dff38c4db5b8cdceb10cd4cdad3d445966 Mon Sep 17 00:00:00 2001 From: Chani Armitage Date: Mon, 17 Aug 2009 22:30:34 +0000 Subject: [PATCH] use contextaction plugins. there are a few defaults, only one real plugin exists so far rightclicks are still overridden by the contextmenu event. the user is warned about plugins that need configuring. svn path=/trunk/KDE/kdelibs/; revision=1012636 --- containment.cpp | 157 +++++++++++++++++++++++++++++++++++----- containment.h | 9 +++ private/containment_p.h | 8 ++ 3 files changed, 154 insertions(+), 20 deletions(-) diff --git a/containment.cpp b/containment.cpp index 0eb2b23ad..36c9617c6 100644 --- a/containment.cpp +++ b/containment.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #include "animator.h" #include "context.h" +#include "contextaction.h" #include "corona.h" #include "extenderitem.h" #include "svg.h" @@ -225,6 +227,22 @@ void Containment::init() } } + //contextactions, from config or defaults + KConfigGroup cfg(&config(), "ContextActions"); + if (cfg.exists()) { + foreach (const QString &key, cfg.keyList()) { + setContextAction(key, cfg.readEntry(key, QString())); + } + } else { + if (d->type == DesktopContainment) { + setContextAction("wheel:Vertical;NoModifier", "switchdesktop"); + setContextAction("wheel:Horizontal;ControlModifier", "test"); + setContextAction("LeftButton;NoModifier", "switchdesktop"); + setContextAction("RightButton;NoModifier", "test"); + } + //TODO defaults for panel etc. + } + } void ContainmentPrivate::addDefaultActions(KActionCollection *actions) @@ -467,7 +485,25 @@ void Containment::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void Containment::mousePressEvent(QGraphicsSceneMouseEvent *event) { event->ignore(); - if (d->wallpaper && d->wallpaper->isInitialized()) { + + int m = QObject::staticQtMetaObject.indexOfEnumerator("MouseButtons"); + int k = QObject::staticQtMetaObject.indexOfEnumerator("KeyboardModifiers"); + QMetaEnum mouse = QObject::staticQtMetaObject.enumerator(m); + QMetaEnum kbd = QObject::staticQtMetaObject.enumerator(k); + + QString context; + context += mouse.valueToKey(event->button()); + context += ";"; + context += kbd.valueToKeys(event->modifiers()); + kDebug() << context; + + //FIXME what if someone changes the modifiers before the mouseup? + if (d->contextActions.contains(context)) { + kDebug() << "accepted mousedown"; + event->accept(); + } + + if (d->wallpaper && d->wallpaper->isInitialized() && !event->isAccepted()) { QGraphicsItem *item = scene()->itemAt(event->scenePos()); if (item == this) { d->wallpaper->mousePressEvent(event); @@ -488,6 +524,26 @@ void Containment::mousePressEvent(QGraphicsSceneMouseEvent *event) void Containment::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { event->ignore(); + + int m = QObject::staticQtMetaObject.indexOfEnumerator("MouseButtons"); + int k = QObject::staticQtMetaObject.indexOfEnumerator("KeyboardModifiers"); + QMetaEnum mouse = QObject::staticQtMetaObject.enumerator(m); + QMetaEnum kbd = QObject::staticQtMetaObject.enumerator(k); + + QString context; + context += mouse.valueToKey(event->button()); + context += ";"; + context += kbd.valueToKeys(event->modifiers()); + kDebug() << context; + + if (d->contextActions.contains(context)) { + if (d->prepareContextAction(context, event->screenPos())) { + d->contextActions.value(context)->contextEvent(event); + } + event->accept(); + return; + } + if (d->wallpaper && d->wallpaper->isInitialized()) { QGraphicsItem *item = scene()->itemAt(event->scenePos()); if (item == this) { @@ -1354,6 +1410,25 @@ void Containment::keyPressEvent(QKeyEvent *event) void Containment::wheelEvent(QGraphicsSceneWheelEvent *event) { + int o = QObject::staticQtMetaObject.indexOfEnumerator("Orientations"); + int k = QObject::staticQtMetaObject.indexOfEnumerator("KeyboardModifiers"); + QMetaEnum orient = QObject::staticQtMetaObject.enumerator(o); + QMetaEnum kbd = QObject::staticQtMetaObject.enumerator(k); + + QString context = "wheel:"; + context += orient.valueToKey(event->orientation()); + context += ";"; + context += kbd.valueToKeys(event->modifiers()); + kDebug() << context; + + if (d->contextActions.contains(context)) { + if (d->prepareContextAction(context, event->screenPos())) { + d->contextActions.value(context)->wheelEvent(event); + } + event->accept(); + return; + } + if (d->wallpaper && d->wallpaper->isInitialized()) { QGraphicsItem *item = scene()->itemAt(event->scenePos()); if (item == this) { @@ -1363,25 +1438,6 @@ void Containment::wheelEvent(QGraphicsSceneWheelEvent *event) if (event->isAccepted()) { return; } - - event->accept(); - } - } - - if (d->type == DesktopContainment) { - QGraphicsItem *item = scene()->itemAt(event->scenePos()); - if (item == this) { - int numDesktops = KWindowSystem::numberOfDesktops(); - int currentDesktop = KWindowSystem::currentDesktop(); - - if (event->delta() < 0) { - KWindowSystem::setCurrentDesktop(currentDesktop % numDesktops + 1); - } else { - KWindowSystem::setCurrentDesktop((numDesktops + currentDesktop - 2) % numDesktops + 1); - } - - event->accept(); - return; } } @@ -1627,6 +1683,44 @@ Plasma::Wallpaper *Containment::wallpaper() const return d->wallpaper; } +void Containment::setContextAction(const QString &trigger, const QString &pluginName) +{ + KConfigGroup cfg(&config(), "ContextActions"); + ContextAction *action = 0; + + if (d->contextActions.contains(trigger)) { + action = d->contextActions.value(trigger); + if (action->pluginName() != pluginName) { + d->contextActions.remove(trigger); + delete action; + action=0; + } + } + if (pluginName.isEmpty()) { + cfg.deleteEntry(trigger); + return; //FIXME config? + } + + if (!action) { + action = ContextAction::load(pluginName); + if (!action) { + cfg.deleteEntry(trigger); + return; + } + cfg.writeEntry(trigger, pluginName); + d->contextActions.insert(trigger, action); + connect(action, SIGNAL(configureRequested()), this, SLOT(requestConfiguration())); + connect(action, SIGNAL(configNeedsSaving()), this, SIGNAL(configNeedsSaving())); + } + + if (action->isInitialized()) { + KConfigGroup actionConfig = KConfigGroup(&cfg, trigger); + action->restore(actionConfig); + } + action->setParent(this); + +} + void Containment::setActivity(const QString &activity) { Context *context = d->context(); @@ -2134,6 +2228,29 @@ void ContainmentPrivate::positionPanel(bool force) } } + +bool ContainmentPrivate::prepareContextAction(const QString &trigger, const QPoint &screenPos) +{ + ContextAction *action = contextActions.value(trigger); + + if (!action->isInitialized()) { + KConfigGroup cfg(&(q->config()), "ContextActions"); + KConfigGroup actionConfig = KConfigGroup(&cfg, trigger); + action->restore(actionConfig); + } + + if (action->configurationRequired()) { + KMenu menu; + menu.addTitle(i18n("This plugin needs to be configured")); + //TODO show reason + //TODO offer config button + menu.exec(screenPos); + return false; + } + return true; +} + + } // Plasma namespace #include "containment.moc" diff --git a/containment.h b/containment.h index ff28bc8ab..400a3c9e0 100644 --- a/containment.h +++ b/containment.h @@ -46,6 +46,7 @@ class Package; class Corona; class View; class Wallpaper; +class ContextAction; class ContainmentPrivate; /** @@ -364,6 +365,14 @@ class PLASMA_EXPORT Containment : public Applet */ virtual void showDropZone(const QPoint pos); + /** + * Sets a contextaction plugin. + * + * @param trigger the mouse button (and optional modifier) to associate the plugin with + * @param pluginName the name of the plugin to attempt to load. blank = set no plugin. + */ + void setContextAction(const QString &trigger, const QString &pluginName); + Q_SIGNALS: /** * This signal is emitted when a new applet is created by the containment diff --git a/private/containment_p.h b/private/containment_p.h index 5c26ffb10..686fa0e42 100644 --- a/private/containment_p.h +++ b/private/containment_p.h @@ -113,6 +113,13 @@ public: */ void dropData(QGraphicsSceneEvent *event); + /** + * inits the contextaction if necessary + * if it needs configuring, this warns the user and returns false + * @return true if it's ok to run the action + */ + bool prepareContextAction(const QString &trigger, const QPoint &screenPos); + Containment *q; FormFactor formFactor; Location location; @@ -120,6 +127,7 @@ public: Applet *focusedApplet; Plasma::Wallpaper *wallpaper; QMap handles; + QHash contextActions; int screen; int desktop; ToolBox *toolBox;