* appletActions -> addAppletActions

* containmentActions -> addContainmentActions
* make both take an event for positioning purposes
* make prepareContainmentActions a more generic so that one code path for handling setting up a ContainmentActions plugin is used everywhere; this also shrinks addContainmentActions down to just being a permissions checker
* make PopupApplet use ContainmentPrive::addAppletActions directly; fewer code paths to track, as it allows removal of ContainmentPrivate::showApplContextMenu

svn path=/trunk/KDE/kdelibs/; revision=1173567
This commit is contained in:
Aaron J. Seigo 2010-09-09 18:37:28 +00:00
parent 5bddabe5d8
commit 23ebeb3bf6
3 changed files with 56 additions and 81 deletions

View File

@ -608,28 +608,14 @@ void Containment::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
return;
}
const QString trigger = ContainmentActions::eventToString(event);
if (d->prepareContainmentActions(trigger, event->screenPos())) {
// create a mouse event for the action plugin
QGraphicsSceneMouseEvent mevent(QEvent::GraphicsSceneMousePress);
mevent.setScreenPos(event->screenPos());
mevent.setScenePos(event->scenePos());
mevent.setPos(event->pos());
mevent.setWidget(event->widget());
mevent.setButtons(Qt::RightButton);
mevent.setModifiers(event->modifiers());
d->actionPlugins.value(trigger)->contextEvent(&mevent);
return;
}
Applet *applet = d->appletAt(event->scenePos());
KMenu desktopMenu;
Applet *applet = d->appletAt(event->scenePos());
//kDebug() << "context menu event " << (QObject*)applet;
if (applet) {
d->appletActions(desktopMenu, applet);
d->addAppletActions(desktopMenu, applet, event);
} else {
d->containmentActions(desktopMenu);
d->addContainmentActions(desktopMenu, event);
}
if (!desktopMenu.isEmpty()) {
@ -660,7 +646,7 @@ void Containment::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
}
}
void ContainmentPrivate::containmentActions(KMenu &desktopMenu)
void ContainmentPrivate::addContainmentActions(KMenu &desktopMenu, QEvent *event)
{
if (static_cast<Corona*>(q->scene())->immutability() != Mutable &&
!KAuthorized::authorizeKAction("plasma/containment_actions")) {
@ -668,39 +654,11 @@ void ContainmentPrivate::containmentActions(KMenu &desktopMenu)
return;
}
QString trigger = "RightButton;NoModifier";
//get base context actions
ContainmentActions *plugin = actionPlugins.value(trigger);
if (plugin) {
if (!plugin->isInitialized()) {
KConfigGroup cfg = q->config();
cfg = KConfigGroup(&cfg, "ActionPlugins");
KConfigGroup pluginConfig = KConfigGroup(&cfg, trigger);
plugin->restore(pluginConfig);
}
if (plugin->configurationRequired()) {
desktopMenu.addTitle(i18n("This menu needs to be configured"));
desktopMenu.addAction(q->action("configure"));
} else {
QList<QAction*> actions = plugin->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);
}
}
}
const QString trigger = ContainmentActions::eventToString(event);
prepareContainmentActions(trigger, QPoint(), &desktopMenu);
}
void ContainmentPrivate::appletActions(KMenu &desktopMenu, Applet *applet)
void ContainmentPrivate::addAppletActions(KMenu &desktopMenu, Applet *applet, QEvent *event)
{
foreach (QAction *action, applet->contextualActions()) {
if (action) {
@ -719,11 +677,13 @@ void ContainmentPrivate::appletActions(KMenu &desktopMenu, Applet *applet)
}
KMenu *containmentMenu = new KMenu(i18nc("%1 is the name of the containment", "%1 Options", q->name()), &desktopMenu);
containmentActions(*containmentMenu);
addContainmentActions(*containmentMenu, event);
if (!containmentMenu->isEmpty()) {
int enabled = 0;
//count number of real actions
foreach (const QAction *action, containmentMenu->actions()) {
QListIterator<QAction *> actionsIt(containmentMenu->actions());
while (enabled < 3 && actionsIt.hasNext()) {
QAction *action = actionsIt.next();
if (action->isVisible() && !action->isSeparator()) {
++enabled;
}
@ -733,7 +693,9 @@ void ContainmentPrivate::appletActions(KMenu &desktopMenu, Applet *applet)
//if there is only one, don't create a submenu
if (enabled < 2) {
foreach (QAction *action, containmentMenu->actions()) {
desktopMenu.addAction(action);
if (action->isVisible() && !action->isSeparator()) {
desktopMenu.addAction(action);
}
}
} else {
desktopMenu.addMenu(containmentMenu);
@ -747,7 +709,9 @@ void ContainmentPrivate::appletActions(KMenu &desktopMenu, Applet *applet)
}
QAction *closeApplet = applet->d->actions->action("remove");
kDebug() << "checking for removal" << closeApplet;
if (closeApplet) {
kDebug() << "boo yah, adding it!" << closeApplet->isEnabled() << closeApplet->isVisible();
desktopMenu.addAction(closeApplet);
}
}
@ -783,19 +747,6 @@ Applet* ContainmentPrivate::appletAt(const QPointF &point)
return applet;
}
bool ContainmentPrivate::showAppletContextMenu(Applet *applet, const QPoint &screenPos)
{
KMenu desktopMenu;
appletActions(desktopMenu, applet);
if (!desktopMenu.isEmpty()) {
desktopMenu.exec(screenPos);
return true;
}
return false;
}
void Containment::setFormFactor(FormFactor formFactor)
{
if (d->formFactor == formFactor) {
@ -2458,7 +2409,7 @@ QPointF ContainmentPrivate::preferredPanelPos(Corona *corona) const
}
bool ContainmentPrivate::prepareContainmentActions(const QString &trigger, const QPoint &screenPos)
bool ContainmentPrivate::prepareContainmentActions(const QString &trigger, const QPoint &screenPos, KMenu *menu)
{
ContainmentActions *plugin = actionPlugins.value(trigger);
if (!plugin) {
@ -2473,11 +2424,28 @@ bool ContainmentPrivate::prepareContainmentActions(const QString &trigger, const
}
if (plugin->configurationRequired()) {
KMenu menu;
menu.addTitle(i18n("This plugin needs to be configured"));
menu.addAction(q->action("configure"));
menu.exec(screenPos);
KMenu *localMenu = menu ? menu : new KMenu();
localMenu->addTitle(i18n("This plugin needs to be configured"));
localMenu->addAction(q->action("configure"));
if (!menu) {
localMenu->exec(screenPos);
delete localMenu;
}
return false;
} else if (menu) {
QList<QAction*> actions = plugin->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...
if (!isPanelContainment() && q->action("configure")) {
menu->addAction(q->action("configure"));
}
} else {
menu->addActions(actions);
}
}
return true;

View File

@ -507,7 +507,15 @@ bool PopupApplet::eventFilter(QObject *watched, QEvent *event)
}
}
return c->d->showAppletContextMenu(applet, static_cast<QContextMenuEvent*>(event)->globalPos());
KMenu desktopMenu;
c->d->addAppletActions(desktopMenu, applet, event);
if (!desktopMenu.isEmpty()) {
desktopMenu.exec(static_cast<QContextMenuEvent*>(event)->globalPos());
return true;
}
return false;
}
}

View File

@ -97,8 +97,8 @@ public:
void remoteAppletReady(Plasma::AccessAppletJob *job);
void mimeTypeRetrieved(KIO::Job *job, const QString &mimetype);
void dropJobResult(KJob *);
void containmentActions(KMenu &desktopMenu);
void appletActions(KMenu &desktopMenu, Applet *applet);
void addContainmentActions(KMenu &desktopMenu, QEvent *event);
void addAppletActions(KMenu &desktopMenu, Applet *applet, QEvent *event);
void checkRemoveAction();
Applet *addApplet(const QString &name, const QVariantList &args = QVariantList(),
@ -138,18 +138,17 @@ public:
/**
* inits the containmentactions if necessary
* if it needs configuring, this warns the user and returns false
* if a menu is passed in, then it populates that menu with the actions from the plugin
* @param trigger the string to identify the correct plugin with
* @param screenPos used to show the configure menu, only used if no menu is passed in
* @param menu an optional menu to use to populate with actions, instead of triggering the
* action directly
* @return true if it's ok to run the action
*/
bool prepareContainmentActions(const QString &trigger, const QPoint &screenPos);
bool prepareContainmentActions(const QString &trigger, const QPoint &screenPos, KMenu *menu = 0);
Applet *appletAt(const QPointF &point);
/**
* force the contextmenu for @p applet to be shown at @p screenPos
* @since 4.4
*/
bool showAppletContextMenu(Applet *applet, const QPoint &screenPos);
/**
* Delayed drop zone display
*/