Development/Tutorials/Plasma4/AbstractRunner: Difference between revisions

    From KDE TechBase
    No edit summary
    Line 107: Line 107:
    Our class definition for this project looks as follows:
    Our class definition for this project looks as follows:


    <code cpp>
    <code qt>
    #ifndef HOMEFILES_H
    #ifndef HOMEFILES_H
    #define HOMEFILES_H
    #define HOMEFILES_H
    Line 143: Line 143:
    </code>
    </code>


    Even though it's a full featured Runner pugin it is just a handful of methods, each of which will be examined.
    Even though it's a full featured Runner plugin it is just a handful of methods, each of which will be examined.
     
    == Initializing the Runner ==
     
    Initialization of the Runner is done in three places: the constructor, init() and in prepareForMatchSession(). The constructor look like this:
     
    <code qt n>
    HomeFilesRunner::HomeFilesRunner(QObject *parent, const QVariantList &args)
        : AbstractRunner(parent, args)
    {
        setIgnoredTypes(Plasma::RunnerContext::NetworkLocation |
                        Plasma::RunnerContext::Executable |
                        Plasma::RunnerContext::ShellCommand);
        setSpeed(SlowSpeed);
        setPriority(LowPriority);
        setHasRunOptions(true);
    }
    </code>


    == Registering Matches ==
    == Registering Matches ==

    Revision as of 22:31, 28 October 2009

    Creating Runners
    Tutorial Series   Plasma
    Previous   None
    What's Next   n/a
    Further Reading   n/a

    Abstract

    The Plasma workspace provides an application called KRunner which, among other things, allows one to type into a text area which causes various actions and information that match the text appear as the text is being typed.

    This functionality is provided via plugins loaded at runtime called "Runners". These plugins can be used by any application using the Plasma library. This tutorial explores how to create a runner plugin.

    Basic Anatomy of a Runner

    Plasma::AbstractRunner is the base class of all Runners. It provides the basic structure for Runner plugins to:

    • Perform one-time setup upon creation
    • Perform setup and teardown before and after matching starts
    • Create and register matches for a given search term
    • Define secondary actions for a given match
    • Take action on a given match registered by the runner
    • Show configuration options

    In addition to Plasma::AbstractRunner there are three other important classes that we will be using from the Plasma library:

    Each of these classes will be covered in more detail as we encounter them in the Runner plugin implementation.

    Note
    The classes provided by the Plasma library are licensed under the LGPL and can therefore be linked to by code released under a variety of Free/Open Source licenses as well as proprietary licenses.


    Creating a Runner Plugin Project

    In this tutorial we will be creating a Runner plugin that finds files in the user's home directory that match the query and offers to open them. We begin by setting up the basic project files including a CMakeLists.txt file for building the plugin, a .desktop file to register the plugin, a class definition in a header file and a source code file containing the class implementation.

    Note
    The example can be found in its entirety in the [KDE Examples module] in the plasma/c++/runner/ directory.


    The CMakeLists.txt File

    CMake makes it very easy to set up the build system for our plugin:

    1. Project Needs a name, of course

    project(runnerexmaple)

    set(KDE_MIN_VERSION "4.3.60") # for the < 4.2 macro find_package(KDE4 4.3.60 REQUIRED) include (KDE4Defaults) include (MacroLibrary)

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

    1. We add our source code here

    set(example_SRCS homefilesrunner.cpp)

    1. Now make sure all files get to the right place

    kde4_add_plugin(plasma_runner_example_homefiles ${example_SRCS}) target_link_libraries(plasma_runner_example_homefiles ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS})

    1. Install the library and .desktop file

    install(TARGETS plasma_runner_example_homefiles DESTINATION ${PLUGIN_INSTALL_DIR}) install(FILES plasma-runner-example-homefiles.desktop DESTINATION ${SERVICES_INSTALL_DIR})

    The first 10 lines are pure boilerplate common to any stand-alone KDE project that uses CMake. We add our source code to the project on line 13, define a plugin 16 and what libraries it needs to link to on line 17. Runner plugins always need to link against the Plasma libraries, but may also require other libraries such as the KIO libraries in this case (for usage of KRun to open matching files). Lines 20 and 21 install the library and .desktop file to the appropriate locations.

    The .desktop Services File

    To register our plugin with the system so that applications such as KRunner are aware of it, we need to create and install a .desktop file that describes the plugin.

    By convention, all Runner plugin .desktop file names start with "plasma-runner-" followed by a unique name part (in this case "example-homefiles") and suffixed with ".desktop".

    The contents of this file, as seen below, contain the name, description and technical details about the plugin.
    

    [Desktop Entry] Name=Home Files Comment=Part of a tutorial demonstrating how to create Runner plugins Type=Service X-KDE-ServiceTypes=Plasma/Runner

    X-KDE-Library=plasma_runner_example_homefiles X-KDE-PluginInfo-Author=Aaron Seigo [email protected] X-KDE-PluginInfo-Name=example-homefiles X-KDE-PluginInfo-Version=0.1 X-KDE-PluginInfo-Website=http://plasma.kde.org/ X-KDE-PluginInfo-Category=Examples X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-License=GPL X-KDE-PluginInfo-EnabledByDefault=true

    There are four entries in the .desktop file in particular that are critical to the proper functioning of the plugin: Type, X-KDE-ServiceTypes, X-KDE-Library and X-KDE-PluginInfo-Name.

    The Type entry tells the system that this is a plugin (or "Service") and the ServiceTypes entry defines this plugin as being a Runner. These two key-value pairs are the same in all runners. The X-KDE-PluginInfo-Name entry is used internally to map configuration data to this runner; its value must be unique among all other installed runners on the system. The X-KDE-Library entry must match the name of the library defined in the CMakeLists.txt file.

    The other entries such as Name, Description, licensing and authorship are information and may be shown in the user interface but have no other technical importance. Try to avoid using jargon in the Name and Description entries, however, to make it easy for people to understand what your plugin does.

    The Class Definition (Header file)

    Our class definition for this project looks as follows:

    1. ifndef HOMEFILES_H
    2. define HOMEFILES_H
    1. include <Plasma/AbstractRunner>
    1. include <QHash>
    1. include <KIcon>

    class HomeFilesRunner : public Plasma::AbstractRunner {

       Q_OBJECT
    

    public:

       HomeFilesRunner(QObject *parent, const QVariantList &args);
    
       void match(Plasma::RunnerContext &context);
       void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match);
       void createRunOptions(QWidget *widget);
       void reloadConfiguration();
    

    protected Q_SLOTS:

       void init();
       void prepareForMatchSession();
       void matchSessionFinished();
    

    private:

       QHash<QString, KIcon> m_iconCache;
       QString m_path;
       QString m_triggerWord;
    

    };

    1. endif

    Even though it's a full featured Runner plugin it is just a handful of methods, each of which will be examined.

    Initializing the Runner

    Initialization of the Runner is done in three places: the constructor, init() and in prepareForMatchSession(). The constructor look like this:

    HomeFilesRunner::HomeFilesRunner(QObject *parent, const QVariantList &args)

       : AbstractRunner(parent, args)
    

    {

       setIgnoredTypes(Plasma::RunnerContext::NetworkLocation |
                       Plasma::RunnerContext::Executable |
                       Plasma::RunnerContext::ShellCommand);
       setSpeed(SlowSpeed);
       setPriority(LowPriority);
       setHasRunOptions(true);
    

    }

    Registering Matches

    Taking Action On Matches

    Configuration Interfaces

    Runner Options

    Match Result Options