Development/Tutorials/KCM HowTo: Difference between revisions
Line 32: | Line 32: | ||
===Exporting more than one module=== | ===Exporting more than one module=== | ||
If you need to export more than one module per library, you have to | If you need to export more than one module per library, you have to declare them another way: you must create C functions named "create_${kcm_name}". For | ||
example if your module exposes two KCMs named Foo1 and Foo2, the | |||
example if your module exposes | |||
"create_" functions would look like this: | "create_" functions would look like this: | ||
Revision as of 13:34, 5 April 2012
Introduction
This HOWTO describes how to write KConfig Modules (KCMs from now on). These KCM can appear in System Settings or in the configuration dialog of individual applications.
A KCM is made of two elements:
- A shared library
- A desktop file
Implementing a KCM is done by:
- Subclassing the KCModule class. In this documentation we assume the class inheriting from KCModule is named FooKcm.
- Exporting the module so that System Settings or kcmshell4 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 the constructor signature of your derived class matches with the signature of KCModule constructor (the QVariantList argument matters).
If the name of your module is "foo", the name of the library should be "kcm_foo.so". It should be installed into $KDEDIR/lib/kde4.
Exporting more than one module
If you need to export more than one module per library, you have to declare them another way: you must create C functions named "create_${kcm_name}". For example if your module exposes two KCMs named Foo1 and Foo2, the "create_" functions would look like this:
extern "C"
{
KCModule *create_foo1(QWidget *parent, const char *name)
{
return new Foo1Kcm(parent, name);
};
KCModule *create_foo2(QWidget *parent, const char *name)
{
return new Foo2Kcm(parent, name);
};
}
Additionally, you will need to add "X-KDE-FactoryName" keys to your desktop file. (see below)
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 a "X-KDE-Init" key 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.
Desktop files are defined in the desktop file specification.
Mandatory keys
A KCM desktop file must contains the following keys:
- Type
Should be "Service".
- X-KDE-ServiceTypes
Should be "KCModule".
- Icon
Specifies the icon for the module.
- Exec
Should be "kcmshell4 foo".
- Name
This will be used by System Settings as your KCM label.
- Comment
This text shows up in the title area in System Settings. If the module is not grouped with other modules it will also be used as a tooltip in the KCM list view.
- Categories
Should contain at least "Qt;KDE;X-KDE-settings-system;".
- 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-System-Settings-Parent-Category
Defines where the KCM will appear in System Settings. (FIXME: Where is the category list?)
- X-KDE-Keywords
A comma-separated list containing words the search functionality should trigger on.
- X-KDE-Library
This is the name of the library, without the kcm_ prefix. So in the example, it should be "foo".
Optional keys
Additionally the KCM desktop file may contains the following keys:
- 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 key 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", kcm_kermit.desktop would contain:
X-KDE-Library=frog
X-KDE-FactoryName=kermit
and "kcm_quak.desktop" would contain:
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-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 System Settings or when viewed with kcmshell4. This is useful when you need to do something at startup using X-KDE-Init but don't want the module to show up in System Settings.
Example CMakeLists.txt
Here is a minimal CMakeLists.txt which builds and installs the shared library and the desktop files at the right places:
find_package(KDE4 REQUIRED)
include(KDE4Defaults)
include(MacroLibrary)
set(FOO_SRCS
foo.cpp
# Other sources go there
)
kde4_add_plugin(kcm_foo ${FOO_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:
The first option is to simply fork and call "kcmshell4 foo".
The second option is to use KCMultiDialog. This is a simple dialog which can show an arbitrary number of modules in a normal KDialog. This approach gives you finer control to the behavior and results than starting kcmshell4 in a separate process.
Since your module is a simple library, you can just link to it anyway.
KCModuleContainer
The class KCModuleContainer allows great flexibility to handle 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 System Settings, make sure you pass --nofork to System Settings on startup.
You really want to use kcmshell4 for debugging as long as your debugging does not involve debugging bad interaction with the System Settings 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 <[email protected]>.
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".