<?xml version="1.0" ?>
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
<!ENTITY tdevelop "<application>KDevelop</application>">
<!ENTITY kappname "&tdevelop;">
<!ENTITY % addindex "INCLUDE">
<!ENTITY % English "INCLUDE" > <!-- change language only here -->
]>
<book lang="&language;">
<bookinfo>
<title>The &tdevelop; Programming Handbook</title>
<date>2002-12-05</date>
<releaseinfo>2.0</releaseinfo>
<authorgroup>
<author>
<firstname>Ralf</firstname>
<surname>Nolden</surname>
<affiliation><address><email>Ralf.Nolden@post.rwth-aachen.de</email></address></affiliation>
</author>
<author>
<firstname>Caleb</firstname>
<surname>Tennis</surname>
<affiliation><address><email>caleb@aei-tech.com</email></address></affiliation>
</author>
</authorgroup>
<copyright>
<year>1999</year>
<holder>Ralf Nolden</holder>
</copyright>
<copyright>
<year>2002</year>
<holder>Caleb Tennis</holder>
</copyright>
<!-- ROLES_OF_TRANSLATORS -->
<legalnotice>&FDLNotice;</legalnotice>
<abstract>
<para>The User Guide to C++ Application Design for the Trinity Desktop Environment (TDE) with
the &tdevelop; IDE</para>
</abstract>
<keywordset>
<keyword>KDE</keyword>
<keyword>KDevelop</keyword>
<keyword>IDE</keyword>
<keyword>development</keyword>
<keyword>programming</keyword>
</keywordset>
</bookinfo>
<chapter id="chapter1">
<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="c1s1">
<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 toolkit as well as the KDE libraries and the design of User Interfaces. Also, you should have made
yourself comfortable with &tdevelop; by reading The User Manual to &tdevelop;, which contains a descriptive
review of the functionality provided by the IDE.
</para>
</sect1>
<sect1 id="c1s2">
<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 sourcecode
already generated and shows how to extend the given sources on various topics such as toolbars, 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 documentation and extending
online-manuals.
</para>
<sect2 id="c1s2s1">
<title>In the next chapter</title>
<para>
We'll take a look at the Qt and KDE libraries, 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 toolkit by using
tdevelop;, so beginners can already see first results with a few steps, and thereby will learn how to make
use of some of &tdevelop;'s best features.
</para>
</sect2>
<sect2 id="c1s2s2">
<title>In the following chapters</title>
<para>
You will learn how to:
<itemizedlist>
<listitem><para>create an application with the KAppWizard</para></listitem>
<listitem><para>What the project skeleton already provides</para></listitem>
<listitem><para>What the code already create 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 toolbars</para></listitem>
<listitem><para>How to make your application user friendly by providing help functions</para></listitem>
<listitem><para>How to write online documentation</para></listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
<sect1 id="c1s3">
<title>Additional Information</title>
<para>
Additional information about Qt/KDE programming is available by various sources:
<itemizedlist>
<listitem><para>Programming with Qt by Matthias Kalle Dalheimer</para></listitem>
<listitem><para><ulink url="www.kdevelop.org">The User Manual to KDevelop, provided with the TDevelop IDE</ulink></para></listitem>
<listitem><para><ulink url="doc.trolltech.com">The Online Reference to the Qt library</ulink></para></listitem>
<listitem><para><ulink url="developer.kde.org">The KDE Developer web site</ulink></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 TDevelop IDE, you should send requests to our mailinglist at
<email>tdevelop@tdevelop.org</email>. 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="chapter2">
<title>The KDE and Qt Libraries</title>
<para>
The Norwegian company TrollTech (<ulink url="http://www.trolltech.com">http://www.trolltech.com</ulink>)
provides a so-called GUI toolkit, named Qt. GUI means "Graphical User Interface", and therefore, Qt-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 offers some technical advantages that make
application design very easy. Additionally, the Qt 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">http://www.kde.org</ulink>) joined together with the goal
to make using Unix Systems more friendly, and decided to use the Qt toolkit for the development of a window
manager on X-Windows, plus a variety of tools included with the KDE packages. The K Desktop Environment
therefore contains the window manager kwm, the file manager kfm and the launch panel kpanel 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 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, offer session management and many more, if all
features offered by the KDE libraries are used. Both, the Qt toolkit and the KDE libraries, 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 and TDE applications are created in general.
</para>
<para>
Both, the Qt toolkit and the KDE libraries, 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 and KDE
applications are created in general.
</para>
<sect1 id="c2s1">
<title>The Qt GUI Toolkit</title>
<para>
As said, the Qt 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:
<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 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-only program; then we'll extend it to a KDE program.
</para>
<sect2 id="c2s1s1">
<title>The first Qt Application</title>
<para>
As usual, programs in C++ have to contain a <function>main()</function> 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 Online Reference Documentation and explain the basic execution
steps; also why and how the application window appears:
<programlisting>
#include <qapplication.h>
#include <qpushbutton.h>
int main( int argc, char **argv )
{
QApplication a( argc, argv );
QPushButton hello( "Hello world!", 0 );
hello.resize( 100, 30 );
a.setMainWidget( &hello );
hello.show();
return a.exec();
}
</programlisting>
</para>
<para>
This application merely paints a window containing a button with "Hello world" as its text. As for
all Qt-based applications, you first have to create an instance of the class <classname>QApplication</classname>, represented by
variable a.
</para>
<para>
Next, the program creates an instance of the class <classname>QPushButton</classname> called hello, this will be the button.
The constructor of hello gets a string as a parameter, which is the contents of the widget visible as
the buttons text.
</para>
<para>
Then the <methodname>resize()</methodname> method is called on the hello button. This changes the default size a widget
(which is in this case the <classname>QPushButton</classname>) has when created to the length of 100 pixels and the height of
30 pixels. Finally, the setMainWidget() method is called for a and the show() method for hello. The
QApplication is finally executed by <methodname>a.exec()</methodname>, 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="c2s1s2">
<title>The Reference Documentation for Qt</title>
<para>
Now, let's have a quick look at the reference documentation of the Qt library. To do this, start
&tdevelop; and select "Qt" from the tree in the Documentation tab. The documentation browser opens
and shows you the start page of the Qt reference. This will be your first place to get information
about Qt, 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,
<classname>QApplication</classname> and <classname>QPushButton</classname>, select "Alphabetical Class List"
and search for the according names. Follow either of them to have a look at the class documentation.
</para>
<para>
Alternatively, you can use the online documentation from Trolltech's <ulink url="doc.trolltech.com">Qt Documentation</ulink>
</para>
<para>
For <classname>QApplication</classname>, 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>
<sect3 id="c2s1s2s1">
<title>Interpretation of the Sample</title>
<para>
Starting with <classname>QApplication</classname>, you will find all the methods used in our first example:
<itemizedlist>
<listitem><para>the constructor <methodname>QApplication()</methodname></para></listitem>
<listitem><para>the <methodname>setMainWidget()</methodname> method</para></listitem>
<listitem><para>the <methodname>exec()</methodname> method</para></listitem>
</itemizedlist>
</para>
<para>
The interpretation why we use these methods is very simple:
<orderedlist>
<listitem><para>Create an instance of the class <classname>QApplication</classname> with the constructor,
so we can make use of the GUI elements provided by Qt</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 a</para></listitem>
<listitem><para>Execute the a instance of <classname>QApplication</classname></para></listitem>
</orderedlist>
</para>
<para>
The second object of our program is the pushbutton, an instance of the class <classname>QPushButton</classname>.
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
<methodname>resize()</methodname> 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 <methodname>show()</methodname> method? Now, you see that like most other widgets,
<classname>QPushButton</classname> is based on a single inheritance, the documentation says, Inherits
<classname>QButton</classname>. Follow the link to the <classname>QButton</classname> class.
This shows you a lot of other widgets that are inherited by <classname>QPushButton</classname>,
which we'll use later to explain the signal/slot mechanism. Anyway, the <methodname>show()</methodname>
method is not listed, therefore, it must be a method that is provided by inheritance as well. The class
that <classname>QButton</classname> inherits is <classname>QWidget</classname>. Just follow the link
again, and you will see a whole bunch of methods that the QWidget class provides; including
the <methodname>show()</methodname> method. Now we understand what was done in the sample with the button:
<orderedlist>
<listitem><para>Create an instance of <classname>QPushButton</classname>, use the second constructor to set the button text</para></listitem>
<listitem><para>Resize the widget to its contents</para></listitem>
<listitem><para>Set the widget as the main widget of the <classname>QApplication</classname> instance a</para></listitem>
<listitem><para>Tell the widget to display itself on the screen by calling <methodname>show()</methodname>, an inherited method from <classname>QWidget</classname></para></listitem>
</orderedlist>
</para>
<para>
After calling the <methodname>exec()</methodname> method, the application is visible to the user,
showing a window with the button showing "Hello world!". Note: 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 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 offers to process
user events.
</para>
<note><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 QWidget class documentation and The KDE Library Reference Guide</para>
</note>
</sect3>
</sect2>
<sect2 id="c2s1s3">
<title>User Interaction</title>
<para>
After reading the last sections, you should already know:
<itemizedlist>
<listitem><para>What the Qt-library provides in terms of GUI applications</para></listitem>
<listitem><para>How a program using Qt 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
<classname>QApplication</classname> then sends them to the active window as a <classname>QEvent</classname>
and the widgets themselves have to decide what to do with them. A widget receives the event and processes
<methodname>QWidget::event(QEvent*)</methodname>, which then decides which event has been executed
and how to react; <methodname>event()</methodname> is therefore the main event handler. Then,
the <methodname>event()</methodname> method 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:
<itemizedlist>
<listitem><para>
Keyboard events -- TAB and Shift-TAB keys:</para>
<itemizedlist>
<listitem><para><methodname>virtual void focusInEvent(QFocusEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void focusOutEvent(QFocusEvent *)</methodname></para></listitem>
</itemizedlist>
</listitem>
<listitem><para>
All other keyboard input:</para>
<itemizedlist>
<listitem><para><methodname>virtual void keyPressEvent(QKeyEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void keyReleaseEvent(QKeyEvent *)</methodname></para></listitem>
</itemizedlist>
</listitem>
<listitem><para>
Mouse movements:</para>
<itemizedlist>
<listitem><para><methodname>virtual void mouseMoveEvent(QMouseEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void enterEvent(QEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void leaveEvent(QEvent *)</methodname></para></listitem>
</itemizedlist>
</listitem>
<listitem><para>
Mouse button actions</para>
<itemizedlist>
<listitem><para><methodname>virtual void mousePressEvent(QMouseEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void mouseReleaseEvent(QMouseEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void mouseDoubleClickEvent(QMouseEvent *)</methodname></para></listitem>
</itemizedlist>
</listitem>
<listitem><para>
Window events containing the widget</para>
<itemizedlist>
<listitem><para><methodname>virtual void moveEvent(QMoveEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void resizeEvent(QResizeEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void closeEvent(QCloseEvent *)</methodname></para></listitem>
</itemizedlist>
</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. <classname>QWidget</classname>
also contains some other virtual methods that can be useful in your programs; anyway, it is sufficient
to know about <classname>QWidget</classname> very well.
</para>
</sect2>
<sect2 id="c1s2s4">
<title>Object Interaction by Signals and Slots</title>
<para>
Now we're coming to the most obvious advantages of the Qt toolkit: the signal/slot mechanism.
This offers a very handy and useful solution to object interaction, which usually is solved by
callback 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 documentation and explained
in Programming with Qt 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:
<itemizedlist>
<listitem><para>
the class declaration of a class using signals/slots has to contain the Q_OBJECT macro at the beginning
(without a semicolon); and have to be derved from the <classname>QObject</classname> class
</para></listitem>
<listitem><para>
a signal can be emitted by the keyword emit, e.g. emit signal(parameters); 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
signals section
</para></listitem>
<listitem><para>
all methods that can be connected with a signal are declared in sections with the additional keyword slot,
e.g. public slots: within the class declaration
</para></listitem>
<listitem><para>
the meta-object compiler moc has to run over the header file to expand the macros and to produce the
implementation (which is not necessary to know). The output files of moc are compiled also by the C++ compiler.
</para></listitem>
</itemizedlist>
</para>
<para>
Another way to use signals without deriving from <classname>QObject</classname> is to use the
<classname>QSignal</classname> class- see the reference documentation for more information and example
usage. In the following, we assume you're deriving from <classname>QObject</classname>.
</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 <methodname>connect()</methodname> methods that
are provided by <classname>QObject</classname> or, where available, special methods that objects provide
to set the connection for a certain signal.
</para>
<sect3 id="c1s2s4s1">
<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:
<programlisting>
#include <qapplication.h>
#include <qpushbutton.h>
int main( int argc, char **argv )
{
QApplication a( argc, argv );
QPushButton hello( "Hello world!" , 0);
hello.resize( 100, 30 );
a.setMainWidget( &hello );
QObject::connect(&hello, SIGNAL( clicked() ), &a, SLOT( quit() ));
hello.show();
return a.exec();
}
</programlisting>
</para>
<para>
You see, the only addition to give the button more interaction is to use a <methodname>connect()
</methodname> method: <methodname>connect(&hello, SIGNAL( clicked() ), &a, SLOT( quit() ))</methodname>;
is all you have to add. What is the meaning now? The class declaration of QObject says about the
<methodname>connect()</methodname> method:
</para>
<para><methodname>
bool connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * member )
</methodname></para>
<para>
This means you have to specify a <classname>QObject</classname> 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 is 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 explicitly
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="developer.kde.org/documentation/library/libraryref.html">The KDE Library Reference Guide</ulink>
and the <ulink url="doc.trolltech.com">Qt online reference</ulink>.
</para>
</sect3>
</sect2>
</sect1>
<sect1 id="c2s3">
<title>What KDE provides</title>
<sect2 id="c2s3s1">
<title>The KDE 3.x libraries</title>
<para>
The main KDE libraries you'll be using for creating your own TDE applications are:
<itemizedlist>
<listitem><para>
the tdecore library, containing all classes that are non-visible elements to provide application functionality
</para></listitem>
<listitem><para>
the tdeui library, containing user interface elements like menubars, toolbars, etc.
</para></listitem>
<listitem><para>
the tdefile library, containing the file selection dialogs
</para></listitem>
</itemizedlist>
</para>
<para>
Additionally, for specific solutions KDE offers the following libraries:
<itemizedlist>
<listitem><para>
the tdefx library, containing pixmaps, image effects the KStyle extension to QStyle
</para></listitem>
<listitem><para>
the tdehtml library, containing KDE's html component
</para></listitem>
<listitem><para>
the kjs library, containing KDE's Javascript support
</para></listitem>
<listitem><para>
the kio library, containing low level access to network files
</para></listitem>
<listitem><para>
the tdeparts library, containing support for re-usable embeddable extendable applications
</para></listitem>
</itemizedlist>
</para>
<para>
Next we'll have a look at what is needed to turn out first Qt Application into a KDE one.
</para>
</sect2>
<sect2 id="c2s3s2">
<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 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 example from above:
<programlisting>
#include <kapplication.h>
#include <qpushbutton.h>
int main( int argc, char **argv )
{
TDEApplication a( argc, argv );
QPushButton hello( "Hello world!", 0 );
hello.resize( 100, 30 );
a.setTopWidget( &hello );
QObject::connect(&hello, SIGNAL( clicked() ), &a, SLOT( quit() ));
hello.show();
return a.exec();
}
</programlisting>
</para>
<para>
You see that first we have changed from <classname>QApplication</classname> to <classname>TDEApplication
</classname>. Further, we had to change the previously used <methodname>setMainWidget()</methodname> method
to <methodname>setTopWidget</methodname>, which <classname>TDEApplication</classname> 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 tdecore library with -ltdecore.
</para>
<para>
As you now know what at least the <function>main()</function> 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 &tdevelop;. 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,
especially the <classname>QApplication</classname>, <classname>QWidget</classname> and <classname>QObject
</classname> class and the tdecore library documentation for the <classname>TDEApplication</classname> class.
The <ulink url="developer.kde.org/documentation/library/libraryref.html">KDE Library Reference handbook</ulink>
also covers a complete description about the invocation of the <classname>QApplication</classname> and
<classname>TDEApplication</classname> constructors including command-line argument processing.
</para>
</sect2>
</sect1>
</chapter>
<chapter id="chapter3">
<title>Creating New Applications</title>
<sect1 id="c3s1">
<title>The Application Wizard</title>
<para>
&tdevelop;'s Application Wizard is intended to let you start working on new project with &tdevelop;. Therefore
all of your projects are first created by the wizard, and then you can start building them and extend what is
already provided by the source skeleton. You can choose from several project types according to your project goals:
<itemizedlist>
<listitem><para>
KDE Application Framework: includes source code for a complete frame structre of a standard KDE application
</para></listitem>
<listitem><para>
QMake Project: Creates an application framework based around Trolltech's qmake configuration system
</para></listitem>
<listitem><para>
Simple hello world program: Creates a C++ terminal based program with no GUI support
</para></listitem>
<listitem><para>
A multitude of other program skeletons
</para></listitem>
</itemizedlist>
</para>
<para>
In this chapter we'll see how the Application Wizard 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 usualyl the same, but you
may not have as many options available.
</para>
</sect1>
<sect1 id="c3s2">
<title>Invoking the Application Wizard and Project Generation</title>
<sect2 id="c3s2s1">
<title>Starting the Application Wizard and the First Page</title>
<para>
To start with your KDE application, open &tdevelop;. From the Project menu, selection New Project. The
Application Wizard starts, and you'll see the selection tree on the first page containing available project
types that can be created. Choose the C++ subtree, then KDE, then Application Framework.
</para>
<para>
For our sample project, we are going to create the application KScribble. Enter this as the application
name, and change any other information at the bottom of this screen that may need it. Then, select Next.
<screenshot><mediaobject><imageobject>
<imagedata fileref="appwizard.png" format="PNG"/>
</imageobject><textobject><phrase>Application Wizard</phrase></textobject>
</mediaobject></screenshot>
</para>
</sect2>
<sect2 id="c3s2s2">
<title>Version control information</title>
<para>
On this screen you have the ability to decide if your project will use a version control system like
CVS. For our sample project we will not use source control, so make sure the selection box reads None
and select Next.
</para>
</sect2>
<sect2 id="c3s2s3">
<title>Header and Source Templates</title>
<para>
The next two pages show example headers that will go at the top of each of the header and source files that
you create using &tdevelop;. For now, just leave these as the default, and select Next, then Finish. If the
Finish button is not activated, you haven't set all of the options correct. Use the Back button to return
to earlier menus and correct any mistakes.
</para>
</sect2>
<sect2 id="c3s2s4">
<title>Finishing Up</title>
<para>
Upon completion, the Application Wizard should close and the messages window should popup displaying
information about the tasks that &tdevelop; is currently doing. At the end of all of the tasks, you
should see **** Success *****. This means the application framework was successfully loaded.
</para>
</sect2>
</sect1>
<sect1 id="c3s3">
<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
of how the application framework looks. This won't only help us get started, but we'll know where to change
what in later steps.
</para>
<para>
This chapter makes the assumption that you understand the basic navigation of &tdevelop;. Consult the
KDevelop User Manual for information if you need it.
</para>
<para>
The Automake manager shows the project files as follows:
<screenshot><mediaobject><imageobject>
<imagedata fileref="kscribblefiles.png" format="PNG"/>
</imageobject><textobject><phrase>Files in our project</phrase></textobject>
</mediaobject></screenshot>
</para>
<para>
Before diving into the sources, we'll let &tdevelop; build an run our new application. To do this, select
Build Project from the Build menu, or press F8. The output window opens and displays output messages during
the compilation phase.
<programlisting>
1 cd /home/caleb/kscribble && WANT_AUTOCONF_2_5=1 WANT_AUTOMAKE_1_6=1 gmake k
2 gmake all-recursive
3 gmake[1]: Entering directory `/home/caleb/kscribble'
4 Making all in doc
5 gmake[2]: Entering directory `/home/caleb/kscribble/doc'
6 Making all in .
7 gmake[3]: Entering directory `/home/caleb/kscribble/doc'
8 gmake[3]: Nothing to be done for `all-am'.
9 gmake[3]: Leaving directory `/home/caleb/kscribble/doc'
10 Making all in en
11 gmake[3]: Entering directory `/home/caleb/kscribble/doc/en'
12 /usr/local/trinity/bin/meinproc --check --cache index.cache.bz2 /home/caleb/kscribble/doc/en/index.docbook
13 gmake[3]: Leaving directory `/home/caleb/kscribble/doc/en'
14 gmake[2]: Leaving directory `/home/caleb/kscribble/doc'
15 Making all in po
16 gmake[2]: Entering directory `/home/caleb/kscribble/po'
17 gmake[2]: Nothing to be done for `all'.
18 gmake[2]: Leaving directory `/home/caleb/kscribble/po'
19 Making all in src
20 gmake[2]: Entering directory `/home/caleb/kscribble/src'
21 source='main.cpp' object='main.o' libtool=no \
22 depfile='.deps/main.Po' tmpdepfile='.deps/main.TPo' \
23 depmode=gcc3 /bin/sh /home/caleb/kscribble/admin/depcomp \
24 g++ -DHAVE_CONFIG_H -I. -I/home/caleb/kscribble/src -I.. -I/usr/local/trinity/include
-I/usr/lib/qt/include -I/usr/X11R6/include -DQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor
-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings
-ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new
-c -o main.o `test -f 'main.cpp' || echo '/home/caleb/kscribble/src/'`main.cpp
25 /usr/lib/qt/bin/moc /home/caleb/kscribble/src/kscribble.h -o kscribble.moc
26 source='kscribble.cpp' object='kscribble.o' libtool=no \
27 depfile='.deps/kscribble.Po' tmpdepfile='.deps/kscribble.TPo' \
28 depmode=gcc3 /bin/sh /home/caleb/kscribble/admin/depcomp \
29 g++ -DHAVE_CONFIG_H -I. -I/home/caleb/kscribble/src -I.. -I/usr/local/trinity/include
-I/usr/lib/qt/include -I/usr/X11R6/include -DQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor
-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings
-ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new
-c -o kscribble.o `test -f 'kscribble.cpp' || echo '/home/caleb/kscribble/src/'`kscribble.cpp
30 kscribble.cpp: In member function `void KScribble::setupActions()'
31 kscribble.cpp:107: warning: unused variable `TDEAction*custom'
32 /usr/lib/qt/bin/moc /home/caleb/kscribble/src/kscribbleview.h -o kscribbleview.moc
33 source='kscribbleview.cpp' object='kscribbleview.o' libtool=no \
34 depfile='.deps/kscribbleview.Po' tmpdepfile='.deps/kscribbleview.TPo' \
35 depmode=gcc3 /bin/sh /home/caleb/kscribble/admin/depcomp \
36 g++ -DHAVE_CONFIG_H -I. -I/home/caleb/kscribble/src -I.. -I/usr/local/trinity/include
-I/usr/lib/qt/include -I/usr/X11R6/include -DQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor
-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi
-D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -c
-o kscribbleview.o `test -f 'kscribbleview.cpp' || echo '/home/caleb/kscribble/src/'`kscribbleview.cpp
37 kscribbleview.cpp: In member function `void KScribbleView::print(QPainter*,
38 int, int)':
39 kscribbleview.cpp:79: warning: unused parameter `QPainter*p'
40 kscribbleview.cpp:79: warning: unused parameter `int height'
41 kscribbleview.cpp:79: warning: unused parameter `int width'
42 /usr/lib/qt/bin/moc /home/caleb/kscribble/src/pref.h -o pref.moc
43 source='pref.cpp' object='pref.o' libtool=no \
44 depfile='.deps/pref.Po' tmpdepfile='.deps/pref.TPo' \
45 depmode=gcc3 /bin/sh /home/caleb/kscribble/admin/depcomp \
46 g++ -DHAVE_CONFIG_H -I. -I/home/caleb/kscribble/src -I.. -I/usr/local/trinity/include
-I/usr/lib/qt/include -I/usr/X11R6/include -DQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor
-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings
-ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new
-c -o pref.o `test -f 'pref.cpp' || echo '/home/caleb/kscribble/src/'`pref.cpp
47 /usr/local/trinity/bin/dcopidl /home/caleb/kscribble/src/kscribbleiface.h > kscribbleiface.kidl ||
( rm -f kscribbleiface.kidl ; /bin/false )
48 /usr/local/trinity/bin/dcopidl2cpp --c++-suffix cpp --no-signals --no-stub kscribbleiface.kidl
49 source='kscribbleiface_skel.cpp' object='kscribbleiface_skel.o' libtool=no \
50 depfile='.deps/kscribbleiface_skel.Po' tmpdepfile='.deps/kscribbleiface_skel.TPo' \
51 depmode=gcc3 /bin/sh /home/caleb/kscribble/admin/depcomp \
52 g++ -DHAVE_CONFIG_H -I. -I/home/caleb/kscribble/src -I.. -I/usr/local/trinity/include
-I/usr/lib/qt/include -I/usr/X11R6/include -DQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor
-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings
-ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new
-c -o kscribbleiface_skel.o `test -f 'kscribbleiface_skel.cpp' ||
echo '/home/caleb/kscribble/src/'`kscribbleiface_skel.cpp
53 /bin/sh ../libtool --silent --mode=link --tag=CXX g++ -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall
-pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500
-D_BSD_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -o kscribble -R
/usr/local/trinity/lib -R /usr/lib/qt/lib -R /usr/X11R6/lib -L/usr/X11R6/lib -L/usr/lib/qt/lib
-L/usr/local/trinity/lib main.o kscribble.o kscribbleview.o pref.o kscribbleiface_skel.o -lkio
54 source='kscribble_client.cpp' object='kscribble_client.o' libtool=no \
55 depfile='.deps/kscribble_client.Po' tmpdepfile='.deps/kscribble_client.TPo' \
56 depmode=gcc3 /bin/sh /home/caleb/kscribble/admin/depcomp \
57 g++ -DHAVE_CONFIG_H -I. -I/home/caleb/kscribble/src -I.. -I/usr/local/trinity/include
-I/usr/lib/qt/include -I/usr/X11R6/include -DQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor
-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings
-ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new
-c -o kscribble_client.o `test -f 'kscribble_client.cpp' || echo
'/home/caleb/kscribble/src/'`kscribble_client.cpp
58 /bin/sh ../libtool --silent --mode=link --tag=CXX g++ -Wnon-virtual-dtor -Wno-long-long -Wundef
-Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500
-D_BSD_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -o kscribble_client -R
/usr/local/trinity/lib -R /usr/lib/qt/lib -R /usr/X11R6/lib -L/usr/X11R6/lib -L/usr/lib/qt/lib
-L/usr/local/trinity/lib kscribble_client.o -ltdecore
59 gmake[2]: Leaving directory `/home/caleb/kscribble/src'
60 gmake[2]: Entering directory `/home/caleb/kscribble'
61 gmake[2]: Nothing to be done for `all-am'.
62 gmake[2]: Leaving directory `/home/caleb/kscribble'
63 gmake[1]: Leaving directory `/home/caleb/kscribble'
64 *** Success ***
</programlisting>
</para>
<para>
As you can see, we've put line numbers in front of each line which won't appear on your output but it makes it
easier to describe what is happening during the build. First of all, gmake works recursively. This means
that it starts from the directory it is invoked and goes into the subdirectories first, one at a time, then
returns to the directory it was started, processes it, then finishes.
</para>
<para>
Our first line of interest is 24. Notice on this line that g++, which is our C++ compiler, gets called by make
to compile the first source code file in our project - in this case main.cpp. Many extra command line options
are also being used with the g++ compiler; some of which are defaults and some of which can be configured
via &tdevelop;.
</para>
<para>
Before the next file (kscribble.cpp, line 29) is compiled, the moc (meta object compiler) is first
invoked on kscribble.h (line 25). This is because KScribble classes use signals/slots, so the
Q_OBJECT macro must be expanded, and the moc does this for us. The resultant file, kscribble.moc, is
used by kscribble.cpp via an #include statement inside of the file.
</para>
</sect1>
<sect1 id="c3s4">
<title>The source skeleton</title>
<para>
To conceptualize 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, 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="c3s4s1">
<title>The main() function</title>
<para>
As the application begins its execution with entering the <function>main()</function> function,
this will be the start for our code examination. The <function>main()</function> function of
KScribble is implemented in the file main.cpp and can also be found using the Class Browser
by selecting the "Global Functions" folder.
<programlisting>
1 int main(int argc, char **argv)
2 {
3 TDEAboutData about("kscribble", I18N_NOOP("KScribble"), version, description,
4 TDEAboutData::License_GPL, "(C) 2002 Your Name", 0, 0, "you@you.com");
5 about.addAuthor( "Your Name", 0, "you@you.com" );
6 TDECmdLineArgs::init(argc, argv, &about);
7 TDECmdLineArgs::addCmdLineOptions(options);
8 TDEApplication app;
9
10 // register ourselves as a dcop client
11 app.dcopClient()->registerAs(app.name(), false);
12
13 // see if we are starting with session management
14 if (app.isRestored())
15 RESTORE(KScribble)
16 else
17 {
18 // no session.. just start up normally
19 TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
20 if (args->count() == 0)
21 {
22 KScribble *widget = new KScribble;
23 widget->show();
24 }
25 else
26 {
27 int i = 0;
28 for (; i < args->count(); i++)
29 {
30 KScribble *widget = new KScribble;
31 widget->show();
32 widget->load(args->url(i));
33 }
34 }
35 args->clear();
36 }
37
38 return app.exec();
39 }
</programlisting>
</para>
<para>
Now, what happens first is the usual creation of a <classname>TDEApplication</classname> object, but we've
added some KDE methods that set program and author information for this application.
</para>
</sect2>
<sect2>
<title>User Application Start</title>
<para>... (not written yet)</para>
</sect2>
<sect2>
<title>The Constructor</title>
<para>
Let's have a look at the constructor and see how this instance is called
<programlisting>
1 KScribble::KScribble()
2 : TDEMainWindow( 0, "KScribble" ),
3 m_view(new KScribbleView(this)),
4 m_printer(0)
5 {
6 // accept dnd
7 setAcceptDrops(true);
8
9 // tell the TDEMainWindow that this is indeed the main widget
10 setCentralWidget(m_view);
11
12 // then, setup our actions
13 setupActions();
14
15 // and a status bar
16 statusBar()->show();
17
18 // allow the view to change the statusbar and caption
19 connect(m_view, SIGNAL(signalChangeStatusbar(const QString&)),
20 this, SLOT(changeStatusbar(const QString&)));
21 connect(m_view, SIGNAL(signalChangeCaption(const QString&)),
22 this, SLOT(changeCaption(const QString&)));
23
24 }
</programlisting>
</para>
<para>
Notice that <classname>KScribble</classname> inherits the <classname>TDEMainWindow</classname> class - a
commonly used base class for TDE applications. We initialize a class called <classname>KScribbleView</classname>
as our central widget, create a <classname>KStatusBar</classname> via the <methodname>statusBar()</methodname>
method (line 16), and connect some signals and slots together.
</para>
</sect2>
</sect1>
</chapter>
<chapter id="chapter4">
<title>Application View Design</title>
<sect1 id="c4s1">
<title>Introduction</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 toolbars
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 Kate, you see the visual interface as the following:
<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: 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 and KDE
libraries; 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, a lot of users won't accept an application that isn't:
<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>
</para>
<para>
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 project, you always have to have a view that inherits QWidget, either by
direct inheritance or because the library widget you want to use inherits QWidget. Therefore, the
Application Wizard already constructed a view that is an instance of a class yourappView, which
inherits QWidget already.
</para>
<para>
This chapter therefore describes how to use library widgets for creating views of KDE or
Qt applications that are generated with &tdevelop;, then we look at the libraries and what kind of
views are already offered.
</para>
</sect1>
<sect1 id="c4s2">
<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 libraries already
contain a set of widgets that can be used for this purpose. To use them, you have two options:
<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"->"Options" from the &tdevelop;
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 -l option.
For libraries that your application has to search for before preparing the Makefiles by the
configure script on the end-user machine, add the according search macro to the configure.in file
located at the root directory of your project and add the macro to the edit line. Mind that you have
to run "Build"->"Autoconf and automake" and "Build"->"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 -I options in the output window on "Make"), you have to add the path to the
Project Options dialog -"Compiler Options" page with the -I option or the according automake macro at
the edit line for "Additional Options".
</para>
<sect2 id="c4s3s1">
<title>Qt Views</title>
<para>
Looking at the first page of the Qt online documentation, you will find a link to
"Widget Screenshots" where you can have a look at how the widgets Qt 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 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 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 provides the class
<classname>QScrollView</classname>, which offers a scrollable child area. As explained, you could
inherit your own widget from <classname>QScrollView</classname> 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 <classname>QWidget</classname>
and add vertical and horizontal <classname>QScrollBars </classname>.
(This is done by KDE`s TDEHTMLView widget.)
</para></listitem>
<listitem><para>
For text processing, use <classname>QTextEdit</classname>. 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 <classname>QTable</classname> to display data that is arranged in a table.
As <classname>QTable</classname> 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 <classname>QSplitter
</classname>. This allows to tile views by horizontal or vertical dividers.
KMail is a good example what 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>
<classname>QListView</classname> 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 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="c4s3s2">
<title>KDE Views</title>
<para>
The KDE libraries were invented to make designing applications for the K Desktop Environment easier
and capable of more functionality than what Qt alone is offering. The tdeui library offers:
<orderedlist>
<listitem><para>
TDEListView: a more powerful version of <classname>QListView</classname>
</para></listitem>
<listitem><para>
KIconView: a graphical viewer of icon files
</para></listitem>
</orderedlist>
</para>
<para>
The tdehtml 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 Konqueror to display HTML files.
</para>
</sect2>
</sect1>
<sect1 id="c4s4">
<title>Creating your own Views</title>
<para>
Not yet written
</para>
</sect1>
</chapter>
<chapter id="chapter5">
<title>Configuring Menubars and Toolbars</title>
<sect1 id="c5s1">
<title>Introduction</title>
<para>
Menubars and toolbars 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 toolbars.
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>
<sect1 id="c5s2">
<title>How does it work?</title>
<para>
Our application inherits the <classname>TDEMainWindow</classname> class, which automatically handles creating
a menu bar and tool bars for us. In the <methodname>KScribble::setupActions()</methodname> method there is
a call to <methodname>TDEMainWindow::createGUI()</methodname>. This method loads a resource file, in this
case kscribbleui.rc, to initialize menus at startup. Note that kscribbleui.rc is listed as one of the
project files in the Automake Manager. Opening that file up reveals this:
<programlisting>
1 <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
2 <kpartgui name="kscribble" version="1">
3 <MenuBar>
4 <Menu name="custom"><text>C&ustom</text>
5 <Action name="custom_action" />
6 </Menu>
7 </MenuBar>
8 </kpartgui>
</programlisting>
</para>
<para>
Explanation...
</para>
<para>
Another way to modify the contents of the menu and tool bars is to directly manipulate them through the
methods provided by their class. For example, the <methodname>menuBar()</methodname> method returns the
<classname>KMenuBar</classname> widget that the menubar for our program. Looking at the documentation for
<classname>KMenuBar</classname> and its inheritor class <classname>QMenuBar</classname>, you will find
a large number of <methodname>insertItem()</methodname> methods which allow you to add items to the
menu bar.
</para>
<para>
<classname>TDEMainWindow</classname>'s methods <methodname>statusBar()</methodname> and <methodname>
toolBar()</methodname> will also provide you with applicable widgets.
</para>
</sect1>
<sect1 id="c5s3">
<title>Keyboard Accelerator Configuration</title>
<para>
A very professional thing you should always add to your application are keyboard accelerators.
Those are mainly used by experienced users that want to work fast with their applications and
are willing to learn shortcuts. For this, the KDE libraries provide the class <classname>
TDEAction</classname>, which provides the keyboard accelerator keys and access to global configured
standard keyboard accelerators.
</para>
<para>
By default, frame applications generated by &tdevelop; only use standard keyboard accelerators
such as F1 for accessing online-help, Ctrl+N for New File etc.
</para>
<para>
If your application contains a lot of accelerators, you should make them configurable
by an Options-menu; either it could be combined with other application configuration in a QWidget
or stand alone. The KDE library already provides a <classname>KKeyChooser</classname>
for use in tab dialogs, whereas <classname>KKeyDialog</classname> provides a ready-to use
key-configuration dialog.
</para>
</sect1>
</chapter>
<!--
<chapter id="chapter6">
<title>Other Features</title>
</chapter>
<chapter id="chapter7">
<title>Printing Support</title>
</chapter>
-->
<chapter id="chapter8">
<title>Help Functions</title>
<sect1 id="c8s1">
<title>Introduction</title>
<para>
A very important part of the development process is to provide help functionality to the user
wherever possible. Most developers tend to delay this, but you should remember that a normal user
isn't necessarily a Unix expert. He may come from the the dark side of computer software usage offering
all sweets that a user may need to work himself into using an application even without ever touching the
manuals. Therefore, the KDE and Qt library provide all means usually considered making an application
professional in the eyes of the normal user by help functions that are ready to use.
Within the application, those are:</para>
<itemizedlist>
<listitem><para>Tool-Tips</para></listitem>
<listitem><para>Statusbar help</para></listitem>
<listitem><para>What's this...? buttons</para></listitem>
</itemizedlist>
<para>
Additionally, the application should provide means to access a HTML-based online manual directly
using the standard help key F1. This context based help system is provided automatically through the
<classname>TDEMainWindow</classname> class, though as the author you must provide the content.
</para>
<para>
As &tdevelop; also offers all types of help as well as the KDE framework generated by the
application wizard already contains support for this, this chapter will help you find out where
and how to add your help functionality. </para>
<para>
During the development of your application you should try to be consistent whatever you're doing;
therefore you should do the necessary steps directly while extending the code. This will prevent you
from diving into the code again and figuring out what your application does or what you intended by
certain parts of the code.
</para>
</sect1>
<sect1 id="c8s2">
<title>Tool-Tips</title>
<para>
A very easy means of providing help are tool-tips. Those are small help messages popping up while
the user moves the mouse over a widget that provides a tool-tip and disappears when the mouse moves away.
The most popular usage of tool-tips is made in toolbars where your tool-tips should be kept as small
as possible because toolbars can be configured to display their contents in various ways:
either displaying the button, button with text on the right, button with text below, text only.
This possibility should be made configurable by the user, but isn't a must-be. The text is shown
as a tool-tip anyway and a toolbar usually consists of buttons and other widgets like lineedits and
combo boxes. For a complete reference, see the <classname>TDEToolBar</classname> class reference located
in the tdeui library.
</para>
<para>
As an example, we have a look at the "New File" button in a generic application:
</para>
<para>
There, the part i18n("New File") provides a tool-tip message. It is enclosed by the i18n()
macro provided by kapp.h to translate the tool-tip towards the currently selected language.
</para>
<para>
Tool-tips can also be added to any custom widget by using the <classname>QToolTip</classname>
provided by Qt. An example of that would be:
</para>
</sect1>
<sect1 id="c8s3">
<title>Extending the Statusbar</title>
<para>
As the applications that inherit <classname>TDEMainWindow</classname> contain a statusbar as well,
it also offers a set of statusbar messages already for all menu and toolbar items. A statusbar
help message is a short message that extends the meaning of a tool-tip or can be seen as a replacement
for a tool-tip over menubar items and is (as the name suggests) displayed in the statusbar when the user
enters a menu and highlights the menu entry.
</para>
</sect1>
<sect1 id="c8s4">
<title>The <guibutton>What's This...?</guibutton> Button</title>
<para>
The <guibutton>What's This...?</guibutton> button provides help windows with the intention
that the user wants to get help about a certain widget within the working view or a toolbar item.
It is placed in the toolbar and gets activated once the user hits the button. The cursor changes
to an arrow cursor with a question mark like the button itself looks like. The the user can press on
a visible widget item and gets a help window. As an exercise, you could try this behavior with the
<guibutton>What's this...?</guibutton> button within &tdevelop;.
</para>
<para>
To add the What's This...? help to one of your widgets, use the static method
<methodname>QWhatsThis::add(QWidget *widget, const QString &text)</methodname>
</para>
</sect1>
</chapter>
<chapter id="chapter9">
<title>Documentation</title>
<sect1 id="c9s1">
<title>Introduction</title>
<para>
Due to the fact that projects often lack a complete set of user documentation,
all &tdevelop; projects contain a pre-build handbook that can be easily adapted;
therefore fulfiling another goal of KDE: providing enough online-help to support users that
are not familiar with an application. This chapter therefore introduces you on how to extend
the provided documentation template and what you have to do to make it available to the user.
</para>
</sect1>
<sect1 id="c9s2">
<title>User Documentation</title>
<para>
The documentation for your project lies in projectdir/doc/en, or perhaps another directory if English
isn't your native language. Therein lies a file, index.docbook, in which the documentation is stored.
The format for editing this file is explained on
<ulink url="http://i18n.kde.org/doc/markup/">KDE's documentation website</ulink>.
</para>
</sect1>
<sect1 id="c9s3">
<title>Programmer Documentation</title>
<para>
Another important part of the documentation is including a descriptive help for your class interfaces.
This will allow you and other programmers to use your classes by reading the HTML class documentation
that can be created with KDoc. &tdevelop; supports the use of KDoc completely by creating the
KDE-library documentation, also your application frameworks are already documented. To work yourself
into the provided code, it would be a good start to read the included documentation online.
The following describes what to do to get the API documentation, where &tdevelop; helps you add it
and what kind of special tags KDoc provides.
</para>
</sect1>
</chapter>
<chapter id="chapter10">
<title>Internationalization</title>
<sect1 id="c10s1">
<title>Introdction</title>
<para>
i18n is an internationalization system that is used to offer internationalized versions of an
application or project. The difficulty with writing applications is that they only support the
language they originally are composed with; visually this can be seen on labels, menu entries and the
like. The goal of the internationalization is to provide applications and library functions in the
language of the user; therefore enabling users that are not native speakers the original language to make
use of the provided functionality and feel more comfortable.
</para>
</sect1>
<!--
<sect1 id="c10s2">
<title>How KDE support Internationalization</title>
<para>
</para>
</sect1> -->
</chapter>
<!--
<chapter id="chapter11">
<title>Finding Errors</title>
</chapter>
<chapter id="chapter12">
<title>Licensing</title>
</chapter>
<chapter id="chapter13">
<title>References</title>
</chapter>
-->
<chapter id="credits">
<title>Credits</title>
<para>
(... to be written ...)
</para>
<!--CREDITS_FOR_TRANSLATORS-->
</chapter> <!-- credits -->
<appendix id="bibliography">
<title>Bibliography</title>
<bibliography>
<biblioentry>
<title><ulink url="info://make/Top">GNU Make Manual</ulink></title>
<authorgroup>
<author><firstname>Richard M.</firstname><surname>Stallman</surname></author>
<author><firstname>Roland</firstname><surname>McGrath</surname></author>
</authorgroup>
</biblioentry>
<biblioentry>
<title><ulink url="info://automake/Top">GNU Automake</ulink></title>
<authorgroup>
<author><firstname>David</firstname><surname>MacKenzie</surname></author>
<author><firstname>Tom</firstname><surname>Tromey</surname></author>
</authorgroup>
</biblioentry>
<biblioentry>
<title><ulink url="info://autoconf/Top">GNU Autoconf</ulink></title>
<authorgroup>
<author><firstname>David</firstname><surname>MacKenzie</surname></author>
<author><firstname>Ben</firstname><surname>Elliston</surname></author>
</authorgroup>
</biblioentry>
<biblioentry>
<title><ulink url="info://gcc/Top">Using the GNU Compiler Collection</ulink></title>
<author><firstname>Richard M.</firstname><surname>Stallman</surname></author>
</biblioentry>
<biblioentry>
<title><ulink url="info://libtool/Top">GNU Libtool</ulink></title>
<authorgroup>
<author><firstname>Gordon</firstname><surname>Matzigkeit</surname></author>
<author><firstname>Alexandre</firstname><surname>Oliva</surname></author>
<author><firstname>Thomas</firstname><surname>Tanner</surname></author>
<author><firstname>Gary V.</firstname><surname>Vaughan</surname></author>
</authorgroup>
</biblioentry>
<biblioentry>
<title>GNU Autoconf, Automake, and Libtool</title>
<edition>1st edition</edition>
<pubdate>October 2000</pubdate>
<authorgroup>
<author><firstname>Gary V.</firstname><surname>Vaughan</surname></author>
<author><firstname>Ben</firstname><surname>Elliston</surname></author>
<author><firstname>Tom</firstname><surname>Tromey</surname></author>
<author><firstname>Ian Lance</firstname><surname>Taylor</surname></author>
</authorgroup>
<publisher><publishername>New Riders Publishing</publishername></publisher>
<isbn>ISBN 1578701902</isbn>
</biblioentry>
<biblioentry>
<title>Advanced Programming in the UNIX(R) Environment</title>
<edition>1st edition</edition>
<pubdate>June 1992</pubdate>
<author><firstname>W. Richard</firstname><surname>Stevens</surname></author>
<publisher><publishername>Addison-Wesley Pub Co</publishername></publisher>
<isbn>ISBN 0201563177</isbn>
</biblioentry>
<biblioentry>
<title>Thinking in C++, Volume 1: Introduction to Standard C++</title>
<edition>2nd Edition</edition>
<pubdate>April 15, 2000</pubdate>
<author><firstname>Bruce</firstname><surname>Eckel</surname></author>
<publisher><publishername>Prentice Hall</publishername></publisher>
<isbn>ISBN 0139798099</isbn>
</biblioentry>
<biblioentry>
<title>Open Source Development with CVS</title>
<edition>2nd Edition</edition>
<pubdate>October 12, 2001</pubdate>
<authorgroup>
<author><firstname>Karl</firstname><surname>Fogel</surname></author>
<author><firstname>Moshe</firstname><surname>Bar</surname></author>
</authorgroup>
<publisher><publishername>The Coriolis Group</publishername></publisher>
<isbn>ISBN 158880173X</isbn>
</biblioentry>
<biblioentry>
<title>Programming PHP</title>
<edition>1st edition</edition>
<pubdate>March 2002</pubdate>
<authorgroup>
<author><firstname>Rasmus</firstname><surname>Lerdorf</surname></author>
<author><firstname>Kevin</firstname><surname>Tatroe</surname></author>
</authorgroup>
<publisher><publishername>O'Reilly & Associates</publishername></publisher>
<isbn>ISBN 1565926102</isbn>
</biblioentry>
<biblioentry>
<title>Programming Python</title>
<edition>2nd Edition</edition>
<pubdate>March 2001</pubdate>
<author><firstname>Mark</firstname><surname>Lutz</surname></author>
<publisher><publishername>O'Reilly & Associates</publishername></publisher>
<isbn>ISBN 0596000855</isbn>
</biblioentry>
<biblioentry>
<title>Gui Programming With Python : Using the Qt Toolkit</title>
<edition>Bk&Cd-r edition</edition>
<pubdate>January 2002</pubdate>
<author><firstname>Boudewijn</firstname><surname>Rempt</surname></author>
<publisher><publishername>Opendocs Llc</publishername></publisher>
<isbn>ISBN 0970033044</isbn>
</biblioentry>
<biblioentry>
<title>Programming Perl</title>
<subtitle>The Camel book</subtitle>
<edition>3rd Edition</edition>
<pubdate>July 2000</pubdate>
<authorgroup>
<author><firstname>Larry</firstname><surname>Wall</surname></author>
<author><firstname>Tom</firstname><surname>Christiansen</surname></author>
<author><firstname>Jon</firstname><surname>Orwant</surname></author>
</authorgroup>
<publisher><publishername>O'Reilly & Associates</publishername></publisher>
<isbn>ISBN 0596000278</isbn>
</biblioentry>
<biblioentry>
<title>Learning Perl</title>
<subtitle>The Lama book</subtitle>
<edition>3rd Edition</edition>
<pubdate>July 15, 2001</pubdate>
<authorgroup>
<author><firstname>Randal L.</firstname><surname>Schwartz</surname></author>
<author><firstname>Tom</firstname><surname>Phoenix</surname></author>
</authorgroup>
<publisher><publishername>O'Reilly & Associates</publishername></publisher>
<isbn>ISBN 0596001320</isbn>
</biblioentry>
</bibliography>
&underFDL;
</appendix>
</book>