Development/Tutorials/KCM HowTo

From KDE TechBase
Revision as of 12:35, 5 April 2012 by Agateau (talk | contribs) (Created page with "==Introduction== A KConfig Module is a small library with a @ref KCModule subclass containing code which builds and support a interface for configuration tasks. The module is th...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Introduction

A KConfig Module is a small library with a @ref KCModule subclass containing code which builds and support a interface for configuration tasks. The module is then encapsulated in a parent application, for example kcmshell, System Settings or a KCMultiDialog.

This HOWTO describes how to write KConfig Modules(KCMs from now on). This technology was originally designed for KControl. Although KControl is the application where the KCM tehnology is the most used, it is used in several other places as well, such as Kopete and Kontact. This HOWTO describes how to write config modules, regardless of where it will be used. KConfig Modules were originally called KControl Modules.

Implementing

Implementing a KCM is done by:

  1. Subclassing the @ref KCModule class. In this documentation we assume the class inheriting from KCModule is named FooKcm.
  2. Exporting the module so that systemsettings or kcmshell can find it.

The prefered way to export the module is through KPluginFactory. Here is how to do it:

    #include <KPluginFactory>

    K_PLUGIN_FACTORY(FooKcmFactory, registerPlugin<FooKcm>();)
    K_EXPORT_PLUGIN(FooKcmFactory("kcm_foo", "kcm_foo"))

If you get errors, make sure that the constructor of your derived class equals the one of the KCModule baseclass (the QStringList argument matters).

If you need to export more than one module per library, you have to use the old loader. That is, you need to create a function like this:

    extern "C"
    {
      KCModule *create_foo(QWidget *parent, const char *name)
      {
        return new FooKcm(parent, name);
      };
    }

This function and the implementation of the module is then compiled as a shared library. If the name of your modules is 'foo', the name of the library should be kcm_foo.so and should be installed into $KDEDIR/lib/kde4 (see @ref kcm_install).

Initializing on startup

If your module needs to initialize on KDE session startup, you must have a construct like:

    extern "C"
    {
      KCModule *init_foo(QWidget *parent, const char *name)
      {
        // Do initialization here
      };
    }

Don't forget to add X-KDE-Init to your desktop file. (see below)

The desktop file

To declare a KCModule's existence a desktop file must be installed in the proper place (see @ref kcm_install).

It could be a good idea to have a look at the desktop file specification.

A KCM's .desktop file supports the following .desktop directives:

X-KDE-Library

This is the name of the library, without the kcm_ prefix. So in the example, the library name would be "foo".

X-KDE-FactoryName

This entry can be used to set the name of the factory function in the library. If you only have one KCModule in a library this directive is not needed. If you have several KCMs in one library you will need a .desktop file for each KCM.

For example, if you have a library named: kcm_frog.so with two modules, named "kermit" and "quak", you would have:

X-KDE-Library=frog
X-KDE-FactoryName=kermit

in one of the .desktop files, and in the other:

X-KDE-Library=frog
X-KDE-FactoryName=quak

The module loader would then call the "create_kermit" and "create_quak" functions respectively.

X-KDE-RootOnly

If this is set to "true", the module must be executed with root permissions. The module loader will then show the module in greyed-out (disabled) state with a warning until the "modify" button is pressed which allows running the module in an root environment using kdesu and QXEmbed.

X-KDE-ParentApp

The application you put in this entry determines in what situations it will show. For example, if the line says "X-KDE-ParentApp=kcontrol" the module will show up in KControl. It is very crucial the selected ParentApp is correct, otherwise the KCM will show up in unnecessary places.

X-KDE-Init

If the module has to perform some action at system startup, use this entry to build the name of a function to call. if X-KDE-Init is "bell", for example, the function "init_bell" is called in the library indicated by X-KDE-Library.

X-KDE-Test-Module

If the module has to perform some action at system startup, use this entry to build the name of a function to call. if X-KDE-Init is "bell", for example, the function "init_bell" is called in the library indicated by X-KDE-Library.

NoDisplay

If this is set to true the module will not show up in kcontrol or when viewed with kcmshell. This is usable when you need to do something at startup(X-KDE- Init etc.) but don't want the module to show up in kcontrol, eg. the module has no GUI.

Name

This is 'labels' for the KCMs and fill the nodes in the three view. Please see the KCM Guidelines on how to pick a good Name.

Comment

This directive shows up in the main area in KControl if you select a top node in the three view. See the same section as for Name in the KCM Guidelines for how to pick a good phrase.

Categories

This describes where the KCM should be put in KControl's navigation. It should look like "Categories=QT;KDE;X;" where X is the category. A list of available categories, as well as which one to choose is found in the KCM Guidelines.

Icon

Specifies the icon for the module.

Exec

Should say "Exec=kcmshell4 modulename".

Type

Should say "Type=Application".

Keywords

A semi colon separated list containing words/phrases search functionality should trigger on.

To summarize, a valid KCM .desktop file must contain these directives:

  • Name
  • Icon
  • Type=Application
  • Exec=kcmshell modulename
  • Categories=Qt;KDE;X; (replace X with your category)
  • Keywords
  • X-KDE-Library
  • X-KDE-ParentApp
  • Comment

Additionally, a KCM .desktop file may contain:

  • X-KDE-Init
  • X-KDE-Test-Module
  • NoDisplay
  • X-KDE-Root-Only
  • X-KDE-Factory-Name
  • DocPath

Any other directives (except translations) can safely be removed, since they most likely are abundant or are left over's from old KDE versions. For example, X-ModuleType was relevant for KDE 2.0 but not in any new versions.

Defining a CMakeLists.txt for the KCM

find_package(KDE4 REQUIRED)

include(KDE4Defaults)
include(MacroLibrary)

set(FOO_KCM_SRCS
    foo_kcm.cpp
    # Other sources go there
)

kde4_add_plugin(kcm_foo ${FOO_KCM_SRCS})

target_link_libraries(kcm_foo
    ${KDE4_KDEUI_LIBS}
    # Other necessary libraries go there
)

install(TARGETS kcm_foo
    DESTINATION ${PLUGIN_INSTALL_DIR}
)

install(FILES kcm_foo.desktop
    DESTINATION ${SERVICES_INSTALL_DIR}
)

What else do I need?

There are a number of additional things for convenience.

kcmshell4

Consider you want to run a module standalone. Call "kcmshell4 module". For example, to get the font and the desktop color settings, use:

kcmshell4 fonts colors

KCMultiDialog

Sometimes, you may want to reuse your KCModule inside an application. There are two ways to accomplish this:

First option is to use KCMultiDialog. This is a simple dialog that can show an abitrary number of modules in a normal KDialogBase. The advantage is that you can control the behaviour and the results much easier that with a separate process. And as your module is a simple library, you can just link to it anyway.

Second option is to call "kcmshell4 modules".

KCModuleContainer

The class KCModuleContainer allows great flexibility with handling modules. The API docs explains its usage the best.

Debugging your module

You can attach gdb, valgrind or whatever to "kcmshell4 [yourmodule]" to track down leaks or crashes. If you need to trace it down inside systemsettings, make sure you pass --nofork to systemsettings on startup.

You really want to use kcmshell4 for debugging as long as your debugging does not involve debugging bad interaction with the systemsettings framework itself.


About this howto

This howto has been imported from http://websvn.kde.org/trunk/www/sites/developer/documentation/other/kcm_howto.html?view=markup and updated to KDE4 by Aurélien Gâteau.

Original copyright header:

Copyright (C) 2003 Daniel Molkentin <[email protected]>
Copyright (C) 2004 Frans Englich <[email protected]>

Permission is granted to copy, distribute and/or modify this document under the
terms of the GNU Free Documentation License, Version 1.2 or any later version
published by the Free Software Foundation; with no Invariant Sections, no
Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included
in the section entitled "GNU Free Documentation License".