From f0a68d537c615421eaa1e497d6e002375a7b4bcd Mon Sep 17 00:00:00 2001 From: Chani Armitage Date: Mon, 17 Aug 2009 22:30:46 +0000 Subject: [PATCH] make rightclick plugins possible this makes rightclicks use the plugin configured for rightclick and adds a new method to the plugin for when an applet is rightclicked (we need a list of actions then that we can insert into the menu) this also adds a signal for immutability and improves handling of needs-configuring plugins svn path=/trunk/KDE/kdelibs/; revision=1012639 --- applet.cpp | 1 + applet.h | 6 ++++ containment.cpp | 83 ++++++++++++++++++++++++++--------------------- contextaction.cpp | 26 +++++++++++++++ contextaction.h | 23 +++++++++++++ 5 files changed, 102 insertions(+), 37 deletions(-) diff --git a/applet.cpp b/applet.cpp index 06699e1c2..8834cb0a0 100644 --- a/applet.cpp +++ b/applet.cpp @@ -1101,6 +1101,7 @@ void Applet::flushPendingConstraintsEvents() action->setVisible(canConfig); action->setEnabled(canConfig); } + emit immutabilityChanged(immutability()); } if (c & Plasma::SizeConstraint) { diff --git a/applet.h b/applet.h index 73e7c0ed7..e2c706976 100644 --- a/applet.h +++ b/applet.h @@ -698,6 +698,12 @@ class PLASMA_EXPORT Applet : public QGraphicsWidget */ void extenderItemRestored(Plasma::ExtenderItem *item); + /** + * Emitted when the immutability changes + * @since 4.4 + */ + void immutabilityChanged(const ImmutabilityType immutable); + public Q_SLOTS: /** * Sets the immutability type for this applet (not immutable, diff --git a/containment.cpp b/containment.cpp index b8dce38d5..072a5d744 100644 --- a/containment.cpp +++ b/containment.cpp @@ -234,25 +234,35 @@ void Containment::init() setContextAction(key, cfg.readEntry(key, QString())); } } else { - if (d->type == DesktopContainment) { - //we need to be very careful here to not write anything - //because we have a group, and so the defaults will get merged instead of overwritten - //when copyTo is used (which happens right before restore() is called) - QHash defaults; + //we need to be very careful here to not write anything + //because we have a group, and so the defaults will get merged instead of overwritten + //when copyTo is used (which happens right before restore() is called) + //FIXME maybe PlasmaApp should handle the defaults? + QHash defaults; + switch (d->type) { + case DesktopContainment: defaults.insert("wheel:Vertical;NoModifier", "switchdesktop"); defaults.insert("wheel:Horizontal;ControlModifier", "test"); defaults.insert("LeftButton;NoModifier", "switchdesktop"); - defaults.insert("RightButton;NoModifier", "test"); - foreach (const QString &trigger, defaults.keys()) { - ContextAction *action = ContextAction::load(defaults.value(trigger)); - if (action) { - d->contextActions.insert(trigger, action); - connect(action, SIGNAL(configureRequested()), this, SLOT(requestConfiguration())); - connect(action, SIGNAL(configNeedsSaving()), this, SIGNAL(configNeedsSaving())); - } + defaults.insert("RightButton;NoModifier", "contextmenu"); + break; + case PanelContainment: + case CustomPanelContainment: + defaults.insert("RightButton;NoModifier", "contextmenu"); + break; + default: + break; + } + + foreach (const QString &trigger, defaults.keys()) { + ContextAction *action = ContextAction::load(defaults.value(trigger)); + if (action) { + d->contextActions.insert(trigger, action); + connect(action, SIGNAL(configureRequested()), this, SLOT(requestConfiguration())); + connect(action, SIGNAL(configNeedsSaving()), this, SIGNAL(configNeedsSaving())); + action->setParent(this); } } - //TODO defaults for panel etc. } } @@ -611,28 +621,28 @@ void ContainmentPrivate::containmentActions(KMenu &desktopMenu) return; } + QString trigger = "RightButton;NoModifier"; //get base context actions - QList actions = q->contextualActions(); - - //find the separator to insert the activity settings before it - QAction *separatorAction = 0; - - //TODO: should a submenu be created if there are too many containment specific - // actions? see folderview containment - foreach (QAction *action, actions) { - if (action) { - desktopMenu.addAction(action); - if (action->isSeparator()) { - separatorAction = action; + if (ContextAction *cAction = contextActions.value(trigger)) { + if (QAction *a = cAction->configurationAction()) { + //it needs configuring + desktopMenu.addAction(a); + } else { + QList actions = cAction->contextualActions(); + if (actions.isEmpty()) { + //it probably didn't bother implementing the function. give the user a chance to set + //a better plugin. + //note that if the user sets no-plugin this won't happen... + //FIXME maybe the behaviour could be better + if (type == Containment::DesktopContainment) { + desktopMenu.addAction(q->action("configure")); + } + } else { + //yay! + desktopMenu.addActions(actions); } } } - - desktopMenu.addSeparator(); - - if (type == Containment::DesktopContainment) { - desktopMenu.addAction(q->action("configure")); - } } void ContainmentPrivate::appletActions(KMenu &desktopMenu, Applet *applet, bool includeApplet) @@ -717,7 +727,8 @@ bool ContainmentPrivate::showContextMenu(const QPointF &point, const QPoint &scr if (applet) { appletActions(desktopMenu, applet, includeApplet); } else { - containmentActions(desktopMenu); + //containmentActions(desktopMenu); + return false; } if (!desktopMenu.isEmpty()) { @@ -2266,11 +2277,9 @@ bool ContainmentPrivate::prepareContextAction(const QString &trigger, const QPoi action->restore(actionConfig); } - if (action->configurationRequired()) { + if (QAction *a = action->configurationAction()) { KMenu menu; - menu.addTitle(i18n("This plugin needs to be configured")); - //TODO show reason - //TODO offer config button + menu.addAction(a); menu.exec(screenPos); return false; } diff --git a/contextaction.cpp b/contextaction.cpp index abad81cdc..6347f8d2d 100644 --- a/contextaction.cpp +++ b/contextaction.cpp @@ -19,6 +19,9 @@ */ #include "contextaction.h" +#include "containment.h" + +#include #include #include @@ -120,6 +123,11 @@ PackageStructure::Ptr ContextAction::packageStructure() return ContextActionPrivate::s_packageStructure; } +Containment *ContextAction::containment() +{ + return qobject_cast(parent()); +} + QString ContextAction::name() const { if (!d->contextActionDescription.isValid()) { @@ -184,6 +192,12 @@ void ContextAction::wheelEvent(QGraphicsSceneWheelEvent *event) Q_UNUSED(event) } +QList ContextAction::contextualActions() +{ + //empty list + return QList(); +} + DataEngine *ContextAction::dataEngine(const QString &name) const { return d->dataEngine(name); @@ -194,6 +208,18 @@ bool ContextAction::configurationRequired() const return d->needsConfig; } +QAction *ContextAction::configurationAction() +{ + if (d->needsConfig) { + //create the "I need configuring" action + QAction *action = new QAction(i18n("This plugin needs to be configured"), this); + //TODO name/reason? + //TODO connect it to something + return action; + } + return NULL; +} + void ContextAction::setConfigurationRequired(bool needsConfig, const QString &reason) { //TODO: implement something for reason. first, we need to decide where/how diff --git a/contextaction.h b/contextaction.h index 5119c3eae..e3b21ebb5 100644 --- a/contextaction.h +++ b/contextaction.h @@ -21,16 +21,21 @@ #ifndef PLASMA_CONTEXTACTION_H #define PLASMA_CONTEXTACTION_H +#include + #include #include #include #include +class QAction; + namespace Plasma { class DataEngine; +class Containment; class ContextActionPrivate; /** @@ -164,6 +169,13 @@ class PLASMA_EXPORT ContextAction : public QObject */ virtual void wheelEvent(QGraphicsSceneWheelEvent *event); + /** + * Implement this to provide a list of actions that can be added to another menu + * for example, when right-clicking an applet, the "Activity Options" submenu is populated + * with this. + */ + virtual QList contextualActions(); + /** * Loads the given DataEngine * @@ -190,6 +202,12 @@ class PLASMA_EXPORT ContextAction : public QObject */ bool configurationRequired() const; + /** + * @return a config action if the contextaction currently needs to be configured, + * otherwise, null + */ + QAction *configurationAction(); + Q_SIGNALS: /** * Emitted when the user wants to configure/change the contextaction. @@ -240,6 +258,11 @@ class PLASMA_EXPORT ContextAction : public QObject */ void setConfigurationRequired(bool needsConfiguring, const QString &reason = QString()); + /** + * return the containment the plugin is associated with, if any. + */ + Containment *containment(); + private: friend class ContextActionPackage; friend class ContextActionPrivate;