here's the beginning of my gsoc project. :)
I've basically copied the wallpaper plugin code to create the ContextAction 
plugin. there are two functions that get called: contextEvent and wheelEvent. 
right now I'm passing the entire event to the plugin, even though I don't 
really want plugins to look at the buttons or modifiers that triggered them. 
the event has three position functions and the wheel also has a delta, and I 
don't like functions with a lot of parameters.

Containment has gained the setContextAction function in the attached diff 
(again I was copying wallpaper code). ContainmentPrivate keeps a QHash of the 
loaded plugins; the key is a string representation of the button (and optional 
modifiers) that triggers it. when there's a mouse or wheel event, Containment 
looks in that hashmap to find the matching plugin (if any). the list of plugins 
is saved in the containment's config under [ContextActions] and loaded if it 
exists.

there are two plugins I've added to kdebase - one is just a dummy for testing, 
and the other is the switch-virtual-desktop plugin I mentioned on my blog.

the code is still rough in places - I haven't written any config UI at all, and 
haven't tried to make any plugin itself configurable (I think it'll be annoying 
to do that without some UI in place). also, the contextMenuEvent function is 
currently eating any rightclicks; dealing with that properly won't be trivial. 
still, I figured I'd put my code out here for some initial API review. and if 
anyone can come up with a better class name than ContextAction, tell me :)

the full code is available at http://gitorious.org/plasma-mouse-plugins in the 
gsoc branch of each repo. attached is just the public API bit.

-- 
This message brought to you by eevil bananas and the number 3.
www.chani3.com
diff --git a/containment.h b/containment.h
index 80e6aec..e43065c 100644
--- a/containment.h
+++ b/containment.h
@@ -41,6 +41,7 @@ class Package;
 class Corona;
 class View;
 class Wallpaper;
+class ContextAction;
 class ContainmentPrivate;
 
 /**
@@ -359,6 +360,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
/*
 *   Copyright 2008 by Aaron Seigo <ase...@kde.org>
 *   Copyright 2008 by Petri Damsten <d...@iki.fi>

 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Library General Public License as
 *   published by the Free Software Foundation; either version 2, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details
 *
 *   You should have received a copy of the GNU Library General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef PLASMA_CONTEXTACTION_H
#define PLASMA_CONTEXTACTION_H

#include <kplugininfo.h>

#include <plasma/plasma.h>
#include <plasma/packagestructure.h>
#include <plasma/version.h>

namespace Plasma
{

class DataEngine;
class ContextActionPrivate;

/**
 * @class ContextAction plasma/contextaction.h <Plasma/ContextAction>
 *
 * @short The base ContextAction class
 *
 * "ContextActions" are components that provide an action (usually displaying a contextmenu) in
 * response to an event with a position (usually a mouse event).
 *
 * ContextAction plugins are registered using .desktop files. These files should be
 * named using the following naming scheme:
 *
 *     plasma-contextaction-\<pluginname\>.desktop
 *
 */

class PLASMA_EXPORT ContextAction : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name READ name)
    Q_PROPERTY(QString pluginName READ pluginName)
    Q_PROPERTY(QString icon READ icon)

    public:
        /**
         * Default constructor for an empty or null contextaction
         */
        explicit ContextAction(QObject * parent = 0);

        ~ContextAction();

        /**
         * Returns a list of all known contextactions.
         *
         * @return list of contextactions
         **/
        static KPluginInfo::List listContextActionInfo();

        /**
         * Attempts to load a contextaction
         *
         * Returns a pointer to the contextaction if successful.
         * The caller takes responsibility for the contextaction, including
         * deleting it when no longer needed.
         *
         * @param name the plugin name, as returned by KPluginInfo::pluginName()
         * @param args to send the contextaction extra arguments
         * @return a pointer to the loaded contextaction, or 0 on load failure
         **/
        static ContextAction *load(const QString &name, const QVariantList &args = QVariantList());

        /**
         * Attempts to load a contextaction
         *
         * Returns a pointer to the contextaction if successful.
         * The caller takes responsibility for the contextaction, including
         * deleting it when no longer needed.
         *
         * @param info KPluginInfo object for the desired contextaction
         * @param args to send the contextaction extra arguments
         * @return a pointer to the loaded contextaction, or 0 on load failure
         **/
        static ContextAction *load(const KPluginInfo &info, const QVariantList &args = QVariantList());

        /**
         * Returns the Package specialization for contextactions.
         */
        static PackageStructure::Ptr packageStructure();

        /**
         * Returns the user-visible name for the contextaction, as specified in the
         * .desktop file.
         *
         * @return the user-visible name for the contextaction.
         **/
        QString name() const;

        /**
         * Returns the plugin name for the contextaction
         */
        QString pluginName() const;

        /**
         * Returns the icon related to this contextaction
         **/
        QString icon() const;

        /**
         * @return true if initialized (usually by calling restore), false otherwise
         */
        bool isInitialized() const;

        /**
         * This method should be called once the wallpaper is loaded or mode is changed.
         * @param config Config group to load settings
         * @see init
         **/
        void restore(const KConfigGroup &config);

        /**
         * This method is called when settings need to be saved.
         * @param config Config group to save settings
         **/
        virtual void save(KConfigGroup &config);

        /**
         * Returns the widget used in the configuration dialog.
         * Add the configuration interface of the contextaction to this widget.
         * To signal that settings have changed connect to
         * settingsChanged(bool modified) in @p parent.
         * @code connect(this, SIGNAL(settingsChanged(bool), parent, SLOT(settingsChanged(bool)))
         * @endcode
         * Emit settingsChanged(true) when the settings are changed and false when the original state is restored.
         */
        virtual QWidget *createConfigurationInterface(QWidget *parent);

        /**
         * Implement this to respond to a mouse button event.
         * The user can configure whatever button and modifier they like, so please don't look at
         * those parameters.
         * @param event the mouse event object
         */
        virtual void contextEvent(QGraphicsSceneMouseEvent *event);

        /**
         * Implement this to respond to a wheel event.
         * The user can configure which wheel and whatever modifier they like, so please don't look at
         * those parameters.
         * @param event the mousewheel event object
         */
        virtual void wheelEvent(QGraphicsSceneWheelEvent *event);

        /**
         * Loads the given DataEngine
         *
         * Tries to load the data engine given by @p name.  Each engine is
         * only loaded once, and that instance is re-used on all subsequent
         * requests.
         *
         * If the data engine was not found, an invalid data engine is returned
         * (see DataEngine::isValid()).
         *
         * Note that you should <em>not</em> delete the returned engine.
         *
         * @param name Name of the data engine to load
         * @return pointer to the data engine if it was loaded,
         *         or an invalid data engine if the requested engine
         *         could not be loaded
         *
         */
        Q_INVOKABLE DataEngine *dataEngine(const QString &name) const;

        /**
         * @return true if the contextaction currently needs to be configured,
         *         otherwise, false
         */
        bool configurationRequired() const;

    Q_SIGNALS:
        /**
         * Emitted when the user wants to configure/change the contextaction.
         */
        void configureRequested();

        /**
         * Emitted when the state of the contextaction requiring configuration
         * changes.
         */
        void configurationRequired(bool needsConfig);

        /**
         * Emitted when the configuration of the contextaction needs to be saved
         * to disk.
         */
        void configNeedsSaving();

    protected:
        /**
         * This constructor is to be used with the plugin loading systems
         * found in KPluginInfo and KService. The argument list is expected
         * to have one element: the KService service ID for the desktop entry.
         *
         * @param parent a QObject parent; you probably want to pass in 0
         * @param args a list of strings containing one entry: the service id
         */
        ContextAction(QObject *parent, const QVariantList &args);

        /**
         * This method is called once the contextaction is loaded or mode is changed.
         *
         * The mode can be retrieved using the renderingMode() method.
         *
         * @param config Config group to load settings
         **/
        virtual void init(const KConfigGroup &config);

        /**
         * When the contextaction needs to be configured before being usable, this
         * method can be called to denote that action is required
         *
         * @param needsConfiguring true if the applet needs to be configured,
         *                         or false if it doesn't
         * @param reason a translated message for the user explaining that the
         *               applet needs configuring; this should note what needs
         *               to be configured
         */
        void setConfigurationRequired(bool needsConfiguring, const QString &reason = QString());

    private:
        friend class ContextActionPackage;
        friend class ContextActionPrivate;
        ContextActionPrivate *const d;
};

} // Plasma namespace

/**
 * Register a contextaction when it is contained in a loadable module
 */
#define K_EXPORT_PLASMA_CONTEXTACTION(libname, classname) \
K_PLUGIN_FACTORY(factory, registerPlugin<classname>();) \
K_EXPORT_PLUGIN(factory("plasma_contextaction_" #libname)) \
K_EXPORT_PLUGIN_VERSION(PLASMA_VERSION)

#endif // multiple inclusion guard

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
Plasma-devel mailing list
Plasma-devel@kde.org
https://mail.kde.org/mailman/listinfo/plasma-devel

Reply via email to