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
This commit is contained in:
Chani Armitage 2009-08-17 22:30:34 +00:00
parent 9d452dc2ea
commit 493196dff3
3 changed files with 154 additions and 20 deletions

View File

@ -26,6 +26,7 @@
#include <QFile>
#include <QGraphicsSceneContextMenuEvent>
#include <QGraphicsView>
#include <QMetaEnum>
#include <QMimeData>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
@ -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"

View File

@ -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

View File

@ -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<Applet*, AppletHandle*> handles;
QHash<QString, ContextAction*> contextActions;
int screen;
int desktop;
ToolBox *toolBox;