Development/Tutorials/Plasma4/ContainmentAction: Difference between revisions

From KDE TechBase
Line 2: Line 2:


= Example =
= Example =
A simple example for Plasma ContainmentAction plugins can be found at https://github.com/tstaerk/kde-contextmenu/tree/0.1. Let's look at it here:
We will now create a simple example for Plasma ContainmentAction plugins. The code can be downloaded at https://github.com/tstaerk/kde-contextmenu/tree/tutorial. It creates a custom context menu that looks like this:
 
[[File:Snapshot-kde-contextmenu-2.png]]
 
The code is here:


== kde-contextmenu.desktop ==
== kde-contextmenu.desktop ==

Revision as of 15:17, 1 March 2013

You can use Plasma ContainmentAction e.g. for Context Menus on your Plasma Desktop. They will run as plugins meaning you can add and remove them after compilation. If they exist, their name will be stored in .desktop files.

Example

We will now create a simple example for Plasma ContainmentAction plugins. The code can be downloaded at https://github.com/tstaerk/kde-contextmenu/tree/tutorial. It creates a custom context menu that looks like this:

The code is here:

kde-contextmenu.desktop

[Desktop Entry]
Name=KDE Context Menu
Type=Service
Icon=favorites
Comment=Simple application launcher

ServiceTypes=Plasma/ContainmentActions

X-KDE-Library=kde-contextmenu
X-KDE-PluginInfo-Author=R. Hacker
[email protected]
X-KDE-PluginInfo-Name=kde-contextmenu
X-KDE-PluginInfo-Version=pre0.1
X-KDE-PluginInfo-Website=http://techbase.kde.org
X-KDE-PluginInfo-EnabledByDefault=true

CMakeLists.txt

project(kde-contextmenu)

set(KDE_MIN_VERSION "4.3.85") # for the < 4.2 macro
find_package(KDE4 4.3.85 REQUIRED)

include(MacroLibrary)
include(KDE4Defaults)

add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES})

set(contextmenu_SRCS
    launch.cpp
)

kde4_add_plugin(kde-contextmenu ${contextmenu_SRCS})
target_link_libraries(kde-contextmenu ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS})

install(TARGETS kde-contextmenu DESTINATION ${PLUGIN_INSTALL_DIR})
install(FILES kde-contextmenu.desktop DESTINATION ${SERVICES_INSTALL_DIR})

launch.h

#ifndef CONTEXTMENU_HEADER
#define CONTEXTMENU_HEADER

#include <plasma/containmentactions.h>

class QAction;
class KMenu;

class ConTextMenu : public Plasma::ContainmentActions
{
    Q_OBJECT
    public:
        ConTextMenu(QObject* parent, const QVariantList& args);
        ~ConTextMenu();

        void init(const KConfigGroup &config);

        void contextEvent(QEvent *event);
        //returns true if something (other than a separator) was successfully added
        bool addApps(QMenu *menu);

    public slots:
        void switchTo(QAction *action);

    protected:
        void makeMenu();

    private:
        KMenu *m_menu;
        QAction *m_action;
};

K_EXPORT_PLASMA_CONTAINMENTACTIONS(favorites, ConTextMenu)

#endif

launch.cpp

#include "launch.h"

#include <QGraphicsSceneMouseEvent>
#include <QGraphicsSceneWheelEvent>
#include <QFileInfo>

#include <KDebug>
#include <KIcon>
#include <KMenu>

#include <Plasma/DataEngine>
#include <Plasma/Containment>
#include <Plasma/Service>

ConTextMenu::ConTextMenu(QObject *parent, const QVariantList &args)
    : Plasma::ContainmentActions(parent, args)
    , m_action(new QAction(this))
{
    m_menu = new KMenu();
    connect(m_menu, SIGNAL(triggered(QAction*)), this, SLOT(switchTo(QAction*)));

    m_action->setMenu(m_menu);
}

ConTextMenu::~ConTextMenu()
{
    delete m_menu;
}

void ConTextMenu::init(const KConfigGroup &)
{
}

void ConTextMenu::contextEvent(QEvent *event)
{
    makeMenu();
    m_menu->adjustSize();
    m_menu->exec(popupPosition(m_menu->size(), event));
}

void ConTextMenu::makeMenu()
{
    m_menu->clear();
    addApps(m_menu);
}

bool ConTextMenu::addApps(QMenu *menu)
{
    QAction* action = menu->addAction(KIcon("system-run"), "Open a console");
    action->setData("kde4-konsole.desktop");

    action = menu->addAction(KIcon("firefox"), "Surf the web");
    action->setData("firefox.desktop");
    
    action = menu->addAction(KIcon("ksnapshot"), "Take a screenshot");
    action->setData("kde4-ksnapshot.desktop");
    return true;
}

void ConTextMenu::switchTo(QAction *action)
{
    QString source = action->data().toString();
    kDebug() << source;
    Plasma::Service *service = dataEngine("apps")->serviceForSource(source);
    if (service)
    {
        service->startOperationCall(service->operationDescription("launch"));
    }
}

#include "launch.moc"

Install it

Compile, link and install it using the command

cmake -DCMAKE_INSTALL_PREFIX=`kde4-config --prefix` . && make -j8 && make install

Test it

To test it, right-click onto your desktop and select "Folder View Settings". Then select Mouse Actions and the context menu:

Then click "Apply". Next time you middle-click (or whatever you selected) onto your desktop, your own context menu will appear:

Debugging

To debug your Plasma ContainmentAction call

kdebugdialog --fullmode

search for "plasma" and direct kDebug's output to /tmp/whatever.txt

See also