<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook V3.1-Based Variant V1.0//EN" [
 <!ENTITY kdevelop "<application>kdevelop</application>">
 <!ENTITY latex "<application>LaTeX</application>">
 <!ENTITY tex "<application>TeX</application>">
 <!ENTITY etago "</">
 <!ENTITY % addindex "IGNORE">
 <![ %addindex; [ <!ENTITY docindex SYSTEM "docindex.docbook"> ]]>
]>
<book lang="de">
<bookinfo>
<title>Das KDevelop-Programmierhandbuch</title>
<subtitle>Leitfaden zur C++-Anwendungsentwicklung f&uuml;r das K Desktop Environment (KDE) mit Hilfe der KDevelop-IDE in der Version 1.2</subtitle>
<authorgroup>
<author>
<firstname>Ralf</firstname>
<surname>Nolden</surname>
<affiliation>
<orgname>Das KDevelop-Team</orgname>
<address><email>Ralf.Nolden@post.rwth-aachen.de</email></address>
</affiliation>
</author>
</authorgroup>
<date>21/03/2000</date>
<releaseinfo>1.02.01</releaseinfo>
<abstract>
<para>
Dieses Handbuch ist selbst Bestandteil der integrierten Entwicklungsumgebung KDevelop 
und unterliegt daher ebenso der GNU General Public License (siehe auch
<link linkend="Copyright">Copyright</link>).</para>
</abstract>
<keywordset>
<keyword>KDE</keyword>
</keywordset>
</bookinfo>

<chapter id="introduction">
<title>Introduction</title>

<para>As Unix Systems are becoming more and more popular to even beginners working with computer machines due to its advantages in regards of
stability and functionality, most are somehow disappointed, because those applications don't have a consistent look and each one
behaves different from another. With KDE, developers have an almost perfect way to create first-class applications for Unix desktop
systems to get a wider user community by the mere quality their applications have to offer. Therefore, KDE becomes more and more
popular as a base for programming design, and developers want to take advantage of the possibilities that the system has to offer.</para>

<sect1 id="what-you-should-know-already">
<title>What you should know already</title>

<para>For making the best use of this programming handbook, we assume that you already know about the C++ programming language; if not, you
should make yourself familiar with that first. Information about C++ is available through various sources either in printed form at
your local bookstore or by tutorials found on the Internet. Knowledge about the design of Graphical User Interfaces is not required, as
this handbook tries to cover the application design for KDE programs, which also includes an introduction into the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> toolkit as well
as the KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> and the design of User Interfaces. Also, you should have made yourself comfortable with KDevelop by reading
<ulink url="../index.html">The User Manual to KDevelop</ulink>, which contains a descriptive review of the functionality provided by
the IDE.</para>
</sect1>

<sect1 id="about-this-handbook">
<title>About this Handbook</title>

<para>This handbook has been written to give developers an introduction into KDE application development by using the KDevelop
Integrated Development Environment.</para>

<para>The following chapters therefore give an introduction on how to create projects, explains the sourcecodes already generated and shows
how to extend the given sources on various topics such as toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s, menu bars and view areas.</para>

<para>Then the dialogeditor is discussed in detail, explaining how widgets are created and covers widget properties settings in detail
for all provided widgets.</para>

<para>Finally, you will learn about several topics that will complete your knowledge in regards of project design and helps you work out
additional issues besides coding such as adding API <indexterm remap="idx"><primary>API</primary></indexterm> documentation and extending online-manuals.</para>

<para><emphasis remap="bf">In the next chapter</emphasis></para>

<para>we'll take a look at the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> and KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm>, showing basic concepts and why things are the way they are.
Also, we will discuss how to create the tutorial applications provided with the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> toolkit by using KDevelop, so beginners can already
see first results with a few steps, and thereby will learn how to make use of some of KDevelop's best features.</para>

<para><emphasis remap="bf">In the following chapters</emphasis> you will learn:
<itemizedlist>
<listitem>
<para>how to create an application with the KAppWizard,</para>
</listitem>
<listitem>
<para>what the project skeleton already provides,</para>
</listitem>
<listitem>
<para>what the code already created means,</para>
</listitem>
<listitem>
<para>how to create your own views,</para>
</listitem>
<listitem>
<para>how to extend your application's functionality by dialog, menu bars and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s</para>
</listitem>
<listitem>
<para>how to make your application user friendly by providing help functions and</para>
</listitem>
<listitem>
<para>how to write SGML <indexterm remap="idx"><primary>SGML</primary></indexterm> online documentation.</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="additional-information">
<title>Additional Information</title>

<para>Additional information about Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>/KDE programming is available by various sources:</para>

<para><itemizedlist>
<listitem>
<para><emphasis>Programming with Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></emphasis> by Matthias Kalle Dalheimer, published by O'Reilly (see <ulink url="http://www.oreilly.com">\|\|</ulink>, covering
almost all aspects of the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> GUI toolkit and contains examples as well.</para>
</listitem>
<listitem>
<para><ulink url="../index.html">The User Manual to KDevelop</ulink>, provided with the KDevelop IDE,</para>
</listitem>
<listitem>
<para><emphasis>Online-Reference</emphasis> to the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>-library, provided with your copy of the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> toolkit in
HTML and available as PostScript on <ulink url="http://www.troll.no">\|\|</ulink></para>
</listitem>
<listitem>
<para>On the Internet, see
<itemizedlist>
<listitem>
<para>the Troll Tech web site at <ulink url="http://www.troll.no">\|\|</ulink>,</para>
</listitem>
<listitem>
<para>the KDE web site at <ulink url="http://www.kde.org">\|\|</ulink>,</para>
</listitem>
<listitem>
<para>the KDE developer web site at <ulink url="http://developer.kde.org">\|\|</ulink></para>
</listitem>
<listitem>
<para>the KDevelop home page at <ulink url="http://www.kdevelop.org">\|\|</ulink></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>

<para>Additionally, you should look for help by subscribing to the various mailing lists, whose addresses are available on the mentioned
web sites, and on the Usenet newsgroups dedicated to users of KDE and Unix Systems as well as about the C and C++ programming language.</para>

<para>For obtaining help about the KDevelop IDE, you should send requests to our mailinglist at <ulink url="mailto:kdevelop@fara3.cs.uni-potsdam.de">kdevelop@fara3.cs.uni-potsdam.de</ulink>. Mind that the KDevelop team is dedicated to
provide the means to enable you to program applications and therefore is not intended as a technical support team in cases where the
applications you're developing don't work due to implementation errors or misconfigurations of your operating system. By this, we ask
all users to take advantage of the mailinglist in any case you're running into problems with the use of the IDE itself, as well as for
bug reports and suggestions for improving the functionality of the development environment.</para>
</sect1>
</chapter>

<chapter id="the-kde-and-qt-qt-libraries">
<title>The KDE and Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Libraries</title>

<para>The Norwegian company Troll Tech (<ulink url="http://www.troll.no">\|\|</ulink>) provides a so-called GUI toolkit, named Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>. Thereby, GUI means
"<emphasis remap="bf">G</emphasis>raphical <emphasis remap="bf">U</emphasis>ser <emphasis remap="bf">I</emphasis>nterface", and therefore, Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>-based applications represent themselves with buttons, windows etc,
allowing user input by visualizing the functions an application provides. Such a toolkit is needed for developing graphical
applications that run on the X-Window interface on Unix Systems, because X does not contain a pre-defined user interface itself.
Although other toolkits are also available to create User Interfaces, Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> offers some technical advantages that make application design
very easy. Additionally, the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> toolkit is also available for Microsoft Windows systems, which allows developers to provide their
applications for both platforms.</para>

<para>The KDE Team (<ulink url="http://www.kde.org">\|\|</ulink>) joined together with the goal to make using Unix
Systems more friendly, and decided to use the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> toolkit for the development of a window manager on X-Window, plus a variety of tools
included with the KDE packages. The K Desktop Environment therefore contains the window manager <emphasis>kwm</emphasis>, the file manager <emphasis>kfm</emphasis> and
the launch panel <emphasis>kpanel</emphasis> as the main components plus a variety of first-class utilities and applications. After KDE was out, a lot
of developers turned their eyes towards the new environment and what it has to offer them. The KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> are providing essential
methods and classes that make all applications designed with them look similar and consistent, so the user has the great advantage that
he only has to get accustomed with an application's specific usage, not with handling dialogs or buttons. Also, KDE programs integrate
themselves into the desktop and are able to interact with the file manager via drag'n drop <indexterm remap="idx"><primary>drag'n drop</primary></indexterm>, offer session management and many more,
if all features offered by the KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> are used.</para>

<para>Both, the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> toolkit and the KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm>, are implemented in the C++ programming language; therefore applications that make use of
these libraries are also mostly written in C++. In the following chapter, we'll make a short trip through the libraries to see what
already is provided and how Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> and KDE applications <indexterm remap="idx"><primary>KDE applications</primary></indexterm> are created in general.</para>

<sect1 id="the-qt-qt-gui-toolkit">
<title>The Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> GUI Toolkit</title>

<para>As said, the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> library is a toolkit that offers graphical elements that are used for creating GUI applications and are needed for
X-Window programming. Additionally, the toolkit offers:</para>

<para><itemizedlist>
<listitem>
<para>A complete set of classes and methods ready to use even for non-graphical programming issues,</para>
</listitem>
<listitem>
<para>A good solution towards user interaction by virtual methods and the signal/slot mechanism,</para>
</listitem>
<listitem>
<para>A set of predefined GUI-elements, called "widgets", that can be used easily for creating the visible elements</para>
</listitem>
<listitem>
<para>Additional completely pre-defined dialogs that are often used in applications such as progress and file dialogs.</para>
</listitem>
</itemizedlist>
</para>

<para>Therefore knowing the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> classes is very essential, even if you only want to program KDE-applications. To have an impression on the
basic concept how GUI-applications are constructed and compiled, we'll first have a look at a sample Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>-only program; then we'll extend
it to a KDE program.</para>

<sect2 id="the-first-qt-qt-application">
<title>The first Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Application</title>

<para>As usual, programs in C++ have to contain a <literal remap="tt">main()</literal> function, which is the starting point for application execution. As we want
them to be graphically visible in windows and offering user interaction, we first have to know, how they can show themselves to the
user. For an example, we'll have a look at the first tutorial included with the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Online Reference Documentation and explain the basic
execution steps; also why and how the application window appears:</para>

<para><screen>#include &lt;qapplication.h&gt;
#include &lt;qpushbutton.h&gt;

int main( int argc, char **argv )
{
QApplication a( argc, argv );

QPushButton hello( "Hello world!" );
hello.resize( 100, 30 );

a.setMainWidget( &&amp;;hello );
hello.show();
return a.exec();
}
</screen>
</para>

<para>This application merely paints a window containing a button with "Hello world" as its text. As for all Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>-based applications, you first
have to create an instance of the class <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>, represented by <literal remap="tt">a</literal>.</para>

<para>Next, the program creates an instance of the class <literal remap="tt">QPushButton</literal> called <literal remap="tt">hello</literal>,  this will be the button. The constructor of
<literal remap="tt">hello</literal> gets a string as a parameter, which is the contents of the widget visible as the buttons text.</para>

<para>Then the <literal remap="tt">resize()</literal> method is called on the <literal remap="tt">hello</literal> button. This changes the default size a widget (which is in this
case the QPushButton) has when created to the length of 100 pixels and the height of 30 pixels. Finally, the <literal remap="tt">setMainWidget()</literal>
method is called for <literal remap="tt">a</literal> and the <literal remap="tt">show()</literal> method for <literal remap="tt">hello</literal>. The <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> is finally executed by <literal remap="tt">a.exec()</literal>,
enters the main event loop and waits until it has to return an integer value to the overlaying Operating System signaling that the
application is exited.</para>
</sect2>

<sect2 id="the-reference-documentation-for-qt-qt">
<title>The Reference Documentation for Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></title>

<para>Now, let's have a quick look at the reference documentation of the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> library. To do this, start KDevelop and select "Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>-library" from
the "Help"-menu in the menubar. The documentation browser opens and shows you the start page of the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> reference. This will be your
first place to get information about Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, it's classes and the available functions they provide. Also, the above program is the first
that is included in the tutorials section. To get to the classes we want to have a look at, <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> and <literal remap="tt">QPushButton</literal>,
select "Alphabetical Class List" and search for the according names. Follow either of them to have a look at the class documentation <indexterm remap="idx"><primary>class documentation</primary></indexterm>.</para>

<para>For <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>, you will see the constructor and all other methods that this class provides. If you follow a link, you will get
more information about the usage and meaning of the methods, which is very useful when you sometimes can't detect the correct use or
want to have an example. This also counts for the KDE library documentation, which uses a similar documentation type; therefore this is
almost all you have to know about using the class-references with the documentation browser.</para>
</sect2>

<sect2 id="interpretation-of-the-sample">
<title>Interpretation of the Sample</title>

<para>Starting with <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>, you will find all the methods used in our first example:</para>

<para><itemizedlist>
<listitem>
<para>the constructor <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication()</literal>,</para>
</listitem>
<listitem>
<para>the <literal remap="tt">setMainWidget()</literal> method and</para>
</listitem>
<listitem>
<para>the <literal remap="tt">exec()</literal> method.</para>
</listitem>
</itemizedlist>
</para>

<para>The interpretation why we use these methods is very simple:</para>

<para><orderedlist><listitem>
<para>first create an instance of the class <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> with the constructor, so we can make use of the GUI elements provided by
Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>,</para>
</listitem>
<listitem>
<para>create a widget which will be the contents of our program window,</para>
</listitem>
<listitem>
<para>set the widget as the main widget for <literal remap="tt">a</literal>,</para>
</listitem>
<listitem>
<para>execute the <literal remap="tt">a</literal> instance of <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>.</para>
</listitem>
</orderedlist>
</para>

<para>The second object of our program is the pushbutton, an instance of the class <literal remap="tt">QPushButton</literal>. From the two constructors given to
create an instance, we used the second: this accepts a text, which is the label contents of the button; here, it is the string "Hello
world!". Then we called the <literal remap="tt">resize()</literal> method to change the size of the button according to it's contents- the button has to be
larger to make the string completely visible.</para>

<para>But what about the <literal remap="tt">show()</literal> method ?  Now, you see that like most other widgets, <literal remap="tt">QPushButton</literal> is based on a single-inheritance-
here, the documentation says, <emphasis>Inherits</emphasis> <literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal>.  Follow the link to the <literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal> class. This shows you a lot of other
methodss that are inherited by QPushButton, which we'll use later to explain the signal/slot mechanism. Anyway, the <literal remap="tt">show()</literal> method
is not listed, therefore, it must be a method that is provided by inheritance as well. The class that <literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal> inherits, is
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>. Just follow the link again, and you will see a whole bunch of methods that the <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> class provides; including the
<literal remap="tt">show()</literal> method. Now we understand what was done in the sample with the button:</para>

<para><orderedlist><listitem>
<para>create an instance of <literal remap="tt">QPushButton</literal>, use the second constructor to set the buttons text,</para>
</listitem>
<listitem>
<para>resize the widget to it's contents,</para>
</listitem>
<listitem>
<para>set the widget as the main widget of the <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> instance <literal remap="tt">a</literal>,</para>
</listitem>
<listitem>
<para>tell the widget to display itself on the screen by calling <literal remap="tt">show()</literal>, an inherited method from <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>.</para>
</listitem>
</orderedlist>
</para>

<para>After calling the <literal remap="tt">exec()</literal> method, the application is visible to the user, showing a window with the button showing "Hello world!".
Now, GUI programs behave somewhat differently than procedural applications. The main thing here is that the application enters a
so-called "main event loop". This means that the program has to wait for user actions and then react to it, also that for a Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>
application, the program has to be in the main event loop to start the event handling. The next section tells you in short what this
means to the programmer and what Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> offers to process user events.</para>

<para>(For already advanced users: The button has no parent declared in the constructor, therefore it is a top-level widget alone and runs in
a local event loop which doesn't need to wait for the main event loop, see the <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> class documentation <indexterm remap="idx"><primary>class documentation</primary></indexterm> and <ulink url="../kde_libref/index.html">The KDE Library Reference Guide</ulink>)</para>

<para><emphasis remap="bf">Summary:</emphasis></para>

<para>A Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> application always has to have one instance of the class <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>. This provides that we can create windows that are the
graphical representation of programs to the user and allow interaction. The window contents itself is called a "Main Widget", meaning
that all graphical elements are based on the class <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> and can be any type of widget that fits the needs of the application to
communicate with the user. Therefore, all user elements somehow have to inherit <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> to be visible.</para>
</sect2>

<sect2 id="user-interaction">
<title>User Interaction</title>

<para>After reading the last sections, you should already know:
<itemizedlist>
<listitem>
<para>What the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>-library provides in terms of GUI applications,</para>
</listitem>
<listitem>
<para>how a program using Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> is created and</para>
</listitem>
<listitem>
<para>where and how to find information about classes that you want to use with the documentation browser</para>
</listitem>
</itemizedlist>
</para>

<para>Now we'll turn to give the application "life" by processing user events. Generally, the user has two ways to interact with a program:
the mouse and the keyboard. For both ways, a graphical user interface has to provide methods that detect actions and methods that do
something as a reaction to these actions.</para>

<para>The Window system therefore sends all interaction events to the according application. The <indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication then sends them to the active
window as a <literal remap="tt"><indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent</literal> and the widgets themselves have to decide what to do with them. A widget receives the event and processes
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>::event(<indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent*)/, which then decides which event has been executed and how to react; event() is therefore the main event
handler. Then, the <literal remap="tt">event()</literal> function passes the event to so-called event filters, that determine what happened and what to do with
the event. If no filter signs responsible for the event, the specialized event handlers are called. Thereby we can decide between:</para>

<para><emphasis remap="bf">a) Keyboard events --TAB and Shift-TAB keys:</emphasis></para>

<para>changes the keyboard input focus from the current widget to the next widget in the focus order. The focus can be set to widgets by
calling <literal remap="tt">setFocusPolicy<indexterm remap="ncdx"><primary><literal>setFocusPolicy()</literal></primary></indexterm>()</literal> and process the following event handlers:</para>

<para><itemizedlist>
<listitem>
<para><literal remap="tt">virtual void focusInEvent<indexterm remap="ncdx"><primary><literal>focusInEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QFocusEvent</literal></primary></indexterm>QFocusEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void focusOutEvent<indexterm remap="ncdx"><primary><literal>focusOutEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QFocusEvent</literal></primary></indexterm>QFocusEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">b) all other keyboard input:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void keyPressEvent<indexterm remap="ncdx"><primary><literal>keyPressEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QKeyEvent</literal></primary></indexterm>QKeyEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void keyReleaseEvent<indexterm remap="ncdx"><primary><literal>keyReleaseEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QKeyEvent</literal></primary></indexterm>QKeyEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">c) mouse movements:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void mouseMoveEvent ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void enterEvent ( <indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void leaveEvent ( <indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">d) mouse button actions:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void mousePressEvent ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void mouseReleaseEvent ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void mouseDoubleClickEvent ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">e) window events containing the widget:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void moveEvent ( <indexterm remap="cdx"><primary><literal>QMoveEvent</literal></primary></indexterm>QMoveEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void resizeEvent ( <indexterm remap="cdx"><primary><literal>QResizeEvent</literal></primary></indexterm>QResizeEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void closeEvent ( <indexterm remap="cdx"><primary><literal>QCloseEvent</literal></primary></indexterm>QCloseEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para>Note that all event functions are virtual and protected; therefore you can re-implement the events that you need in your own
widgets and specify how your widget has to react. <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> also contains some other virtual methods that can be useful in your
programs; anyway, it is sufficient to know about <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> very well generally.</para>
</sect2>

<sect2 id="object-interaction-by-signals-and-slots">
<title>Object Interaction by Signals and Slots</title>

<para>Now we're coming to the most obvious advantages of the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> toolkit: the signal/slot mechanism. This offers a very handy and useful
solution to object interaction, which usually is solved by <literal remap="tt">callback</literal> functions for X-Window toolkits. As this communication
requires a strict programming and sometimes makes user interface creation very difficult (as referred by the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> documentation and
explained in <emphasis>Programming with Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></emphasis> by K.Dalheimer), Troll Tech invented a new system where objects can emit signals that can be
connected to methods declared as slots. For the C++ part of the programmer, he only has to know some things about this mechanism:</para>

<para><orderedlist><listitem>
<para>the class declaration of a class using signals/slots has to contain the <literal remap="tt">Q&&lowbar;;OBJECT</literal> macro at the beginning (without the
semicolon); and have to be derived from the <literal remap="tt">QObject</literal> class,</para>
</listitem>
<listitem>
<para>a signal can be emitted by the keyword <literal remap="tt">emit</literal>, e.g. <literal remap="tt">emit signal(parameters);</literal> from within any member function
of a class that allows signals/slots,</para>
</listitem>
<listitem>
<para>all signals used by the classes that are not inherited have to be added to the class declaration by a <literal remap="tt">signals:</literal> section,</para>
</listitem>
<listitem>
<para>all methods that can be connected with a signal are declared in sections with the additional keyword <literal remap="tt">slot</literal>, e.g.
<literal remap="tt-bf">public slots:</literal> within the class declaration,</para>
</listitem>
<listitem>
<para>the meta-object compiler <literal remap="tt">moc</literal> has to run over the header file to expand the macros and to produce the implementation (which
is not needed to know.). The output files of <literal remap="tt">moc</literal> are compiled as well by the C++ compiler.</para>
</listitem>
</orderedlist>
</para>

<para>Another way to use signals without deriving from <literal remap="tt">QObject</literal> is to use the <literal remap="tt">QSignal</literal> class- see the reference documentation for
more information and example usage. In the following, we assume you're deriving from <literal remap="tt">QObject</literal>.</para>

<para>This way, your class is able to send signals anywhere and to provide slots that signals can connect to. By using the signals, you don't
have to care about who's receiving it- you just have to emit the signal and whatever slot you want to connect to it can react to the
emission. Also the slots can be used as normal methods during implementation.</para>

<para>Now, to connect a signal to a slot, you have to use the <literal remap="tt">connect()</literal> methods that are provided by <literal remap="tt">QObject</literal> or, where available,
special methods that objects provide to set the connection for a certain signal.</para>

<sect3 id="sample-usage">
<title>Sample Usage</title>

<para>To explain the way how to set up object-interaction, we'll take our first example again and extend it by a simple connection:</para>

<para><screen>#include &lt;qapplication.h&gt;
#include &lt;qpushbutton.h&gt;

int main( int argc, char **argv )
{
QApplication a( argc, argv );

QPushButton hello( "Hello world!" );
hello.resize( 100, 30 );

a.setMainWidget( &&amp;;hello );

connect(&&amp;;hello, SIGNAL( clicked() ), &&amp;;a, SLOT( quit() ));

hello.show();
return a.exec();
}
</screen>
</para>

<para>You see, the only addition to give the button more interaction is to use a <literal remap="tt">connect()</literal> method:
<literal remap="tt">connect(&&amp;;hello, SIGNAL( clicked() ), &&amp;;a, SLOT( quit() ));</literal> is all you have to add. What is the meaning now ? The class
declaration of <literal remap="tt">QObject</literal> says about the <literal remap="tt">connect()</literal> method:</para>

<para><literal remap="tt">bool connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * member )</literal></para>

<para>This means, you have to specify a QObject instance pointer that is the sender of the signal, meaning that it can emit this signal as
first parameter; then you have to specify the signal that you want to connect to. The last two parameters are the receiver object that
provides a slot, followed by the member function which actually <emphasis>is</emphasis> the slot that will be executed on signal emission.</para>

<para>By using signals and slots, your program's objects can interact with each other easily without explicitely depending on the type of
the receiver object. You will learn more about using this mechanism for productive usage later in this handbook. More information about
the Signals/Slot mechanism can also be found in <ulink url="../kde_libref/index.html">The KDE Library Reference Guide</ulink> and the
Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> online reference.</para>
</sect3>
</sect2>
</sect1>

<sect1 id="what-kde-provides">
<title>What KDE provides</title>

<sect2 id="the-kde-1.1.x-libraries">
<title>The KDE 1.1.x libraries</title>

<para>For the time of this writing and due to the fact that KDevelop uses KDE 1.1, I'm referring to the state of the KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> at that
release. The main KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> you'll be using for creating your own KDE applications <indexterm remap="idx"><primary>KDE applications</primary></indexterm> are:</para>

<para><itemizedlist>
<listitem>
<para>the KDE-Core library, containing all classes that are non-visible elements and provide functionality your application may use.</para>
</listitem>
<listitem>
<para>the KDE-UI library, containing user interface elements like menu bars, toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s and the like,</para>
</listitem>
<listitem>
<para>the KFile library, containing the file selection dialogs,</para>
</listitem>
</itemizedlist>
</para>

<para>Additionally, for specific solutions KDE offers the following libraries:</para>

<para><itemizedlist>
<listitem>
<para>the KHTMLW library, offering a complete HTML-interpreting widget that is used by various programs like KDEHelp <indexterm remap="idx"><primary>KDEHelp</primary></indexterm>, KFM, KDevelop,</para>
</listitem>
<listitem>
<para>the KFM library, allowing to use the KDE file manager from within your application.</para>
</listitem>
<listitem>
<para>the KAb library, the KAddressBook. Provides address-book access for e.g. email applications</para>
</listitem>
<listitem>
<para>the KSpell library, offering widgets and functionality to integrate the use of Ispell, the common spell-checker, in applications
like editors; used for the KEdit application.</para>
</listitem>
</itemizedlist>
</para>

<para>Next, we'll have a look at what is needed to turn our first Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> application into a KDE one.</para>
</sect2>

<sect2 id="example-kde-application">
<title>Example KDE Application</title>

<para>In the following, you will see that writing a KDE application is not much more difficult than a Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> application. For the use of KDE's
features, you just have to use some other classes, and you're almost done. As an example, we'll discuss the changed version of the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>
example from above:</para>

<para><screen>#include &lt;kapp.h&gt;
#include &lt;qpushbutton.h&gt;

int main( int argc, char **argv )
{
KApplication a( argc, argv );

QPushButton hello( "Hello world!" );
hello.resize( 100, 30 );

a.setTopWidget( &&amp;;hello );

connect(&&amp;;hello, SIGNAL( clicked() ), &&amp;;a, SLOT( quit() ));

hello.show();
return a.exec();
}
</screen>
</para>

<para>You see that first we have changed from <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> to <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>. Further, we had to change the previously used
<literal remap="tt">setMainWidget()</literal> method to <literal remap="tt">setTopWidget</literal>, which <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> uses to set the main widget. That's it ! Your first KDE
application is ready- you only have to tell the compiler the KDE include path and the linker to link in the KDE-Core library with
-lkdecore.</para>

<para>As you now know what at least the main() function provides generally and how an application gets visible and allows user and object
interaction, we'll go on with the next chapter, where our first application is made with KDevelop- there you can also test everything
which was mentioned before and see the effects.</para>

<para>What you should have looked into additionally until now is the reference documentation for Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, especially the <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>,
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> and <literal remap="tt">QObject</literal> class and the KDE-Core library documentation for the <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> class. The <ulink url="../kde_libref/index-3.html">KDE Library Reference</ulink> handbook also covers a complete description about the invocation of the
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> and <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> constructors including command-line argument processing.</para>
</sect2>
</sect1>
</chapter>

<chapter id="creating-new-applications">
<title>Creating new Applications</title>

<para>The KAppWizard, or also called the KDE Application Wizard, is intended to let you start working on new projects with KDevelop.
Therefore, all your projects are first created by the wizard; then you can start building them and extend the already provided source
skeleton. KAppWizard also allows to choose between several project types according to your project's goals:</para>

<para><itemizedlist>
<listitem>
<para>Normal KDE Application: includes source code for a complete frame structure of a standard KDE application with support for the
Document-View-Controller model, a menubar, toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> and statusbar as well as a set of standard documentation based on SGML <indexterm remap="idx"><primary>SGML</primary></indexterm>, KDE-links
and application icons. This is the application type usually needed for a new KDE project.</para>
</listitem>
<listitem>
<para>Mini KDE Application: contains the same general structure as the Normal KDE Application type but with the difference that the
application's code only provides a widget as a window.</para>
</listitem>
<listitem>
<para>Normal Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Application: works like the normal KDE application by it's code with the difference that the project is based on the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>
library only and doesn't contain KDE support. This is intended for projects that have to be portable to Windows platforms or that don't
want to require KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> by the end-user.</para>
</listitem>
<listitem>
<para>C Application: Is based on the C compiler only and runs in a console.</para>
</listitem>
<listitem>
<para>C++ Application: Is based on the C++ compiler only and runs in a console like the C application, therefore doesn't require
X-Window.</para>
</listitem>
<listitem>
<para>Custom project: creates an empty project without any sourcecode. This is intended for already existing projects to port
to KDevelop or for projects where you want to start from scratch. Mind that you have to take care for makefiles and configure scripts
all by yourself.</para>
</listitem>
</itemizedlist>
</para>

<para>In this chapter we'll see how the KAppWizard can be invoked and what has to be done to generate a KDE application project. This will
also be the initial step of our coverage, where we will create the initial version of a sample project. For all other project types the
steps are usually the same, just you may not have certain options available.</para>

<sect1 id="invoking-kappwizard-and-project-generation">
<title>Invoking KAppWizard and Project Generation</title>

<sect2 id="starting-kappwizard-and-the-first-page">
<title>Starting KAppWizard and the First Page</title>

<para>To start with your first KDE application, open KDevelop. Then select "New..." from the "Project"-menu. The KAppWizard starts, and you
see a tree on the first page, containing the project types. When a type is selected, you see a preview how it will look like after the
initial build process. Choose the KDE subtree, Normal type. Then press the "Next" button on the bottom of the first wizard page. This
will switch to the next page, where you have to set the general project options.</para>
</sect2>

<sect2 id="the-generate-settings-page">
<title>The Generate Settings Page</title>

<para>For our sample application, we choose the project name <literal remap="tt">KScribble</literal>; therefore insert this in the field "Projectname". Then select
the directory you want to have your project build in; the default is your home directory. You can enter the path manually or you can as
well press the button on the right to select the directory by a dialog.</para>

<para>Next, you have to enter the Version number. For the first version, set this to <literal remap="tt">0.1</literal>. It is usual to number new applications that are
in development for the first release lower than 1, and as the initial version will only contain the standard framework, we'll name this
the 0.1 version.</para>

<para>Finally, add your name to the "Author" field and your email address. You can leave all other options to their default settings.</para>

<para>To give you some information about all other options, you can press the right mouse button over the options, and you will get a quick-help
window that describes the option's purpose.</para>

<para>These are:
<itemizedlist>
<listitem>
<para><emphasis remap="bf">generate sources and headers:</emphasis>  generates the application source code</para>
</listitem>
<listitem>
<para><emphasis remap="bf">GNU-Standard-Files:</emphasis>  adds a copy of the GNU-General Public License to the project as well as some standard files for user
information when distributing the package.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">User-Documentation:</emphasis> the user handbook in SGML <indexterm remap="idx"><primary>SGML</primary></indexterm>, already prepared for your project.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">API <indexterm remap="idx"><primary>API</primary></indexterm>-Documentation:</emphasis> creates an initial HTML documentation set for the <emphasis remap="bf">A</emphasis>pplication <emphasis remap="bf">P</emphasis>rogramming <emphasis remap="bf">I</emphasis>nterface.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">lsm-File:</emphasis> the Linux Software Map, used by distribution sites and contains short information about the project's purpose and
requirements.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm>-File: </emphasis> a KDE link that will install your application in the "Applications" tree of the KDE-Panel.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Program-Icon: </emphasis> an Icon that represents your project and can be used to create a link on the desktop.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Mini-Icon: </emphasis> a Mini-version of the program icon that represents your application besides its name in the KDE-Panel and is
shown in your application's dialogs and main-window in the left upper corner.</para>
</listitem>
</itemizedlist>
</para>

<para>Now we'll switch to the next page by pressing the "Next" button again to set the template for the header files of your project.</para>
</sect2>

<sect2 id="the-header-and-source-templates">
<title>The Header and Source Templates</title>

<para>The header template page allows you to automatically include a preface for your header files, containing the filename, the construction
date, the year of the copyright, also your name and your email address. You don't have to change those uppercase parts yourself, as
KAppWizard does this automatically and stores the template for this project, so it can be used later again for creating new files.</para>

<para>The second part of the default header template contains a license information. By default, your project is set under the GNU General
Public License, which is also included in the package. This license is used to protect your source code against any person that just
copies your sources for his own purpose. The General Public License offers you this license for free and thereby protects your rights
as the author, and is common for distributing free software. To get more information about the license, you should read the COPYING
file in the base directory of your new project later which is a copy of the GPL and ships with your application already.</para>

<para>Anyway, you may want to choose another license or another header template you're already using for your projects. Therefore you can
either edit the given default template directly. To do this, you're given the template in an editing window. To clear the default page,
select "New", to use another template, select "Load...", which lets you choose the template file.</para>

<para>When you're done, go to the next page by entering "Next". This is the template page for your source files and is generally the same as
the header template page. The only difference is that this template is used for your implementation files.</para>
</sect2>

<sect2 id="creating-the-project">
<title>Creating the Project</title>

<para>Now that you've set all options for <emphasis>KScribble</emphasis>, select "Next" and press the "Generate" button on the bottom of the wizard window.
If the button is not available, you haven't set all options correctly. To correct any errors, step back in the Wizard with "Back".</para>

<para>Then you'll see what KAppWizard does- he copies all templates to your project directory and creates the new project. After KAppWizard
is finished, the "Cancel" button changes to an "Exit" button to leave the wizard.</para>

<para>After this last step, you're finished with creating a new project. KDevelop then loads it and the tree-views let you browse through the
project's files and classes.</para>

<para>In the next section, we'll discuss how to build and run your first version of <emphasis>KScribble</emphasis> and how the source code is organized.</para>
</sect2>
</sect1>

<sect1 id="the-first-build">
<title>The First Build</title>

<para>After our project is generated, we'll first make a trip through the source code to get a general understanding how the application frame
works. This won't only help to get started but we'll know where to change what in later steps.</para>

<para>When opening the LFV (Logical File Viewer) page on the tree-view, you see some folders that already sort the project files relevant to
the developer. The first two folders are "Header" and "Sources". The Header-folder therefore logically contains all header files of the
project, the Sources-folder all sourcecodes. All other folders are of no interest right now, so we'll turn back here later to see what
they contain.</para>

<para>The two folders then contain the following files:</para>

<para><emphasis remap="bf">Headers:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">kscribble.h :</emphasis> contains the class declaration for the class <emphasis remap="bf">KScribbleApp</emphasis>.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">kscribbledoc.h :</emphasis> contains the class declaration for the class <emphasis remap="bf">KScribbleDoc</emphasis>.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">kscribbleview.h :</emphasis> contains the class declaration for the class <emphasis remap="bf">KScribbleView</emphasis>.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">resource.h :</emphasis> contains a macro collection for the menu-ID's</para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">Sources:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">kscribble.cpp :</emphasis> contains the implementation of the class <emphasis remap="bf">KScribbleApp</emphasis>.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">kscribbledoc.cpp :</emphasis> contains the implementation of the class <emphasis remap="bf">KScribbleDoc</emphasis>.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">kscribbleview.cpp :</emphasis> contains the implementation of the class <emphasis remap="bf">KScribbleView</emphasis>.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">main.cpp :</emphasis> contains the <emphasis remap="bf">main()</emphasis> function implementation.</para>
</listitem>
</itemizedlist>
</para>

<para>Before diving into the sources, we'll let KDevelop build and run our new application. To do this, select "Make" from the "Build"-menu
or hit the according button on the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>. The output window opens from the bottom of KDevelop and lets you see what <literal remap="tt">make</literal> does by
the messages it gives us:</para>

<para><screen>1   Making all in docs
2   make[1]: Entering directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs'
3   Making all in en
4   make[2]: Entering directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs/en'
5   make[2]: Nothing to be done for `all'.
6   make[2]: Leaving directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs/en'
7   make[2]: Entering directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs'
8   make[2]: Nothing to be done for `all-am'.
9   make[2]: Leaving directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs'
10  make[1]: Leaving directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs'
11  make[1]: Entering directory `/home/rnolden/Tutorial/kscribble1/kscribble'
12  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c
    kscribbleview.cpp
13  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c
    kscribbledoc.cpp
14  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c 		
    kscribble.cpp
15  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c
    main.cpp
16  /usr/bin/moc ./kscribble.h -o kscribble.moc.cpp
17  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c
    kscribble.moc.cpp 		
18  /usr/bin/moc ./kscribbledoc.h -o kscribbledoc.moc.cpp
19  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c
    kscribbledoc.moc.cpp
20  /usr/bin/moc ./kscribbleview.h -o kscribbleview.moc.cpp
21  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c
    kscribbleview.moc.cpp

22  /bin/sh ../libtool --silent --mode=link g++  -O0 -g -Wall   -o kscribble -L/opt/kde/lib  -L/usr/X11R6/lib -rpath /opt/kde/lib
    -rpath /usr/X11R6/lib kscribbleview.o kscribbledoc.o kscribble.o main.o kscribble.moc.o kscribbledoc.moc.o kscribbleview.moc.o
    -lkfile -lkfm -lkdeui -lkdecore -lqt -lXext -lX11

23  make[1]: Leaving directory `/home/rnolden/Tutorial/kscribble1/kscribble'
</screen>
</para>

<para>As you see, we've put line numbers in front of each line, which won't appear in your output; it just makes it easier to describe what
happened during the build now. First of all, <literal remap="tt">make</literal> works recursively. That means, it starts from the directory it is invoked in and
then goes into the subdirectories first, returns and processes the next directory. Finally, the directory it was started is processed
and <literal remap="tt">make</literal> finishes. Therefore, <literal remap="tt">make</literal> started in the main project directory containing the sources first. In line 1 and 2, you
see how the <literal remap="tt">make</literal> process goes into the <literal remap="tt">docs</literal> directory, then into the <literal remap="tt">en</literal> subdirectory. As there isn't anything to do, it
leaves these directories until it returns to the source-directory <literal remap="tt">kscribble</literal> in line 11. Then, the real work starts: <literal remap="tt">make</literal>
invokes the compiler, here <literal remap="tt">g++</literal> to compile the source-file <literal remap="tt">kscribbleview.cpp</literal>. The macro <literal remap="tt">-DHAVE&&lowbar;;CONFIG&&lowbar;;H</literal> says that the file
<literal remap="tt">config.h</literal> should be used. This is a file containing macros for the specific platform and application and is located in the main
project directory. The following <literal remap="tt">-I</literal> commands add the include path where <literal remap="tt">g++</literal> can find the includes it needs. These are the
current directory, the main project directory (by <literal remap="tt">-I..</literal>) and the include path for the KDE, Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> and X11 library header files. The
directories for these include files were determined by the <literal remap="tt">configure</literal> script and set in the Makefiles, therefore, the compiler
knows where these are located. Finally, <literal remap="tt">-O0</literal> sets the optimization to zero (no optimization), <literal remap="tt">-g</literal> enables debugging, <literal remap="tt">-Wall</literal>
sets the compiler warnings to <literal remap="tt">all</literal> and <literal remap="tt">-c</literal> tells the compiler to produce an object file, so only compile the file.</para>

<para>This is done for the other source files of our project as well in lines 13-15. Obviously, our sources are compiled, but instead of
linking the object files of the sources to the final binary, we see some other commands. In line 16, you see that the program "moc" is
called to process the header file  <literal remap="tt">kscribble.h</literal>, with its output in <literal remap="tt">kscribble.moc.cpp</literal>. Then, in line 17, this source file is
compiled as well. The same happens with the other project header files until line 21. Now, as the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> toolkit contains the signal/slot
mechanism, but still stays a C++ implementation, you're using certain keywords that are not originally C++ language, such as the
<literal remap="tt">signals:</literal> and <literal remap="tt">slots:</literal> declaration in your classes. This gives you the ability to easily allow object communication for all
class objects that inherit the class <literal remap="tt">QObject</literal>, so you can avoid the usual callback pointer functions. Therefore, the application
needs the sources that implement this functionality, and that is why <literal remap="tt">moc</literal> is called. <literal remap="tt">Moc</literal> is the Meta Object Compiler of the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>
toolkit and builds the implementation for signals and slots mechanisms by parsing the header file and producing a source output that
has to be compiled in the binary. As KDevelop projects use <literal remap="tt">automoc</literal> to determine, which header file needs to be processed, you
don't have to take care for any call on <literal remap="tt">moc</literal> and the C++ compiler on the moc output files. Just remember the rules that make a
class use the signals and slots- inheritance from <literal remap="tt">QObject</literal> or any class that inherits <literal remap="tt">QObject</literal> itself, inclusion of the
<literal remap="tt">Q&&lowbar;;OBJECT</literal> macro (without semicolon !) at the beginning of the class declaration and the declarations for signals and slots.</para>

<para>Finally, your binary is built by the compiler. The output binary is called <literal remap="tt">kscribble</literal>, the linker includes the path for the KDE and
X11 libraries and links the sources against the libraries <literal remap="tt">kfile, kfm, kdeui, kdecore, qt, Xext</literal> and <literal remap="tt">X11</literal>. Then you're done and
make exits.</para>
</sect1>

<sect1 id="the-source-skeleton">
<title>The Source Skeleton</title>

<para>To gain a concept of how a KDE application works, we'll first have a very close look at the source skeleton already provided by the
Application Wizard. As we already saw, we're having a set of source and header files that build the initial code for the application
and make it ready-to-run. Therefore, the easiest way to explain the code is to follow the implementation line by line as it is
processed during executing the program until it enters the main event loop and is ready to accept user input. Then, we'll have a look
at the functionality that enables user interaction and how certain things work. This is probably the best way to explain the framework
and, as it is similar to almost all KDE applications <indexterm remap="idx"><primary>KDE applications</primary></indexterm>, will enable you to read source codes from other projects as well; additionally,
you will know where to change what part of the code to make your applications behave the way they are designed for.</para>

<sect2 id="the-main-function">
<title>The <literal remap="tt">main()</literal> Function</title>

<para>As the application begins its execution with entering the <literal remap="tt">main()</literal> function, this will be the start for our code examination. The
<literal remap="tt">main()</literal> function of <emphasis>KScribble</emphasis> is implemented in the file <literal remap="tt">main.cpp</literal> and can also be found using the Class Browser by
selecting the "Globals" folder, sub-folder "Functions":</para>

<para><screen>1  #include "kscribble.h"
2
3  int main(int argc, char* argv[]) {
4    KApplication app(argc,argv,"KScribble");
5
6    if (app.isRestored())
7    {
8       RESTORE(KScribbleApp);
9    }
10   else
11   {
12      KScribbleApp* kscribble = new KScribbleApp;
13      kscribble-&gt;show();
14      if(argc &gt; 1){
15        kscribble-&gt;openFile(argv[1]);
16      }
17    }
18    return app.exec();
19  }
</screen>
</para>

<para>Now, what happens first is the usual creation of a <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> object, which gets our application name <emphasis>KScribble</emphasis> as a third
parameter. When creating a new <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>, a new <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> instance is created as well which is connected to a configuration
file in $HOME/.kde/share/config/appname + rc which stores all information we want to use when starting application windows. The name we
passed the constructor of <literal remap="tt">app</literal> will be used as the window title later.</para>

<para>Despite of the example code for turning the first Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> application into a KDE one, the following code is somewhat different. After the
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> object is present, we're testing if the application is started by the session management of <literal remap="tt">kwm</literal> or manually by
the user. This can be found out when calling <literal remap="tt">isRestored()</literal> on the <literal remap="tt">app</literal> object, which returns <literal remap="tt">true</literal> for session management
and <literal remap="tt">false</literal> for a normal start.</para>

<para>As session management is a main feature of KDE applications <indexterm remap="idx"><primary>KDE applications</primary></indexterm> and widely used by the framework but a lot more to explain, we'll follow
the <literal remap="tt">else&&lcub;;&&rcub;;</literal> section first; then we'll come back and explain the session functionality in a later step.</para>
</sect2>

<sect2 id="user-application-start">
<title>User Application Start</title>

<para>The <literal remap="tt">else&&lcub;;&&rcub;;</literal> section now creates an instance of the class <literal remap="tt">KScribbleApp</literal> in line 12. This object is called to show itself in line
13 as usual; line 14 determines if a command-line argument has been passed and, as this is usually the name of a file, calls the
<literal remap="tt">kscribble</literal> object to open it with <literal remap="tt">openFile()</literal>.</para>

<para>Note that we didn't call the method <literal remap="tt">setTopWidget(kscribble)</literal> for our application- this is already done by the class that <literal remap="tt">KScribbleApp</literal>
inherits. Now we'll have a look at our <literal remap="tt">KScribbleApp</literal> object- what is it and what does it provide already ?  The only thing we know
until now is that it has to be a Widget to represent the user interface in the main window. Let's turn to the class implementation of
<literal remap="tt">KScribbleApp</literal>, which can be found in the file <literal remap="tt">kscribble.cpp</literal> or by a click on the class icon in the Class Browser. As the
instance is created by the constructor.
First of all, we see that it inherits the class <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>, which is a part of the <literal remap="tt">kdeui</literal> library. This class itself
inherits <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>, so, as usual, we have a normal widget as the top-level window. <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> contains a lot of functionality
that the class <literal remap="tt">KScribbleApp</literal> makes use of. It provides a menubar, toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>, statusbar and session management support. The only thing
we have to do when sub-classing <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> is to create all the objects we need and create another widget that is managed by our
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> instance as the main view in the center of the window; usually this is the place where the user works like a
text-editing view.</para>

<sect3 id="the-constructor">
<title>The Constructor</title>

<para>Let's have a look at the code for the constructor and see how the instance is created:</para>

<para><screen>1   KScribbleApp::KScribbleApp()
2   {
3     config=kapp-&gt;getConfig();
4	
5
6     ///////////////////////////////////////////////////////////////////
7     // call inits to invoke all other construction parts
8     initMenuBar();
9     initToolBar();
10    initStatusBar();
11    initKeyAccel();
12    initDocument();
13    initView();
14
15    readOptions();
16
17    ///////////////////////////////////////////////////////////////////
18    // disable menu and toolbar items at startup
19    disableCommand(ID_FILE_SAVE);
20    disableCommand(ID_FILE_SAVE_AS);
21    disableCommand(ID_FILE_PRINT);
22
23    disableCommand(ID_EDIT_CUT);
24    disableCommand(ID_EDIT_COPY);
25    disableCommand(ID_EDIT_PASTE);
26  }
</screen>
</para>

<para>We see that our config instance of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> now points to the applications configuration, so we can operate
with the configuration file entries later.</para>

<para>Then, all parts of the application that are needed are created by their according member functions that are specific to our main
window:</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">initMenuBar():</emphasis>  constructs the menubar,</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initToolBar():</emphasis>  constructs the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>,</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initStatusBar():</emphasis> creates the statusbar,</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initKeyAccel():</emphasis>  sets all keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s for our application by the global and application specific keyboard
configuration</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initDocument():</emphasis> creates the document object for the application window</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initView():</emphasis>      creates the main widget for our view within the main window</para>
</listitem>
<listitem>
<para><emphasis remap="bf">readOptions():</emphasis>  reads all application specific settings from the configuration file and initializes the rest of the
application such as the recent file list, the bar positions and the window size.</para>
</listitem>
</itemizedlist>
</para>

<para>Finally, we disable some commands that the user can do, because they should not be available in the current application state.
As we now have a general overview how the application window is created, we will look into the details of how the user elements are
constructed by following the above methods.</para>
</sect3>

<sect3 id="the-menubar">
<title>The Menubar</title>

<para>As shown above, the menubar of <emphasis>KScribble</emphasis> is created by the method <literal remap="tt">initMenuBar()</literal>. There, we create a set of
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QPopupMenu</literal></primary></indexterm>QPopupMenu</literal>s that pop up if the user selected a menuentry. Then, we insert them into the menubar and connect to the entries.</para>

<para>First, we create our <literal remap="tt">recent&&lowbar;;file&&lowbar;;menu</literal>, which will contain the names of the last 5 opened files. We have to do this first, because
this menu is inserted into the <literal remap="tt">file&&lowbar;;menu</literal>. Then we add the connection directly- we just retrieve the signal that is emitted by the
menuentry with its entry number and call the <literal remap="tt">slotFileOpenRecent( int )</literal>, which then calls the right file from the recent file list
to be opened.</para>

<para>Then we create our "File"-menu. This will be the menu that will be visible in the menubar. The standard actions are then inserted into
the popup-menu one by one- first the commands for creating a new file, open a file, close a file etc., finally "E&&amp;;xit" to close the
application. All menu entries have to be created in the order as they appear later, so we have to keep an eye on which we want to have
at what place. As an example, we look at the following entries:</para>

<para><screen>file_menu-&gt;insertItem(Icon("fileopen.xpm"), i18n("&&amp;;Open..."), ID_FILE_OPEN );
file_menu-&gt;insertItem(i18n("Open &&amp;;recent"), recent_files_menu, ID_FILE_OPEN_RECENT );
</screen>
</para>

<para>The first one inserts the "Open..." entry. As we want to have it with an icon, we use the <literal remap="tt">insertItem()</literal> method with the icon's
name. To understand the icon loading process, we need to know what or where <literal remap="tt">Icon()</literal> is declared- in fact, it is a macro provided by
the class <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>:</para>

<para><screen>#define Icon(x) kapp-&gt;getIconLoader()-&gt;loadIcon(x)
</screen>

Additionally, it uses the following macro internally to get access to the application object:
<screen>#define kapp KApplication::getKApplication()
</screen>
</para>

<para>This means that the <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> object already contains an Icon loader instance- we only have to get access to it; then it will
load the according icon. As our icons are all from the KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm>, we don't have to take care for anything else- they are installed
on the system automatically, therefore we also don't have to include them into our application package to use them.</para>

<para>After the icon parameter (which is optional), we insert the menuentry name by <literal remap="tt">i18n("&&amp;;Open...")</literal>.  There, we have to watch two
things: first, the entry is inserted with the <literal remap="tt">i18n()</literal> method. Like the <literal remap="tt">Icon()</literal> entry, it is a macro defined in <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal> as
well and calls the <literal remap="tt">KLocale</literal> object of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> to translate the entry to the currently used language:</para>

<para><screen>#define i18n(X) KApplication::getKApplication()-&gt;getLocale()-&gt;translate(X)
</screen>
</para>

<para>Hereby, it should be mentioned that one could think "I don't want to use macros"- you can do that in most cases. But here it is
immanent to use <literal remap="tt">i18n()</literal> because for internationalization the according language files have to be build. As this build process
depends on the <literal remap="tt">i18n</literal> string, you have to use the macro.</para>

<para>As you might have already guessed, the ampersand within menu entries is later interpreted as a line under the following letter in the
menuentry. This allows fast access to the menu command via the keyboard when the user presses the <literal remap="tt">Alt</literal>-key in conjuction with the
underlined letter.</para>

<para>Finally, we're giving the menuentry an ID, which is an integer value by which we can find the entry later. To keep
an overview over the used values, these are defined by macros and are collected in the file <literal remap="tt">resource.h</literal> within your project. For
consistency, these macros are all uppercase and begin with ID&&lowbar;;, then the menu name followed by the entry. This makes it very easy to
remember the sense of each entry anywhere within the code, so you don't have to turn to the menubar implementation again to look up the
entries.</para>

<para>The second example entry shows another variant of the <literal remap="tt">insertItem()</literal> method. Here, we add  the recent&&lowbar;;files&&lowbar;;menu popup menu as a
menuitem. This means, that the entry shows itself with the given string "Open recent", followed by a right arrow. On selection, the
recent file popup menu appears and the user can choose the last file.</para>

<para>Last but not least there are a lot of other ways to insert menu items- the framework keeps this as simple as possible. More information
can be obtained in the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> documentation about the <literal remap="tt"><indexterm remap="cdx"><primary><literal>QMenuData</literal></primary></indexterm>QMenuData</literal> class.</para>

<para>Now, after we created the popup menus <literal remap="tt">file&&lowbar;;menu, edit&&lowbar;;menu</literal> and <literal remap="tt">view&&lowbar;;menu</literal>, we have to include a "Help"-menu as well. We could
do this like the others as well, but the <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> class offers a nice and quick method to cover this:</para>

<para><screen>help_menu = kapp-&gt;getHelpMenu(true, i18n("KScribble\n" VERSION ));
</screen>
</para>

<para>This is all we have to do to get a help menu that contains an entry for the help contents with the F1 keyboard shortcut<indexterm><primary>shortcuts</primary></indexterm>, an about-box
for the application and an about-box for the KDE (which can be disabled by calling <literal remap="tt">getHelpMenu(false,...);</literal>).  The contents for our
applications about-box is set with the <literal remap="tt">i18n()</literal> string again- VERSION takes the macro that is defined for the project version number
in the file <literal remap="tt">config.h</literal>, so we don't have to change this every time manually when we want to give out a new release. Feel free to add
any information about your application here, e.g. your name, email address, copyright and the like.</para>

<para>Now we only have to insert the pop-ups into the menubar. As <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> already constructs a menubar for us, we just insert them
by calling <literal remap="tt">menuBar()-&gt;insertItem();</literal>.</para>

<para>What is left to do is to connect the menu-entries with the methods they will execute. Therefore, we connect each popup menu by its
signal <literal remap="tt">activated( int )</literal> to a method <literal remap="tt">commandCallback( int )</literal>, which contains a <literal remap="tt">switch</literal> statement that calls the according
methods for the menu entries. Additionally, we connect the pop-ups by their signal <literal remap="tt">highlighted( int )</literal> to provide statusbar help on
each entry. Whenever the user moves his mouse or keyboard focus <indexterm remap="idx"><primary>keyboard focus</primary></indexterm> to an entry, the statusbar then shows the according help message.</para>

<para>After we finished with the menubar, we can continue with the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> in the following section. Mind that an instance of a
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> can only have one menubar visible at a time; therefore if you want to construct several menu bars, you have to create
them separately with instances of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KMenuBar</literal></primary></indexterm>KMenuBar</literal> and set one of them by the according methods of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> as the current
menubar. See the class documentation <indexterm remap="idx"><primary>class documentation</primary></indexterm> of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KMenuBar</literal></primary></indexterm>KMenuBar</literal> for more detailed information about how to extend the features, also see <link linkend="Configuring-Menubars-and-Toolbars">Configuring Menubars and Toolbars</link>.</para>
</sect3>

<sect3 id="the-toolbar">
<title>The Toolbar</title>

<para>The creation of toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s now is even simpler than that of menubars. As <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> already provides toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s, which are created
by the first insertion, you are free to create several ones. Just add the buttons for the functions you want to provide:</para>

<para><screen>toolBar()-&gt;insertButton(Icon("filenew.xpm"), ID_FILE_NEW, true, i18n("New File") );
</screen>
</para>

<para>This adds a left-aligned button with the icon "filenew.xpm" with the according ID to the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>. The third parameter decides if the
button should be enabled or not; by default we set this to <literal remap="tt">true</literal>, because our <literal remap="tt">disableCommand()</literal> methods at the end of the
constructor do this for us automatically for both menu and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> entries. Finally, the last parameter is uses as a so-called
"Quick-Tip"- when the user moves the mouse pointer over the button so that it gets highlighted, a small window appears that contains a
short help message, whose contents can be set here.</para>

<para>Finally, all toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> buttons are connected to our <literal remap="tt">commandCallback()</literal> method again by their signal <literal remap="tt">clicked()</literal>. On the signal
<literal remap="tt">pressed()</literal>, we let the user receive the according help message in the statusbar.</para>

<para><emphasis remap="bf">Additional Information:</emphasis></para>

<para>As toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s are created using the class <literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal>, you should have a look at the according documentation. With
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal>, a lot of things needed in a toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> can be realized such as delayed pop-ups if your button wants to pop up a menu
when the button keeps being pressed or even widgets like combos. Also, by default, the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> fills the complete width of the
window, which makes it look nice for using a single bar. When using more than one, you should also think about setting the bar
size to end at the most right button, so other bars can be displayed in the same row below the menubar. We will discuss certain
techniques about designing and extending toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s in section <link linkend="Configuring-Menubars-and-Toolbars">Configuring Menubars and Toolbars</link>.</para>
</sect3>

<sect3 id="the-statusbar">
<title>The Statusbar</title>

<para>The statusbar is, as well as the other bars, already provided by the <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> instance, so we just have to insert our items as
we want to. By default, the framework contains only one entry that displays statusbar help. For a lot of applications this may not
last; then you would add the entries you need for displaying e.g. coordinates and the like.</para>

<para>Also, an application can only have one statusbar at a time like a menubar. If you want to construct several ones, you should create
them separately and set the current bar by the according method of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>.  The statusbar also offers to insert widgets,
which can be used to produce nice habits for displaying progress-bars like KDevelop does. Refer to the class documentation <indexterm remap="idx"><primary>class documentation</primary></indexterm> of
<literal remap="tt">KStatusBar</literal>.</para>
</sect3>

<sect3 id="keyboard-accelerators">
<title>Keyboard Accelerators</title>

<para>With reaching the method <literal remap="tt">initKeyAccel()</literal>, we already constructed the standard items of an application main window- the menubar,
toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> and statusbar. Indeed, we didn't set any keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s by which advanced users that only want
to work with the keyboard have a quick access to certain commands that are used most often during work with our program. To do this, we
could have inserted the accelerator<indexterm><primary>accelerator</primary></indexterm> keys by the insertion of the menu-items for example, but KDE offers a good
solution to construct and maintain keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s. A lot of users want to have them configurable on one hand
and on the other standard accelerator<indexterm><primary>accelerator</primary></indexterm>s should be the same over all applications. Therefore, the KDE control center
offers configuring standard keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s globally by using the <literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal> class. Additionally, the
KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> contain a widget that lets users configure application specific keyboard shortcut<indexterm><primary>shortcuts</primary></indexterm>s easily. As the
application framework only uses menu-items that have standard actions such as "New" or "Exit", these are set by the method
<literal remap="tt">initKeyAccel()</literal>. Standard actions just have to be connected, for your application specific keyboard values, you have to insert them
first by specifying the keyboard accelerator<indexterm><primary>accelerator</primary></indexterm> name and then connect them. As our accelerator<indexterm><primary>accelerator</primary></indexterm>s are
all present in the menubar, we have to change the accelerator<indexterm><primary>accelerator</primary></indexterm>s for the popup entries. Finally we call
<literal remap="tt">readSettings()</literal>, which reads the current settings from the root window of KDE containing the configuration of standard
accelerator<indexterm><primary>accelerator</primary></indexterm>s, then the settings for accelerator<indexterm><primary>accelerator</primary></indexterm>s specified in the application's config file. When
we're going further into our example project, we will also talk about how to configure our application specific
accelerator<indexterm><primary>accelerator</primary></indexterm>s by a configuration dialog, see <link linkend="Configuring-Menubars-and-Toolbars">Configuring Menubars and Toolbars</link> for that part of the development process.</para>
</sect3>

<sect3 id="the-document-view-model">
<title>The Document-View Model</title>

<para>The next two member function calls, <literal remap="tt">initDocument()</literal> and <literal remap="tt">initView()</literal>, are finally building the part that the application windows
are supposed to provide to the user: an interface to work with data that the application is supposed to manipulate; and that is also
the reason why the application framework contains three classes, an <literal remap="tt">*App</literal>, <literal remap="tt">*View</literal> and <literal remap="tt">*Doc</literal> class. To understand, why this
structure is helpful, we'll look a bit aside the actual code and introduce some theory, then we'll switch to the program again to see
how the KDevelop frameworks support such a model.</para>

<para>Basically, all what has been explained about the framework is that we need an application instance that contains a main window. This
window is responsible to provide the basic interface for the user- it contains the menubar, toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s and statusbar and the event
controlling for user interaction. Also, it contains an area, that is described as a "view". Now, the purpose of a view is generally, to
display the data that the user can manipulate, e.g. a part of a text file. Although the text file is probably larger than the view is
able to display on the screen, it offers the user to go to the part that he wants to see (therefore it is a view), and there the user
can as well change the data of the file contents. To give the programmer a better way to separate parts of the application by code, the
Document-View Model has been invented. Although not a standard, it provides a structure how an application should work:</para>

<para><itemizedlist>
<listitem>
<para> The application contains a controller object,</para>
</listitem>
<listitem>
<para> a View object that displays the data the user works with</para>
</listitem>
<listitem>
<para> and a Document object that actually contains the data to manipulate.</para>
</listitem>
</itemizedlist>
</para>

<para>Back to the example of working with a text file- there, this model would work the way that the Document would read the file contents and
provides methods to change the data as well as to save the file again. The view then processes the events that the user produces by the
keyboard and the mouse and uses the document object's methods to manipulate the document data.</para>

<para>Finally, the controller object is responsible for user interaction by providing the document and the view objects as well as the
interfaces to send commands like opening and saving. Additionally, certain methods of the view object can be provided by commands that
can be accessed via keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s or the mouse on menubars and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s.</para>

<para>This Document-View model has some advantages- it separates the program's code more object-oriented and by this offers more flexibility
in general, e.g. the same document object could be displayed by two views at the same time; either by a new view in a new window or by
tiling the current one that then contains two view object that build the actual window view region.</para>

<para>Now, if you're coming from MS-Windows systems you may have some experience with that- the MFC already provide a document model that is
ready to use. For KDE and Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> applications, things are a bit different. Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> is a powerful toolkit as it provides the most
needed classes, widgets etc. But there wasn't any intention to take care of the document-view model, and as KDE is inheriting Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>,
there weren't any tendencies to introduce such a model either. This somehow has its reason in the fact that usually X-applications
don't work with an MDI (Multiple Document Interface).  Each main window is responsible for its data and that reduces the need of a
document model to the fact that methods to work on documents are always implied into widgets. The only exception from this currently is
the <emphasis>KOffice</emphasis> project that is intended to provide a complete office suite of applications like a word processor, a spreadsheet etc.
Technically, this is realized by two changes two the normal usage of Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> and KDE:</para>

<para><itemizedlist>
<listitem>
<para>KOffice uses KOM and the free MICO implementation of CORBA for object communication,</para>
</listitem>
<listitem>
<para>the KOffice applications use a document-view model to allow all applications to work with any KOffice data objects</para>
</listitem>
</itemizedlist>
</para>

<para>But as KDevelop currently targets on using the current libraries of KDE 1.1.x and Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> 1.4x, we can't use this model by default-
this will come in further releases of a KDE 2, which will (hopefully) contain two new major changes in relation to the current
situation:
<orderedlist><listitem>
<para>an MDI interface for <indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</para>
</listitem>
<listitem>
<para>the KOM libraries that provide a document model</para>
</listitem>
</orderedlist>
</para>

<para>Therefore, the current way for application developers can be to either implement all needed document methods within their view or to
try to reproduce a document model by themselves. KDevelop therefore contains such a reproduction by providing the needed classes and
the basic methods that are generally used for a Document-View model with the application frameworks for Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> and KDE.</para>

<para>Back to the code, you now can imagine the purpose of the two methods we mentioned at the beginning of this section: the
<literal remap="tt">initDocument()</literal> and <literal remap="tt">initView()</literal> functions. The <literal remap="tt">initDocument()</literal> constructs the document object that represents the
application window data and initializes the basic attributes like setting the modification bit that indicates if the data currently
used has been changed by the user. Then, the <literal remap="tt">initView()</literal> method constructs the <literal remap="tt">*View</literal> widget, connects it to the document and
calls the <literal remap="tt">setView()</literal> method of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> to tell the <literal remap="tt">*App</literal> window to use the <literal remap="tt">*View</literal> widget as it's center view.</para>

<para>For the developer, it is important to know that during the development process he has to:</para>

<para><itemizedlist>
<listitem>
<para>re-implement the virtual methods for mouse and keyboard events provided by <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> in the <literal remap="tt">*View</literal> object to provide the
means to manipulate data,</para>
</listitem>
<listitem>
<para>re implement the <literal remap="tt">paintEvent()</literal> of <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> in the <literal remap="tt">*View</literal> object to repaint() the view after changes,</para>
</listitem>
<listitem>
<para>complete the implementation for printing the document via the printing method of the <literal remap="tt">*View</literal> object,</para>
</listitem>
<listitem>
<para>add the serialization for the <literal remap="tt">*Doc</literal> object to provide file loading and saving,</para>
</listitem>
<listitem>
<para>add the document data structure implementation to the <literal remap="tt">*Doc</literal> object that is representing the document data logically in the
memory.</para>
</listitem>
<listitem>
<para>add any methods that have to be accessible by the user via accelerator<indexterm><primary>accelerator</primary></indexterm> keys and menus/toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s.</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="application-configuration">
<title>Application Configuration</title>

<para>Now, after we created all instances of the <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> instance of our application to create the first window, we have to
initialize certain values that influence the look of the program. For this, we call <literal remap="tt">readOptions()</literal>, which gets all values and calls
the methods needed to set the according attributes. The KDE-Core library contains the class <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> that provides a good
possibility to store values in configuration files as well as to read them in again. Also, as each <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> instance
creates it's resource file already, we only have to access this file and create our values. As <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> provides us the file
object, we have to use the class <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfigBase</literal></primary></indexterm>KConfigBase</literal> to read and write all entries. As writing is very easy to do with
<literal remap="tt">writeEntry()</literal> methods, reading depends on the attribute type which we want to initialize. Generally, an entry in the configuration
file contains a value name and a value. Values that belong together in some context can be collected in groups, therefore we have to
set the group name before we access the value afterwards; the group has to be set only once for reading a set of attributes that are in
the same group. Let's have a look at what we want to read in:</para>

<para><screen>1   void KScribbleApp::readOptions()
2   {
3
4      config-&gt;setGroup("General Options");
5
6      // bar status settings
7      bool bViewToolbar = config-&gt;readBoolEntry("Show Toolbar", true);
8      view_menu-&gt;setItemChecked(ID_VIEW_TOOLBAR, bViewToolbar);
9      if(!bViewToolbar)
10       enableToolBar(KToolBar::Hide);
11
12     bool bViewStatusbar = config-&gt;readBoolEntry("Show Statusbar", true);
13     view_menu-&gt;setItemChecked(ID_VIEW_STATUSBAR, bViewStatusbar);
14     if(!bViewStatusbar)
15       enableStatusBar(KStatusBar::Hide);
16
17     // bar position settings
18     KMenuBar::menuPosition menu_bar_pos;
19     menu_bar_pos=(KMenuBar::menuPosition)config-&gt;readNumEntry("MenuBar Position", KMenuBar::Top);
20
21     KToolBar::BarPosition tool_bar_pos;
22     tool_bar_pos=(KToolBar::BarPosition)config-&gt;readNumEntry("ToolBar Position", KToolBar::Top);
23
24     menuBar()-&gt;setMenuBarPos(menu_bar_pos);
25     toolBar()-&gt;setBarPos(tool_bar_pos);
26
27     // initialize the recent file list
28     recent_files.setAutoDelete(TRUE);
29     config-&gt;readListEntry("Recent Files",recent_files);
30
31     uint i;
32     for ( i =0 ; i &lt; recent_files.count(); i++){
33       recent_files_menu-&gt;insertItem(recent_files.at(i));
34     }
35
36     QSize size=config-&gt;readSizeEntry("Geometry");
37     if(!size.isEmpty())
38       resize(size);
39   }
</screen>
</para>

<para>As we have seen in one of the above code parts, the first action our constructor does was:</para>

<para><screen>config=kapp-&gt;getConfig();
</screen>
</para>

<para>which sets the <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> pointer <literal remap="tt">config</literal> to the application configuration. Therefore, we don't have to care for the location of
the configuration file. Indeed, the file is, according to the KDE File System Standard (KDE FSS), located in
<literal remap="tt">&&dollar;;HOME/.kde/share/config/</literal>; we will have a closer look about the KDE FSS in a later step when we're setting installation
locations for project files. As the config file is placed in the user's home directory, each user has it's own appearance of his
application except for values that are located in a system wide configuration file that can optionally be created and installed by the
programmer in the KDE directory. But, although this could help in some cases, we should avoid any dependency of our application towards
the existing of file entries. Therefore, all read methods provided by <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfigBase</literal></primary></indexterm>KConfigBase</literal> allow to add a default value to be used
when the entry doesn't exist. Another thing important to a programmer is that the configuration file is stored in plain text, and this
is for some reasons as well as you have to watch some criteria:</para>

<para><itemizedlist>
<listitem>
<para>the user is able change the configuration file by a plain text editor</para>
</listitem>
<listitem>
<para>if the user wants to change values by hand, the entries should be very transparent to determine their purpose</para>
</listitem>
<listitem>
<para>for entries that have to be saved, but are critical in terms of security like passwords, you have to look for a proper solution
to ensure the security.</para>
</listitem>
</itemizedlist>
</para>

<para>Now that we know the basics, we're going to analyze the code. As said, we only have to use our config pointer to access the values.
First, in line 4, we set the current group to "General Options". This indicates that the values used are somewhat general attributes
for the application. Then we read the values for the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> and statusbar- these have to be saved when the application closes to
restore their status again when the user restarts the program. As the bars can only be on or off, we use a boolean value, therefore,
our method is <literal remap="tt">readBoolEntry()</literal>. The process is identical for both bars, so we only have a look at the lines 7-10 to watch what's
happening for the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>. First, we read the value into the temporary variable <literal remap="tt">bViewToolbar</literal> at line 7. The value name in
the file is "Show Toolbar" and, if the value is not present (which would be the case the first time the application starts), the
default value is set to <literal remap="tt">true</literal>. Next, we set the checkmark for the menuentry for en-/disabling the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> by this value: we
call <literal remap="tt">setItemChecked()</literal> on the view menu, entry <literal remap="tt">ID&&lowbar;;VIEW&&lowbar;;TOOLBAR</literal> with our attribute. Finally, we set the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> to use
the value. By default, the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> is visible, therefore, we only have to do something if <literal remap="tt">bViewToolbar</literal> is <literal remap="tt">false</literal>. With
<literal remap="tt">enableToolBar()</literal> (line 10) we're setting the bar to hide itself if it is disabled.</para>

<para>Next, we have to read the bar positions. As the user might have changed the bar position by dragging a bar with the mouse to another
view area, these have to be saved as well and their status restored. Looking at the classes <literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal> and
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KMenuBar</literal></primary></indexterm>KMenuBar</literal>, we see that the bar positions can be:</para>

<para><screen>enum BarPosition {Top, Left, Bottom, Right, Floating, Flat}
</screen>
</para>

<para>As this value has been written in a numeric value, we have to read it with <literal remap="tt">readNumEntry()</literal> and convert it to a position value. With
<literal remap="tt">setMenuBarPos()</literal> and <literal remap="tt">setBarPos()</literal> we tell the bars where to show up.</para>

<para>Now you probably have noticed that our "File" menu contains a menu for recently used files. The filenames are stored in a list of
strings, which has to be saved on application closing and now has to be read in to restore the menu. First, we initialize the list with
the entries stored by using the <literal remap="tt">readListEntry()</literal>. Then, in a <literal remap="tt">for-</literal>loop, we create a menu entry for each list item.</para>

<para>Finally, we only have to take care for the geometry of our window. We read in the appearance by a <literal remap="tt">QSize</literal> variable containing an x
and y value for width and height of the window. As the window is initialized by <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>, we don't have to take care for
a default value and only will use <literal remap="tt">resize()</literal> if the entry is not empty.</para>

<para>What is left to explain on application construction is that we initially have to disable available user commands that shouldn't be
available if some instances don't match the needed criteria. These are file saving and operations that are using the clipboard. During
the application's lifetime, we have to take care of these several times, but which is quite easy. The framework only gives us two
methods to enable/disable menubar and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> items with one method call at the same time.</para>
</sect3>

<sect3 id="executing">
<title>Executing</title>

<para>During the past section, we have only monitored what happens during the constructor call of our <literal remap="tt">KScribbleApp</literal> instance providing us
the main window. After returning to the <literal remap="tt">main()</literal> function, we have to call <literal remap="tt">show()</literal> to display the window. What is different from
any <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> or <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> here is that when we're using <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> as the instance for our
main widget, we don't have to set it with <literal remap="tt">setMainWidget()</literal>. This is done by <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> itself and we don't have to
take care of that.
The only thing left then is to interpret the command-line. We get the command-line option and ask, if <literal remap="tt">int argc</literal> is &gt; 1, which
indicates that the user called our application with <literal remap="tt">kscribble filename&&lowbar;;to&&lowbar;;open</literal>. Our window is then asked to open the file by it's
name and calls <literal remap="tt">openDocumentFile()</literal> with the filename.</para>

<para>The last line of the <literal remap="tt">main()</literal> function does the known job: it executes the application instance and the program enters the event
loop.</para>

<para>Now, in section <link linkend="The-main-Function">The main() Function</link>, we started to separate the execution process by
<literal remap="tt">if( app.isRestored() )</literal> and described the usual invocation process. The following now gives an introduction to session
management and how our application makes use of this.</para>
</sect3>
</sect2>

<sect2 id="invocation-by-session-management">
<title>Invocation by Session Management</title>

<para>As we said, the <literal remap="tt">main()</literal> function tests, if the application is invoked by the session manager. The session manager is responsible to
save the current status of all open application windows on the user's desktop and has to restore them when the user logs in the next
time, which means that the application is not started by the user but automatically invoked. The part of the code which is executed
was:
<screen>6    if (app.isRestored())
7    {
8       RESTORE(KScribbleApp);
9    }
</screen>
</para>

<para>In <link linkend="The-main-Function">The main() Function</link>, we stated that we test the invocation by asking
<literal remap="tt">app.isRestored()</literal>. Then line 8 gets executed. It looks like a simple statement, but in fact this will result in a complex execution
process which we want to follow in this section.</para>

<para>RESTORE() itself is a macro provided by <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>. It expands to the following code:</para>

<para><screen>if (app.isRestored()){
  int n = 1;
  while (KTMainWindow::canBeRestored(n)){
    (new KScribbleApp)-&gt;restore(n);
    n++;
  }
}
</screen>
</para>

<para>This will restore all application windows of the class <literal remap="tt">KScribbleApp</literal> by creating the instances and calling <literal remap="tt">restore()</literal> to the
new window. It is important to realize that if your application uses several different widgets that inherit <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>, you have
to expand the macro and determine the type of the top widgets by using <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow::classNameOfToplevel(n)</literal> instead of the class
<literal remap="tt">KScribbleApp</literal>.
The <literal remap="tt">restore()</literal> method then reads the part of the session file that contains the information about the window. As <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>
stores all of this for us, we don't have to care for anything else. Only information that belong to our specific instance of
<literal remap="tt">KScribbleApp</literal> has to be found then. Usually this would be a temporary file that we created to store the document or other
initialization that we might need. To get to this restoration information, we only have to overwrite two virtual methods of
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>, <literal remap="tt">saveProperties()</literal> and <literal remap="tt">readProperties()</literal>. The information we have to save on session end is if the currently
opened document is modified or not and the filename. If the file is modified, we will get a temporary filename to save it to. On
session beginning, this information now is used to restore the document contents:</para>

<para><screen>void KScribbleApp::readProperties(KConfig*)
{
  QString filename = config-&gt;readEntry("filename","");
  bool modified = config-&gt;readBoolEntry("modified",false);
  if( modified ){
    bool b_canRecover;
    QString tempname = kapp-&gt;checkRecoverFile(filename,b_canRecover);

    if(b_canRecover){
      doc-&gt;openDocument(tempname);
      doc-&gt;setModified();
      QFileInfo info(filename);
      doc-&gt;pathName(info.absFilePath());
      doc-&gt;title(info.fileName());
      QFile::remove(tempname);
    }
  }
  else if(!filename.isEmpty()){
  doc-&gt;openDocument(filename);
  }
  setCaption(kapp-&gt;appName()+": "+doc-&gt;getTitle());
}		
</screen>

Here, the line <literal remap="tt">kapp-&gt;checkRecoverFile()</literal> seems a bit strange, as <literal remap="tt">b&&lowbar;;canRecover</literal> is not initialized. This is done by the method
which sets it to <literal remap="tt">true</literal>, if there is a recover file. As we only saved a document in a recover file if it was modified, we set the
modified bit directly to indicate that the information hasn't been saved to the belonging file. Also we have to take care that the
recover file has another filename than the original file which was opened. Therefore, we have to reset the filename and path to the old
filename. Finally, we have the information we wanted to recover and we can delete the temporary file by the session manager.</para>

<para><emphasis remap="bf">Summary:</emphasis></para>

<para>During this chapter, you got to know how the application starts either by normal user invocation or by the session manager. We went
through the code to learn how the parts of the visual interface of the application are constructed as well as how to initialize
attributes by configuration file entries. Now you can execute the framework application to test these functions and see how the
program window reacts.</para>
</sect2>
</sect1>

<sect1 id="additional-contents-of-kdevelop-projects">
<title>Additional Contents of KDevelop Projects</title>

<para>Besides the source code provided, KDevelop projects contain a lot of other additional parts that are of interest to the developer. These
are:
<itemizedlist>
<listitem>
<para>a program icon</para>
</listitem>
<listitem>
<para>a program mini-icon</para>
</listitem>
<listitem>
<para>a .kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm> file</para>
</listitem>
<listitem>
<para>a sample SGML <indexterm remap="idx"><primary>SGML</primary></indexterm>-documentation file</para>
</listitem>
<listitem>
<para>a set of API <indexterm remap="idx"><primary>API</primary></indexterm>-documentation generated from the framework source</para>
</listitem>
</itemizedlist>
</para>

<para>Except the API <indexterm remap="idx"><primary>API</primary></indexterm>-documentation, these elements of the project will be installed together with the application binary. As the project
framework has to be as open as possible, you have to adapt these parts towards your project goals. These are first to edit the icons
provided. This will give your application a unique identifier by which the user can determine your application visually in window
manager menus. The .kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm> file then is a file that installs your application into <literal remap="tt">kpanel</literal> in the <literal remap="tt">Applications</literal> menu. This has
to be edited by setting the installation path which will be discussed later in this handbook. Finally, the documentation that you will
provide to the user is written in SGML <indexterm remap="idx"><primary>SGML</primary></indexterm>. This makes it very easy to create several different output from the same source. By default,
KDevelop offers to create a set of HTML files from this source, for KDE-projects this will automatically use the <literal remap="tt">ksgml2html <indexterm remap="idx"><primary>ksgml2html</primary></indexterm></literal>
program to add a consistent KDE look and feel to the documentation. In a later section, we will see how the SGML <indexterm remap="idx"><primary>SGML</primary></indexterm> source is edited and
what we have to watch for installation on the end-user.</para>

<para>Finally, the API <indexterm remap="idx"><primary>API</primary></indexterm> (Application Programming Interface) documentation allows you and other developers to quickly get into the code and use
the classes without having to guess what purpose each class is for. We will learn how to extend the API <indexterm remap="idx"><primary>API</primary></indexterm> documentation in a later step,
for now it lasts to know that the documentation is generated by the <literal remap="tt">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></literal> program, which processes the header files and creates the
HTML output, therefore all documentation is placed in the headers.</para>
</sect1>
</chapter>

<chapter id="application-view-design">
<title>Application View Design</title>

<para>When developing an application with a graphical user interface, the main work takes place in providing a so-called "view" for the
application. A view generally is a widget that displays the data of a document and provides methods to manipulate the document
contents. This can be done by the user via the events he emits by the keyboard or the mouse; more complex operations are often
processed by toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s and menubars which interact with the view and the document. The statusbar then provides information about the
document, view or application status. As an example, we look at how an editor is constructed and where we can find which part.</para>

<para>An editor generally is supposed to provide an interface to view and/or change the contents of a text document for the user. If you
start <emphasis>KEdit</emphasis>, you see the visual interface as the following:</para>

<para><itemizedlist>
<listitem>
<para>The menubar: providing complex operations as well as opening, saving and closing files and exiting the application.</para>
</listitem>
<listitem>
<para>The toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>: offers icons which allow quicker access for most needed functions,</para>
</listitem>
<listitem>
<para>The statusbar: displays the status of the cursor position by the current row and column,</para>
</listitem>
<listitem>
<para>The view in the center of the window, displaying a document and offering a cursor connected to the keyboard and the mouse
to operate on the data.</para>
</listitem>
</itemizedlist>
</para>

<para>Now it's easy to understand, that a view is the most unique part of the application and the design of the view decides about the
usability and acceptability of an application. This means that one of the first steps in development is to determine the purpose of the
application and what kind of view design would match best to allow any user to work with the application with a minimum of work
learning how to handle the user interface.</para>

<para>For some purposes like text editing and displaying HTML files, views are provided by the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> and KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm>; we will discuss certain
aspects of these high-level widgets in the next section. But for most applications new widgets have to be designed and implemented. It
is that what makes a programmer also a designer and where his abilities on creativity are asked. Nevertheless, you should watch for
intuitivity first. Remember that a lot of users won't accept an application that isn't</para>

<para><itemizedlist>
<listitem>
<para>graphically nice,</para>
</listitem>
<listitem>
<para>offering a lot of features,</para>
</listitem>
<listitem>
<para>easy to handle,</para>
</listitem>
<listitem>
<para>fast to learn how to use it.</para>
</listitem>
</itemizedlist>

Needless to say that stability is a major design goal. Nobody can prevent bugs, but a minimum can be reached at least by clever design
goals and wide use of object-oriented design. C++ makes programming a joy if you know how to exploit it's capabilities- inheritance,
information hiding and reusablitity of already existing code.</para>

<para>When creating a KDE or Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> project, you always have to have a view that inherits <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>, either by direct inheritance or because
the library widget you want to use inherits <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>. Therefore, the Application Wizard already constructed a view that is an
instance of a class <literal remap="tt">&&lt;;yourapp&&gt;;View</literal>, which inherits <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> already. The application creates your view in the method
<literal remap="tt">initView()</literal>, where an instance is created and connected to the main widget as it's view with <literal remap="tt">KTMainWidget::setView()</literal>.</para>

<para>This chapter therefore describes how to use library widgets for creating views of KDE or Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> applications that are generated with
KDevelop, then we're looking at the libraries and what kind of views are already offered.</para>

<sect1 id="using-library-views">
<title>Using Library Views</title>

<para>When your application design has been set up, you first should look for already existing code that will make your life a lot easier. A
part of this search is to look for a widget that can be used as a view or at least as a part of it; either directly or by inheritance.
The KDE and Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> libraries already contain a set of widgets that can be used for this purpose. To use them, you have two options:</para>

<para><orderedlist><listitem>
<para> remove the new view class and create an instance of a library widget; then set this as the view,</para>
</listitem>
<listitem>
<para> change the inheritance of the provided view class to the class of the library widget to use.</para>
</listitem>
</orderedlist>
</para>

<para>In either way, it is important to know that if the application framework is currently not linked against the library that contains the
widget, the linker will fail. After you decided to use a certain widget, look for the library to link to; then open
"Project"-&gt;"Options" from the KDevelop menubar. Switch to the "Linker Options" page and look for the checkmarks indicating the
libraries that are currently used. If the library of your view widget is already checked, you can leave the project options untouched
and start doing the necessary changes due to your choice. If not, and the linker options offer to add the library by a check box,
check it and press "OK" to leave the project options dialog again. In any other case, add the library in the edit line below with the
<literal remap="tt">-l</literal> option. For libraries that your application has to search for before preparing the Makefiles by the <literal remap="tt">configure</literal> script on
the end-user machine, add the according search macro to the <literal remap="tt">configure.in</literal> file located at the root directory of your project and
add the macro to the edit line. Mind that you have to run "Build"-&gt;"Autoconf and automake" and "Build"-&gt;"Configure" before the
Makefiles contain the correct expansion for the library macro.</para>

<para>Also, if the include files for the library to add are not in the current include path (which can be seen by the <literal remap="tt">-I</literal> options in the
output window on "Make"), you have to add the path to the Project Options dialog -"Compiler Options" page with the <literal remap="tt">-I</literal>
option or the according automake macro at the edit line for "Additional Options".</para>

<sect2 id="qt-qt-views">
<title>Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Views</title>

<para>Looking at the first page of the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> online documentation, you will find a link to "Widget Screenshots" where you can have a look at
how the widgets Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> contains look like. These are ready to use and can be combined together to form complex widgets to create
application views or dialogs. In the following, we'll discuss some of these which are very usable for creating application views, but
keep in mind that the KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> sometimes contain other widgets for the same purpose; those will be reviewed in the next section.</para>

<para>Here are a set of hints for what purpose you could use which Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> component:
<orderedlist><listitem>
<para>if your view area isn't big enough to display all your data, the user must be enabled to scroll over the document with bars on
the left and bottom of the view. For this, Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> provides the class <literal remap="tt">QScrollView</literal>, which offers a scrollable child area. As explained,
you could inherit your own widget from <literal remap="tt">QScrollView</literal> or use an instance to manage your document's view widget.</para>
</listitem>
<listitem>
<para>to create a ScrollView yourself, inherit the View widget from <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> and add vertical and horizontal <literal remap="tt">QScrollBar</literal>s.
(this is done by KDE`s KHTMLView widget).</para>
</listitem>
<listitem>
<para>for text processing, use <literal remap="tt">QMultiLineEdit</literal>. This class provides a complete text editor widget that is already capable to cut,
copy and paste text and is managed by a scrollview.</para>
</listitem>
<listitem>
<para>use <literal remap="tt">QTableView</literal> to display data that is arranged in a table. As <literal remap="tt">QTableView</literal> is managed by scrollbars as well, it offers a
good solution for table calculation applications.</para>
</listitem>
<listitem>
<para>to display two different widgets or two widget instances at the same time, use <literal remap="tt">QSplitter</literal>. This allows to tile views by
horizontal or vertical dividers. Netscape's Mail window is a good example how this would look like- the main view is separated by a
splitter vertically, the right window then is divided again horizontally.</para>
</listitem>
<listitem>
<para><literal remap="tt">QListView</literal> displays information in a list and tree. This is useful for creating file trees or any other hierarchical
information you want to interact with.</para>
</listitem>
</orderedlist>
</para>

<para>You see that Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> alone offers a whole set of widgets which are ready to use so you don't have to invent new solutions if these match
your needs. The sideffect when using standard widgets is that users already know how to handle them and only have to concentrate on
the displayed data.</para>
</sect2>

<sect2 id="kde-views">
<title>KDE Views</title>

<para>The KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> were invented to make designing applications for the K Desktop Environment easier and capable of more functionality
than what Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> alone is offering. To see what's available, we have a look at the documentation tree in KDevelop. You see that the KDE
libraries start with <literal remap="tt">kdecore</literal>, which is a base for all KDE applications <indexterm remap="idx"><primary>KDE applications</primary></indexterm>. Then,<literal remap="tt">kdeui</literal> offers user interface elements. This is
where we will find some useful things first. For creating new applications, the <literal remap="tt">kdeui</literal> library offers:</para>

<para><orderedlist><listitem>
<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KTabListBox</literal></primary></indexterm>KTabListBox</literal>: offers a multi-column list box where the user can change the rows with drag'n drop <indexterm remap="idx"><primary>drag'n drop</primary></indexterm>.</para>
</listitem>
<listitem>
<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KTreeList</literal></primary></indexterm>KTreeList</literal>: inherited from <literal remap="tt"><indexterm remap="cdx"><primary><literal>QTableView</literal></primary></indexterm>QTableView</literal>, offering a collapsible tree. This could be used instead of
<literal remap="tt">QListView</literal>. In KDE 2.0, this class will disappear.</para>
</listitem>
<listitem>
<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KEdit</literal></primary></indexterm>KEdit</literal>: the base classes for the <emphasis>KEdit</emphasis> application offered with KDE. This could be used instead of
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QMultiLineEdit</literal></primary></indexterm>QMultiLineEdit</literal>.</para>
</listitem>
<listitem>
<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KNewPanner</literal></primary></indexterm>KNewPanner</literal>: manage two child widgets like <literal remap="tt"><indexterm remap="cdx"><primary><literal>QSplitter</literal></primary></indexterm>QSplitter</literal>. In KDE 2.0, this class will disappear.</para>
</listitem>
</orderedlist>
</para>

<para>The <literal remap="tt">khtmlw</literal> library on the other hand offers a complete HTML-interpreting widget that is ready to use. It is scrollable already,
so you don't even have to take care for that. A possible use could be to integrate it as a preview widget for an HTML editor; used by
applications such as KFM, KDEHelp <indexterm remap="idx"><primary>KDEHelp</primary></indexterm> and KDevelop to display HTML files.</para>
</sect2>
</sect1>

<sect1 id="creating-your-own-views">
<title>Creating your own Views</title>

<para>Now that you have a general overview of what is already provided, you may notice that for a lot of purposes already existing widgets
can be used or combined together. KMail is an example as well as KDevelop itself makes use of library view components to display data.</para>

<para>For applications that use a special file format or have to deal with graphics, you are probably forced to create your own view widget
to allow data manipulation. This is realized in our sample by the class <literal remap="tt">KScribbleView</literal>, already providing a base for a view area.</para>

<para>The inheritance from <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> is necessary to overwrite the virtual methods to process user events, this is probably the most work
besides providing popup menus for easier access of certain functions. Also it is likely that you have to implement a set of slots which
can be accessed by toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> buttons or menu bar commands to connect to as well as methods to manipulate variables such as e.g. a painter
color.</para>

<para>For completeness, we will repeat the necessary methods:</para>

<para><emphasis remap="bf">a) Keyboard events --TAB and Shift-TAB keys:</emphasis></para>

<para>changes the keyboard input focus from the current widget to the next widget in the focus order. The focus can be set to widgets by
calling <literal remap="tt">setFocusPolicy<indexterm remap="ncdx"><primary><literal>setFocusPolicy()</literal></primary></indexterm>()</literal> and process the following event handlers:</para>

<para><itemizedlist>
<listitem>
<para><literal remap="tt">virtual void focusInEvent<indexterm remap="ncdx"><primary><literal>focusInEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QFocusEvent</literal></primary></indexterm>QFocusEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void focusOutEvent<indexterm remap="ncdx"><primary><literal>focusOutEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QFocusEvent</literal></primary></indexterm>QFocusEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">b) all other keyboard input:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void keyPressEvent<indexterm remap="ncdx"><primary><literal>keyPressEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QKeyEvent</literal></primary></indexterm>QKeyEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void keyReleaseEvent<indexterm remap="ncdx"><primary><literal>keyReleaseEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QKeyEvent</literal></primary></indexterm>QKeyEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">c) mouse movements:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void mouseMoveEvent<indexterm remap="ncdx"><primary><literal></literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void enterEvent<indexterm remap="ncdx"><primary><literal>enterEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void leaveEvent<indexterm remap="ncdx"><primary><literal>leaveEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">d) mouse button actions:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void mousePressEvent<indexterm remap="ncdx"><primary><literal>mousePressEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void mouseReleaseEvent<indexterm remap="ncdx"><primary><literal>mouseReleaseEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void mouseDoubleClickEvent<indexterm remap="ncdx"><primary><literal>mouseDoubleClickEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">e) window events containing the widget:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void moveEvent<indexterm remap="ncdx"><primary><literal>moveEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QMoveEvent</literal></primary></indexterm>QMoveEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void resizeEvent<indexterm remap="ncdx"><primary><literal>resizeEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QResizeEvent</literal></primary></indexterm>QResizeEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void closeEvent<indexterm remap="ncdx"><primary><literal>closeEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QCloseEvent</literal></primary></indexterm>QCloseEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para>When re-implementing these functions, you should watch certain issues to avoid implementation mistakes that will make it almost
impossible to change the widget's behavior afterwards:</para>

<para><orderedlist><listitem>
<para>declare your virtual methods as <emphasis remap="bf">virtual</emphasis> as well and keep the access to protected. This allows code-reuse by inheritance and
is consistent.</para>
</listitem>
<listitem>
<para>don't hard-code any event-processing which should be made configurable. This counts most for keyboard events which should be
realized with keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s if any function is called. This even counts for text processing ! (Imagine that a lot of users are
familiar with their favorite editor's behavior. If this is configurable, they can use the behavior they like and are used to)</para>
</listitem>
<listitem>
<para>forward popup menu highlighting signals to the main widget to enable statusbar help</para>
</listitem>
</orderedlist>
</para>
</sect1>
</chapter>

<chapter id="configuring-menubars-and-toolbars">
<title>Configuring Menubars and Toolbars</title>

<para>Menubars and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s are one of the most important parts of an application to provide methods to work with a document structure. As a
general rule, you should make all functions available by the menubar. Those methods that should not be available at a current stage of
the application process should be disabled.</para>

<para>Further, an application can only contain one menubar, but several toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s. Toolbars on the other hand should contain only the most
frequently used commands by pixmap icons or provide quick access methods like combos to select values.</para>

<sect1 id="how-does-it-work">
<title>How does it work ?</title>

<para>Each entry, may it be a menuentry or a toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> item, has a resource ID which is an integer value. As these values can't be used twice,
those are set by macros, where the numeric values are replaced by a descriptive ID name that can be used in your sources then.</para>

<para>All resource ID's are collected in the file <literal remap="tt">resource.h</literal>, where you can keep an overview over the used values. Anyway, the compiler
will inform you if you've used a value twice for constructing entries. Also, the resource file should contain all menu accelerator<indexterm><primary>accelerator</primary></indexterm>s by
IDK macro replacements. An example:</para>

<para><programlisting>(resource.h)

#define ID_VIEW_TOOLBAR             12010


(kscribble.cpp)

// menu entry Toolbar in the "view" menubar menu
view_menu-&gt;insertItem(i18n("&&amp;;Toolbar"), ID_VIEW_TOOLBAR);
</programlisting>
</para>

<para>This inserts the entry Toolbar to the View popup menu of the menubar in the kscribble application. The resource ID's name is held to
contain the menu name and the action's name visible. The ampersand is set in front of the letter that functions as a keyboard
accelerator<indexterm><primary>accelerator</primary></indexterm> and the entry itself is embraced by the i18n() internationalization macro.</para>

<para>On activating the menu item, the commandCallback() switch is called with the ID number. There, you have to add an according comparator
value with the method you want to execute on activating the menuentry:</para>

<para><programlisting>    case ID_VIEW_TOOLBAR:
    	slotViewToolBar();
    	break;</programlisting>
</para>

<para><note remap="comment"><para>Note: you don't have to use the ID system. If no ID is given, the menu gets numbered automatically. The KDevelop framework
uses this as it allows accessing menu and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> ID's to create <literal remap="tt">switch</literal> statements that select the slot to call on
<literal remap="tt">activated()</literal> for menus, <literal remap="tt">clicked()</literal> for toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> buttons. The connection can also be made directly using the provided methods of
the classes providing menus and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s.</para></note></para>
</sect1>

<sect1 id="adding-a-new-menu">
<title>Adding a new menu</title>

<para>A new menubar is added to an application by the following:</para>

<para><orderedlist><listitem>
<para>add a pointer to the new menu in the App-class header</para>
</listitem>
<listitem>
<para>call the constructor of <literal remap="tt"><indexterm remap="cdx"><primary><literal>QPopupMenu</literal></primary></indexterm>QPopupMenu</literal> to the pointer in <literal remap="tt">initMenuBar()</literal> at the location where your menubar should appear
later.</para>
</listitem>
<listitem>
<para>insert the according menu-items into the popup menu and set their resource ID's in the resource file</para>
</listitem>
<listitem>
<para>add connects for <literal remap="tt">commandCallback()</literal> and <literal remap="tt">statusCallback()</literal> to the menu at the end of <literal remap="tt">initMenuBar()</literal></para>
</listitem>
<listitem>
<para>add the methods you want to call by the menu-entries in the header and implementation file.</para>
</listitem>
<listitem>
<para>add the switch statements for the entries to the <literal remap="tt">commandCallback()</literal> and <literal remap="tt">statusCallback()</literal> methods</para>
</listitem>
</orderedlist>
</para>
</sect1>

<sect1 id="integrating-toolbar-buttons">
<title>Integrating Toolbar buttons</title>

<para>Toolbar buttons can be added like menu-entries with the difference that the used method is <literal remap="tt">insertButton()</literal> and takes a button
pixmap and tool-tip text instead of a menu text.</para>

<para>The icons you want to use can be loaded by <literal remap="tt">KIconLoader</literal>, where <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> offers the macros <literal remap="tt">ICON()</literal> and <literal remap="tt">Icon()</literal> to
access the icon loader and load the icon. These macros take the filename of the pixmap as their parameter to load the icon from the KDE
file system in a certain order (see <literal remap="tt">KIconLoader</literal> for the search order).</para>

<para>The KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> also offer a set of toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> buttons that can be used for standard actions. In cases where they don't meet your needs,
you will have to paint your own pixmaps. KDevelop supports this by selecting "New" from the "File" menu, then select Pixmap as the file
type. Usually you will place your toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> pixmaps in a project subdirectory "toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>" and install them into your application specific
toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> directory.</para>
</sect1>

<sect1 id="configuring-statusbars">
<title>Configuring Statusbars</title>

<para>The KDevelop projects already make use of the statusbar by providing statusbar messages for menu-entries and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> buttons. When
adding a menuentry, also add your status message in the method <literal remap="tt">statusCallback()</literal>.</para>

<para><literal remap="tt">statusCallback()</literal> uses the method <literal remap="tt">slotStatusHelpMsg()</literal> to display a statusbar message for two seconds. When executing a
command, you should use the method <literal remap="tt">slotStatusMsg()</literal> at the beginning with the string describing what your application does; before
a return or method end, you should reset the statusbar message with a "Ready." string calling the same method.</para>
</sect1>

<sect1 id="keyboard-accelerator-configuration">
<title>Keyboard Accelerator Configuration</title>

<para>A very professional thing you should always add to your application are keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s. Those are mainly used by experienced
users that want to work fast with their applications and are willing to learn shortcut<indexterm><primary>shortcuts</primary></indexterm>s. For this, the KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> provide the class
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal>, which provides the keyboard accelerator<indexterm><primary>accelerator</primary></indexterm> keys and access to global configured standard keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s.</para>

<para>By default, frame applications generated by KDevelop only use standard keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s such as F1 for accessing online-help,
Ctrl+N for New File etc. You should look for the keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s already set in <literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal> first before adding a new
accelerator<indexterm><primary>accelerator</primary></indexterm>.</para>

<para>If your application contains a lot of accelerator<indexterm><primary>accelerator</primary></indexterm>s, you should make them configurable by an Options-menu; either it could be combined
with other application configuration in a <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> or stand alone. The KDE library already provides a <literal remap="tt">KKeyChooser</literal> for use
in tab dialogs, whereas <literal remap="tt">KKeyDialog</literal> provides a ready-to use key-configuration dialog.</para>

<para>See the following classes for more information:</para>

<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal>(<indexterm remap="cdx"><primary><literal>kdecore</literal></primary></indexterm>kdecore), <literal remap="tt"><indexterm remap="cdx"><primary><literal>KKeyChooser</literal></primary></indexterm>KKeyChooser</literal>, <literal remap="tt"><indexterm remap="cdx"><primary><literal>KKeyDialog</literal></primary></indexterm>KKeyDialog</literal> (<indexterm remap="cdx"><primary><literal>kdeui</literal></primary></indexterm>kdeui)</para>
</sect1>
</chapter>

<chapter id="the-dialogeditor-where-your-dialogs-are-buil">
<title>The Dialogeditor: Where your Dialogs are Build</title>

<sect1 id="what-the-dialogeditor-provides">
<title>What the Dialogeditor provides</title>

<para>The built-In dialogeditor of KDevelop is designed to help you construct widgets and dialogs that fit your application's purpose and
reduces the time rapidly to extend the GUI of your application. The only limitation for now is that the dialogeditor does not support
geometry management that is provided by Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>; therefore the dialogs are static in their size and this may lead to certain circumstances
where e.g. the label width is not long enough to support the full length of a translation.</para>

<para>On the other hand, the current state of the editor in conjunction with KDevelop's project management offers the fastest way to create
full-featured applications for the K Desktop Environment.</para>
</sect1>

<sect1 id="qt-qt-and-kde-widgets">
<title>Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> and KDE Widgets</title>

<para>Currently provided widgets are:</para>

<para><emphasis remap="bf">QT-Widgets:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</emphasis> - a widget that can be specified by yourself and can contain other widgets as well. This allows creating a widget
hierarchy within your dialog.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm></emphasis> - a label that represents text information on the widget. Use QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm> e.g. in front of lineedits to signal what the
purpose of the line-edit is or which variable e.g. a combo box allows to set.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QPushButton</emphasis> - a button that allows to e.g. call another dialog like QFileDialog for selecting a filename.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QCheckBox</emphasis> - a check box for e.g. enabling/disabling options. QCheckBox is widely used for configuration dialogs.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QLCDNumber</emphasis> - displays numbers in LCD style. Often used for clocks.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QRadioButton</emphasis> - like QCheckBox often used to let the user set any options. QRadioButton specializes the options setting when more
of them depend on each other, e.g. you have three radio-buttons, but you want the user to choose one of three offered options. See
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QButtonGroup</literal></primary></indexterm>QButtonGroup</literal> for additional information.</para>
</listitem>
<listitem>
<para><emphasis remap="bf"><indexterm remap="cdx"><primary><literal>QComboBox</literal></primary></indexterm>QComboBox</emphasis> - a combo box lets the user set a value by selecting it from a
drop-down menu or by inserting the value, if the box is write enabled.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QListBox</emphasis> - provides a single-column list of items that can be scrolled.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QListView</emphasis> - creates a multi-column list view that can be used to display e.g. file trees etc. in tree and table view.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QMultiLineEdit</emphasis> - offers a multi-line editor.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QProgressBar</emphasis> - displays the progress of an action that takes a longer time to be finished.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QSpinBox</emphasis> - allows choosing numeric values by up- and down buttons or insertion if write enabled.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QSlider</emphasis> - sets a value in a program-defined range by a slider.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QScrollBar</emphasis> - indicates the range of a value and sets the current value by a slider as well as up- and down buttons; often
used for widgets whose contents is larger than the actually visible view area. By using the scrollbar, the visible area can be changed
to another part of the widgets' contents.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QGroupBox</emphasis> - provides a group box frame with title to indicate that child widgets within the box belong together.</para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">KDE-Widgets:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">KColorButton</emphasis> - a pushbutton displaying a selected color. On a button press, the KDE Color dialog is shown where the user can
select another color. Often used for drawing applications or in any case where color values can be set.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KCombo</emphasis> - similar to <literal remap="tt"><indexterm remap="cdx"><primary><literal>QComboBox</literal></primary></indexterm>QComboBox</literal>. Lets the user choose a value by a drop-down list box.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KDatePicker</emphasis> - a complete widget to get a date value by the user.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KDateTable</emphasis> - a calendar table to select a date of a month. Used by <literal remap="tt">KDatePicker</literal> to build the date picker dialog.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KKeyButton</emphasis> - a button to select a key value. If the button is selected, it gets activated. Pressing a keyboard button will
change the key value for the button which can be used to configure key-bindings.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KLed</emphasis> - and LED (Light Emitting Diode) widget to display a certain state.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KLedLamp</emphasis> - and LED lamp that also supports click actions</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KProgress</emphasis> - similar to <literal remap="tt">QProgressBar</literal>, <literal remap="tt">KProgress</literal> supports certain other values.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KRestrictedLine</emphasis> - a <literal remap="tt">QLineEdit</literal> that only accepts certain user input. This can be used to restrict access to certain data
by password dialogs.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KSeparator</emphasis> - a separator widget to be used in all cases where KDE applications <indexterm remap="idx"><primary>KDE applications</primary></indexterm> require a separator to provide a unique look.
Often used in dialogs to separate logical parts where <literal remap="tt">QGroupBox</literal> doesn't fit.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KTreeList</emphasis> - a collapsible list view to display trees similar to <literal remap="tt">QListView</literal>.</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="properties-of-qt-qt-supported-widgets">
<title>Properties of Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> supported Widgets</title>

<para>The following chapter gives a complete overview over the currently supported widgets of the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> toolkit. To achieve a better
understanding of the properties, these are separated to their inheritance. As all of them inherit <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>, this class is described
first. All <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> properties are available for all other widgets as well, so these are not listed for them again. For widget groups
that inherit an abstract subclass of <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> as their base-class, the base-classes' properties are listed first (though this class does
not provide a widget in the dialogeditor itself). Then the widget properties for the available widget of the group contains the
properties that are specific to it. For a better understanding the inheritance tree of the available widgets is listed below:</para>

<para><itemizedlist>
<listitem>
<para><link linkend="QWidget">QWidget</link>
<itemizedlist>
<listitem>
<para><link linkend="QButton">QButton</link> (abstract)
<itemizedlist>
<listitem>
<para><link linkend="QCheckBox">QCheckBox</link></para>
</listitem>
<listitem>
<para><link linkend="QPushButton">QPushButton</link></para>
</listitem>
<listitem>
<para><link linkend="QRadioButton">QRadioButton</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="QComboBox">QComboBox</link></para>
</listitem>
<listitem>
<para><link linkend="QFrame">QFrame</link> (abstract for now)
<itemizedlist>
<listitem>
<para><link linkend="QGroupBox">QGroupBox</link></para>
</listitem>
<listitem>
<para><link linkend="QLCDNumber">QLCDNumber</link></para>
</listitem>
<listitem>
<para><link linkend="QLabel">QLabel</link></para>
</listitem>
<listitem>
<para><link linkend="QProgressBar">QProgressBar</link></para>
</listitem>
<listitem>
<para><link linkend="QScrollView">QScrollView</link> (abstract for now)
<itemizedlist>
<listitem>
<para><link linkend="QListView">QListView</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="QSpinBox">QSpinBox</link></para>
</listitem>
<listitem>
<para><link linkend="QTableView">QTableView</link> (abstract)
<itemizedlist>
<listitem>
<para><link linkend="QListBox">QListBox</link></para>
</listitem>
<listitem>
<para><link linkend="QMultiLineEdit">QMultiLineEdit</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="QLineEdit">QLineEdit</link></para>
</listitem>
<listitem>
<para><link linkend="QScrollBar">QScrollBar</link></para>
</listitem>
<listitem>
<para><link linkend="QSlider">QSlider</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>

<sect2 id="qwidget">
<title><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget Properties </title>

<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> is the base class for almost all widgets in Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> and KDE. Therefore widgets that inherit <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> will allow to use the same
settings in most cases.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Appearance:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">BgColor:</emphasis> Background color of the widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">BgMode:</emphasis> Background mode of the widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">BgPalColor:</emphasis> Color pallette for the background</para>
</listitem>
<listitem>
<para><emphasis remap="bf">BgPixmap:</emphasis> filename for a background pixmap</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Cursor:</emphasis> Cursor over the widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Font:</emphasis> Font for the widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MaskBitmap:</emphasis> filename for a masking bitmap.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">C++ Code:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">AcceptsDrops:</emphasis> if set to true, the widget item will accept drops by drag'n drop <indexterm remap="idx"><primary>drag'n drop</primary></indexterm> mechanisms (Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> drag'n drop <indexterm remap="idx"><primary>drag'n drop</primary></indexterm>
protocol, not KDE 1.x !)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Connections:</emphasis> connects the item's signals to slots</para>
</listitem>
<listitem>
<para><emphasis remap="bf">FocusProxy:</emphasis> the item that gives its focus to this widget.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">HasFocus:</emphasis> sets if the item has the focus by default. Mind that only one item per dialog can have this value as true</para>
</listitem>
<listitem>
<para><emphasis remap="bf">ResizeToParent:</emphasis> resizes the widget to its parent's size (not visible in editing mode)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">VarName:</emphasis> Variable name of the item. Change this to names that describe the item's purpose.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">IsEnabled:</emphasis> sets if the widget will accept user events</para>
</listitem>
<listitem>
<para><emphasis remap="bf">IsHidden:</emphasis> sets the item to be visible(false) or hidden(true)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Name:</emphasis> sets the name of the widget. Mind that the name is different from the VarName in C++ Code.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Geometry:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Height:</emphasis> height of the item</para>
</listitem>
<listitem>
<para><emphasis remap="bf">IsFixedSize:</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">MaxHeight:</emphasis> maximum value for Height</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MaxWidth:</emphasis> maximum value for Width</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinHeight:</emphasis> minimum value for Height</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinWidth:</emphasis> minimum value for Width</para>
</listitem>
<listitem>
<para><emphasis remap="bf">SizeIncX:</emphasis> pixel steps for resize actions to X direction</para>
</listitem>
<listitem>
<para><emphasis remap="bf">SizeIncY:</emphasis> pixel steps for resize actions to Y direction</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Width:</emphasis> width of the item</para>
</listitem>
<listitem>
<para><emphasis remap="bf">X:</emphasis> position horizontal, counted from the left corner</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Y:</emphasis> position vertical, counted up to down</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="qbutton">
<title><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton inherited widgets </title>

<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal> is an abstract widget class that provides properties common to buttons.</para>

<para>Inherits <link linkend="QWidget">QWidget</link></para>

<para>Inherited by <link linkend="QCheckBox">QCheckBox</link>, <link linkend="QPushButton">QPushButton</link> and <link linkend="QRadioButton">QRadioButton</link> inherit <literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal>.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Appearance:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">setPixmap:</emphasis> sets the pixmap filename to use</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">setText:</emphasis> the text on labels, buttons and boxes, also pre-set text for lineedits.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">setAutoRepeat:</emphasis> if enabled, the clicked() signal is emitted at regular intervals while the button is down. No effect on
toggle buttons.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">setAutoResize:</emphasis> Enables auto-resizing if TRUE. When auto-resize is enabled, the button will resizes itself
whenever the contents changes.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>

<sect3 id="qcheckbox">
<title>QCheckBox Properties </title>

<para>Inherits <link linkend="QWidget">QWidget</link> and <link linkend="QButton">QButton</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">isChecked: (setChecked)</emphasis> defines is the checkbox is set checked on construction</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qpushbutton">
<title>QPushButton Properties </title>

<para>Inherits <link linkend="QWidget">QWidget</link> and <link linkend="QButton">QButton</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">isAutoDefault: (setAutoDefault)</emphasis> the auto-default button becomes the default push button if it receives the keyboard input focus.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isDefault: (setDefault)</emphasis> there can be only one default button and it is only allowed to use in a dialog (see <literal remap="tt">QDialog</literal>). The
default button emits <literal remap="tt">clicked()</literal> if the user presses the Enter key.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isMenuButton: (setIsMenuButton)</emphasis> tells the button to draw
a menu indication triangle if enabled. The menu has to be inserted separately.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isToggleButton::(setToggleButton)</emphasis> makes a push button a toggle button, so the button has a similar state as check
boxes.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isToggledOn: (setOn)</emphasis> (public slot) switches a toggle button on.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qradiobutton">
<title>QRadioButton Properties </title>

<para>Inherits <link linkend="QWidget">QWidget</link> and <link linkend="QButton">QButton</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">isChecked: (setChecked)</emphasis> defines is the radio button is set checked on construction</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>
</sect2>

<sect2 id="qcombobox">
<title><indexterm remap="cdx"><primary><literal>QComboBox</literal></primary></indexterm>QComboBox Properties </title>

<para>Inherits <link linkend="QWidget">QWidget</link></para>

<para>( no additional properties for now)</para>
</sect2>

<sect2 id="qframe">
<title>QFrame inherited widgets </title>

<para>Inherits <link linkend="QWidget">QWidget</link></para>

<para>For now only used as an abstract class.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Appearance:</emphasis>
<itemizedlist>
<listitem>
<para>Margin (setMargin): sets the margin, which is the distance from the innermost pixel of the frame and the outermost pixel of the
contents.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>

<sect3 id="qgroupbox">
<title>QGroupBox Properties </title>

<para>Inherits <link linkend="QWidget">QWidget</link> and <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Title: (setTitle)</emphasis> sets the group box title that is displayed in the box frame.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qlcdnumber">
<title>QLCDNumber Properties  </title>

<para>Inherits <link linkend="QWidget">QWidget</link> and <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">NumDigits:(setNumDigits)</emphasis> sets the number of digits displayed in QLCDNumber</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Value: (display)</emphasis> (public slot) sets the initial value for QLCDNumber</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qlabel">
<title>QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm> Properties  </title>

<para>Inherits <link linkend="QWidget">QWidget</link> and <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Appearance:</emphasis>
<itemizedlist>
<listitem>
<para>Margin (setMargin): sets the margin, which is for QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm> the distance from the frame to the first letter of the label text,
depending on the alignment of the label.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">C++ Code: </emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Buddy: (setBuddy)</emphasis> sets the buddy widget of the label.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Text: (setText)</emphasis> sets the label text.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoResize: (setAutoResize)</emphasis> if TRUE, the label will resize itself if the contents changes. The top left corner is not
moved.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qprogressbar">
<title>QProgressBar Properties  </title>

<para>Inherits <link linkend="QWidget">QWidget</link> and <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">TotalSteps: (setTotalSteps)</emphasis> (public slot) sets the total steps of the progress bar. During the iteration of your action to
display the progress, you have to call setProgress(int) to advance the progress step displayed to (int).</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qscrollview">
<title>QScrollView </title>

<para>Inherits <link linkend="QWidget">QWidget</link> and <link linkend="QFrame">QFrame</link></para>

<para>Inherited by <link linkend="QListBox">QListBox</link>
(abstract for now)</para>

<para>Provides a scrollable widget that manages the display of a child widget by a vertical and horizontal scrollbar.</para>

<sect4 id="qlistview">
<title>QListView</title>

<para>Inherits <link linkend="QWidget">QWidget</link>, <link linkend="QFrame">QFrame</link> and <link linkend="QListView">QListView</link></para>

<para>Provides a list view to display hierarchical data either in a table or a tree. Manages itself by scrollbars through <link linkend="QScrollView">QScrollView</link>.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Appearance:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">ListViewFont:</emphasis> (setFont()) Sets the font of the ListView items</para>
</listitem>
<listitem>
<para><emphasis remap="bf">ListViewPalette:</emphasis> (setPalette()) Sets the palette of the list view items</para>
</listitem>
<listitem>
<para><emphasis remap="bf">TreeStepSize:</emphasis> (setTreeStepSize(int)) Offset of pixels of a child item to its parent item</para>
</listitem>
<listitem>
<para><emphasis remap="bf">hScrollBarMode:</emphasis> Scrollbar mode provided by <link linkend="QScrollView">QScrollView</link> for the horizontal scrollbar</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAllColumnsShowFocus:</emphasis> (setAllColumnsShowFocus(bool)) displays focus on all columns of an item.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isMultiSelection:</emphasis> enables multi-selection of list items</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isRootDecorated:</emphasis> enables the + and - decoration to open and close trees</para>
</listitem>
<listitem>
<para><emphasis remap="bf">vScrollBarMode:</emphasis>Scrollbar mode provided by <link linkend="QScrollView">QScrollView</link> for the vertical scrollbar</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Entries:</emphasis> lets you insert a list of entries that are pre-set as QListViewItems.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoUpdate:</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect4>
</sect3>

<sect3 id="qspinbox">
<title>QSpinBox Properties </title>

<para>Inherits <link linkend="QWidget">QWidget</link> and <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">MaxValue:</emphasis>  the maximum value the user can choose</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinValue:</emphasis>  the minimum value the user can choose</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Prefix:</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">Suffix:</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">Value:</emphasis>     the pre-set value when the widget is shown</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isWrapping:</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qtableview">
<title>QTableView inherited widgets </title>

<para>Inherits <link linkend="QWidget">QWidget</link>, <link linkend="QFrame">QFrame</link> and <link linkend="QTableView">QTableView</link></para>

<para>Inherited by <link linkend="QListBox">QListBox</link> and <link linkend="QMultiLineEdit">QMultiLineEdit</link></para>

<sect4 id="qlistbox">
<title>QListBox Properties </title>

<para>Inherits <link linkend="QWidget">QWidget</link>, <link linkend="QFrame">QFrame</link> and <link linkend="QTableView">QTableView</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">isAutoBottomScrollBar: (setAutoBottomScrollBar)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoScroll: (setAutoScroll)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoScrollBar: (setAutoScrollBar)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoUpdate: (setAutoUpdate)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isBottomScrollBar: (setBottomScrollBar)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isDragSelect: (setDragSelect)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isSmoothScrolling: (setSmoothScrolling)</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Geometry:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">setFixedVisibleLines:</emphasis> sets a fixed height for the widget so that the given number of text lines are displayed using the
current font.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect4>

<sect4 id="qmultilineedit">
<title>QMultiLineEdit Properties </title>

<para>Inherits <link linkend="QWidget">QWidget</link>, <link linkend="QFrame">QFrame</link> and <link linkend="QTableView">QTableView</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Text: (setText) </emphasis> (public slot) sets the text of the widget.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoUpdate: (setAutoUpdate)</emphasis> used to avoid flicker during large changes; the view is not updated if disabled.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isOverWriteMode: (setOverwriteMode) </emphasis>(public slot) sets overwrite enabled or disabled.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isReadOnly: (setReadOnly)</emphasis> (public slot) sets the widget text to read only; disables text input.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTextSelected: (selectAll)</emphasis>(public slot) marks the whole text selected</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Geometry:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">setFixedVisibleLines:</emphasis> sets a fixed height for the widget so that the given number of text lines are displayed using the current font.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect4>
</sect3>
</sect2>

<sect2 id="qlineedit">
<title>QLineEdit Properties </title>

<para>Inherits <link linkend="QWidget">QWidget</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">CursorPosition: (setCursorPosition)</emphasis> sets the default cursor position.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MaxLength: (setMaxLength) </emphasis> sets the maximum string length</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Text: (setText) </emphasis> (public slot) sets the contents displayed on construction</para>
</listitem>
<listitem>
<para><emphasis remap="bf">hasFrame: (setFrame) </emphasis> draws the line edit within a two-pixel frame if enabled.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTextSelected: (selectAll) </emphasis> (public slot) sets the text to be selected.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="qscrollbar">
<title>QScrollBar Properties </title>

<para>Inherits <link linkend="QWidget">QWidget</link> and <literal remap="tt">QRangeControl</literal>.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">MaxValue:</emphasis> sets the maximum slider value; used in constructor (optional)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinValue:</emphasis> sets the minimum slider value; used in constructor (optional)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Orientation: (setOrientation)</emphasis> sets the orientation of the scrollbar to horizontal or vertical.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Value: </emphasis> sets the initial value of the scrollbar in the constructor (optional)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTracking: (setTracking)</emphasis> if enabled, the scrollbar emits <literal remap="tt">valueChanged()</literal> whenever the bar is dragged; otherwise only on
mouse release.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="qslider">
<title>QSlider Properties </title>

<para>Inherits <link linkend="QWidget">QWidget</link> and <literal remap="tt">QRangeControl</literal>.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">MaxValue:</emphasis> sets the maximum slider value; used in constructor (optional)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinValue:</emphasis> sets the minimum slider value; used in constructor (optional)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Orientation: (setOrientation)</emphasis> sets the orientation of the slider to horizontal or vertical.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Value: (setValue)</emphasis> (public slot) uses <literal remap="tt">QRangeControl::setValue()</literal> to set the value.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTracking:(setTracking)</emphasis> if enabled, the slider emits <literal remap="tt">valueChanged()</literal> whenever the slider is dragged; otherwise only on
mouse release.</para>
</listitem>
</itemizedlist>

</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>

<sect1 id="properties-of-kde-supported-widgets">
<title>Properties of KDE supported Widgets</title>

<para><itemizedlist>
<listitem>
<para><link linkend="QWidget">QWidget</link>
<itemizedlist>
<listitem>
<para><link linkend="QButton">QButton</link> (abstract)
<itemizedlist>
<listitem>
<para><link linkend="QPushButton">QPushButton</link>
<itemizedlist>
<listitem>
<para><link linkend="KColorButton">KColorButton</link></para>
</listitem>
<listitem>
<para><link linkend="KKeyButton">KKeyButton</link></para>
</listitem>
</itemizedlist>
		</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="QComboBox">QComboBox</link>
<itemizedlist>
<listitem>
<para><link linkend="KCombo">KCombo</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="QFrame">QFrame</link> (abstract for now)
<itemizedlist>
<listitem>
<para><link linkend="KDatePicker">KDatePicker</link></para>
</listitem>
<listitem>
<para><link linkend="KLedLamp">KLedLamp</link></para>
</listitem>
<listitem>
<para><link linkend="KProgress">KProgress</link></para>
</listitem>
<listitem>
<para><link linkend="KSeparator">KSeparator</link></para>
</listitem>
<listitem>
<para><link linkend="QTableView">QTableView</link> (abstract)
<itemizedlist>
<listitem>
<para><link linkend="KDateTable">KDateTable</link></para>
</listitem>
<listitem>
<para><link linkend="KTreeList">KTreeList</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="QLineEdit">QLineEdit</link>
<itemizedlist>
<listitem>
<para><link linkend="KRestrictedLine">KRestrictedLine</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="KLed">KLed</link></para>
</listitem>
</itemizedlist>
</para>

<sect2 id="kcolorbutton">
<title>KColorButton</title>

<para>Inherits <link linkend="QPushButton">QPushButton</link></para>

<para><itemizedlist>
<listitem>
<para>General
<itemizedlist>
<listitem>
<para><emphasis remap="bf">DisplayedColor (setColor())</emphasis> the displayed color on the button</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="kkeybutton">
<title>KKeyButton</title>
	<para></para>
</sect2>

<sect2 id="kcombo">
<title>KCombo</title>

<para>Inherits: <link linkend="QComboBox">QComboBox</link></para>

<para><itemizedlist>
<listitem>
<para>General
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Entries</emphasis> the string list of entries displayed in the combo box</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Text</emphasis> the text displayed in the combo box currently</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoResize</emphasis> resizes the combo box to the current item</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="kdatepicker">
<title>KDatePicker</title>

<para><itemizedlist>
<listitem>
<para>Appearance
<itemizedlist>
<listitem>
<para><emphasis remap="bf">FontSize</emphasis> the font size for the date picker</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="kledlamp">
<title>KLedLamp</title>
	<para></para>
</sect2>

<sect2 id="kprogress">
<title>KProgress</title>
	<para></para>
</sect2>

<sect2 id="kseparator">
<title>KSeparator</title>

<para><itemizedlist>
<listitem>
<para>General
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Orientation</emphasis> sets the orientation of the separator to horizontal or vertical; default is horizontal</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="kdatetable">
<title>KDateTable</title>
	<para></para>
</sect2>

<sect2 id="ktreelist">
<title>KTreeList</title>

<para><itemizedlist>
<listitem>
<para>Appearance
<itemizedlist>
<listitem>
<para><emphasis remap="bf">TreeListBgColor</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">TreeListPalette</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isBottomScrollbar</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isScrollBar</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isShowItemText</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isSmoothScrolling</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTreeDrawing</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>General
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Entries</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoUpdate</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="krestrictedline">
<title>KRestrictedLine</title>
	<para></para>
</sect2>

<sect2 id="kled">
<title>KLed</title>

<para>Inherits <link linkend="QWidget">QWidget</link></para>

<para><itemizedlist>
<listitem>
<para>Appearance
<itemizedlist>
<listitem>
<para><emphasis remap="bf">LedColor: (setColor())</emphasis> sets the displayed LED color</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>

<sect1 id="constructing-a-new-dialog">
<title>Constructing a new Dialog</title>

<para>Constructing a new dialog is very easy if you already have experience with graphical construction applications. KDevelop offers to
create a widget visually and displays the look as it will be shown to the user directly. Further, you can have a preview of your widget
by selecting "Preview" from the "View" menu.</para>

<para>To begin constructing a dialog or any other widget, switch to the Dialogeditor and select "New" from the "File" menu. Select "Qt/KDE Dialgo (*.kdevdlg)
from the New File dialog and enter the dialog filename. Construct your dialog and when you´re finished, select "Generate all Sources" from the "Build"-menu.</para>

<para>Then enter all needed information to the appearing dialog. Those are:</para>

<para><orderedlist><listitem>
<para>The Dialog inheritance. This is necessary because any widget is at least derived from <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>. Besides the widget types
provided by Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, you can inherit e.g. form an abstract base class you constructed yourself within your project. In this case, select
"custom" and enter the header file path to the line edit below.</para>
</listitem>
<listitem>
<para>The Dialog name. This sets the class name of the generated dialog. Select a classname that is descriptive for what the dialog
does; in cases of inheritance from <literal remap="tt">QDialog</literal>, you may enter a name that ends with <literal remap="tt">Dlg</literal> to remember yourself it's a dialog.
Naming convention should match that of KDE and Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>: Use uppercase letters for your classname. For e.g. a grid-size selection dialog, you
would enter <literal remap="tt">GridSizeDlg</literal>.</para>
</listitem>
<listitem>
<para>The generated filenames. Those are preset when entering the dialog name, but can be changed afterwards. If you want to use other
filenames, the naming convention should also match that of KDE and Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>: the filenames are all lowercase and contain the classname to
remember what class is kept where. The data file that has to be set will later contain the generated code that will build up your
dialog. You should not edit this file manually afterwards; use the implementation file for any additions towards dialog construction
code and method implementations.</para>
</listitem>
</orderedlist>
</para>

<para>The dialog will then show itself as a widget with a grid. As the dialogeditor uses the grid to snap any child widgets to the geometry,
you can change the grid size with the "Grid Size" entry in the "View" menu, if the preset values don't match your needs.</para>

<para>Then select the "Widgets" tabulator on the left pane and press the button for the widget item you want to add to the main widget. It
directly appears on the main widget's left upper corner and gets selected by a resizable frame. Then move or resize the widget with the
mouse. The cursor will change to indicate which action can be done at the current position.</para>

<para>After having finished the construction, select "Generate Files" from the "Build" menu or hit the according toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> button. The files
will then be generated at the preset location and included into your project sources. A rebuild or make will compile all generated
files within your project and you can add the according constructor call to the application to invoke the dialog or widget. For KDE
projects, all widget properties that will be visible later, e.g. label texts, are set with the <literal remap="tt">i18n()</literal> macro of <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal> to
support internationalization. Therefore you should do a "Make Messages and merge" when finished with construction and implementation.</para>

<para>When creating a dialog or widget, you should watch the following guidelines:
<itemizedlist>
<listitem>
<para>Always try to be consistent! This is probably the most important rule when constructing GUI elements. Mind that the user will
only accept an application that is easy to understand no matter how complex it's purpose may be.</para>
</listitem>
<listitem>
<para>Add help wherever you can by tool-tips, What's this..? help or Quick-help. This allows getting direct information about the
purpose of the GUI elements.</para>
</listitem>
<listitem>
<para>watch the <emphasis remap="bf">keyboard focus <indexterm remap="idx"><primary>keyboard focus</primary></indexterm></emphasis> !  The generator does not take care of that- this has to be watched when constructing any widget;
otherwise you have to reorder your initialization code by hand which is a very unthankful job. The keyboard focus <indexterm remap="idx"><primary>keyboard focus</primary></indexterm> on any widget means
the oder on which items get the keyboard input focus when the user presses the tab and shift+tab button. It would be very annoying if
the focus changes everywhere but not to the next widget visible below or to the right of the current widget. Therefore start
constructing your widget top down from left to right to ensure the consistency of the focus.</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="setting-widget-properties">
<title>Setting Widget Properties</title>

<para><indexterm><primary>widget properties</primary></indexterm><indexterm><primary>dialogeditor</primary></indexterm><indexterm><primary>properties window</primary></indexterm>
Widget properties can be set easily with the properties window entries. When a widget gets selected, the properties window
automatically updates to the properties of the current widget. As all widgets are derived from <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>, you can set the
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> properties plus an amount of properties that are specific to the selected widget. Properties can be:</para>

<para><itemizedlist>
<listitem>
<para>Integer values, such as the geometry of a widget or the font size</para>
</listitem>
<listitem>
<para>Boolean values to enable/disable certain parameters of the widget. Set with combos containing true and false</para>
</listitem>
<listitem>
<para>enumerable values of a widget, e.g. the palette. Set with combos containing all possible values</para>
</listitem>
<listitem>
<para>Color values for e.g. the displayed color. Set with the KDE Color Dialog</para>
</listitem>
<listitem>
<para>Font values for e.g. labels. Be careful to set Font values other than the default because this may prevent KDE from updating the
font. Set with the KDE Font Dialog</para>
</listitem>
<listitem>
<para>File names for e.g. background pixmaps. Do not use gif images here as these may get
unsupported by further Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> versions &gt; 1.42</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="integrating-the-dialog">
<title>Integrating the Dialog</title>

<para>Whenever you created a widget, you probably want to add it to the project to execute the action it is designed for. As a widget can be
constructed for several purposes, we will watch for two cases: a <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> inherited widget and a <literal remap="tt">QDialog</literal> one.</para>

<sect2 id="qwidgetqwidget-inherited">
<title><literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> inherited</title>

<para>Let's say you created a widget that will be part of the main view. If it fills the whole view area, you have to add an instance pointer
to the header declaration of your <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> instance replacing the currently set view widget. Then change the code in the
<literal remap="tt">initView</literal> method to set this widget the main view. Additionally, you could remove the View class of the generated project, but mind
that the document instance and the App instance depends on the view class. In this case, it is technically a much better way to create
a mini-KDE application and construct your <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> instance yourself.</para>

<para>More often the widget is intended to be a part of the view area, which means it is combined with other widgets. This can be done by
using one of the following classes that provide a divider to separate two widgets:</para>

<para><orderedlist><listitem>
<para><literal remap="tt">QSplitter</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">KPanner</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">KNewPanner</literal></para>
</listitem>
</orderedlist>
</para>

<para>If the main view shall contain more than two widgets, you have to use another instance of the divider as one of the two managed widgets
by the first one. Then add the according widgets to each panner and set the first panner the view area.</para>
</sect2>

<sect2 id="qdialog-inherited">
<title><literal remap="tt">QDialog</literal> inherited</title>

<para>If your widget inherits <literal remap="tt">QDialog</literal>, it is probably intended to change one or more values; often this is used to set the application
preferences. To invoke the dialog, you have to add a slot to the <literal remap="tt">App</literal> class by adding the method declaration and the implementation
body. Then add the constructor call to the method as well as a call to <literal remap="tt">show()</literal> or <literal remap="tt">exec()</literal> the dialog. Finally, you should take
care for processing the results of the dialog; this can either be done by the dialog who changes values of the parent widget itself or
by retrieving the values from the dialog (which would make your dialog a lot more reusable in other projects). Mind that you should call
<literal remap="tt">delete</literal> if you called the dialog instance with <literal remap="tt">new</literal> to avoid memory leaks.</para>

<para>Finally, you have to connect a menuentry (with according statusbar help) to the new slot invoking the dialog; optionally a keyboard
accelerator<indexterm><primary>accelerator</primary></indexterm> and a toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> icon. For this, add a resource ID to the file <literal remap="tt">resource.h</literal> with a define. Then add
an according menuentry to one of the popup menus already present in the menubar or create a new popup to add your menuentry. The
menuentry consists of:</para>

<para><itemizedlist>
<listitem>
<para>an optional icon pixmap. Call this with the <literal remap="tt">Icon("iconname.xpm")</literal> macro of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> to use the provided
<literal remap="tt">KIconLoader</literal> instance.</para>
</listitem>
<listitem>
<para>the menuentry name. Add this with the <literal remap="tt">i18n("&&amp;;entryname")</literal> macro of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> to allow
internationalization. The ampersand should be in front of the letter that will be displayed underlined to access the entry directly by
keyboard acceleration.</para>
</listitem>
<listitem>
<para>the member instance to call. Normally this would be the <literal remap="tt">this</literal> pointer.</para>
</listitem>
<listitem>
<para>the member slot to call. Use <literal remap="tt">SLOT(yourmethod()</literal> to call the slot on the signal <literal remap="tt">activated()</literal>.</para>
</listitem>
<listitem>
<para>the accelerator<indexterm><primary>accelerator</primary></indexterm> key. This should be set to zero as this is done by an entry in <literal remap="tt">initKeyAccel()</literal> where you
have to introduce an accelerator<indexterm><primary>accelerator</primary></indexterm> key together with the slot to call. Then call <literal remap="tt">changeMenuAccel()</literal> to change the
menu item's accelerator<indexterm><primary>accelerator</primary></indexterm>. This will make it configurable by a key-chooser dialog later. For standard actions, use the
enumerable values given by <literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal>. </para>
</listitem>
<listitem>
<para>the menu ID as set in <literal remap="tt">resource.h</literal></para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
</chapter>

<chapter id="printing-support">
<title>Printing Support</title>

<para><indexterm remap="ncdx"><primary><literal>QPrinter</literal></primary></indexterm><indexterm remap="ncdx"><primary><literal>QPainter</literal></primary></indexterm><indexterm remap="ncdx"><primary><literal>QPrintdialog</literal></primary></indexterm><indexterm><primary>printing</primary></indexterm>
Printing is usually provided by your application to let the user create a printed version of the document he created with the
application; therefore only needed for those programs that are used to produce something the user may want to print out, e.g. text or
pictures. In any case, this requires an interface that is provided by the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> library by two classes: the <literal remap="tt">QPrintDialog</literal> class,
offering the printing dialog, and the <literal remap="tt">QPainter</literal> class that is also used to draw the widget's contents usually. As the view-class of
an application is responsible for displaying a document, it also is responsible for printing.</para>

<sect1 id="the-qt-qt-print-dialog">
<title>The Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Print Dialog</title>

<para>The Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Printer dialog can be used including <literal remap="tt">qprintdialog.h</literal>. When using the KDE framework application, this is already used by the
view class, so you only have to complete the implementation of the method <literal remap="tt">print()</literal> by using <literal remap="tt">QPainter</literal>.</para>
</sect1>

<sect1 id="the-qpainter-class">
<title>The QPainter Class</title>

<para>Independent of the printer's capabilities, you can use <literal remap="tt">QPainter</literal> to draw your document onto the printer provided by <literal remap="tt">QPrinter</literal>
like you would when drawing onto a widget. The only difficulty would be where you have to implement the way things have to be printed.</para>
</sect1>
</chapter>

<chapter id="help-functions">
<title>Hilfefunktionen</title>

<para>Wer Software entwickelt, darf eines nicht vergessen: den zukünftigen Benutzern, wo immer es geht, Hilfe zu bieten. Die meisten Entwickler neigen dazu,
dies möglichst weit aufzuschieben. Sie aber sollten sich immer vor Augen halten, dass Ihr Benutzer nicht unbedingt Unix-Experte ist. Er mag von der dunklen Seite der
Softwarewelt kommen, wo ihm eingeflüstert wurde, er könne eine Anwendung bedienen, ohne jemals ein Handbuch angefasst zu haben.
Um diesen Anspr&uuml;chen zu gen&uuml;gen, statten die KDE- und Qt-Bibliotheken <indexterm remap="idx"><primary>Qt</primary></indexterm> Sie mit allen Mitteln aus, um eine Anwendung in den Augen 
des Durchschnittsusers professionell wirken zu lassen -- z.B. mit vorgefertigten Hilfefunktionen.
Innerhalb der Anwendung sind das</para>

<para><itemizedlist>
<listitem>
<para>Kurztipps</para>
</listitem>
<listitem>
<para>Schnellhilfe</para>
</listitem>
<listitem>
<para>Kurzerklärungen im Statusbalken</para>
</listitem>
<listitem>
<para>Kontexthilfe-("Was-ist-das?")-Buttons</para>
</listitem>
</itemizedlist>
</para>

<para>Zusätzlich sollte die Applikation mit F1, der Standard-Hilfetaste, Zugang zu einem HTML-basierten Online-Handbuch bieten.</para>

<para>Da KDevelop zum einen selbst alle diese Hilfen eingebaut hat, zum anderen der Applikationswizard ein KDE-Framework generiert, das diese schon unterstützt,
zeigen wir Ihnen hier, wo und wie Sie Hilfefunktionalität einbauen.</para>

<para>Wichtig bei der Anwendungsentwicklung ist, dass Sie konsistent bleiben. Daher sollten Sie die nötigen Schritte zur Hilfegenerierung zu dem Zeitpunkt einleiten, da Sie Ihren Code erweitern.
Das verhindert, dass Sie Ihren Quelltext später noch einmal neu durchdenken m&uuml;ssen, um heraus zu finden, was Ihre Anwendung
tut oder was Sie mit Teilen des Codes &uuml;berhaupt bezwecken.</para>

<sect1 id="tool-tips">
<title>Kurztipps</title>

<para>Kurztipps leisten auf sehr einfache Art Hilfe. Diese kleinen Mitteilungen erscheinen, wenn der Benutzer mit der Maus &uuml;ber ein entsprechend ausgestattetes Widget f&auml;hrt,
und verschwinden wieder, wenn die Maus weiter bewegt wird. Am popul&auml;rsten sind sie in Werkzeugleisten <indexterm remap="idx"><primary>Werkzeugleiste</primary></indexterm>, wo sie allerdings
so klein wie m&ouml;glich gehalten werden sollten. Werkzeugleisten lassen sich n&auml;mlich <indexterm remap="idx"><primary>Werkzeugleiste</primary></indexterm>so konfigurieren, dass sie ihre Inhalte auf verschiedene Weisen darstellen: entweder
sie zeigen den Button, den Button mit dem Text zur Rechten, die Schaltfl&auml;che mit dem Tipp darunter oder einfach nur die Mitteilung. Normalerweise sollte der Benutzer die ihm genehmste Darstellungsart w&auml;hlen k&ouml;nnen, 
aber das ist kein Muss. Der Text wird so oder so als Kurztipp angezeigt, und eine Werkzeugleiste <indexterm remap="idx"><primary>Werkzeugleiste</primary></indexterm> besteht normalerweise aus Schaltfl&auml;chen und anderen Widgets 
wie Lineedits und Komboboxen. Eine komplette Beschreibung finden Sie in der Klassenreferenz zu <literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal> in der KDE-UI-Library.</para>

<para>Sehen wir uns als Beispiel die "Neue Datei"-Schaltfl&auml;che einer generischen Anwendung an:</para>

<para><screen>toolBar()-&gt;insertButton(Icon("filenew.xpm"), ID_FILE_NEW, true, i18n("New File") );
</screen>

<indexterm remap="ncdx"><primary><literal>toolBar()</literal></primary></indexterm><indexterm><primary>KToolBar</primary></indexterm>
Der <literal remap="tt">i18n("New File")</literal>-Teil erzeugt den Kurztipp. Er wird vom i18n()-Makro aus <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal> in die 
aktuell eingestellte Sprache (also z.B. zu "Neue Datei") &uuml;bersetzt.</para>

<para>Kurztipps lassen sich mit den Qt-<indexterm remap="idx"><primary>Qt</primary></indexterm>Klassen <literal remap="tt">QToolTip</literal> und <literal remap="tt"><indexterm remap="cdx"><primary><literal>QToolTipGroup</literal></primary></indexterm>QToolTipGroup</literal> zu jedem beliebigen Widget hinzu f&uuml;gen.
Ein Beispiel:</para>

<para><screen>QToolTip::add( yourwidget, i18n("your Tip") );
</screen>

N&auml;here Informationen dazu finden Sie in der Qt-<indexterm remap="idx"><primary>Qt</primary></indexterm>Online-Referenz zur Klasse <literal remap="tt"><indexterm remap="cdx"><primary><literal>QToolTip</literal></primary></indexterm>QToolTip</literal>.</para>
</sect1>

<sect1 id="adding-quick-help">
<title>Schnellhilfe</title>

<para>"Quick-Help"- oder Schnellhilfe-Fenster sind ein weiteres Beispiel guter Hilfestellung. Der Benutzer dr&uuml;ckt dazu
den rechten Mausbutton und w&auml;hlt "Schnellhilfe" im Kontextmen&uuml;. Es handelt sich bei dieser Art Hilfe also um ein Mittelding
zwischen einem detaillierten Referenzhandbuch und den Kurztipps: Ersteres w&auml;re zu ausschweifend, ein Tipp b&ouml;te hingegen zu
wenig Information. Um zu sehen, wie Quick-Help funktioniert, &ouml;ffnen Sie einen beliebigen Dialog in KDevelop und dr&uuml;cken die rechte Maustaste &uuml;ber dem gew&uuml;nschten Eintrag.
Dann w&auml;hlen Sie den Men&uuml;punkt "Schnellhilfe", und schon erscheint eine hilfreiche Mitteilung. Diese kann mit verschiedenen Farben und Schriften aufgepeppt werden 
and darf sogar URLs enthalten, die auf eine bestimmte Webseite (oder genau so gut auf das beiliegende Online-Handbuch) verweisen.</para>

<para>Um Quick-Help einzusetzen, f&uuml;gen Sie das Include-File <literal remap="tt"><indexterm remap="cdx"><primary><literal>kquickhelp.h</literal></primary></indexterm>kquickhelp.h</literal> in die passende Quelldatei ein. Da die
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KQuickHelp</literal></primary></indexterm>KQuickHelp</literal>-Klasse Bestandteil der KDE-UI-Bibliothek ist, sollte sie ohne weiteres Zutun von Ihrer Anwendung benutzt werden k&ouml;nnen. Ist dem nicht so, setzen Sie das Linker-Flag Ihres Projekts so, dass
kdeui eingebunden wird.</para>

<para>Das Beispiel</para>

<para><screen>KQuickHelp::add( yourwidget, i18n("your Tip") );
</screen>
</para>
<para>erinnert stark an das, mit dem wir QToolTip vorgestellt haben. Wenn Sie mit dem KDevelop-Dialogeditor einen Dialog erstellen, tragen Sie Ihre Kurztipps und Schnellhilfen
in die Implementierungsdatei ein, und  NICHT ins Quelltextfile, da dieses vom Dialogeditor jedes Mal neu erstellt wird, wenn Sie etwas an Ihrem Widget &auml;ndern.</para>

<para>Doch zur&uuml;ck zu dem, was die <literal remap="tt"><indexterm remap="cdx"><primary><literal>KQuickHelp</literal></primary></indexterm>KQuickHelp</literal>-Klasse bietet. Wie schon erw&auml;hnt, haben Sie die M&ouml;glichkeit, Text mit Hilfe von Tags zu formatieren. Sie k&ouml;nnen Hyperlinks eintragen, die von Internetprotokollen wie http Gebrauch machen, Farben,
Schriftarten und -gr&ouml;&szlig;en fest legen. Im <ulink url="../kde_libref/index.html">KDE Library Reference Guide</ulink> und der Klassendokumentation
<indexterm remap="idx"><primary>class
documentation</primary></indexterm> zu <literal remap="tt"><indexterm remap="cdx"><primary><literal>KQuickTip</literal></primary></indexterm>KQuickTip</literal> finden Sie n&auml;hrere Informationen.</para>
</sect1>

<sect1 id="extending-the-statusbar-help">
<title>Erweitern der Statusbalkenhilfe</title>

<para>Das von KDevelop bereit gestellte Anwendungsframework enth&auml;lt nicht nur einen Statusbalken, sondern auch ein Set vorgefertigter Statusbalkenmeldungen f&uuml;r alle Men&uuml;- und Werkzeugleisten<indexterm remap="idx"><primary>Werkzeugleiste</primary></indexterm>eintr&auml;ge. 
DDabei handelt es sich um einen kurzen Text, der etwas mehr Information als ein Kurztipp liefert, der aber auch als
Ersatz f&uuml;r Kurztipps bei Men&uuml;eintr&auml;gen angesehen werden kann. Wie der Name schon verr&auml;t, taucht er im Statusbalken auf, wenn der Benutzer einen Men&uuml;punkt 
anw&auml;hlt. Alle Men&uuml;eintr&auml;ge binden ihr <literal remap="tt">highlighted(int)</literal>-Signal an die Methode <literal remap="tt">statusCallback(int)</literal>, 
die die passende Kurzmitteilung aus einer switch-Anweisung heraus sucht. Wann immer Sie einen Men&uuml;eintrag zu einem bereits existierenden Men&uuml; oder einer Werkzeugleiste<indexterm remap="idx"><primary>Werkzeugleiste</primary></indexterm> hinzu f&uuml;gen,
sollten Sie einen entsprechenden Eintrag in der Methode daher  nicht vergessen. Dieser sollte eine kurze Beschreibung dessen enthalten, was den Benutzer erwartet, wenn er den Button oder Men&uuml;eintrag   
aktiviert.</para>

<para>Der folgende Codeausschnitt</para>

<para><screen>    case ID_FILE_NEW:
 	  	slotStatusHelpMsg(i18n("Creates a new document"));
 	  	break;
</screen>
</para>

<para>bewirkt, dass im Statusbalken durch den Aufruf der Methode <literal remap="tt">slotStatusHelpMsg()</literal> eine passend &uuml;bersetzte Mitteilung erscheint, wenn
ein Benutzer den Men&uuml;punkt oder das Icon in der Werkzeugleiste <indexterm remap="idx"><primary>Werkzeugleiste</primary></indexterm> mit der Kennung ID&&lowbar;;FILE&&lowbar;;NEW anw&auml;hlt, das seinerseits mit der <literal remap="tt">statusCallback()</literal>-Methode verbunden ist.
Werkzeugleisten kommunizieren mit dieser Methode &uuml;ber das Signal <literal remap="tt">pressed(int)</literal>. Dies erlaubt es dem Anwender, die Maus &uuml;ber einem Icon in der Werkzeugleiste <indexterm remap="idx"><primary>Werkzeugleiste</primary></indexterm> gedr&uuml;ckt zu halten und wieder weg zu bewegen, wenn er es sich doch anders &uuml;berlegen sollte.
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal> bietet das Signal <literal remap="tt">highlighted(int, bool)</literal> an, das zur Anzeige einer Mitteilung benutzt werden kann, 
wenn der Benutzer die Schaltfl&auml;che lediglich ber&uuml;hrt, nicht aber dr&uuml;ckt.</para>
</sect1>

<sect1 id="the-whats-this...-button">
<title>Kontexthilfe-Buttons</title>

<para>&Auml;hnlich wie bei KQuickHelp <indexterm><primary>KQuickHelp</primary></indexterm> verstecken sich hinter Kontexthilfe-("What's This...?"-)<indexterm remap="idx"><primary>"What's This...?"</primary></indexterm>-Buttons Hilfefenster -- allerdings mit dem Unterschied, dass der  User in diesem Fall 
Hilfe zu einem bestimmten Widget innerhalb der aktuellen Ansicht oder zu einem Werkzeugleistenicon <indexterm remap="idx"><primary>Werkzeugleiste</primary></indexterm> sucht. Die im englischen "What's This...?" genannte "Fragezeichen"-Schaltfl&auml;che hat ihren Platz in der Werkzeugleiste<indexterm remap="idx"><primary>toolbar</primary></indexterm> und wird aktiviert,
sobald der Benutzer darauf klickt. Im Gegenzug &auml;ndert der Cursor seine Form zu einem Fragezeichen -- ganz so wie das, was auf dem Button selbst steht. Der 
Anwender kann damit auf ein beliebiges sichtbares Widget klicken und erh&auml;lt daraufhin ein Hilfefenster. Um zu sehen, wie das funktioniert, probieren Sie dieses Verhalten einfach mit dem Fragezeichen-Button
in KDevelop aus.
</para>
<para>Einen solchen Kontexthilfe-Button erzeugen Sie folgenderma&szlig;en:</para>

<para><orderedlist><listitem>
<para>Binden Sie <literal remap="tt">qwhatsthis.h</literal> in Ihren Quellcode ein.</para>
</listitem>
<listitem>
<para>F&uuml;gen Sie eine private Instanz der Klasse <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWhatsThis</literal></primary></indexterm>QWhatsThis</literal> namens whats&&lowbar;;this/ o.&auml;. zu Ihrer von  <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> abgeleiteten Klassendeklaration hinzu.
</para>
</listitem>
<listitem>
<para>Legen Sie eine Ressourcenkennung f&uuml;r Ihren Kontexthilfe-Button in der Datei <literal remap="tt">resource.h</literal> fest, z.B. <literal remap="tt">&&num;;define ID&&lowbar;;HELP&&lowbar;;WHATS&&lowbar;;THIS
10100</literal></para>
</listitem>
<listitem>
<para>Geben Sie in der Methode, mit der Sie die Werkzeugleiste <indexterm remap="idx"><primary>Werkzeugleiste</primary></indexterm> erzeugen (normalerweise <literal remap="tt">initToolBar()</literal>) an, wo der Fragezeichen-Button erscheinen soll:
<screen>  whats_this = new QWhatsThis;
  QToolButton *btnwhat = whats_this-&gt;whatsThisButton(toolBar());
  QToolTip::add(btnwhat, i18n("What's this...?"));
  toolBar()-&gt;insertWidget(ID_HELP_WHATS_THIS, btnwhat-&gt;sizeHint().width(), btnwhat);
  btnwhat-&gt;setFocusPolicy(QWidget::NoFocus);
</screen>

<indexterm remap="ncdx"><primary><literal>setFocusPolicy()</literal></primary></indexterm></para>
</listitem>
<listitem>
<para>Zum Schluss  f&uuml;gen Sie den Text hinzu, den ein Klick mit dem Fragezeichencursor erscheinen l&auml;sst:
<screen>whats_this-&gt;add(class_tree, i18n("Class Viewer\n\n"
                                  "The class viewer shows all classes, methods and variables "
                                  "of the current project files and allows switching to declarations "
                                  "and implementations. The right button popup-menu allows more specialized "
                                  "functionality."));
</screen>
</para>
</listitem>
</orderedlist>
</para>
</sect1>
</chapter>

<chapter id="extending-the-documentation-with-sgml-sgml">
<title>Erweitern der Dokumentation mit SGML <indexterm remap="idx"><primary>SGML</primary></indexterm></title>

<para>Gerade bei der Dokumentation lassen viele Softwarepakete ihre Anwender im Regen stehen. Um dem zu begegnen, enthalten alle KDevelop-Projekte ein vorgefertigtes Handbuch, das sich leicht
anpassen l&auml;sst, und kommen damit dem Ziel von KDE entgegen, Benutzern, die  den Umgang mit der Software erlernen wollen, ausreichend Online-Hilfe an die Hand zu geben.
Dieses Kapitel erl&auml;utert Ihnen daher, wie man das Dokumentationsger&uuml;st mit Leben f&uuml;llt und was Sie zu tun haben,
um den Anwender Ihre Erweiterungen zug&auml;nglich zu machen.</para>

<sect1 id="why-sgml">
<title>Warum SGML?</title>

<para>SGML <indexterm remap="idx"><primary>SGML</primary></indexterm> (Standard Generalized Markup Language) ist eine Sprache, mit der sich die Spezifikation von Auszeichnungssprachen (engl.: markup languages) beschreiben l&auml;sst, nicht aber die Auszeichnungssprache selbst. 
Die Spezifikation einer Auszeichnungssprache nennt man DTD (Document Type Definition). Diese enth&auml;lt
die Struktur eines Dokuments sowie die zul&auml;ssigen Auszeichnungen (Tags). Ein SGML-System bringt verschiedene Dateien mit, die die DTD-Tags ins gew&uuml;nschte Ausgabeformat &uuml;bersetzen -- und das ist schon das ganze Geheimnis. Das am weitesten verbreitete Ausgabeformat ist vermutlich HTML -- Online-Hilfe via WWebbrowser kann in einer Zeit,
in der Internetstandards bis zum Einzelplatzrechner vorgedrungen sind, als g&auml;ngig angesehen werden. KDE macht mit KDEHelp <indexterm remap="idx"><primary>KDEHelp</primary></indexterm> ausgiebig Gebrauch von
HTML-Dokumentation: Dieses Programm listet alle installierten KDE-Anwendungen <indexterm remap="idx"><primary>KDE-Anwendung</primary></indexterm> und bietet Zugriff auf deren Benutzerhandb&uuml;cher. &Uuml;ber ein Hilfemen&uuml; 
erh&auml;lt der Benutzer direkt aus der jeweiligen Anwendung Zugang zur Online-Hilfe.</para>

<para>KDE (und daher auch KDevelop) nutzt das SGML-Tools-1.x-Paket (vgl. <ulink url="http://www.sgmltools.org/">\|\|</ulink>), das fr&uuml;her unter dem Namen 
LinuxDoc bekannt war. Es enth&auml;lt eine DTD namens <literal remap="tt">LinuxDoc</literal>, eine Reihe Dateien, die die Umwandlung in verschiedene Ausgabeformate steuern, und die
n&ouml;tigen Werkzeuge, die die tats&auml;chliche Ersetzung der <literal remap="tt">LinuxDoc</literal>-Tags vornehmen. Die LinuxDoc-DTD basiert auf der Qwertz-DTD, die entwickelt wurde, um
speziell Tag-&Uuml;bersetzungen f&uuml;r das &latex;-Satzsystem vorzunehmen. Daher eignet sie sich besonders zum Erzeugen von Dokumenten in vern&uuml;nftiger Ausdruckqualit&auml;t. 
Das Paket selbst bekam seinen Namen, weil es vom LDP (Linux Documentation Project) zur Dokumentation verwendet wurde.
Er wurde lediglich deshalb ge&auml;ndert, weil ein SGML-System nicht notwendigerweise auf Linux beschr&auml;nkt ist, sondern auf jedem
Unix-System benutzt werden kann. Sie k&ouml;nnen nat&uuml;rlich auch Ihre eigene DTD und die zugeh&ouml;rigen "Mappings" schreiben, wenn Sie Lust dazu haben. </para>

<para>Mittlerweile erf&uuml;llt eine andere DTD genau so gut den selben Zweck: die DocBook-DTD. DocBook hat einige offensichtliche Vorteile gegen&uuml;ber 
LinuxDoc, insbesondere, weil sie bessere Tags und Mappings f&uuml;r Tabellen und Grafikeinbindung enth&auml;lt (was nicht hei&szlig;t, dass LinuxDoc das nicht auch k&ouml;nnte...).
Die SGML-Tools unterst&uuml;tzen daher in den 2.x-Versionen die DocBook-DTD und enthalten einen
Konverter, der aus LinuxDoc-Dokumenten DocBook-SGML erzeugt.</para>

<para>Augenblicklich setzen wir bei der KDE-Entwicklung allerdings weiterhin auf die LinuxDoc-DTD. Das hat folgende Gr&uuml;nde:
<itemizedlist><listitem>
<para>Dokumentation in LinuxDoc l&auml;sst sich leicht schreiben.</para>
</listitem>
<listitem>
<para>Die Installation der SGML-Tools der 1.x-Versionen zum Gebrauch mit LinuxDoc ist weitaus einfacher.</para>
</listitem>
<listitem>
<para>KDE bringt ein zus&auml;tzliches Werkzeug namens <literal remap="tt">ksgml2html</literal> mit, das die HTML-Ausgabe des 
1.x-SGML-Tools <literal remap="tt">sgml2html</literal> in den KDE-typischen Dokumentationsstil &uuml;berf&uuml;hrt.</para>
</listitem>
</itemizedlist></para>

<para>Meine pers&ouml;nliche -- beim Schreiben der KDevelop-Handb&uuml;cher gewonnene -- Erfahrung mit der LinuxDoc-DTD ist, dass sie sehr einfach ist und  alle Bed&uuml;rfnisse abdeckt, die beim Erstellen von Dokumentation so anfallen.
Da die Lernkurve sehr steil verl&auml;uft, werden vermutlich auch Sie innerhalb k&uuml;rzester Zeit zum SGML-Tools/LinuxDoc-Guru aufsteigen und
eine Menge Zeit sparen, die es br&auml;uchte, um sich in ein Formatierungssystem a la &tex; (f&uuml;r die Druckausgabe Ihrer Dokumentation) oder
eine Auszeichnungssprache f&uuml;r die HTML-Ausgabe einzuarbeiten.</para>

<para>Einer der Hauptgr&uuml;nde, immer noch die SGML-Tools 1.x zu verwenden, ist sicherlich auch der, dass die meisten Distributionen dieses Paket und all die zus&auml;tzlichen Werkzeuge mitbringen, die Sie zur Umwandlung in 
andere Ausgabeformate ben&ouml;tigen. Das macht die Installation so einfach wie m&ouml;glich, und dass das Schreiben selbst nicht sehr kompliziert ist, werden Sie selbst sehen. 
Folgende Ausgabeformate k&ouml;nnen Sie mit den SGML-Tools erzeugen:</para>

<para><itemizedlist>
<listitem>
<para>HTML. Das spezielle KDE-Look&amp;Feel erhalten Sie, wenn Sie zus&auml;tzlich <literal remap="tt">ksgml2html</literal> benutzen.</para>
</listitem>
<listitem>
<para>Einfachen, unformatierten Text.</para>
</listitem>
<listitem>
<para>GNU-info.</para>
</listitem>
<listitem>
<para>Das Lyx-Format.</para>
</listitem>
<listitem>
<para>&tex;, DVI, PostScript und PDF.</para>
</listitem>
<listitem>
<para>Das Rich-Text-Format (RTF).</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="what-the-documentation-already-contains">
<title>Was die Dokumentation schon enth&auml;lt</title>

<para>Bei jedem neuen KDevelop-Projekt enth&auml;lt das Verzeichnis <literal remap="tt">docs/en</literal> bereits die englische Dokumentationsdatei <literal remap="tt">index.sgml</literal> und
die daraus generierten HTML-Files. Nicht genug damit, dass sie schon im Projekt eingebunden sind -- auch ihr Installationsziel liegt mit dem
KDE-HTML-Verzeichnis fest, ohne dass Sie etwas dazu tun m&uuml;ssen. Dieser Dokumentationsgrundstock wird von KDevelop automatisch an den Projektnamen und die Versionsnummer angeglichen und enth&auml;lt Ihre Autoreninformation. 
Die HTML-Ausgabe umfasst zudem die Datei index.html mit dem Inhaltsverzeichnis (das von KDEHelp ge&ouml;ffnet wird, wenn der Nutzer Hilfe anfordert),
eine Installationsanleitung und das Copyright (die GNU Public License).</para>

<para>Da KDevelop Ihnen auf diese Weise das Erstellen einer ganzen Menge allgemeiner Informationen erspart, m&uuml;ssen Sie lediglich noch projektspezifische Einzelheiten hinzu f&uuml;gen. Denken Sie daran,
dass Sie bei KDE-Projekten im Anschluss an deren Erstellung noch einmal den Men&uuml;punkt "Benutzerhandbuch erstellen" aus dem "Projekt"-Men&uuml; aufrufen m&uuml;ssen. Die  index.sgml-Datei wird
so ein weiteres Mal von <literal remap="tt">ksgml2html <indexterm remap="idx"><primary>ksgml2html</primary></indexterm></literal> bearbeitet und der HTML-Ausgabe das  KDE-Layout &uuml;bergest&uuml;lpt. &Ouml;ffnen Sie im Reiter RFC das <literal remap="tt">doc/en</literal>-Verzeichnis, und
f&uuml;gen Sie &uuml;ber das Kontextmen&uuml; die  Datei <literal remap="tt">logotp3.gif</literal> zum Projekt hinzu; anschlie&szlig;end passen Sie seine Eigenschaften so an, dass das Logo im selben Verzeichnis wie
die HTML-Dateien zu liegen kommt: <literal remap="tt">$(kde&&lowbar;;htmldir)/en/&&lt;;your&&lowbar;;project&&gt;;/logotp3.gif</literal>.</para>
</sect1>

<sect1 id="writing-sgml-documentation">
<title>Schreiben von SGML-Dokumentation</title>

<para>Die Erfahrung lehrt, dass SGML (um es genau zu sagen: die LinuxDoc-DTD) Neulingen doch gewisse Schwierigkeiten bereitet.
Wirft man einen Blick auf eine Handvoll KDE-Anwendungen, so bemerkt man rasch, dass eine nicht unbedeutende Anzahl lediglich die SGML-Ger&uuml;stdatei enth&auml;lt, w&auml;hrend der Autor
die generierten HTML-Dateien bearbeitete. Das f&uuml;hrt zu Problemen bei der &Uuml;bersetzung in andere Sprachen: Die jeweiligen &Uuml;bersetzer
m&uuml;ssen jede HTML-Datei einzeln bearbeiten, ohne eine M&ouml;glichkeit 
zu haben, ihre Arbeit auch in anderen Formaten wieder verwenden zu
k&ouml;nnen (letzteres gilt nat&uuml;rlich auch f&uuml;r die originale englische Fassung). 
Eine ziemlich kurzsichtige und verfahrene Situation, deren Ursache meiner Meinung nach darin liegt, dass viele Autoren &uuml;ber HTML-Kenntnisse verf&uuml;gen, jedoch kein SGML k&ouml;nnen.
Das Erlernen einer neuen Auszeichnungssprache vermeidet man gern, und so muss das generierte HTML als Vorlage herhalten.
Sobald Sie jedoch heraus finden, wie einfach (und n&uuml;tzlich) SGML mit LinuxDoc ist, werden Sie sicher einsehen, dass es sich lohnt, die paar Tags mehr zu lernen, aus denen SGML-Formatierung besteht.</para>

<para>Die folgenden Abschnitte stellen Ihnen die wichtigsten Bestandteile einer LinuxDoc-SGML-Datei vor und zeigen Ihnen, wie Sie Ihre
Dokumentation erweitern.</para>

<sect2 id="the-dtd-declaration">
<title>Die DTD-Deklaration</title>

<para>Jede SGML-Datei, ganz gleich, welche DTD Sie verwenden, beginnt immer mit der DTD-Deklaration. Hier teilen Sie dem SGML-Parser mit, welche DTD er verwenden soll.
Daher ist der erste Tag (ein spitz geklammerter Ausdruck wie &&lt;;meintag&&gt;; mein Inhalt &&lt;;/meintag&&gt;;) in einem SGML-Dokument immer der DOCTYPE:</para>

<para><literal remap="verb">&&lt;;!doctype linuxdoc system&&gt;;</literal></para>

<para>Diese Zeile weist Ihren SGML-Formatierer an, die LinuxDoc-DTD zu verwenden.</para>

<sect3 id="the-document-structure">
<title>Die Dokumentstruktur</title>

<para>Verwendet man LinuxDoc, folgt als N&auml;chstes ein Tag, das den Anfang eines bestimmten Dokumenttyps markiert. Die DTD bietet eine ganze Reihe verschiedener Stile an, aus der Sie, abh&auml;ngig von Zweck und L&auml;nge des Dokuments, einen passenden ausw&auml;hlen. Folgende Formate stehen zur Wahl:
</para>

<para><itemizedlist>
<listitem>
<para><literal remap="tt">&&lt;;notes&&gt;;</literal> f&uuml;r kurze Erl&auml;uterungen.</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;article&&gt;;</literal> wird f&uuml;r Artikel von ca. 10--20 Seiten empfohlen. Diesen Dokumenttyp verwenden  die KDevelop-Vorlagen und die meisten KDE-Anwendungen.</para>
</listitem>
<listitem>
<para>L&auml;ngere Artikel formatiert man als <literal remap="tt">&&lt;;report&&gt;;</literal>.</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;book&&gt;;</literal> eignet sich zum Schreiben dicker B&uuml;cher -- die KDevelop-Handb&uuml;cher wurden in diesem Format verfasst.</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;slides&&gt;;</literal> benutzt man f&uuml;r Pr&auml;sentationen. Als Ausgabeformat werden Sie hier normalerweise auf &latex; zur&uuml;ck greifen.
</para>
</listitem>
<listitem>
<para>Briefe verfassen Sie mit <literal remap="tt">&&lt;;letter&&gt;;</literal>, </para>
</listitem>
<listitem>
<para>Faxe mit <literal remap="tt">&&lt;;telefax&&gt;;</literal> und </para>
</listitem>
<listitem>
<para>Manpages unter Zuhilfenahme von <literal remap="tt">&&lt;;manpage&&gt;;</literal>. </para>
</listitem>
</itemizedlist>
</para>

<para>Denken Sie daran, dass diese Stile lediglich die Struktur des Dokuments (also den allgemeinen Aufbau) beschreiben -- nicht jedoch, wie die Ausgabe letztendlich aussieht. Wie erw&auml;hnt benutzt die von
KDevelop erzeugte Dokumentvorlage die &&lt;;article&&gt;;-Struktur. Die KDevelop-Dokumentation selbst bildet eine Ausnahme: Sie macht Gebrauch vom
&&lt;;book&&gt;;-Format. Der HTML-Ausgabe sieht man diesen Unterschied nicht weiter an -- anders ist das z.B., wenn das Zielformat &latex; hei&szlig;t.
Da werden die Handb&uuml;cher zu echten B&uuml;chern, in denen -- im Unterschied zu einem Artikel -- jedes Kapitel  auf einer separaten Seite beginnt.</para>

<para>Wenn man schon den Beginn eines Dokumentstrukturtyps extra auszeichnet, so liegt es nahe, dass es auch ein Ende-Tag am Schluss der SGML-Datei geben muss: F&uuml;r einen &&lt;;article&&gt;; w&auml;re das
&&etago;;article&&gt;;.</para>
</sect3>
</sect2>

<sect2 id="titlepages">
<title>Titelseiten</title>

<para>Auf die Festlegung der Dokumentstruktur folgt ein Abschnitt, der alle Elemente einer Titelseite beschreibt. Die automatisch erzeugte Vorlage
macht davon zwar keinen gro&szlig;en Gebrauch, legt aber dennoch Titel (<literal remap="tt">&&lt;;title&&gt;;</literal>), Autoren (<literal remap="tt">&&lt;;author&&gt;;</literal>) und Datum (<literal remap="tt">&&lt;;date&&gt;;</literal>) fest und deckt dabei das Wichtigste f&uuml;r die meisten Einsatzzwecke ab.
Wenn Sie allerdings die <literal remap="tt">&&lt;;book&&gt;;</literal>-Struktur einsetzen, liegt es nahe, eine komplette Titelseite zu definieren. Folgende
Tags kommen daf&uuml;r in Frage (die Liste wurde dem SGML-Quelltext dieses Handbuchs entnommen):</para>

<para><programlisting>&&lt;;!doctype linuxdoc system&&gt;;
&&lt;;book&&gt;;
&&lt;;titlepag&&gt;;
&&lt;;title&&gt;;Das KDevelop-Programmierhandbuch
&&lt;;subtitle&&gt;;Leitfaden zur C++-Anwendungsentwicklung f&uuml;r das K Desktop Environment (KDE) mit Hilfe der KDevelop-IDE in der Version 1.2
&&lt;;author&&gt;;
&&lt;;name&&gt;;Ralf Nolden &&lt;;htmlurl url="mailto:Ralf.Nolden@post.rwth-aachen.de"
                                   name = "&&lt;;Ralf.Nolden@post.rwth-aachen.de&&gt;;"&&gt;;
&&lt;;inst&&gt;;Das KDevelop-Team
&&lt;;date&&gt;;Version 1.2 , 21. M&auml;rz 2000
&&lt;;abstract&&gt;;
Dieses Handbuch ist selbst Bestandteil der integrierten Entwicklungsumgebung KDevelop 
und unterliegt daher ebenso der GNU General Public License (siehe auch
&&lt;;ref id="Copyright" name="Copyright"&&gt;;).
&&etago;;abstract&&gt;;</programlisting>
</para>

<para>Dieses Beispiel enth&auml;lt alles, was eine g&auml;ngige Titelseite ausmacht. Das <literal remap="tt">&&lt;;author&&gt;;</literal>-Tag wird u.U. noch um  ein <literal remap="tt">&&lt;;thanks&&gt;;</literal>-Tag erweitert, mit
dem Co-Autoren, Lektoren etc. gedankt wird. <literal remap="tt">&&lt;;inst&&gt;;</literal> nennt die Organisation oder Firma, f&uuml;r die der Autor die Dokumentation verfasste;
Sie k&ouml;nnten ebenso gut den Namen Ihres Teams an dieser Stelle einf&uuml;gen, so, wie ich es hier getan habe. <literal remap="tt">&&lt;;abstract&&gt;;</literal> wiederum enth&auml;lt eine kurze Zusammenfassung des Inhalts und wird ebenfalls
auf der Titelseite platziert. In einer gedruckten Ausgabe ist dies etwas &auml;rgerlich, da Sie diese Kurzbeschreibung hier eher auf der R&uuml;ckseite des Titels (gemeinsam mit
dem Copyright etc.) erwarten w&uuml;rden. Doch auch das ist kein un&uuml;berwindbares Problem: Schlie&szlig;lich l&auml;sst sich das bei der &latex;-Ausgabe erzeugte &tex;-File editieren.</para>
</sect2>

<sect2 id="indices">
<title>Indizes und Verzeichnisse</title>

<para>Die LinuxDoc-DTD definiert eine Reihe von Tags f&uuml;r die verschiedenen Verzeichnisarten, wie sie in nicht allzu exotischen Publikationsformen auftauchen. Dies sind</para>

<para><itemizedlist>
<listitem>
<para>&&lt;;toc&&gt;; f&uuml;r das Inhaltsverzeichnis,</para>
</listitem>
<listitem>
<para>&&lt;;lof&&gt;; f&uuml;r das Abbildungsverzeichnis und </para>
</listitem>
<listitem>
<para>&&lt;;lot&&gt;; f&uuml;r das Tabellenverzeichnis.</para>
</listitem>
</itemizedlist>
</para>

<para>Diese Start-Tags m&uuml;ssen nicht unbedingt mit einem Ende-Tag abgeschlossen werden; sie werden einfach nach der Titelseite und vor dem tats&auml;chlichen Dokumentanfang 
und den folgenden Kapiteln und Abschnitten eingef&uuml;gt.</para>

<para>Wenn Sie sp&auml;ter die Stichworte f&uuml;r den Index am Ende des Dokuments markieren wollen, k&ouml;nnen Sie sich aus einem Pool von vier verschiedenen Tags bedienen:
Zwei belassen den indizierten Ausdruck auf der Seite, die anderen beiden markieren Indexeintr&auml;ge, die nicht im Flie&szlig;text auftauchen sollen.</para>

<para><itemizedlist><listitem>
<para>&&lt;;idx&&gt;; markiert einen "ganz normalen" Indexeintrag,</para>
</listitem>
<listitem>
<para>&&lt;;cdx&&gt;; einen, der in Listingsschrift erscheinen soll,</para>
</listitem>
<listitem>
<para>&&lt;;nidx&&gt;; leitet einen Indexeintrag ein, der nicht im Flie&szlig;text erscheinen soll, und </para>
</listitem>
<listitem>
<para>&&lt;;ncdx&&gt;; ist das im Flie&szlig;text "unsichtbare" &Auml;quivalent zum cdx-Indexeintrag.</para>
</listitem>
</itemizedlist></para>

<para>Alle Backends (Das sind Werkzeuge, die SGML-Tags in das jeweilige Dokumentenformat &uuml;bersetzen.) au&szlig;er 
<literal remap="tt">sgml2latex</literal> ignorieren diese Tags. <literal remap="tt">sgml2latex</literal> erstellt ein Index-File namens <literal remap="tt">index.idx</literal>, dass sich mit <literal remap="tt">makeindex index.idx</literal> in einen &tex;-Index umwandeln l&auml;sst. Der
Index selbst kann anschlie&szlig;end mit <literal remap="tt">\printindex</literal> in die &tex;-Ausgabedatei eingef&uuml;gt werden. Ich habe mein &latex;-Mapping so angepasst, dass es dies automatisch tut, allerdings 
wei&szlig; ich noch nicht genau, wie ich das Inhaltsverzeichnis um den Eintrag f&uuml;r	den Index erweitere...</para>
</sect2>

<sect2 id="the-document-contents">
<title>Der Inhalt</title>

<para>Nachdem wir uns bislang mit der Einzelheiten der Dokumentenstruktur auseinander gesetzt haben, kommen wir nun zum tats&auml;chlichen Inhalt. Abh&auml;ngig vom Strukturtyp leiten wir den mit 
einem <literal remap="tt">&&lt;;sect&&gt;;</literal>-Tag ein, ein Dokument vom Typ <literal remap="tt">&&lt;;book&&gt;;</literal> beginnt man hingegen mit <literal remap="tt">&&lt;;chapt&&gt;;</literal>, das ein Kapitel beginnt.
</para>

<para>Anschlie&szlig;end erlauben Ihnen vier Unterkapitelebenen (<literal remap="tt">&&lt;;sect1&&gt;;</literal>, <literal remap="tt">&&lt;;sect2&&gt;;</literal> etc.) pro Kapitel eine Feinstrukturierung des Inhalts.</para>

<para>Auf das Kapitelstarttag folgt gew&ouml;hnlich eine (optionale) &Uuml;berschrift. Daf&uuml;r nutzen Sie die Tags <literal remap="tt">&&lt;;title&&gt;;</literal> und
<literal remap="tt">&&etago;;title&&gt;;</literal>. Mit einem &&lt;;p&&gt;; leiten Sie dann den 
tats&auml;chlichen Unterkapiteltext ein. Innerhalb eines solchen Absatzes (das p stammt von paragraph) k&ouml;nnen Sie Ihr Dokument mit Aufz&auml;hlungen, nummerierten und beschreibenden Listen f&uuml;llen.
Auch Zitate, Code-Schnipsel u.&auml;. finden hier -- von den entsprechenden Tags umrahmt -- ihren Platz. Eine komplette Aufz&auml;hlung bieten die Dokumentationsrichtlinien  zuu den 
<literal remap="tt">sgmltools</literal>.
Im  Kapitel &uuml;ber "special characters" werden Sie f&uuml;ndig, wenn Sie nach der Schreibweise f&uuml;r Sonderzeichen (Umlaute u.a. Buchstaben aus nicht-englischen Alphabeten, Klammern, Schr&auml;gstriche, das Trademark-Symbol u.&auml;.) suchen.
</para>
</sect2>
</sect1>

<sect1 id="how-to-call-help-in-dialogs">
<title>Hilfe anfordern in Dialogen</title>

<para><indexterm><primary>Hilfefunktionen</primary></indexterm>
Oft bietet  es sich an, in Dialogen &uuml;ber einen Hilfe-Button Hilfe anzubieten. Dann f&uuml;gen Sie einen Slot ein, der angesprochen wird, wenn der Knopf gedr&uuml;ckt wird. Beim  Implementieren des 
Slots rufen Sie zu diesem Zweck</para>

<para><screen>kapp-&gt;invokeHTMLHelp( QString aFilename, QString aTopic );
</screen>
</para>

<para>auf, wobei <literal remap="tt">aFilename</literal> den Dateinamen im HTML-Dokumentationsverzeichnis Ihrer Anwendung (z.B.  index-3.html) bezeichnet.
<literal remap="tt">aTopic</literal> gibt an, zu welchem Thema Hilfe gerufen werden soll. Das Hash-Pr&auml;fix  wird automatisch hinzu gef&uuml;gt; geben Sie einfach an, welches Kapitel Sie auf der entsprechenden Seite ben&ouml;tigen. Normalerweise handelt es sich dabei um den Namen desselben.</para>
</sect1>
</chapter>

<chapter id="class-documentation-with-kdoc-kdoc">
<title>Klassendokumentation mit KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></title>

<para>Ihre Dokumentation sollte eine Beschreibung der von Ihnen geschriebenen 
Klassenschnittstellen enthalten. So schaffen Sie  sich und anderen
Programmierern die M&ouml;glichkeit, sich Ihre Klassen durch das Lesen der 
&uuml;ber <literal remap="tt">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></literal> zug&auml;nglichen HTML-Klassendokumentation zu erschlie&szlig;en <indexterm remap="idx"><primary>Klassendokumentation</primary></indexterm> oder Ihr Wissen rasch aufzufrischen. KDevelop unterst&uuml;tzt 
<literal remap="tt">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></literal> in allen Belangen, indem es die KDE-Library-Dokumentation erstellt, sogar Ihr Application-Framework ist schon vordokumentiert. Um sich in den
so vorgegebenen Code einzuarbeiten, bietet es sich an, die beiliegenden Dokumentationsdateien am Rechner durchzusehen. Im Folgenden sehen Sie, wie man eine API-Dokumentation 
<indexterm remap="idx"><primary>API</primary></indexterm> erstellt, wie KDevelop Ihnen hilft, sie in Ihr Projekt einzubinden, und welche speziellen Tags <literal remap="tt">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></literal> erlaubt.</para>

<sect1 id="how-to-use-kdevelops-documentation-features">
<title>So nutzen Sie KDevelops Dokumentationsfeatures</title>

<para>Nachdem Sie ein Projekt erstellt haben, f&uuml;gen Sie das Dokumentationsger&uuml;st f&uuml;r Ihre API <indexterm remap="idx"><primary>API</primary></indexterm> hinzu, indem Sie "API<indexterm remap="idx"><primary>API</primary></indexterm>-Dokumentation erstellen" aus dem "Projekt"-Men&uuml; w&auml;hlen. Damit werden alle 
Header-Files durchgesehen und das HTML-Ger&uuml;st erstellt. Nun k&ouml;nnen Sie die erstellte Dokumentation &uuml;ber den Men&uuml;punkt "API<indexterm remap="idx"><primary>API</primary></indexterm>-Dokumentation des Projekts" aus dem Hilfe-Men&uuml; bzw. &uuml;ber das entsprechende
Buchsymbol im Katalog "Aktuelles Projekt" auf der Karteikarte DOC aufrufen.</para>

<para>Sie enth&auml;lt ganz ohne Ihr Zutun bereits Verweise auf die KDE- und Qt-<indexterm remap="idx"><primary>Qt</primary></indexterm>Klassendokumentation <indexterm remap="idx"><primary>Klassendokumentation</primary></indexterm>, so dass Sie Vererbungen einfach verfolgen k&ouml;nnen.
Auf diese Weise werden Sie gleichzeitig mit der KDE- und Qt-<indexterm remap="idx"><primary>Qt</primary></indexterm>Dokumentation vertraut.</para>
</sect1>

<sect1 id="adding-class-and-member-documentation">
<title>Klassen- und Memberdokumentation hinzuf&uuml;gen</title>

<para>So wie KDevelop Ihnen alle m&ouml;glichen Hilfsmittel zum automatischen
Erstellen von Code an die Hand gibt, bietet es Ihnen auch die M&ouml;glichkeit,
die passende Dokumentation generisch zu erstellen. Wann auch immer Sie den Klassengenerator &uuml;ber "Projekt"-&gt;"Neue Klasse..." aufrufen, sollten Sie im Dokumentationsfeld einen beschreibenden Hilfetext einf&uuml;gen. Dieser erscheint im zugeh&ouml;rigen Headerfile als erl&auml;uternder Kommentar.
</para>

<para>Wenn Sie die Klasse &uuml;ber das Kontextmen&uuml;
mit neuen Memberfunktionen und Attributen<indexterm remap="idx"><primary>Klassenkontextmen&uuml;</primary></indexterm> ausstatten, sollten Sie jeweils auch das zugeh&ouml;rige Dokumentationsfeld ausf&uuml;llen.
</para>

<para>M&ouml;glicherweise weisen Sie dem Schreiben von Dokumentation als Bestandteil des Entwicklungsprozesses gar keinen so gro&szlig;en Stellenwert zu. Bedenken Sie jedoch, dass -- je weiter Ihr Projekt w&auml;chst und je mehr Leute daran beteiligt sind -- eine vern&uuml;nftige Klassendokumentation 
<indexterm remap="idx"><primary>Klassendokumentation</primary></indexterm> sehr viel Zeit spart. Wenn Entwickler
aus dem Methodennamen erraten m&uuml;ssen, was die Methode tut, werden Missverst&auml;ndnisse  wahrscheinlich. Im schlimmsten Fall macht die Methode eben nicht das, was der
Entwickler erwartet hat. Daher sollten Sie Ihre Dokumentation nicht vernachl&auml;ssigen und so oft wie m&ouml;glich aktualisieren.
</para>

<para>Behalten Sie dabei im Hinterkopf, dass die Dokumentationsdateien NICHT im Projekt abgespeichert werden und auch keine Internationalisierungsunterst&uuml;tzung enthalten. Halten Sie s&auml;mtliche
API-<indexterm remap="idx"><primary>API</primary></indexterm>Dokumentation daher in englischer Sprache. So erm&ouml;glichen Sie es auch internationalen Entwicklerteams, an und mit Ihren Quelltexten zu arbeiten.</para>

<para>Wenn Sie einem Headerfile von Hand Kommentare hinzu f&uuml;gen, die in die Dokumentation eingehen sollen, so platzieren Sie sie wie einen gew&ouml;hnlichen C-Kommentar <emphasis remap="bf">oberhalb</emphasis> der Methode oder Klasse -- mit einer Ausnahme: Die erste Zeile muss mit einem Schr&auml;gstrich und zwei
Sternchen beginnen.
</para>

<para>Ein Beispiel:</para>

<para><screen>  /** enables menuentries/toolbar items
  	*/
  void enableCommand(int id_);
</screen>
</para>
</sect1>

<sect1 id="special-tags">
<title>Spezielle Tags</title>

<para>Die Beschreibungen in diesem Kapitel sind der KDoc-<indexterm remap="idx"><primary>KDoc</primary></indexterm>Dokumentation des KDoc<indexterm remap="idx"><primary>KDoc</primary></indexterm>-Autors
Sirtaj S. Kang (<ulink url="mailto:taj@kde.org">taj@kde.org</ulink>) von 1997 entnommen.</para>

<para>In der Dokumentation erlaubt sind</para>

<para><itemizedlist>
<listitem>
<para>"normale" Textabschnitte, die durch mindestens eine Leerzeile voneinander getrennt werden m&uuml;ssen,
</para>
</listitem>
<listitem>
<para>Text in der Art von
<programlisting>&&lt;;pre&&gt;;
.....Code-Fragmente....
&&&lt;;/pre&&gt;;</programlisting>
sowie
</para>
</listitem>
<listitem>
<para>verschiedene Tags in folgender Schreibweise:
<screen>@tagname [Tag-Parameter]
</screen>
</para>
</listitem>
</itemizedlist>
</para>

<para>Folgende Tags sind f&uuml;r die einzelnen Code-Bestandteile zul&auml;ssig:</para>

<para><itemizedlist>
<listitem>
<para>Klassen
<screen>  @short [ein Satz]
    eine kurze Klassenbeschreibung,
  @author [eine Zeile Text]
    der Autor der Klasse,
  @version [eine Textzeile]
    Klassenversion (Ich setze diese normalerweise auf das RCS/CVS-Tag "Id".),
  @see [ein oder mehrere Verweise auf Klassen oder Methoden] 	
    Verweise auf verwandte Dokumentation.
</screen>

</para>
</listitem>
<listitem>
<para>Methoden

<screen>  @see
    wie oben,
  @return [ein Satz]
    Kurzbeschreibung des R&uuml;ckgabewerts,
  @param [Name des Parameters] [Parameterbeschreibung]
   beschreibt einen Parameter. Die Parameterbeschreibung kann mehrere Zeilen
    umfassen und wird durch eine Leerzeile, ein Kommentarende oder einen neuen 
    Parametereintrag abgeschlossen.
    Daher sollten Parametereintr&auml;ge normalerweise an letzter Stelle
    im Dokumentationskommentar stehen.
</screen>

</para>
</listitem>
<listitem>
<para>Konstanten, Aufz&auml;hlungen, Eigenschaften
<screen>  @see
    wie oben.
</screen>
</para>
</listitem>
<listitem>
<para>sowie <literal remap="tt">@ref</literal>
</para>
<para>
Abweichend vom Javadoc-Format hat der Metatag "@ref" dasselbe Format wie @see, kann jedoch an jeder beliebigen Stelle innerhalb der Dokumentation erscheinen
(Alle anderen Tags m&uuml;ssen im Format "eins pro Zeile" auftauchen).</para>
</listitem>
</itemizedlist>
</para>
</sect1>
</chapter>

<chapter id="internationalization">
<title>Internationalisierung</title>

<sect1 id="what-is-i18n">
<title>Was hat es mit i18n auf sich?</title>

<para>Die Schwierigkeit
beim Schreiben von Applikationen besteht darin, dass sie zun&auml;chst nur in ihrer Originalsprache existieren -- wie an 
Labels, Men&uuml;eintr&auml;gen u.&auml;. leicht zu erkennen ist. Internationalisierung hat zum Ziel, Anwendungen und Bibliotheksfunktionen in der Muttersprache 
ihrer Benutzer zu Verf&uuml;gung zu stellen. Damit erhalten auch diejenigen, die der Originalsprache nicht m&auml;chtig sind, die M&ouml;glichkeit, sich die Funktionalit&auml;t der Software vollst&auml;ndig zu erschlie&szlig;en und sicher mit dem Programm umzugehen. Hier setzt das Internationalisierungssystem i18n an. Es erm&ouml;glicht an verschiedene Sprachkreise angepasste Versionen einer Anwendung oder eines Projekts. </para>
</sect1>

<sect1 id="how-kde-supports-internationalization">
<title>Wie unterst&uuml;tzt KDE Internationalisierung?</title>

<para>Als eine der modernsten Desktopumgebungen legt KDE gro&szlig;en Wert darauf, Anwendungen in der  jeweiligen Muttersprache ihrer Benutzer zur Verf&uuml;gung zu stellen. Daher hilft es Entwicklern dabei, die jeweilige Software in allen unterst&uuml;tzten Sprachen anzubieten.</para>

<para>Auf der technischen Seite kommt hier zum Einen der KDE-Filesystemstandard<indexterm remap="idx"><primary>KDE-Filesystemstandard</primary></indexterm> zum Tragen, der die sprachliche Lokalisierung der
Dokumentation unterst&uuml;tzt. Der Gebrauch der Klasse <literal remap="tt">KLocale</literal> aus der KDE-Core-Library gew&auml;hrleistet zum Anderen die Internationalisierung der Anwendung selbst. Diese Klasse
&uuml;bernimmt die Darstellung in der Sprache, die im KDE-Kontrollzentrum als Standardsprache fest gelegt wurde.</para>

<para>Als Entwickler muss man eigentlich nur drei Dinge wissen, will man diese Features nutzen: </para>

<para><orderedlist><listitem>
<para>Binden Sie die Headerdatei <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal> immer dann in Ihren Sourcecode ein, wenn Ihre Applikation Text sichtbar darstellt, so zum Beispiel in Quelldateien, die
QLabel<indexterm remap="idx"><primary>QLabel</primary></indexterm>s benutzen.</para>
</listitem>
<listitem>
<para>Jede sichtbare Zeichenkette sollten Sie mit dem <literal remap="tt">i18n()</literal>-Makro umschlie&szlig;en, das von <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal>  bereit gestellt wird. Damit werden &Uuml;bersetzungen &uuml;berhaupt erst
m&ouml;glich.</para>
</listitem>
<listitem>
<para>Wollen Sie auf ein locale-Objekt zugreifen, benutzen Sie bitte das <literal remap="tt">klocale</literal>-Makro (ebenfalls aus <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal>).</para>
</listitem>
</orderedlist>
</para>

<para>Das ist eigentlich alles, worauf Sie beim Programmieren achten m&uuml;ssen. Internationalisieren Sie jedoch niemals Konfigurationsstrings, wie sie von 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> genutzt werden. Dies ist v&ouml;llig unn&ouml;tige Arbeit, da die &uuml;bersetzten Zeichenketten gar nicht ausgelesen werden k&ouml;nnen.</para>
</sect1>

<sect1 id="adding-a-language-to-your-project">
<title>Hinzuf&uuml;gen einer Sprache zu einem Projekt</title>

<para>Selbstverst&auml;ndlich erleichtert KDevelop das Bereitstellen der Anwendung in verschiedenen Sprachen. Wenn Sie ein
neues KDE-Projekt anlegen, wird ein Verzeichnis namens <literal remap="tt">po</literal> in Ihrem Projekthauptverzeichnis erstellt. Dabei wird eine Datei namens <emphasis>&&lt;;anwendungsname&&gt;;</emphasis>.pot abgelegt.
Dieses File enth&auml;lt alle vom  i18n()-Makro umschlossenen Zeichenketten aus Ihrem Quellcode. 
Von Zeit zu Zeit bietet es sich an, die pot-Datei mit "Projekt"-"Meldungen erstellen und
verbinden" zu aktualisieren.
<indexterm><primary>"Projekt"-Men&uuml;</primary></indexterm><indexterm><primary>PO-Dateien</primary></indexterm><indexterm><primary>&Uuml;bersetzung</primary></indexterm><indexterm remap="ncdx"><primary><literal>KLocale</literal></primary></indexterm></para>

<para>Unterst&uuml;tzung f&uuml;r eine Sprache f&uuml;gt man &uuml;ber den Men&uuml;punkt "Projekt"-"Neue &Uuml;bersetzung hinzuf&uuml;gen" ein. Im nun erscheinenden Sprachauswahldialog suchen Sie sich die passende 
Sprache  aus und dr&uuml;cken OK. Damit wird das entsprechende <emphasis>&&lt;;sprache&&gt;;</emphasis>.po-File im <literal remap="tt">po</literal>-Verzeichnis erstellt. Beginnen Sie mit der &Uuml;bersetzung der po-Datei, indem Sie sie in der Dateiansicht (RFV -- "Real File View") unterhalb des po-Directories oder aus dem LFV-Reiter unter "&Uuml;bersetzungen" anw&auml;hlen. Falls Sie
KTranslator <indexterm remap="idx"><primary>KTranslator</primary></indexterm> installiert haben, steht dieser nun im "Werkzeuge"-Fenster <indexterm remap="idx"><primary>KTranslator</primary></indexterm> zur Verf&uuml;gung, anderenfalls erscheint die Textdatei in der Karteikarte "Header/Ressource-Dateien".
KTranslator <indexterm remap="idx"><primary>KTranslator</primary></indexterm> vereinfacht die &Uuml;bersetzung insofern, als dass es in Ihrer lokalen KDE-Installation vorhandene &Uuml;bersetzungen scannt und Ihnen diese Zeichenketten zur Wiederverwendung zur Verf&uuml;gung stellt.
</para>

<para>Editieren Sie das po-File von Hand, so lohnt es sich, zun&auml;chst ein Beispiel anzusehen:
<screen>#: kscribble.cpp:619
msgid "Opens an existing document"
msgstr ""
</screen>
</para>
<para>Es zeigt eine Zeichenkette, die aus der Datei <literal remap="tt">kscribble.cpp</literal> und dort aus Zeile 619 stammt. Die Tags <literal remap="tt"><indexterm remap="cdx"><primary><literal>msgid</literal></primary></indexterm>msgid</literal> and <literal remap="tt"><indexterm remap="cdx"><primary><literal>msgstr</literal></primary></indexterm>msgstr</literal> enthalten das ganze Geheimnis
der &Uuml;bersetzung:  <literal remap="tt"><indexterm remap="cdx"><primary><literal>msgid</literal></primary></indexterm>msgid</literal> bezeichnet den originalen,  <literal remap="tt"><indexterm remap="cdx"><primary><literal>msgstr</literal></primary></indexterm>msgstr</literal> nimmt den &uuml;bersetzten String auf. Achten Sie hier auf Escape-Sequenzen wie
\n or \t, die auch in der &Uuml;bersetzung wieder auftauchen m&uuml;ssen. Nachdem ein deutscher &Uuml;bersetzer seine Arbeit getan hat, s&auml;hen die obigen Zeilen folgenderma&szlig;en aus:</para>

<para><screen>#: kscribble.cpp:619
msgid "Opens an existing document"
msgstr "Öffnet ein existierendes Dokument"
</screen>
</para>

<para>Das w&auml;re schon alles, was es bei der &Uuml;bersetzung zu beachten gibt, solange Sie darauf achten, die ge&auml;nderte po-Datei auch abzuspeichern. Wenn make im po-Verzeichnis seine Arbeit verrichtet, wird auch diese Datei
abgearbeitet. Fehlermeldungen treten an dieser Stelle auf, wenn die &Uuml;bersetzung nicht mit dem Original konsistent ist, sprich: wenn Escape-Sequenzen vergessen wurden. In diesem Fall
berichtigen Sie die entsprechende Zeichenkette und pr&uuml;fen, dass make nun fehlerfrei l&auml;uft.</para>

<para>Lassen Sie Vorsicht walten bei kaufm&auml;nnischen Und-Zeichen innerhalb von Zeichenketten. Der Buchstabe nach dem &amp; wird in Verbindung mit der ALT-Taste als
Shortcut<indexterm><primary>Shortcut</primary></indexterm>  oder Keyboard-Akzellerator<indexterm><primary>Akzellerator</primary></indexterm> gebraucht, um den Tastaturfokus <indexterm remap="idx"><primary>Tastaturfokus</primary></indexterm> schneller  zu einem ins Auge gefassten Men&uuml;punkt oder Button zu dirigieren. 
Wenn das  Akzellerator<indexterm><primary>Akzellerator</primary></indexterm>-Zeichen mehr als einmal in Reichweite ein und desselben Keyboard-Fokus <indexterm remap="idx"><primary>Tastaturfokus</primary></indexterm> auftaucht (das wird von Fall zu Fall das Hauptwidget 
 oder ein Dialog sein), kann au&szlig;er dem ersten Ziel kein weiteres mehr &uuml;ber den Shortcut<indexterm><primary>Shortcut</primary></indexterm> angesprochen werden. Daher haben sogar  
&Uuml;bersetzer eine gewisse Verantwortung daf&uuml;r, das die Anwendung in ihrer Sprache vern&uuml;nftig verwendbar bleibt. Da es keinerlei Garantie daf&uuml;r gibt, 
dass der Originalbuchstabe in der &Uuml;bersetzung &uuml;berhaupt auftaucht, m&uuml;ssen &Uuml;bersetzer mit Bedacht  einen passenden Shortcut aussuchen und die Anwendung in der &Uuml;bersetzung vor allem  sehr sorgf&auml;ltig auf Fehlfunktionen testen.
</para>
</sect1>

<sect1 id="translation-team-contacts">
<title>Kontakt zu den &Uuml;bersetzungsteams</title>

<para>Die &Uuml;bersetzer des KDE-Projekts koordinieren sich &uuml;ber Sprachteams.
Eine aktuelle Liste, an wen Sie sich wenden k&ouml;nnen, wenn Sie an der &Uuml;bersetzung Ihres Programms interessiert sind, finden Sie unter <ulink url="http://www.kde.org">\|\|</ulink>.</para>

<para>Die hier zitierte Kontaktliste stammt von der KDE-Webseite und enth&auml;lt die am 6. M&auml;rz 1999 g&uuml;ltigen Kontaktadressen. Wenn Sie in einem &Uuml;bersetzungsteam mitwirken wollen, wenden Sie sich bitte 
direkt an einen der Teamkoordinatoren.</para>

<para>Die &Uuml;bersetzung von KDE wird von Juraj Bednar (<ulink url="mailto:bednar@rak.isternet.sk">bednar@rak.isternet.sk</ulink>) und Matthias Elter (<ulink url="mailto:me@kde.org">me@kde.org</ulink>) koordiniert.</para>

<para>Sie k&ouml;nnen sich in die KDE-Internationalisierungsmailingliste kde-i18n-doc@kde.org eintragen, indem Sie eine Mail mit dem Subject "subscribe" an <ulink url="mailto:kde-i18n-doc-request@kde.org?subject=subscribe">kde-i18n-doc-request@kde.org</ulink> senden.
</para>

<para>Bitte kontaktieren Sie auf jeden Fall den jeweils passenden Koordinator, bevor Sie sich auf eine &Uuml;bersetzung st&uuml;rzen -- das vermeidet doppelte Arbeit.</para>

<para><variablelist>
<varlistentry>
<term>br Bretonisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator: Jañ-Mai DRAPIER, <ulink url="mailto:jdrapier@club-internet.fr">jdrapier@club-internet.fr</ulink>,
Webseite: <ulink url="http://perso.club-internet.fr/jdrapier/">http://perso.club-internet.fr/jdrapier/</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>ca Katalanisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator: Sebastià Pla, <ulink url="mailto:sastia@redestb.es">sastia@redestb.es</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>cs Tschechisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Miroslav Flídr, <ulink url="mailto:flidr@kky.zcu.cz">flidr@kky.zcu.cz</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>da D&auml;nisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Erik Kjær Pedersen, <ulink url="mailto:erik@binghamton.edu">erik@binghamton.edu</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>de Deutsches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator: Thomas Diehl, <ulink url="mailto:th.diehl@gmx.net">th.diehl@gmx.net</ulink>
, Webseite: <ulink url="http://www.dtp-service.com/kde/de/">\|\|</ulink>
, Mailingliste:  Schicken Sie eine Mail mit dem Subject 'subscribe' an: <ulink url="mailto:kde-i18n-de-request@kde.org?subject=subscribe">kde-i18n-de-request@kde.org</ulink>, Webforum f&uuml;r  Diskussionen und Benutzerfeedback: <ulink url="http://www.dtp-service.com/discus_d">\|\|</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>el Griechisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Theodore J. Soldatos, <ulink url="mailto:theodore@eexi.gr">theodore@eexi.gr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>eo &Uuml;bersetzungsteam Esperanto:</term>
<listitem>
<para>Teamkoordinator:  Wolfram Diestel, <ulink url="mailto:diestel@rzaix340.rz-uni-leipzig.de">diestel@rzaix340.rz-uni-leipzig.de</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>es Spanisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinatoren:  Boris Wesslowski, Alonso Lara, <ulink url="mailto:Boris@Wesslowski.com">Boris@Wesslowski.com</ulink>
, Webseite: <ulink url="http://members.xoom.com/keko5/">\|\|</ulink>
, Mailingliste: Senden Sie eine Mail mit der Subject-Zeile 'subscribe' an <ulink url="mailto:kde-es@kde.org?subject=subscribe">kde-es@kde.org</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>et Estnisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Hasso C. Tepper, <ulink url="mailto:hasso@ewsound.estnet.ee">hasso@ewsound.estnet.ee</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>fi Finnisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator: Kim Enkovaara, <ulink url="mailto:kim.enkovaara@iki.fi">kim.enkovaara@iki.fi</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>fr Franz&ouml;sisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Francois-Xavier Duranceau, <ulink url="mailto:Francois-Xavier.Duranceau@loria.fr">Francois-Xavier.Duranceau@loria.fr</ulink>
, Webseite: <ulink url="http://www.loria.fr/~durancea/kde/wip-apps.html">\|\|</ulink>
, Mailingliste: Schicken Sie eine leere Mail an:  <ulink url="mailto:kde-traduc-fr-subscribe@egroups.com">kde-traduc-fr-subscribe@egroups.com</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>he Hebr&auml;isches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Erez Nir, <ulink url="mailto:erez-n@actcom.co.il">erez-n@actcom.co.il</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>hr Kroatisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Vladimir Vuksan, <ulink url="mailto:vuksan@veus.hr">vuksan@veus.hr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>hu Ungarisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Marcell Lengyel, <ulink url="mailto:miketkf@yahoo.com">miketkf@yahoo.com</ulink>
, Webseite:<ulink url="http://sophia.jpte.hu/~kde">\|\|</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>is Isl&auml;ndisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinatoren:
Logi Ragnarsson, <ulink url="mailto:logir@imf.au.dk">logir@imf.au.dk</ulink>,
Thorarinn R. Einarsson, <ulink url="mailto:thori@mindspring.com">thori@mindspring.com</ulink>,
Bjarni R. Einarsson, <ulink url="mailto:bre@netverjar.is">bre@netverjar.is</ulink>,
Hrafnkell Eiriksson, <ulink url="mailto:hkelle@rhi.hi.is">hkelle@rhi.hi.is</ulink>,
Gudmundur Erlingsson, <ulink url="mailto:gudmuner@lexis.hi.is">gudmuner@lexis.hi.is</ulink>,
Richard Allen, <ulink url="mailto:ra@hp.is">ra@hp.is</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>it Italienisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Andrea Rizzi, <ulink url="mailto:rizzi@kde.org">rizzi@kde.org</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>ko Koreanisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordination:  LinuxKorea Co., <ulink url="mailto:kde@linuxkorea.co.kr">kde@linuxkorea.co.kr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>mk Mazedonisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Sasha Konecni, <ulink url="mailto:sasha@msi-uk.com">sasha@msi-uk.com</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>nl Niederl&auml;ndisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Miroslav Flídr, <ulink url="mailto:flidr@CyberGate.zcu.cz">flidr@CyberGate.zcu.cz</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>no Norwegisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Hans Petter Bieker, <ulink url="mailto:zerium@webindex.no">zerium@webindex.no</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>pl Polnisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Piotr Roszatycki, <ulink url="mailto:dexter@fnet.pl">dexter@fnet.pl</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>pt Portugiesisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Pedro Morais, <ulink url="mailto:pmmm@camoes.rnl.ist.utl.pt">pmmm@camoes.rnl.ist.utl.pt</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>pt&&lowbar;;BR Brasilianisch-portugiesisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Elvis Pfützenreuter, <ulink url="mailto:epx@netville.com.br">epx@netville.com.br</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>ro Rum&auml;nisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Paul Ionescu, <ulink url="mailto:ipaul@romsys.ro">ipaul@romsys.ro</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>ru Russisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Denis Y. Pershin, <ulink url="mailto:dyp@inetlab.com">dyp@inetlab.com</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>sk Slowakisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Juraj Bednar, <ulink url="mailto:bednar@isternet.sk">bednar@isternet.sk</ulink>
, Mailingliste:  Schicken Sie eine Mail mit dem Betreff 'subscribe' an: <ulink url="mailto:sk-i18n@rak.isternet.sk?subject=subscribe">sk-i18n@rak.isternet.sk</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>sl Slowenisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:   <ulink url="mailto:blazzupancic@hotmail.com">blazzupancic@hotmail.com</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>sv Schwedisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Anders Widell, <ulink url="mailto:d95-awi@nada.kth.se">d95-awi@nada.kth.se</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>tr T&uuml;rkisches &Uuml;bersetzungsteam:</term>
<listitem>
<para>Teamkoordinator:  Gorkem Cetin, <ulink url="mailto:gorkem@linux.org.tr">gorkem@linux.org.tr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>zh&&lowbar;;GB2312 &Uuml;bersetzungsteam f&uuml;r vereinfachtes Chinesisch:</term>
<listitem>
<para>Teamkoordinator:  Wang Jian, <ulink url="mailto:larkw@263.net">larkw@263.net</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>zh&&lowbar;;TW&&lowbar;;Big5 &Uuml;bersetzungsteam f&uuml;r BIG5-Chinesisch:</term>
<listitem>
<para>Teamkoordinator:  Chou Yeh-Jyi, <ulink url="mailto:ycchou@ccca.nctu.edu.tw">ycchou@ccca.nctu.edu.tw</ulink></para>
</listitem>
</varlistentry>
</variablelist>
</para>
</sect1>
</chapter>

<chapter id="finding-errors">
<title>Fehler finden</title>

<para><indexterm><primary>Debugging-Makros</primary></indexterm></para>

<sect1 id="debugging-macros-provided-by-qt-qt">
<title>Von Qt zur Verf&uuml;gung gestellte Debugging-Makros<indexterm remap="idx"><primary>Qt</primary></indexterm></title>

<para>Die Debugging-Makros, die die Qt-<indexterm remap="idx"><primary>Qt</primary></indexterm>Bibliothek mitbringt, werden ausf&uuml;hrlich auf der debug.html-Seite Ihrer Qt-<indexterm remap="idx"><primary>Qt</primary></indexterm>Online-Referenz
erl&auml;utert, die Sie &uuml;ber den Link "Debugging Techniques" auf der Indexseite der Qt<indexterm remap="idx"><primary>Qt</primary></indexterm>-Dokumentation finden.</para>

<para>Am gebr&auml;uchlichsten sind</para>

<para><itemizedlist>
<listitem>
<para>ASSERT(b) und</para>
</listitem>
<listitem>
<para>CHECK&&lowbar;;PTR(p)</para>
</listitem>
</itemizedlist>
</para>

<para>b ist dabei ein Boolescher Ausdruck. Wenn b falsch ist, erh&auml;lt  man eine Warnung im Debugging-Output. Ist der Pointer p Null, wird ebenfalls eine Warnung ausgegeben.
</para>

<para>Ausf&uuml;hrlichere Informationen finden Sie in der Qt-<indexterm remap="idx"><primary>Qt</primary></indexterm>Online-Referenz.</para>
</sect1>

<sect1 id="kde-macros">
<title>KDE-Makros</title>

<para>Im Folgenden zitiere ich Kalle Dalheimers (<ulink url="mailto:kalle@kde.org">kalle@kde.org</ulink>) Erl&auml;uterung zu den 
KDEBUG-<indexterm remap="idx"><primary>KDEBUG</primary></indexterm>Makros aus der mit dem KDElibs-Paket mitgelieferten Datei kdebug.html.</para>

<para>Letzte &Auml;nderung am Samstag, 13. Sep 1997, 11:56:01 MESZ </para>

<para><emphasis remap="bf">Was ist KDebug?</emphasis></para>

<para>KDebug ist eine Sammlung von Makros und Funktionen, die Diagnosemeldungen effizient
in Ihren Code integrieren. Die Meldungen definieren sich &uuml;ber vier verschiedene Schweregrade sowie einen
G&uuml;ltigkeitsbereich. Sie entscheiden zur Laufzeit, wo und welche Diagnosemeldungen ausgegeben werden. Wie wendet man KDebug nun an? </para>

<para><emphasis remap="bf">Das KDEBUG-Makro <indexterm remap="idx"><primary>KDEBUG</primary></indexterm></emphasis></para>

<para>KDebug l&auml;sst sich sehr einfach benutzen. Sie m&uuml;ssen dazu lediglich die Zeile &&num;;include &&lt;;kdebug.h&&gt;; am Anfang jeder Quelltextdatei einf&uuml;gen, in der Sie von Diagnosemeldungen Gebrauch machen wollen. Die Meldungen selbst erzeugen Sie,
indem Sie das Makro KDEBUG <indexterm remap="idx"><primary>KDEBUG</primary></indexterm> aufrufen. Es erwartet drei Parameter. Der erste definiert den 
Schweregrad. Benutzen Sie dazu eine der folgenden Konstanten:</para>

<para><itemizedlist>
<listitem>
<para>KDEBUG&&lowbar;;INFO <indexterm remap="idx"><primary>KDEBUG&&lowbar;;INFO</primary></indexterm></para>
</listitem>
<listitem>
<para>KDEBUG&&lowbar;;WARN <indexterm remap="idx"><primary>KDEBUG&&lowbar;;WARN</primary></indexterm></para>
</listitem>
<listitem>
<para>KDEBUG&&lowbar;;ERROR <indexterm remap="idx"><primary>KDEBUG&&lowbar;;ERROR</primary></indexterm></para>
</listitem>
<listitem>
<para>KDEBUG&&lowbar;;FATAL <indexterm remap="idx"><primary>KDEBUG&&lowbar;;FATAL</primary></indexterm></para>
</listitem>
</itemizedlist>
</para>

<para>Der zweite Parameter gibt den G&uuml;ltigkeitsbereich an, der einen von Ihnen definierten Teil von KDE umfasst. Zur Laufzeit legen Sie fest, welchen Bereich die Ausgaben betreffen sollen. 
In der Datei kdelibs/kdecore/kdebugareas.txt finden Sie eine Liste aller bislang vordefinierten Bereiche.
W&auml;hlen Sie einen G&uuml;ltigkeitsbereich, der Ihre Anwendung abdeckt. Falls Ihre Applikation nicht in der Liste zu finden ist, k&ouml;nnen Sie im CVS einen Bereich f&uuml;r Ihre Anwendung festlegen, wenn Sie keinen CVS-Zugang haben, schreiben Sie mir einfach.
In den meisten F&auml;llen ist es sinnvoll, symbolische Konstanten f&uuml;r die Bereiche zu definieren, die Sie nutzen wollen, aber das
k&ouml;nnen Sie halten, wie Sie wollen.</para> 
<para>
Schlie&szlig;lich w&auml;re da noch der dritte Parameter, der Text, den Sie ausgeben wollen. Wenn Sie die Diagnosemeldungen in eine Datei, auf STDERR oder im Syslog mitprotokollieren, stellt KDebug ihnen
den logischen Namen der Applikation voran. Ein Zeilenumbruch wird ebenfalls immer im Anschluss an die Meldung ausgegeben, sodass Sie das 
nicht von Hand tun m&uuml;ssen (und auch gar nicht sollen). Wenn Sie zus&auml;tzliche Parameter ben&ouml;tigen, nutzen Sie eins der Makros KDEBUG1 bis KDEBUG9. Diese bieten Raum f&uuml;r  ein bis neun
zus&auml;tzliche Argumente. Die Syntax gleicht der von printf, d.h., Sie reichern Ihren Meldungstext mit den Formatangaben an, die zur Laufzeit durch die zus&auml;tzlichen Parameter ersetzt werden.
Ein Beispiel:</para>

<para><screen>KDEBUG3( &lt;idx/KDEBUG_INFO/, kmail_composer, "Message no. %d to %s has %d bytes",
          message_no, aMessage.to(), aMessage.length() );
</screen>
</para>

<para><emphasis remap="bf">KASSERT <indexterm remap="idx"><primary>KASSERT</primary></indexterm></emphasis></para>

<para>Zudem gibt es noch die Makros KASSERT, KASSERT1, ..., KASSERT9,
die genau wie Ihre KDEBUG<indexterm remap="idx"><primary>KDEBUG</primary></indexterm>-Gegenst&uuml;cke wirken, mit einer Ausnahme: Als erstes Argument ben&ouml;tigen sie einen zus&auml;tzlichen Booleschen
Parameter. Die zugeh&ouml;rige Meldung wird nur dann ausgegeben, wenn dieser falsch ist. Beachten Sie dabei, dass Sie weder
KDEBUG <indexterm remap="idx"><primary>KDEBUG</primary></indexterm> noch KASSERT <indexterm remap="idx"><primary>KASSERT</primary></indexterm> verwenden d&uuml;rfen, bevor Sie Ihr <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication-Objekt erzeugt haben. Und noch ein Weiteres: KDebug bietet keine Internationalisierungsm&ouml;glichkeit, da es ausschlie&szlig;lich f&uuml;r Entwickler gedacht ist. Wenn Sie Ihre Benutzer &uuml;ber einen Fehlerfall (beispielsweise "Diese Datei ist nicht schreibbar.") informieren wollen, benutzen Sie bitte 
KMsgBox.</para>

<para><emphasis remap="bf">Compilerswitches</emphasis></para>

<para>F&uuml;r KDebug ben&ouml;tigen Sie keinerlei Compilerswitches. Wenn Sie Ihre Software jedoch vertreiben wollen
(dies trifft haupts&auml;chlich auf Distributoren zu, die .rpm-, .deb- o.&auml;. Pakete erstellen), sollten Sie sie mit dem 
-DNDEBUG-Switch kompilieren. Damit entfernen Sie s&auml;mtlichen Debugging-Code aus Ihrer Anwendung und sorgt daf&uuml;r, dass sie kleiner und schneller wird (und beispielsweise 256K weniger 
dedizierten Speicher verbraucht).</para>

<para><emphasis remap="bf">Diagnosemeldungen zur Laufzeit ein- und abschalten </emphasis></para>

<para>In jeder  <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication  k&ouml;nnen Sie mit der Tastenkombination Strg-Umschalt-F12 zu jeder Zeit Ctrl-Shift-F12 den Dialog "Debug-Einstellungen" aufrufen. Hier legen Sie f&uuml;r jeden Schweregrad einzeln fest,
was mit einer Diagnosemeldung dieser Ebene passiert. Folgende Einstellungen sind
m&ouml;glich:</para>

<para><itemizedlist>
<listitem>
<para>Output: In dieser Kombobox bestimmen Sie, ob und wohin Meldungen ausgegeben werden. M&ouml;glich sind: "File", "Message Box", "Shell"
(also STDERR) und "syslog". Bitte dirigieren Sie FATAL-Meldungen nur dann ins Syslog, wenn Sie tats&auml;chlich der Systemadministrator der betreffenden Maschine sind. Voreingestellt ist
"Message Box".</para>
</listitem>
<listitem>
<para>File: Ein Eintrag hier ist lediglich dann sinnvoll, wenn Sie "File" als Ausgabemedium eingestellt haben. Dann geben Sie an dieser Stelle den Namen der Datei (relativ zum aktuellen Verzeichnis) an.
Voreingestellt ist kdebug.dbg.
</para>
</listitem>
<listitem>
<para>Area: Die G&uuml;ltigkeitsbereiche, deren Meldungen ausgegeben werden sollen. Alle hier nicht aufgef&uuml;hrten Bereiche werden schlicht und einfach nicht ber&uuml;cksichtigt  -- es sei denn, das Feld bleibt wie voreingestellt leer.
Das hat zur Folge, dass alle Meldungen ausgegeben werden. Die Bereiche werden durch Kommata voneinander getrennt, es sind aber auch Von-Bis-Angaben m&ouml;glich, die Sie in der Form  
Anfang-Ende angeben. Ein g&uuml;ltiger Eintrag w&auml;re: 117,214-289,356-359,221. Achten Sie darauf, keine Leerzeichen zu
verwenden.</para>
</listitem>
</itemizedlist>
</para>

<para>Abgesehen davon k&ouml;nnen Sie auch die Checkbox "Abort on fatal errors" ankreuzen. In diesem Fall beendet sich die Anwendung mit SIGABRT, wenn sie eine Diagnosemeldung des Schweregrads
"KDEBUG&&lowbar;;FATAL <indexterm remap="idx"><primary>KDEBUG&&lowbar;;FATAL</primary></indexterm>" ausgegeben hat.
</para>
<para>
Wenn Sie den Dialog mit OK beenden, werden Ihre Einstellungen sofort aktiv und 
im Konfigurationsfile der Anwendung gespeichert. Beachten Sie bitte, dass sich Ihre Einstellungen lediglich auf eine spezielle Applikation beziehen. 
W&auml;hlen Sie hingegen cancel, werden s&auml;mtliche neuen Einstellungen verworfen und die alten wieder hergestellt.</para>
</sect1>
</chapter>

<chapter id="the-kde-file-system-standard">
<title>Der KDE-Dateisystemstandard</title>

<para>Dieses Kapitel gibt den KDE-Filesystemstandard so wieder, wie er auf der KDE-Website unter <ulink url="http://www.kde.org/">\|\|</ulink> zu finden ist. Der Text wurde von 
Richard Moore <ulink url="rich@kde.org">rich@kde.org</ulink> verfasst.</para>

<para><emphasis remap="bf">Der KDE-Filesystemstandard</emphasis></para>

<para>Diese Datei beschreibt die Verzeichnisstruktur, wie sie von KDE und allen zu KDE kompatiblen Applikationen genutzt werden sollte. Hierbei handelt es sich um Version 0.0.4 des
Standards.</para>

<sect1 id="introduction-0">
<title>Einleitung</title>

<para>Sinn und Zweck des KDE-FSSTD <indexterm remap="idx"><primary>KDE-FSSTD</primary></indexterm> ist es, sicher zu stellen, dass alle von KDE-Applikationen ben&ouml;tigten Ressourcen (Icons, Mimetypes etc.) <indexterm remap="idx"><primary>KDE-Applikationen</primary></indexterm> in einer konsistenten Verzeichnisstruktur abgelegt werden.
Anwendungen, die sich an diese Struktur halten, haben die M&ouml;glichkeit, Werkzeuge wie die KIconLoader-Klasse zu verwenden. Zudem ist es so m&ouml;glich,
von KDE benutzte plattformabh&auml;ngige Daten von plattformunabh&auml;ngigen zu trennen und die Software recht problemlos  auf unterschiedlichen Architekturen zu installieren.
</para>
<para>
Verzeichnisnamen werden im Folgenden mit dem Suffix `/` versehen. Erscheint der String 'appname' in spitzen Klammern 
(&&lt;;wie hier&&gt;;), sollten Sie ihn gedanklich durch die Namen aller installierten KDE-Anwendungen ersetzen. Der Platzhalter
'lang' wird entsprechend verwendet und wird zu jeweils einem standardisierten Zweibuchstabencode f&uuml;r jede unterst&uuml;tzte Sprache expandiert (z.B. zu 
'fr' f&uuml;r Franz&ouml;sisch, 'de' f&uuml;r Deutsch usw.</para>
</sect1>

<sect1 id="directory-layout">
<title>Die Verzeichnisstruktur</title>

<para>Die KDE-Verzeichnisstruktur, wie sie unten gezeigt wird, beginnt mit dem Installationsverzeichnis (meistens '/opt/kde'). Dieses l&auml;sst sich zur Laufzeit mit der
zu  <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication geh&ouml;renden kdedir()-Methode auslesen, (Dieser Mechanismus ersetzt die Umgebungsvariable KDEDIR, die nicht mehr benutzt werden sollte.) Im Folgenden
benutzen wir f&uuml;r dieses Verzeichnis die Schreibweise kdedir().
<indexterm><primary>KDE-Verzeichnisstruktur</primary></indexterm><indexterm><primary>.kdelnk-Dateien</primary></indexterm></para>

<para><itemizedlist>
<listitem>
<para>kdedir()/
<itemizedlist>
<listitem>
<para>bin/
<itemizedlist>
<listitem>
<para>ausf&uuml;hrbare bin&auml;re Anwendungsprogramme</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>lib/
<itemizedlist>
<listitem>
<para>die KDE-Standardbibliotheken (libkdecore etc.)</para>
</listitem>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>anwendungsspezifische, plattformabh&auml;ngige Daten</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>include/
<itemizedlist>
<listitem>
<para>Standard-KDE-Headerdateien</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>parts/</para>
</listitem>
<listitem>
<para>cgi-bin/
<itemizedlist>
<listitem>
<para>CGI-Programme f&uuml;r kdehelp</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>share/
<itemizedlist>
<listitem>
<para>doc/
<itemizedlist>
<listitem>
<para>HTML/
<itemizedlist>
<listitem>
<para>default --&gt; Link zu kdedir()/share/doc/HTML/en</para>
</listitem>
<listitem>
<para><emphasis>&&lt;;lang&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>index.html</para>
</listitem>
<listitem>
<para>weitere Hilfsdateien f&uuml;r Applikationen</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>config/</para>
</listitem>
<listitem>
<para>applnk/
<itemizedlist>
<listitem>
<para>System/</para>
</listitem>
<listitem>
<para>Utilities/</para>
</listitem>
<listitem>
<para>Applications/</para>
</listitem>
<listitem>
<para>Games/</para>
</listitem>
<listitem>
<para>kfind.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
<listitem>
<para>khelp.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
<listitem>
<para>khome.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
<listitem>
<para>krefresh.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>mimelnk/
<itemizedlist>
<listitem>
<para>magic</para>
</listitem>
<listitem>
<para>text/</para>
</listitem>
<listitem>
<para>audio/</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>partlnk/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;partname&&gt;;</emphasis>.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>icons/
<itemizedlist>
<listitem>
<para>Icons, die in kdelnk-Dateien benutzt werden</para>
</listitem>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>.xpm</para>
</listitem>
<listitem>
<para>mini/
<itemizedlist>
<listitem>
<para>Mini-Icons f&uuml;r kpanel</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>/
<itemizedlist>
<listitem>
<para>Standard-Pixmaps f&uuml;r die Werkzeugleiste <indexterm remap="idx"><primary>Werkzeugleiste</primary></indexterm> (z.B. fileopen.xpm)</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>wallpapers/
<itemizedlist>
<listitem>
<para>Hintergrundbilder f&uuml;r kdisplay</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>apps/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>/
<itemizedlist>
<listitem>
<para>Pixmaps f&uuml;r die Werkzeugleiste</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>pics/
<itemizedlist>
<listitem>
<para>Pixmaps f&uuml;r andere Anwendungen</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>anwendungsspezifische, zwingend plattformunabh&auml;ngige Daten </para>
</listitem>
</itemizedlist>
				</para>
</listitem>
<listitem>
<para><emphasis>&&lt;;libname&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>pics/</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>locale/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;lang&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>LC&&lowbar;;MESSAGES/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>.mo</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="what-does-this-mean-to-application-developer">
<title>Was bedeutet das f&uuml;r Anwendungsentwickler? </title>

<para>Eine dem Standard folgende KDE-Anwendung wird bei der Installation verschiedene Dateien auf die oben genannten Verzeichnisse verteilen. Die einzigen Files, die unter allen Umst&auml;nden ben&ouml;tigt werden, sind das Anwendungsbinary selbst und die passende
kdelnk-Datei, das Anwendungsicon und die Hilfedateien -- alles andere ist optional. Gew&ouml;hnlich wird Folgendes installiert:
</para>

<para><screen>
Art der Datei                                           Ort

das Anwendungsprogramm selbst (unverzichtbar)           kdedir()/bin/
das zugeh&ouml;rige kdelnk-File (unverzichtbar)              kdedir()/share/applnk/
das passende Icon (unverzichtbar)                       kdedir()/share/icons/&&lt;;appname&&gt;;.xpm
Hilfsdateien (unverzichtbar)                            kdedir()/share/doc/default/HTML/&&lt;;appname&&gt;;/&&lt;;index&&gt;;.html
die n&ouml;tigen Pixmaps f&uuml;r die Werkzeugleiste              kdedir()/share/apps/&&lt;;appname&&gt;;/toolbar/
anwendungsspezifische, plattformunabh&auml;ngige Daten       kdedir()/share/apps/&&lt;;appname&&gt;;/
applikationsspezifische, plattformabh&auml;ngige Daten       kdedir()/lib/&&lt;;appname&&gt;;/
</screen>

<indexterm><primary>KDE-Dateisystem</primary></indexterm></para>
</sect1>

<sect1 id="application-documentation">
<title>Dokumentation</title>

<para>Mein Vorschlag ist, mindestens eine Seite in</para>

<para>kdedir()/doc/default/HTML/&&lt;;appname&&gt;;/&&lt;;appname&&gt;;.html</para>

<para>f&uuml;r alle KDE-Anwendungen zur Pflicht zu machen. Abgesehen davon steht es jeder Applikation frei, in diesem Verzeichnis jegliche f&uuml;r n&ouml;tig erachtete Hilfedateien abzulegen.</para>

<para>Anwendungen, die mehr als eine Sprache unterst&uuml;tzen, nutzen daf&uuml;r kdedir()/doc/&&lt;;lang&&gt;;/HTML/&&lt;;appname&&gt;;/&&lt;;appname&&gt;;.html, wobei
ein 'lang'-Verzeichnis f&uuml;r jeden Sprachcode &uuml;blich ist. Indem man diese Dateien so anordnet, ist es m&ouml;glich, Links zwischen den  Hilfedateien
zweier verschiedener Anwendungen zu setzen, vorausgesetzt, beide unterst&uuml;tzen ein und dieselbe Sprache.</para>

<para>100&&percnt;; gl&uuml;cklich bin ich mit dieser von mir vorgeschlagenen L&ouml;sung nicht, da man damit  im Zweifelsfall nicht auf die Originalsprache zur&uuml;ck zur&uuml;ck greifen kann, wenn keine &Uuml;bersetzung vorhanden ist.
</para>
</sect1>

<sect1 id="what-does-this-mean-to-library-developers">
<title>Welche Folgen hat das f&uuml;r Bibliotheksentwickler?</title>

<para><itemizedlist>
<listitem>
<para>kdedir()/share/apps/&&lt;;libname&&gt;;/toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm></para>
</listitem>
</itemizedlist>

Werkzeugleistenicons f&uuml;r Library-Widgets.</para>

<para><itemizedlist>
<listitem>
<para>kdedir()/share/apps/&&lt;;libname&&gt;;/pics</para>
</listitem>
</itemizedlist>

sonstige Bitmaps f&uuml;r Library-Widgets.</para>
</sect1>
</chapter>

<chapter id="file-system-usage-for-kdevelop-projects">
<title>File System Usage for KDevelop Projects</title>

<para>As the last chapter covered the KDE File System Standard, this chapter deals with what you have to do to use the file system. A KDE
project uses the file system at least for installation routines; therefore we will discuss setting installation properties for your
project files. Your application may make use of files that are installed afterwards, where it is important to know how to get the
relative pathname by the standard. This enables your application to work wherever the KDE file system may be and prevents hard-coding
any file information.</para>

<sect1 id="accessing-files-during-runtime">
<title>Accessing Files during Runtime</title>

<para>After the installation of your project by end-users, your application may require file information during runtime. During the
development process, you will experience at least one error which is caused when running your application within the KDevelop IDE and
requiring the application manual by "Help"-"Contents" or pressing the F1 key. This will result in a message box, saying that the
index.html file could not be found- if you haven't installed your application on your local KDE file system. Your application asks
KDEHelp <indexterm remap="idx"><primary>KDEHelp</primary></indexterm> to open your index page with detecting the installation directory first through <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>'s methods to access the file
system, therefore, we will have a look at what <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> offers and make some example usage. Also other classes of
<literal remap="tt">KDE-Core</literal> make use of the KDE File System like <literal remap="tt">KIconLoader</literal> and <literal remap="tt">KLocale</literal>, which will be reviewed afterwards.</para>
</sect1>

<sect1 id="kapplicationkapplication-methods">
<title><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication Methods</title>

<para>The <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication class offers the following methods to access the KDE File System:
<screen>void invokeHTMLHelp ( QString aFilename, QString aTopic ) const
static const QString& kde_htmldir ()
static const QString& kde_appsdir ()
static const QString& kde_icondir ()
static const QString& kde_datadir ()
static const QString& kde_localedir ()
static const QString& kde_cgidir ()
static const QString& kde_sounddir ()
static const QString& kde_toolbardir ()
static const QString& kde_wallpaperdir ()
static const QString& kde_bindir ()
static const QString& kde_configdir ()
static const QString& kde_mimedir ()
static QString localkdedir ()
static QString localconfigdir ()
static QString findFile ( const char *file )
</screen>

<indexterm><primary>KDE File System</primary></indexterm>
The methods are generally used with the <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> object of your application, where <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> offers the macro
<literal remap="tt">kapp</literal> to receive the pointer:</para>

<para>&&num;;define kapp <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication::getKApplication()</para>

<para>Therefore, the methods are generally used like this:
<screen>QString sounddir=kapp-&gt;kde_sounddir();
</screen>

This example stores the path of the KDE sounddirectory under a <literal remap="tt">QString</literal>, where you would append e.g. the sound filename. Then you
can process this information and play a sound file that is located there. You should always test for the existence of a file by using
<literal remap="tt">QFileInfo</literal>'s <literal remap="tt">exists()</literal> method.</para>

<para>Within these methods,</para>

<para><screen>void invokeHTMLHelp( QString aFilename, QString aTopic ) const [public]
</screen>
</para>

<para>takes a special position to invoke the KDE help. Generally, you should use it everywhere a user needs to access information, e.g. when
he is presented a modal dialog. The F1 key will not work to invoke the help contents, also the user should be presented the according
help page. To make a good use of it, add a "Help" button to your dialog and create a slot that is used to connect on signal
<literal remap="tt">pressed()</literal>. In this method, use <literal remap="tt"><indexterm remap="cdx"><primary><literal>invokeHTMLHelp()</literal></primary></indexterm>invokeHTMLHelp()</literal> with the according page and subject; in case your application's documentation
isn't written completely yet, leave this open to complete it after the documentation is in sync with the application.</para>

<para>The documentation of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> says:</para>

<para>Invoke the kdehelp HTML help viewer.</para>

<para>Parameters: aTopic
This allows context-sensitive help. Its value will be appended to the filename, prefixed with a "&&num;;" (hash) character.</para>

<para>aFilename: The filename that is to be loaded. Its location is computed automatically according to the KFSSTND. If aFilename is empty,
the logical appname with .html appended to it is used.</para>

<para>The methods of  <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> will retrieve the following path's.</para>

<para><screen>kde_htmldir()         kdedir()/share/doc/HTML         Returns the directory where KDE stores
                                                      its HTML documentation

kde_appsdir()         kdedir()/share/applnk           Returns the directory where KDE applications
                                                      store their .kdelnk file

kde_icondir()         kdedir()/share/icons            Returns the directory where KDE icons are stored

kde_datadir()         kdedir()/share/apps             Returns the directory where KDE applications
                                                      store their specific data

kde_localedir()       kdedir()/share/locale           Returns the directory where locale-specific
                                                      information (like translated on-screen messages) are stored

kde_cgidir()          kdedir()/cgi-bin                Returns the directory where cgi scripts are stored

kde_sounddir()        kdedir()/share/sounds           Returns the directory where sound data are stored.
                                                      This directory is for KDE specific sounds.
                                                      Sound data of Applications should go
                                                      into kde_datadir()

kde_toolbardir()      kdedir()/share/toolbar          Returns the directory where toolbar icons are stored

kde_wallpaperdir()    kdedir()/share/wallpapers       Returns the directory where KDE wallpaper files are stored

kde_bindir()          kdedir()/bin                    Returns the directory where KDE application binaries are stored

kde_configdir()       kdedir()/share/config           Returns the directory where config files are stored

kde_mimedir()         kdedir()/share/mimelnk          Returns the directory where mimetypes are stored

localkdedir()         $HOME/.kde                      Get the local KDE base dir

localconfigdir()      $HOME/.kde/share/config         Get the local KDE config dir
</screen>
</para>

<para>To search for a specific file, use <literal remap="tt">findFile(const char *file)</literal> which will search several path's of the KDE File System:</para>

<para><orderedlist><listitem>
<para>$KDEDIR,</para>
</listitem>
<listitem>
<para>$KDEPATH,</para>
</listitem>
<listitem>
<para>"&&lsqb;;KDE Setup&&rsqb;;:Path=" entry in a config file.</para>
</listitem>
</orderedlist>
</para>

<para>If the file is not found, the QString method isEmpty() will  return True</para>
</sect1>

<sect1 id="kiconloader-methods">
<title>KIconLoader Methods</title>

<para>QPixmap loadIcon ( const QString &&amp;;name, int w = 0, int h = 0 )</para>

<para>QPixmap reloadIcon ( const QString &&amp;;name, int w = 0, int h = 0)</para>

<para>QPixmap loadMiniIcon ( const QString &&amp;;name , int w = 0, int h = 0 )</para>

<para>QPixmap loadApplicationIcon ( const QString &&amp;;name, int w = 0, int h = 0 )</para>

<para>QPixmap loadApplicationMiniIcon ( const QString &&amp;;name, int w = 0, int h = 0 )</para>

<para>bool insertDirectory ( int index, const QString &&amp;;dir&&lowbar;;name )</para>
</sect1>

<sect1 id="setting-file-installation-properties">
<title>Setting File Installation Properties</title>

<para>As the above explained where KDE applications <indexterm remap="idx"><primary>KDE applications</primary></indexterm> should place their files and how to access them at runtime, the following will explain
how to set the file properties correctly to ensure the files get installed at the right place. The Makefiles support a set of macros to
install your files into the KDE File System and which have to be used for setting the file installation properties.</para>

<para>To set the properties, open your project and select "Project"-"File Properties" which opens the File Properties dialog.
The file properties are displayed if you select a filename currently included in the project. First of all, a file has a type property,
which can be one of the following:</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">HEADER:</emphasis>  specifies a file as a header file</para>
</listitem>
<listitem>
<para><emphasis remap="bf">SOURCE:</emphasis> specifies a file as a source file</para>
</listitem>
<listitem>
<para><emphasis remap="bf">SCRIPT:</emphasis> specifies a file as a script file</para>
</listitem>
<listitem>
<para><emphasis remap="bf">DATA:</emphasis> specifies a file as a data file that usually gets installed like pixmaps or HTML documentation files</para>
</listitem>
<listitem>
<para><emphasis remap="bf">PO:</emphasis> specifies a file as a translation file</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KDEV&&lowbar;;DIALOG:</emphasis> specifies a file as a dialog file to be interpreted by the dialog library</para>
</listitem>
</itemizedlist>
</para>

<para>Further, a file is included in the project, if "Include in Distribution" is checked. This ensures that the file is included in the
distribution tarball or package.</para>

<para>If a file has to be installed, you have to enable "Install". This will allow setting the Installation path for the selected file, where
the filename is already inserted.</para>

<para>Now, as said above, the Makefile already is capable of a set of macros for the KDE File System Standard. These are used to set the
installation path and ensure that the files actually will land in the KDE file system and not somewhere else. Macros that can be used,
have to be embraced in round brackets and are marked with the dollar sign in front of the macro. When configure builds the Makefiles on
the end-user's system, it will determine values for these macros that match the real directory name and will expand the Makefile.am
macro towards the actual destination.</para>

<para>When looking a standard KDE application project, you will see on the file property of your <literal remap="tt">index.html</literal> file that it already uses a
macro to determine where it should go:</para>

<para>$(kde&&lowbar;;htmldir)/en/kscribble/index.html</para>

<para>This says, that make should install the file index.html in the kde-html directory, subdirectory en for English, the application
subdirectory and the filename. You could as well use another filename if you like to rename the file on the installation destination.</para>

<para>For the destination of your binary you currently have to edit the project's Makefile.am if your destination should be different form
the "Applications" section of kpanel:</para>

<para>APPSDIR = $(kde&&lowbar;;appsdir)/Applications</para>

<para>Possible values are (as the KDE-File System Standard says):</para>

<para><itemizedlist>
<listitem>
<para>Applications</para>
</listitem>
<listitem>
<para>Games</para>
</listitem>
<listitem>
<para>Graphics</para>
</listitem>
<listitem>
<para>Internet</para>
</listitem>
<listitem>
<para>Multimedia</para>
</listitem>
<listitem>
<para>Settings</para>
</listitem>
<listitem>
<para>System</para>
</listitem>
<listitem>
<para>Utilities</para>
</listitem>
</itemizedlist>
</para>

<para>Setting no directory will end your applnk directly in kpanel's root.</para>

<para>The following list contains the macros that can be used in the installation setup for files:</para>

<para><screen>kde_htmldir       Where your docs should go to. (contains lang subdirs)
kde_appsdir       Where your application file (.kdelnk) should go to.
kde_icondir       Where your icon should go to.
kde_minidir       Where your mini icon should go to.
kde_datadir       Where you install application data. (Use a subdir)
kde_locale        Where translation files should go to.(contains lang subdirs)
kde_cgidir        Where cgi-bin executables should go to.
kde_confdir       Where config files should go to.
kde_mimedir       Where mimetypes should go to.
kde_toolbardir    Where general toolbar icons should go to.
kde_wallpaperdir  Where general wallpapers should go to.
</screen>
</para>

<para>Use these macros in conjunction with the according necessary subdirectories and the filename for setting the installation properties.
By default, the currently created HTML documentation files, the kdelnk file, Icon, Miniicon and the translation files (also newly
create ones) are already set up for their destination; therefore you don't have to make any changes for your default installation
routine that has been set up by the application wizard of KDevelop.</para>
</sect1>

<sect1 id="organizing-project-data">
<title>Organizing Project Data</title>

<para>Another issue in creating projects often appears to the programmer if he has or wants to include additional data that have to be
installed with the project. You already know where to install it, but what about organizing it in the source tree ?</para>

<para>A good advice here may be to collect all data in directories that more or less match the KDE File System Standard, e.g. your
application needs additional toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> icons. Creating these icons in the main project directory is potentially not a good idea as they
will be difficult to locate in the real file viewer and a removal will result in much work for each icon. Therefore, create your icon
with "File"- "New" and choose a subdirectory <literal remap="tt">toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm></literal>; if it doesn't exist, it can be easily created with the "select directory"
dialog. Existing icons can be copied and included into the project with "Project"-"Add existing file(s)", where you have to choose the
files and the destination. When selecting the destination directory, you can create the <literal remap="tt">toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm></literal> subdirectory first within the
selection dialog. After being finished, press OK and the files will be copied as well as included in the project.</para>

<para>As an example, a toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> icon should go to the following:</para>

<para>$(kde&&lowbar;;datadir)/<emphasis>&&lt;;appname&&gt;;</emphasis>/toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>/<emphasis>&&lt;;youricon&&gt;;</emphasis>.xpm</para>

<para>Pictures or additional icons that are not used as toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> icons should go to a subdirectory <emphasis>pics</emphasis> instead of <emphasis>toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm></emphasis>.</para>
</sect1>

<sect1 id="the-kdelnk-file">
<title>The <literal remap="tt">kdelnk</literal> File</title>

<para>The <emphasis>&&lt;;appname&&gt;;</emphasis>.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm> file currently included in your project will install itself in KDE's kpanel structure. You should think
it is already created and complete, therefore shouldn't require any further notification. Despite of KDevelop's advanced qualities to
help you with creating, programming and designing applications, it cannot determine the exact purpose of your application- and that is
the information you have to add to the kdelnk file. As this is a text file, select it from the RFV or the LFV; it will be opened in the
Header/Resource window.</para>

<para>The sample kdelnk file would look like this:
<screen># KDE Config File
&&lsqb;;KDE Desktop Entry&&rsqb;;
Type=Application
Exec=kscribble
Icon=kscribble.xpm
DocPath=kscribble/index.html
Comment=
Comment&&lsqb;;de&&rsqb;;=
Terminal=0
Name=kscribble
Name&&lsqb;;de&&rsqb;;=kscribble
</screen>
</para>

<para>This already contains the basic configuration for the application specific data such as the icon, binary name, application name etc.
You see that the section Comment is still empty. There you have to insert the Quick-Tip that will be displayed when the mouse cursor
moves over the kdelnk file icon on the desktop or in kpanel. If scribble would be a small drawing program, you would enter e.g.</para>

<para><screen>Comment=A simple drawing program
</screen>
</para>

<para>Each comment line afterwards will contain the same description translated in the language the brackets symbolize. Ask translators to
insert a good translation in their native language or include the kdelnk file when asking for translating the application's po file;
the same applies to the name of the application set in the Name lines.
<footnote>
<para>for more information about the purpose of the .kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm> file, especially its use for commandline processing, see
<ulink url="kde_libref.html">The KDE Library Reference Guide</ulink></para>
</footnote>
</para>
</sect1>
</chapter>

<chapter id="programming-guidelines">
<title>Programming Guidelines</title>

<para>Close to the end of this handbook, I want to summarize several issues that programmers should watch out while coding. These are mostly
C++ programming tips that relate to KDE and Qt programming especially and are partly taken from the KDE 
Developer's Center which can be found on the Internet at <ulink url="http://www.kde.org">\|\|</ulink>, some have been added 
by my own experience.</para>

<sect1 id="general-rules">
<title>General Rules</title>

<para><variablelist>
<varlistentry>
<term>Filenames</term>
<listitem>
<para>First of all, when creating sourcefiles, you should always use lowercase filenames. KDevelop supports
this guideline already if you stick to its filename aut-suggestion. This makes it easier for other developers to remember what source
files to look for when they have to debug your application.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Classnames</term>
<listitem>
<para>The classnaming for KDE projects is recommended to be:
<itemizedlist>
<listitem>
<para>class names should begin with a prefixed <emphasis remap="bf">K</emphasis> followed by the name of the class by purpose (your choice). This would be e.g.
<literal remap="tt">KMyWidget</literal> for an application specific widget.</para>
</listitem>
<listitem>
<para>the class members should always begin with lowercase letters, followed by uppercase beginnings for the next word, e.g.
<literal remap="tt">myWidgetPointer()</literal></para>
</listitem>
<listitem>
<para>methods that return a private members value shouldn't use the <literal remap="tt">get</literal>-prefix. You should prefer using a descriptive name for
those types of classmembers. Example: <literal remap="tt">b&&lowbar;;myboolean</literal> is a private member. The method returning the current value would be e.g.
<literal remap="tt">myBoolean()</literal>.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>File access within code</term>
<listitem>
<para>Hardcoding any path should be avoided by using the KDE File System Standard. You only have to watch the installation path for your
files by the according macros of the <literal remap="tt">Makefile.am</literal> as described in this handbook. Within the code, you should use the methods of
<literal remap="tt">KApplication</literal> to retrieve the actual path.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Class documentation</term>
<listitem>
<para>Another thing already mentionend is class documentation. You should stick to use <literal remap="tt">KDoc</literal> formatting rules as they are used by all KDE
developers to document their classes. You should at least add a single line to all of your classmembers for yourself to remember the
prurpose and for others to reuse code. The code-reuse by the GPL makes much more sense if you know where to find an already existing
solution if classes are documented. The Qt library referece is a good example of well-documented interfaces, though it doesn't use
<literal remap="tt">KDoc</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Use <literal remap="tt">new</literal> to create widgets</term>
<listitem>
<para>Within your implementation, you should always prefer to create widgets on the heap with <literal remap="tt">new</literal>. The Qt library has a nice habbit to
automatically delete all child widgets you created with <literal remap="tt">new</literal>, so you don't ever have to use <literal remap="tt">delete</literal> again in those cases. This
is one of the most important practical features of the Qt library and you should make wide use of this.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Debugging</term>
<listitem>
<para>When it comes to debugging, you should make use of the macros <literal remap="tt">KDebug</literal> provides. Those are similar to the Qt macros, but can be
retrieved by the keycode STRG+ALT+F12. See the <ulink url="../kde_libref/index-4.html#ss4.4">KDE Library Reference Guide</ulink> for
more information about the event filtering of these Macros. You could as well use <literal remap="tt">assert()</literal>, but should try to be consistent with
your debugging code.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal remap="tt">const</literal>-declarations</term>
<listitem>
<para>Further, you should use <literal remap="tt">const</literal> declarations for member functions that should or do not change any private member. This would be the
case for all methods that only return the current value of a private member. This avoids changing the value accidently and will catch
those logical errors at compile time. Now, towards initializing const members you should stick to do that together with using
<literal remap="tt">static</literal> in the declaration and initialize the value outside the constructor like this:
<screen>class foo {
	static const int value;
};

const foo::value = 10;
</screen>

ANSI C++ allows to initialize the member inside the constructor but you should avoid this as a few compilers are not capable of this
feature.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Virtual methods</term>
<listitem>
<para>As explained in section <link linkend="User-Interaction">User Interaction</link>, you should stick to the access rights and the declaration
by <literal remap="tt">virtual</literal> when overwriting virtual methods. At least you shouldn't reduce the access of a virtual method from protected to
private.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Forward declarations</term>
<listitem>
<para>Class-headers should be included where you dereference any object or instance of a class in your sourcecode. That means if your class
uses a member of another class, replace the &&num;;include directive with a forward declaration of the class, e.g  instead of:</para>
<para><screen>#include &lt;qpushbutton.h&gt;

class KMyWidget:public QWidget
{

private:
  QPushButton* ok_button;
};
</screen>
</para>
<para>you should prefer to only declaring the class <literal remap="tt">QPushButton</literal> in the header file:</para>
<para><screen>class QPushButton;

class KMyWidget:public QWidget
{

private:
  QPushButton* ok_button;
};
</screen>
</para>
<para>and place the include directive into the according sourcefile where e.g. the instance <literal remap="tt">ok&&lowbar;;button</literal> is dereferenced with any method of
the class <literal remap="tt">QPushButton</literal>. This saves compile time at any rate, especially if you're using instances of classes that your're working
on. The compiler will recompile all souces that include the header file if you made any changes on the interface of the class,
therefore a simple addition of a method that only returns an internal value will lead to a recompilation of all sources tha include
the header file of the class.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Unused Parmeter Warnings and default arguments</term>
<listitem>
<para>Also you should leave out formal parameters of methods that don't necessarily require the actual parameter to work. This avoids the
<literal remap="tt">unused parameter</literal> warnings of your compiler when he sees a method that retrieves a formal parameter but doesn't use it in its
implementation. Usually, you will set some default arguments for several methods. Those should always be placed in the declaration of
the class member instead of setting them in the member implementation.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Using <literal remap="tt">config.h</literal></term>
<listitem>
<para>KDevelop projects as well as any other project that is using <literal remap="tt">autoconf</literal> to create a <literal remap="tt">configure</literal>-script produce a file
<literal remap="tt">config.h</literal> after executing the <literal remap="tt">configure</literal>-script on the target machine. The values found by <literal remap="tt">configure</literal> are listed there and
can be used within the sourcecode. The directive to include the <literal remap="tt">config.h</literal> file is:</para>
<para><screen>#ifdef HAVE_CONFIG_H
#include &lt;config.h&gt;
#endif
</screen>
</para>
<para>One of the most recently used entries of <literal remap="tt">config.h</literal> is probably the type-definition of <literal remap="tt">bool</literal> for compilers that don't comply
with the newest ANSI C++ draft.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Use <literal remap="tt">0</literal> instead of <literal remap="tt">NULL</literal></term>
<listitem>
<para>You should stickt to using <literal remap="tt">0</literal> directly instead of <literal remap="tt">NULL</literal> for preset values like the Qt and KDE libraries already do. This
increases portablility of your applications towards different compilers that have problems with <literal remap="tt">NULL</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Temporaries</term>
<listitem>
<para>You should declare temporary instances always before using them. This is generally considered better than direct use. Example:
<screen>// Don't:
for( int i=0; i&lt;n; i++){
  //do something
  };

// Do:
int i;

for(i=0; i&lt;n; i++){
  //do something
  };
</screen>
</para>
<para>This also counts on using temporaries in function calls:
<screen>// Don't:
setColor( &&amp;;(QColor(black)) );

// Do:
QColor color(black);
setColor( &&amp;;color );
</screen>
</para>
</listitem>
</varlistentry>
</variablelist>
 </para>
</sect1>

<sect1 id="operating-system-dependencies">
<title>Operating System Dependencies</title>

<para>As KDevelop projects use the GNU tools to create projects, it is ensured that your application will run on 
almost every Unix system. However, you may encounter problems when actually compiling your application under 
another Unix, because header files are located somewhere different or you need another implementation 
especially when it comes to using OS-specific low-level functions which can differ from system to system.</para>

<para>When programming with C++ and Qt/KDE you should also notice that the Qt collection classes have a rich set of 
functionality that is already compiler/OS independend and makes things much easier, starting with strings 
(QString) to file reading/writing (QFile); so using Qt will make using OS defines almost obsolete in most 
cases.</para>

<para>Anyway, when using Qt and you still have to use &&num;;defines for your application, you should include 
<literal remap="tt">qglobal.h</literal> and make use of the already predefined defines for various Operating Systems and compilers 
which preselects the below defines already.</para>

<para>Instead of letting the packagers of OS-Vendors applying any patches to your application (like most do where 
necessary e.g. for building rpm´s or packages/ports), you should use defines for those sections that are 
operating-system specific (but you don´t have to use -D for compiling, the Operating System defines are 
handled automatically). The following lists the available systems and their defines (additional defines in 
brackets): </para>

<para><variablelist>
<varlistentry>
<term>AIX:</term>
<listitem>
<para>&&num;;ifdef &&lowbar;;AIX</para>
</listitem>
</varlistentry>
<varlistentry>
<term>BSDI Unix:</term>
<listitem>
<para>&&num;;if defined(bsdi) &&verbar;;&&verbar;; defined(&&lowbar;;&&lowbar;;bsdi&&lowbar;;&&lowbar;;)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Dec Ultrix:</term>
<listitem>
<para>&&num;;if defined (ultrix) &&verbar;;&&verbar;; defined(&&lowbar;;&&lowbar;;ultrix) &&verbar;;&&verbar;; defined(&&lowbar;;&&lowbar;;ultrix&&lowbar;;&&lowbar;;)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>DG Unix:</term>
<listitem>
<para>&&num;;if defined(DGUX)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>FreeBSD:</term>
<listitem>
<para>&&num;;ifdef &&lowbar;;&&lowbar;;FreeBSD&&lowbar;;&&lowbar;;</para>
</listitem>
</varlistentry>
<varlistentry>
<term>GNU Hurd:</term>
<listitem>
<para>&&num;;if defined(&&lowbar;;&&lowbar;;GNU&&lowbar;;&&lowbar;;)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>HP-UX:</term>
<listitem>
<para>&&num;;if defined (hpux) &&verbar;;&&verbar;; defined (&&lowbar;;&&lowbar;;hpux) &&verbar;;&&verbar;; defined (&&lowbar;;&&lowbar;;hpux&&lowbar;;&&lowbar;;)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Linux:</term>
<listitem>
<para>&&num;;if defined(linux) &&verbar;;&&verbar;; defined(&&lowbar;;&&lowbar;;linux) &&verbar;;&&verbar;; defined(&&lowbar;;&&lowbar;;linux&&lowbar;;&&lowbar;;)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>NetBSD:</term>
<listitem>
<para>&&num;;ifdef &&lowbar;;&&lowbar;;NetBSD&&lowbar;;&&lowbar;;</para>
</listitem>
</varlistentry>
<varlistentry>
<term>OpenBSD:</term>
<listitem>
<para>&&num;;ifdef &&lowbar;;&&lowbar;;OpenBSD&&lowbar;;&&lowbar;;</para>
</listitem>
</varlistentry>
<varlistentry>
<term>OSF Unix:</term>
<listitem>
<para>&&num;;if defined(&&lowbar;;&&lowbar;;osf&&lowbar;;&&lowbar;;)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>QNX:</term>
<listitem>
<para>&&num;;if defined(&&lowbar;;&&lowbar;;QNX&&lowbar;;&&lowbar;;)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>SCO UnixWare:</term>
<listitem>
<para>&&num;;if defined(&&lowbar;;UNIXWARE)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>SCO UnixWare 7:</term>
<listitem>
<para>&&num;;if defined(sco) &&verbar;;&&verbar;; defined(&&lowbar;;UNIXWARE7)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>SCO:</term>
<listitem>
<para>&&num;;if defined(&&lowbar;;SCO&&lowbar;;DS) &&verbar;;&&verbar;; defined(M&&lowbar;;UNIX) &&verbar;;&&verbar;; defined(M&&lowbar;;XENIX)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>SGI Irix:</term>
<listitem>
<para>&&num;;if defined(sgi) &&verbar;;&&verbar;; defined(&&lowbar;;&&lowbar;;sgi)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>SunOS:</term>
<listitem>
<para>&&num;;if defined (sun) &&verbar;;&&verbar;; defined (&&lowbar;;&&lowbar;;sun) &&verbar;;&&verbar;; defined (&&lowbar;;&&lowbar;;sun&&lowbar;;&&lowbar;;)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Sun Solaris:</term>
<listitem>
<para>&&num;;if defined  (&&lowbar;;OS&&lowbar;;SUN&&lowbar;;) &&verbar;;&&verbar;; defined (&&lowbar;;&&lowbar;;SVR4)</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</sect1>
</chapter>

<chapter id="licensing">
<title>Licensing</title>

<para>This section deals with questions that come up in regards to licensing applications that are created with the KDevelop IDE. First, we
will have a look at the default behavior, discuss adavantages of licensing your applications under the GPL and finally will cover
issues that come up when developing commercial applications.</para>

<sect1 id="the-gpl-license">
<title>The GPL License</title>

<para>The KDevelop IDE itself is licensed under the GNU General Public License. This license ensures that any user can copy, modify and
redistribute the KDevelop sourcecode package under the terms of this license. The license itself guarantees this as well as the rights
of the KDevelop Team members as the authors of this product.</para>

<para>Out of this reason and the dedication to help free software authors developing their products, all KDevelop generated frameworks
contain a GPL licensing reference as well as a copy of the license as well. Developers on the other hand <emphasis>can</emphasis> use this license as a
base for distributing their product but are in no way bound to do so.</para>

<para>The author, when using the GPL as the license for his product, also takes advantage out of this:</para>

<para><itemizedlist>
<listitem>
<para>you can use any existing code also licensed under the GPL and include it into your package (as long as there are no restrictions
that interfere to any code-reuse due to the limitations of the used software's licensing),</para>
</listitem>
<listitem>
<para>your code has a copyright license that protects your rights as the original author,</para>
</listitem>
<listitem>
<para>the re-use of your code by other authors improve the general development of free applications.</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="kde-and-qt-licensing-issues">
<title>KDE and Qt Licensing Issues</title>

<para>Especially the Qt licensing caused a lot of trouble for the KDE development community until Qt 2.0 which comes with the new QPL
license. The Troll Tech company, as the owner and creator of Qt, delivers the Unix version of the library free of charge, but with the
restriction that you cannot change the delivered code and redistribute it without an explicit agreement on their side. This was the
reason why many free software developers tended to condemn this licensing, as it wasn't absolutely free, especially to do any changes.
On the other hand, the Qt library offers a lot of advantages that make it also very attractive for developing commercial applications:</para>

<para><itemizedlist>
<listitem>
<para>By buying a commercial license, you can write portable applications for Unix and Windows platforms</para>
</listitem>
<listitem>
<para>The provided classes and application framework are providing a good solution for easy application design</para>
</listitem>
<listitem>
<para>You can develop for Unices without being dependend on the GPL licensing when holding a commercial license</para>
</listitem>
</itemizedlist>
</para>

<para>The KDE project on the other hand chose the Qt library as a base for developing a desktop environment for Unix systems as well as an
extended application framework enhancing the facilities of the capabilities Qt provides. Developers can make use of KDE's advantages by
using the provided libraries, distributed as the KDE libraries.</para>

<para>The KDE libraries themselves are distributed under the LGPL, the GNU Library General Public License. What does this mean to application
developers ?</para>

<sect2 id="non-commercial-development">
<title>Non-commercial Development</title>

<para>For non-commercial development, the Qt library is provided free of charge. Your application can make use of the library as far as it
does not change the library and the developer delivers his application sourcecode free of charge as well.</para>

<para>The LGPL of the KDE libraries ensures using the KDE libraries as well for non-commercial development. You can make use of the KDE
libraries as you like to or your application may require.</para>
</sect2>

<sect2 id="commercial-development">
<title>Commercial Development</title>

<para>For commercial developement, the Troll Tech company offers buying a commercial license. This allows using the Qt library for
development purposes as your application or project may require. You can ship your application in any form, as binaries only or by
sourcecode, independed of any GPL licensing.</para>

<para>When using the KDE libraries, you have to watch the LGPL license, which explicitely allows commercial development using the library
distributed under the LGPL. You just have to watch the rules of the license to know the restrictions that may arise when using the KDE
libraries as a base for commercial application development based on KDE.</para>
</sect2>
</sect1>

<sect1 id="your-product-license">
<title>Your Product License</title>

<para>Hereby, the KDevelop Team, as the authors of the KDevelop Integrated Development Environment, allows you to distribute any application
that has been created by and with using the KDevelop IDE under a license of your choice; only depending on licensing terms that arise
from the restrictions that are given by the use of code that is placed in libraries the final product uses. These are:</para>

<para><itemizedlist>
<listitem>
<para>For Qt applications: The restrictions of the Qt license that apply to the status of your distribution, whether it may be for
non-commercial (free) software or commercial purpose.</para>
</listitem>
<listitem>
<para>For KDE applications: The restrictions of the Qt license according to the status of your distribution <emphasis>plus</emphasis> the restrictions
of the LGPL (GNU Library General Public License) as shipped with your copy of the used KDE libraries.</para>
</listitem>
<listitem>
<para>for all other pre-generated sourcecode you are free to choose the license</para>
</listitem>
</itemizedlist>
</para>

<para>Therefore you can change the default licensing as it is included with any KDevelop generated application framework or base application
towards your choice, only by watching the restrictions that arise from any library that is linked to your application.</para>

<para>If you have any additional questions about licensing, feel free to ask the KDevelop Team.</para>
</sect1>
</chapter>

<chapter id="references">
<title>References</title>

<para>The KDevelop Programming Handbook contains information that are taken from various sources on the Internet and by mails to various
mailing lists, as:</para>

<para><emphasis remap="bf">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm> documentation:</emphasis> Sirtaj S. Kang <ulink url="mailto:taj@.kde.org">taj@.kde.org</ulink></para>

<para><emphasis remap="bf">KDE Developer's Center</emphasis> maintained by Sirtaj S. Kang <ulink url="mailto:taj@.kde.org">taj@.kde.org</ulink></para>

<para><emphasis remap="bf">KDE Internationalization:</emphasis> Matthias Elter <ulink url="mailto:me@kde.org">me@kde.org</ulink></para>

<para><emphasis remap="bf">KDebug documentation:</emphasis> Kalle Dalheimer <ulink url="mailto:kalle@kde.org">kalle@kde.org</ulink></para>

<para><emphasis remap="bf">The KDE File System Standard:</emphasis> Richard Moore <ulink url="mailto:rich@kde.org">rich@kde.org</ulink></para>

<para><emphasis remap="bf">KDE-Developer's mini-HOWTO:</emphasis> David Sweet <ulink url="mailto:dsweet@chaos.umd.edu">&lt;dsweet@chaos.umd.edu&gt;</ulink></para>

<para>The contents of the according chapters are copyright of the original authors.</para>
</chapter>

<chapter id="copyright">
<title>Copyright</title>

<para><screen>
KDevelop Copyright 1998, 1999, 2000 The KDevelop Team.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</screen>
</para>
</chapter>
<appendix id="additional-information-0">
<title>Additional Information</title>

<sect1 id="example-makefile.am-for-a-shared-library">
<title>Example Makefile.am for a Shared Library</title>

<para><screen># Example Makefile.am for a shared library.  It makes a library
#  called "example" as libexample.so.2.1.2
# This Makefile.am was taken from the kdelibs distribution and modified
#  to serve as an example.
#
# David Sweet
#

INCLUDES=  $(all_includes)

lib_LTLIBRARIES  = libexample.la

# Note:  If you specify a:b:c as the version in the next line,
#  the library that is made has version (a-c).c.b.  In this
#  example, the version is 2.1.2.
libexample_la_LDFLAGS = -version-info 3:2:1 $(all_libraries)

include_HEADERS = header1.h header2.h\
                  header3.h

# Which headers shouldn't be installed when a   make install  is done?
noinst_HEADERS = version.h

libexample_la_SOURCES = code1.cpp code2.cpp
                        code3.cpp

#  USE_AUTOMOC is great.  This takes care of all of your  moc'ing
#   dependencies.
#  (You still need to include, for example, header1.moc in code1.cpp.)
libexample_la_METASOURCES = USE_AUTOMOC
</screen>
</para>
</sect1>
  </appendix>
<![ %addindex; [ &docindex; ]]>

<chapter id="credits"> 
                     <title>Mitwirkende</title> 
                     <para> 
                     Deutsche &Uuml;bersetzung: 
                     <itemizedlist> 
                     <listitem> 
                     <para>Patricia Jung
                     <email>trish@trish.de</email></para> 
                     </listitem> 
                     </itemizedlist> 
                     </para> 
                     </chapter> 
</book>
<!--
Local Variables:
mode: sgml
sgml-omittag: nil
sgml-shorttag: t
sgml-general-insert-case: lower
End:
-->
