Table of Contents
This guide is geared toward developers, and it will show you how KTutorial can be used in your own application. First, the general changes to enable KTutorial will be presented, and then it will be shown how to develop a tutorial. Tutorials can be made using C++ or any script language supported by Kross. Finally, some more advanced topics about KTutorial use not covered in the previous sections will be addressed.
Also, remember that KTutorial provides KTutorial editor, a graphical application that can be used to create full tutorials, or tutorial skeletons to be completed in a text editor (if the tutorial needs something not supported by the editor yet). Although you will probably create most of your tutorials using KTutorial editor, its usage is not covered in this guide; instead, the editor provides tutorials (made with the editor itself :) ) to help you to learn how to use it.
Most of this guide is based on KTutorial test app and the example tutorials in it. The test app is just a basic text editor: it has all the KDE standard menu and toolbars plus a text area and a "Clean" action. For further information, refer to the code of the test application itself.
In order to use KTutorial in your application you'll have to make three little changes in your code. First, you must adjust your CMakeLists.txt file to find the KTutorial headers and link your application against KTutorial library. Then you must help XMLGUI to put
menu item in its proper place. And finally you must modify how your application is initialized to setup KTutorial and the C++ tutorials.In the blog of the project there are several examples showing how to add support for KTutorial in real KDE4 applications.
Each change is explained with more detail in the following sections.
To build an application that uses KTutorial, the compiler and linker must know where the KTutorial headers and its library can be found. This is specified in the build system, which in case of KDE4 applications is CMake.
KTutorial provides a CMake module to find KTutorial and set some CMake variables to the paths of the headers and library. It is a Find*.cmake module, so it is called using find_package
command, or a wrapper for it, like macro_optional_find_package
(since KTutorial 0.5, you can specify a KTutorial version in those commands). If KTutorial is found, the variables are set by those commands and they just have to be added to the include_directories
command and the target_link_libraries
command, depending on the variable. The definition KTUTORIAL_FOUND
is also added, so the compiler knows whether the library was found or not to perform conditional compilation.
Note that if KTutorial isn't installed its CMake module won't be installed either. In that case, CMake will complain that it can't find the module to look for KTutorial. Also, if for any reason the module to find KTutorial is installed but the headers or the library are not, CMake will also complain. In either case, the build will be performed without KTutorial support (unless you call find_package
with the
REQUIRED
option, which would cause the configuration to fail, and the build not to be performed).
Example 3.1. CMakeLists.txt changes
... find_package(KDE4 REQUIRED) find_package(KTutorial) ... if(KTUTORIAL_FOUND) add_definitions(-DKTUTORIAL_FOUND) include_directories(${KTUTORIAL_INCLUDE_DIRS}) endif(KTUTORIAL_FOUND) ... if(KTUTORIAL_FOUND) target_link_libraries(applicationTarget ${KTUTORIAL_LIBRARIES}) endif(KTUTORIAL_FOUND) ) ...
KTutorial uses XMLGUI technology to merge its menu entry with those of the application using it. So your application must also use XMLGUI (unless you customize KTutorial, refer to the section called “KTutorial customization” section for further information). If you don't know if you are using XMLGUI, you are probably doing it, as it is the rule more than the exception in KDE applications.
If you are using XMLGUI, you will have an applicationnameui.rc
file, where
applicationname
is, of course, the name of your application.
This file, combined with a general KDE one, sets the menus and toolbars of your application. In order to show KTutorial in the right place a little change must be done. Why it can't be done automatically by KTutorial depends on XMLGUI internals and is out of the scope of this document. If you are curious, and know Spanish, I wrote an explanation in Añadiendo la entrada "Tutoriales" al menú ayuda de KDE.
KTutorial uses a
menu item to show the tutorial manager dialog. This item must appear under menu, but not anywhere. To keep a consistent menu order between applications, the item must be the first one in the area for application specific menu items.To do this, just define the group ktutorial as the first element in Help menu, like shown in the next example.
Example 3.2. applicationnameui.rc changes
<gui name="applicationname"> ... <MenuBar> ... <Menu name="help" > <DefineGroup name="ktutorial" /> ... </Menu> </MenuBar> </gui>
Note that, if KTutorial is not installed, this will have no effect in the menus of your application.
Now, the changes in the code of the application. The changes needed when no KTutorial customization is used are very easy to do, although they must be done in the right point in the sequence of initialization of the application.
As you are using XMLGUI, there must be a call to the inherited method setupGUI
somewhere during the creation of your application main class (the one derived from KXmlGuiWindow
).
The method setup(KXmlGuiWindow*)
in KTutorial
class must be called before calling setupGUI
.
Once KTutorial is set up, C++ tutorials can be registered with it (scripted tutorials are registered automatically), and you are done.
Oh, and note the use of the KTUTORIAL_FOUND
definition to perform conditional compilation.
Example 3.3. Code changes to setup KTutorial
... #ifdef KTUTORIAL_FOUND #include <ktutorial/KTutorial.h> #endif ... ApplicationMainWindow::ApplicationMainWindow(QWidget* parent): KXmlGuiWindow(parent) { ... #ifdef KTUTORIAL_FOUND ktutorial::KTutorial::self()->setup(this); ktutorial::KTutorial::self()->registerTutorial(new TutorialDerivedClass()); #endif ... setupGUI(); }