Development/Tutorials/Generic Calligra Plugin Creation

< Development‎ | Tutorials
Revision as of 15:02, 2 May 2007 by Zander (Talk | contribs) (New page)

Jump to: navigation, search

Writing a plugin for KOffice technically means the following things are created;

  • An interface that is shipped in the base-libraries will be inherited from, and functionality implemented unique to the plugin. Examples of these interfaces are KoShape, KoTool and KoColorSpace.
  • A factory class is created. The factory design pattern allows the plugin to create as many instances of the plugin code as required in a flexible manner. Each plugin type has its own Factory object that should be inherited from.
  • A plugin object is created. This is really a plugin-loader object and it will be created and immediately deleted by the KOffice libraries.

The concept of a plugin.

The concept is really based on what Object Orientated design is saying, it means that you can create programmer-interface and encapsulate that in a class without being very clear as to what that implementation is suppost to do. You can then supply serveral classes that actually contains the implementation of the programmer-interface, each in their own way. The actual way that the class responds to the same environment is thus the implementation and not the programmer-interface. Plugins are a way to provide a different implementation for a known interface.

KOffice has defined several classes as base classes and has made the programmer interface of those base classes generic enough so a wide range of functionality can be accomplished by providing a plugin with a new implemntation for such a base class.

An example; one plugin type that KOffice supports is a docker widget. A docker widget is really a widget that can be shown on screen like a button or a text field are widgets as well. The plugin can ship a new implementation of the QDockWidget class by inheriting from that QDockWidget and providing text/buttons and functionality using the full API of the Qt and KDE/KOffice libraries to do their work. This means I can provide a plugin that ships a docker. And the docker shows the time of day, for example. By installing the plugin according to the instructions for that type of KOffice-plugin the KOffice application are able to find it and the docker will be created and shown on screen.





  • This factory is registered in a Registry.



in the header file:

#include <QObject>
class MyPlugin : public QObject {
   MyPlugin(QObject * parent, const QStringList &list);

in the cpp file;

#include "MyPlugin.h"
#include <kgenericfactory.h>
#include <KoShapeRegistry.h>
#include <KoToolRegistry.h>
MyPlugin::MyPlugin(QObject * parent, const QStringList &)  : QObject(parent) { KoToolRegistry::instance()->add(new MyToolFactory(parent)); KoShapeRegistry::instance()->add(new MyShapeFactory(parent)); } #include <MyPlugin.moc>

This example registeres 2 factories, but you can register any number you want to ship in 1 plugin. Note how only the factory is created, and nothing else is done. This makes loading of the plugin as fast as possible. If you copy paste this code make sure you update the 'libraryname' to be the (all lowercase) name of your plugin-library. Which is also repeated in the desktop file. Note that the name is without any extentions. In the K_EXPORT_COMPONENT_FACTORY macro the 'MyPlugin' is repeated twice. Its easiest to just replace that with the class name you choose for your project.


A plugin is technically implemented as a library, at least on Linux and other unixes. It is loaded as a library by KOffice near the start of the application start. As the plugin is a library all development software can create them using a linker. It is worth noting that it is possible for your plugin to depend on external shared libraries, apart from the koffice ones. But you should install that shared library as well as your plugin. In cmake the creation of a library goes like this;

project( myPlugin)
include_directories( ${KOFFICEUI_INCLUDES} )
SET ( myplugin_SRCS MyPlugin.cpp # other cpp files )
kde4_automoc(${myplugin_SRCS}) kde4_add_plugin(textshape ${myplugin_SRCS}) target_link_libraries(myplugin kofficeui) install(TARGETS myplugin DESTINATION ${PLUGIN_INSTALL_DIR}) install( FILES myplugin.desktop DESTINATION ${SERVICES_INSTALL_DIR})

And last is the desktop-file component after which the plugin will be found and used by KOffice. A desktop file is basically a database record for the KDE database of what is installed. In this case the component is a 'Service'. For our running example here is myplugin.desktop

[Desktop Entry]
Name=My Shape

A couple of things are important;

  • The name is used for the plugin-manager.
    This gets confusing and we don't want one plugin to be loaded twice, so instead we take the more generic 'KOffice/flake' which will be searched for when either a shape or a tool is requested. Each plugin type will show the best matching ServiceType, but if you are doubtful you can always use 'KOffice/Flake'.