]>

# Le Manuel de Programmation de KDevelop

Le Manuel de l'Utilisateur pour la Conception d'Applications C++ pour l'Environnement de Bureau KDE avec l'EDI KDevelop, Version 1.2
Auteur : Ralf Nolden
L'Équipe KDevelop

    <Ralf.Nolden@post.rwth-aachen.de>

François-Xavier
Duranceau

    <duranceau@kde.org>

Anne-Marie
Mahfouf

    <a-m.mahfouf@lineone.net>

Ludovic
Grossard

    <ludovic.grossard@libertysurf.fr>

Erwan
Loisant

    <erwan@fr.st>

Version 1.2, 7 juillet 1999

Ce manuel fait partie intégrante de l'Environnement de Développement Intégré KDevelop et est donc sous licence GNU General Public License ; consulter Copyright pour plus de détails.

KDE

## Introduction

Les systèmes Unix deviennent, même pour les débutants, de plus en plus populaires grâce à leur stabilité et à leurs fonctionnalités. Cependant, la plupart de ces utilisateurs sont déçus car les applications n'ont pas une apparence et une ergonomie homogènes, chacune se comportant de façon différente. Avec KDE, les développeurs ont un moyen presque parfait de créer des applications de premier plan pour les systèmes de bureau Unix et ainsi attirer une plus grande communauté d'utilisateurs par la grande qualité offerte par leurs applications. C'est aussi pourquoi KDE devient de plus en plus populaire comme base de conception de programmes et les développeurs veulent profiter des avantages offerts par le système.

### Ce que vous devriez déjà savoir

Pour tirer profit de ce manuel de programmation, nous considérons que vous connaissez déjà le langage de programmation C++ ; sinon, vous devrez commencer par vous familiariser avec celui-ci. Différentes sources d'informations sur le C++ sont disponibles (ouvrages de librairie, tutoriels trouvés sur Internet...). Aucune connaissance spécifique aux Interfaces Graphiques Utilisateur n'est nécessaire puisque ce manuel essaie de traiter de la conception d'application KDE, ce qui inclut une introduction à la boîte à outils Qt
ainsi que les bibliothèques de KDE
et la conception d'Interfaces Utilisateur. Vous devriez aussi vous familiariser avec KDevelop en lisant Le Manuel d'Utilisation de KDevelop qui contient une description complète des fonctionnalités fournies par l'EDI.

### À propos de ce Manuel

Ce manuel a été écrit pour donner aux développeurs une introduction au développement d'application KDE en utilisant l'Environnement de Développement Intégré KDevelop. Les chapitres suivants vous expliqueront donc comment créer des projets, le code source auto-généré et vous montreront comment étendre les sources données sur différents sujets comme les barres d'outils
, les barres de menus et les zones de vues.

Ensuite, l'éditeur de boîte de dialogue sera présenté en détail, en expliquant comment créer des widgets et traitera des propriétés de tous les widgets fournis.

Enfin, vous apprendrez différentes choses qui complèteront vos connaissances sur la conception de projets et vous aideront, au-delà du codage, à ajouter une documentation de l'API
et à étoffer les manuels en ligne. Dans le chapitre suivant, nous nous attarderons sur les bibliothèques de KDE et de Qt
, montrant ainsi les concepts de base et pourquoi les choses se font de la sorte. Nous expliquerons aussi comment créer les applications du tutoriel fourni par la boîte à outils Qt
en utilisant KDevelop ; ainsi, les débutants pourront voir de premiers résultats en quelques étapes et, automatiquement, apprendront à utiliser les meilleures fonctionnalités de KDevelop.

Dans les chapitres suivants, vous apprendrez :

- comment créer une application avec le KAppWizard

- ce que les squelettes de projet fournissent eux-mêmes

- ce que signifie le code déjà créé

- comment créer vos propres vues

- comment étendre les fonctionnalités de votre application avec des boîtes de dialogue, des barres de menus et des barres d'outils

- comment rendre votre application conviviale en fournissant des fonctions d'aide et

- comment écrire une documentation en ligne en SGML
  .

### Informations supplémentaires

Des informations supplémentaires sur la programmation avec Qt
/KDE sont accessibles de différentes manières :

- Programmer avec Qt
  par Matthias Kalle Dalheimer, publié par O'Reilly (voir \|\|), qui traite de presque tous les aspects de la boîte à outils graphique Qt
  et contient aussi des exemples

- Le Manuel d'Utilisation de KDevelop, fourni avec l'EDI KDevelop,

- Référence en ligne de la bibliothèque Qt
  , fournie au format HTML avec votre copie de Qt
  et disponible en PostScript sur \|\|

- Sur Internet, consultez

  - le site web de Troll Tech à \|\|

  - le site web de KDE à \|\|

  - le site web du développeur KDE à \|\|

  - la page d'accueil de KDevelop à \|\|

En plus, vous pourrez obtenir de l'aide en vous abonnant aux différentes listes de discussion dont les adresses sont données sur les sites web cités ci-dessus, ou aux forums de discussion Usenet dédiés à KDE et aux Systèmes Unix, ainsi qu'aux langages de programmation C et C++.

Pour obtenir de l'aide sur l'EDI KDevelop, vous pouvez envoyez vos requêtes à notre liste de discussion à kdevelop@fara3.cs.uni-potsdam.de. Rappelez-vous cependant que l'équipe KDevelop s'occupe de fournir les moyens d'écrire vos programmes applicatifs et n'a donc pas pour but d'être une équipe de support technique au cas où l'application que vous développez ne fonctionne pas du fait d'erreurs d'implantation ou d'une mauvaise configuration de votre système d'exploitation. Par là, nous invitons tous les utilisateurs à consulter la liste de discussion au cas où vous rencontriez des problèmes avec l'utilisation de l'EDI en lui-même, ainsi que pour des rapports de bogue ou des suggestions visant à améliorer les fonctionnalités de l'environnement de développement.

## Les Bibliothèques de KDE et Qt

La société norvégienne Troll Tech (\|\|) fournit une boîte à outils graphique (NdT& ;: GUI toolkit) nommée Qt
. Ici, graphique doit être pris au sens d'"Interface Utilisateur Graphique" (NdT& ;: GUI signifie littéralement Graphical User Interface). Les applications basées sur Qt
sont donc représentées par des boutons, des fenêtres, etc, permettant ainsi à l'utilisateur de visualiser les fonctions fournies par l'application. Une telle boîte à outils est nécessaire pour développer des applications graphiques qui s'exécutent sur l'interface X-Window des Systèmes Unix car X ne contient pas en lui-même d'interface utilisateur prédéfinie. Bien que d'autres boîtes à outils soient aussi disponibles pour créer des Interfaces Utilisateur, Qt
offre des avantages techniques qui rendent la conception d'applications vraiment simple. En plus, Qt
est aussi disponible pour les systèmes Microsoft Windows, ce qui permet aux développeurs de fournir leurs applications pour les deux plates-formes.

L'équipe KDE (\|\|) dont le but est de rendre l'utilisation des Systèmes Unix plus conviviale a décidé d'utiliser la boîte à outils Qt
pour le développement d'un gestionnaire de fenêtres basé sur X-Window, et la réalisation d'un grand nombre d'outils inclus dans les paquetages de KDE. Les composants principaux de l'Environnement de Bureau KDE sont le gestionnaire de fenêtres kwm, le gestionnaire de fichiers kfm et le tableau de bord kpanel ainsi que d'autres outils et applications de premier plan. Après la sortie de KDE, beaucoup de développeurs se sont intéressés à ce nouvel environnement et ce qu'il avait à leur offrir. Les bibliothèques de KDE
fournissent les classes et les méthodes essentielles pour donner à vos applications une apparence similaire et homogène. Ainsi, l'utilisateur a l'énorme avantage de ne pas avoir besoin de s'accoutumer au comportement spécifique de chaque application ou à la façon de gérer les boîtes de dialogue ou les boutons. En plus, les programmes KDE s'intègrent eux-mêmes dans le bureau, sont capables d'interagir avec le gestionnaire de fichiers par glisser-déposer
, autorisent la gestion de session et bien plus si toutes les fonctionnalités offertes par les bibliothèques de KDE
sont utilisées.

La boîte à outils Qt
et les bibliothèques de KDE
sont toutes implantées dans le langage de programmation C++ ; aussi, les applications qui les utilisent sont généralement écrites en C++. Dans le chapitre suivant, nous survolerons les bibliothèques pour voir ce qui est déjà disponible et comment les applications KDE
et Qt
sont créées, en général.

### La boîte à outils graphique Qt

Comme mentionné précédemment, la bibliothèque Qt
est une boîte à outils qui fournit des éléments graphiques qui sont utilisés pour créer des applications graphiques (NdT : GUI applications) et sont nécessaires pour programmer X-Window. De plus, cette boîte à outils offre :

- un ensemble complet de classes et de méthodes prêtes à être utilisées même pour des fonctions non graphiques

- une bonne solution pour les interactions avec l'utilisateur par l'intermédiaire des méthodes virtuelles et du mécanisme signal/slot

- un ensemble d'éléments graphiques prédéfinis appelés widgets qui peuvent facilement être utilisés pour créer les entités visibles

- des boîtes de dialogue complètement pré-définies supplémentaires qui sont souvent utilisées dans les applications (ouverture/enregistrement de fichiers, progression d'opération...).

Il apparaît donc essentiel de connaître les classes de Qt
, même si vous voulez seulement programmer des applications KDE. Pour avoir un aperçu de la façon dont les applications graphiques sont compilées et construites, nous allons d'abord jeter un oeil à un exemple de programme basé uniquement sur Qt
; ensuite, nous en ferons un programme KDE.

#### La première Application Qt

Comme d'habitude, les programmes écrits en C++ doivent contenir une fonction `main()` qui est le point de départ de l'exécution de l'application. Comme nous voulons qu'ils soient affichés graphiquement dans des fenêtres et qu'ils permettent d'interagir avec l'utilisateur, nous devons d'abord savoir comment ils peuvent s'afficher eux-mêmes à l'utilisateur. À titre d'exemple, nous allons regarder le premier tutoriel inclus dans la Documentation de Référence en ligne de Qt
, expliquer les étapes de base de l'exécution et voir pourquoi et comment la fenêtre de l'application apparaît :

    #include <qapplication.h>
    #include <qpushbutton.h>

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

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

    a.setMainWidget( &&;hello );
    hello.show();
    return a.exec();
    }

Globalement, l'application dessine une fenêtre contenant un bouton dont le texte est "Hello world". Comme pour toute application basée sur Qt
, vous devez d'abord créer une instance de la classe `
QApplication`, ici représentée par `a`.

Ensuite, le programme crée une instance de la classe `QPushButton` appelée `hello`, ce sera le bouton. Le constructeur de `hello` prend en paramètre une chaîne de caractères qui est le contenu de la partie visible du widget, c'est-à-dire le texte du bouton.

Ensuite, la méthode `resize()` est appelée pour le bouton `hello`. Cela remplace la taille par défaut qu'un widget (ici, c'est un QPushButton) a lorsqu'il est créé par une longueur de 100 pixels et une hauteur de 30 pixels. Enfin, la méthode `setMainWidget()` est appelée pour `a` et la méthode `show()` pour `hello`. La `
QApplication` est enfin exécutée par le `a.exec()`, entre dans la boucle principale d'événements et attend jusqu'à devoir retourner une valeur entière au Système d'Exploitation sous-jacent pour lui signaler que l'application s'est terminée.

#### Le Manuel de Référence de Qt

Maintenant, regardons rapidement le manuel de référence de la bibliothèque Qt
. Pour cela, lançons KDevelop et choisissons "Bibliothèque Qt
" dans le menu "Aide" de la barre de menus. Le navigateur de documentation s'ouvre et affiche la page d'accueil de la référence de Qt
. Ce sera votre source d'information privilégiée sur Qt
, ses classes et les fonctions disponibles. D'ailleurs, le programme ci-dessus est le premier qui est inclus dans la section des tutoriels. Pour accéder aux classes qui nous intéressent (`
QApplication` et `QPushButton`), sélectionnez "Alphabetical Class List" et cherchez les noms correspondants. Cliquez sur le lien pour consulter la documentation de la classe
.

Pour `
QApplication`, vous verrez le constructeur et toutes les autres méthodes que fournit cette classe. Si vous suivez le lien, vous obtiendrez plus d'informations sur l'utilisation et la signification des méthodes, ce qui est très utile quand vous ne devinez pas l'utilisation appropriée ou que vous voulez un exemple. Cela s'applique aussi à la documentation des bibliothèques de KDE qui utilise un type de documentation similaire ; c'est donc presque tout ce que vous avez à savoir sur l'utilisation des références (croisées) de classes dans le navigateur de documentation.

#### Dissection de l'exemple

En commençant par `
QApplication`, vous trouverez toutes les méthodes utilisées dans notre premier exemple :

- le constructeur `
  QApplication()`

- la méthode `setMainWidget()` et

- la méthode `exec()`.

Disséquons l'utilisation de ces méthodes :

1. créer d'abord une instance de la classe `
   QApplication` avec le constructeur afin de pouvoir utiliser les éléments graphiques fournis par Qt

2. créer un widget qui sera le contenu de la fenêtre du programme

3. définir le widget comme widget principal pour `a`

4. exécuter l'instance `a` de `
   QApplication`.

Le second objet de notre programme est le PushButton, une instance de la classe `QPushButton`. Nous utilisons le second des deux constructeurs donnés pour créer une instance ; ici, c'est la chaîne de caractères "Hello world!". Ensuite, nous avons appelé la méthode `resize()` pour changer la taille du bouton en fonction de son contenu - le bouton doit être agrandi pour que la chaîne apparaisse complètement.

Et la méthode `show()` ? Eh bien, vous constatez que, comme la plupart des autres widgets, `QPushButton` est basé sur un héritage simple - ici, la documentation indique Inherits `
QButton`. Suivez le lien vers la classe `
QButton`. Cela affiche beaucoup de méthodes qui sont héritées par QPushButton, que nous utiliserons plus tard pour expliquer le mécanisme signal/slot. De toute façon, la méthode `show()` n'est pas listée, c'est sûrement une méthode fournie par l'héritage. La classe dont hérite `
QButton` est `
QWidget`.

Suivez à nouveau le lien et vous verrez un grand nombre de méthodes que la classe `
QWidget` définit (dont la méthode `show()`). Maintenant, nous comprenons mieux ce qui s'est passé avec le bouton dans l'exemple :

1. créer une instance de `QPushButton`, utiliser le deuxième constructeur pour définir le texte du bouton

2. redimensionner le widget pour que tout le texte qu'il contient apparaisse

3. définir le widget comme étant le widget principal de l'instance `a` de `
   QApplication`

4. dire au widget de s'afficher sur l'écran en appelant `show()`, une méthode héritée de `
   QWidget`.

Après l'appel à la méthode `exec()`, l'application est visible pour l'utilisateur, elle a dessiné une fenêtre avec le bouton affichant "Hello world!". Par contre, les programmes graphiques se comportent un peu différemment des applications procédurales. Ici, le point essentiel est que l'application entre dans une "boucle d'événements principale". Cela signifie que le programme doit attendre des actions de l'utilisateur et ensuite y réagir. Pour une application Qt
, le programme doit être dans la boucle d'événements principale pour commencer à traiter les événements. La section suivante vous explique brièvement ce que cela signifie pour le programmeur et ce que Qt
fournit pour traiter les événements utilisateur.

(Pour les utilisateurs déjà expérimentés : le bouton n'a pas de parent déclaré dans le constructeur, c'est donc un "top-level widget" seul et s'exécute dans une boucle d'événements locale qui ne nécessite pas d'attendre la boucle d'événements principale, voir la documentation de la classe
`
QWidget` et le Guide de Référence des Bibliothèques de KDE).

Résumé :

Une application Qt
doit toujours avoir une instance de la classe `
QApplication`. Cela garantit que nous pouvons créer des fenêtres qui sont la représentation graphique pour l'utilisateur et permettent d'interagir avec l'utilisateur. Le contenu de la fenêtre est appelé "Main Widget", signifiant que tous les éléments graphiques sont basés sur la classe `
QWidget` et peuvent être de n'importe quel type de widget correspondant aux besoins de l'application pour interagir avec l'utilisateur. Aussi, tous les éléments utilisateur doivent hériter de `
QWidget` pour être visibles.

#### Interaction avec l'Utilisateur

Après avoir lu les dernières sections, vous devriez déjà savoir :

- ce que fournit la bibliothèque Qt
  en termes d'applications graphiques

- comment un programme utilisant Qt
  est créé

- où et comment chercher des informations, avec le navigateur de documentation, sur les classes que vous voulez utiliser.

Maintenant, nous allons commencer à donner de la "vie" à l'application en traitant les événements utilisateur. Généralement, l'utilisateur a deux façons d'interagir avec un programme : la souris et le clavier. Pour tous les deux, une interface graphique utilisateur doit fournir des méthodes qui détectent les actions et des méthodes qui font quelque chose en réaction à ces actions.

Pour cela, le système de fenêtrage (NdT : Window system) envoie tous les événements d'interaction à l'application correspondante. La
QApplication les envoie ensuite à la fenêtre active sous la forme d'un `
QEvent` et les widgets eux-mêmes doivent décider ce qu'ils veulent en faire. Un widget reçoit l'événement et traite `
QWidget`::`event(
QEvent*)`, qui décide ensuite quel événement doit être exécuté et comment réagir ; event() est donc le gestionnaire d'événement principal. Ensuite, la fonction `event()` passe l'événement à des filtres d'événements qui déterminent ce qui s'est passé et quoi faire avec l'événement. Si aucun filtre n'est responsable de l'événement, les gestionnaires d'événements spécialisés sont appelés. Nous pouvons alors décider entre :

a) Événements clavier -- touches TAB et Shift-TAB :

change le focus d'entrée du clavier du widget courant vers le widget suivant dans l'ordre du focus. Le focus peut être défini en appelant `setFocusPolicy
()` et traitant les gestionnaires d'événements :

- `virtual void focusInEvent
  (
  QFocusEvent * )`

- `virtual void focusOutEvent
  (
  QFocusEvent * )`

b) toutes les autres entrées du clavier :

- `virtual void keyPressEvent
  (
  QKeyEvent * )`

- `virtual void keyReleaseEvent
  (
  QKeyEvent * )`

c) mouvements de la souris :

- `virtual void mouseMoveEvent (
  QMouseEvent * )`

- `virtual void enterEvent (
  QEvent * )`

- `virtual void leaveEvent (
  QEvent * )`

d) actions des boutons de la souris :

- `virtual void mousePressEvent (
  QMouseEvent * )`

- `virtual void mouseReleaseEvent (
  QMouseEvent * )`

- `virtual void mouseDoubleClickEvent (
  QMouseEvent * )`

e) événements de la fenêtre contenant le widget :

- `virtual void moveEvent (
  QMoveEvent * )`

- `virtual void resizeEvent (
  QResizeEvent * )`

- `virtual void closeEvent (
  QCloseEvent * )`

Remarquez que toutes les fonctions d'événements sont virtuelles et protégées ; ainsi, vous pouvez ré-implanter les événements dont vous avez besoin dans vos propres widgets et spécifier comment votre widget doit réagir. `
QWidget` contient aussi d'autres méthodes virtuelles qui peuvent être utiles dans vos programmes ; en règle générale, il est suffisant de bien connaître `
QWidget`.

#### Interaction entre Objets par Signal et Slot

Nous arrivons maintenant à l'avantage le plus évident de la boîte à outils Qt
: le mécanisme signal/slot. Il offre une solution très pratique et utile pour l'interaction entre objets, qui est souvent réalisée par des fonctions `callback` par les boîtes à outils pour X-Window. Comme cette communication nécessite une programmation stricte et rend parfois la création d'interfaces utilisateur très difficile (comme indiqué par la documentation de Qt
et expliqué dans Programmer avec Qt
par K.& ;Dalheimer), Troll Tech a inventé un nouveau système où les objets peuvent émettre des signaux qui sont connectés à des méthodes déclarées comme des slots. Du point de vue du programmeur C++, celui-ci a seulement peu de choses à savoir sur le mécanisme :

1. la déclaration d'une classe utilisant des "signaux/slots" doit contenir la macro `Q&&lowbar;;OBJECT` au début (sans le point-virgule) et doit dériver de la classe `QObject`

2. un signal peut être émis par le mot-clé `emit`, exemple `emit signal(parameters);` de l'intérieur de n'importe quelle fonction membre d'une classe qui autorise les signaux/slots

3. tous les signaux utilisés par les classes qui ne sont pas héritées doivent être ajoutés dans la déclaration de la classe par une section `signals:`

4. toutes les méthodes qui peuvent être connectées à un signal sont déclarées dans des sections avec le mot-clé supplémentaire `slot`, exemple : `public slots:` dans la déclaration de la classe

5. le compilateur de méta-objet `moc` doit être exécuté sur le fichier d'en-tête pour traiter les macros et produire l'implantation (mais le savoir n'est pas vraiment nécessaire). Les fichiers générés par `moc` sont ensuite compilés par le compilateur C++.

Une autre façon d'utiliser les signaux sans hériter de `QObject` est d'utiliser la classe `QSignal` - voir le manuel de référence pour plus d'informations et un exemple d'utilisation. Dans la suite, nous dériverons toujours de `QObject`.

De cette façon, votre classe est capable d'envoyer des signaux n'importe où et de fournir des "slots" qui seront connectés à des signaux. Quand vous utilisez des signaux, vous n'avez pas à vous soucier de qui les reçoit - vous émettez juste le signal et quelque soit le slot que vous y avez connecté, il peut réagir à l'émission. Par ailleurs, les slots peuvent aussi être utilisés comme des méthodes normales pendant l'implantation.

Maintenant, pour connecter un signal à un slot, vous devez utiliser les méthodes `connect()` qui sont fournies par `QObject` ou, lorsque c'est possible, des méthodes spéciales que des objets fournissent pour définir la connexion pour un certain signal.

##### Exemple d'utilisation

Pour expliquer la façon de définir une interaction entre objets, nous allons reprendre notre premier exemple et l'étendre avec une connexion simple :

    #include <qapplication.h>
    #include <qpushbutton.h>

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

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

    a.setMainWidget( &&;hello );

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

    hello.show();
    return a.exec();
    }

Vous voyez, le seul ajout pour donner plus d'interaction au bouton est d'utiliser une méthode `connect()` : `connect(&&;hello, SIGNAL( clicked() ), &&;a, SLOT( quit() ));` et c'est tout ce que vous devez ajouter. Qu'est-ce que cela signifie réellement& ;? La déclaration de la classe `QObject` décrit ainsi la méthode `connect()` :

`bool connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * member )`

Cela signifie que vous devez donner un pointeur sur une instance de QObject qui est l'émetteur du signal, ce qui veut dire qu'il peut émettre ce signal comme premier paramètre. Ensuite, vous devez spécifier le signal auquel vous voulez vous connecter. Les deux derniers paramètres sont l'objet receveur qui fournit un slot, suivi de la fonction membre qui, en fait, est le slot qui sera exécuté lors de l'émission du signal.

En utilisant des signaux et des slots, les objets de votre programme peuvent interagir facilement les uns avec les autres sans dépendre explicitement du type de l'objet receveur. Vous en apprendrez plus sur l'utilisation de ce mécanisme pour un usage intensif dans la suite de ce manuel. Plus d'informations sur le mécanisme Signal/Slot peuvent être trouvées dans Le Guide de Référence des Bibliothèques de KDE et dans le Manuel de Référence de Qt
.

### Ce que fournit KDE

#### Les bibliothèques de KDE 1.1.x

Au moment d'écrire ce manuel, et du fait que KDevelop utilise KDE 1.1, je me réferre à l'état des bibliothèques de KDE
dans cette version. Les principales bibliothèques de KDE
que vous allez utiliser pour créer vos propres applications KDE
sont& ;:

- la bibliothèque KDE-Core, contenant toutes les classes qui sont des éléments non visibles et fournit des fonctionnalités que votre application pourrait utiliser

- la bibliothèque KDE-UI, contenant des éléments d'interface utilisateur comme les barres de menus, les barres d'outils
  , etc

- la bibliothèque KFile, contenant les boîtes de dialogue de sélection de fichier.

En plus, pour des applications spécifiques, KDE fournit les bibliothèques suivantes :

- la bibliothèque KHTMLW, contenant un widget complet interprétant du HTML, qui est utilisé dans différents programmes comme KDEHelp
  , KFM ou KDevelop

- la bibliothèque KFM, permettant d'utiliser le gestionnaire de fichiers de KDE à l'intérieur de n'importe quelle application

- la bibliothèque KAB, le KAddressBook. Elle fournit un accès au carnet d'adresses pour des applications telles que les clients de messagerie

- la bibliothèque KSpell, contenant des widgets et des fonctionnalités pour intégrer l'utilisation d'Ispell, le vérificateur d'orthographe, dans des applications comme les éditeurs (utilisée notamment dans l'application KEdit).

Maintenant, nous allons regarder ce qui doit être fait pour convertir notre application Qt
en une application KDE.

#### Exemple d'Application KDE

Dans la suite, vous allez voir qu'écrire une application KDE n'est vraiment pas plus difficile que d'écrire une application Qt
. Pour accéder aux fonctionnalités de KDE, vous devez seulement utiliser quelques classes supplémentaires et c'est presque tout. Comme exemple, nous allons traiter la version modifiée de l'exemple de Qt
utilisé précédemment :

    #include <kapp.h>
    #include <qpushbutton.h>

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

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

    a.setTopWidget( &&;hello );

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

    hello.show();
    return a.exec();
    }

D'abord, vous voyez que nous avons changé `
QApplication` en `
KApplication`. Ensuite, nous avons du changer la méthode `setMainWidget()` précédemment utilisée en `setTopWidget` que `
KApplication` utilise pour définir le widget principal. C'est fini ! Votre première application KDE est prête - vous devez seulement indiquer au compilateur les chemins menant aux fichiers "include" de KDE et à l'éditeur de liens de lier la bibliothèque KDE-Core avec -lkdecore.

Comme vous savez déjà ce que la fonction main() fait généralement et comment une application devient visible et permet les interactions avec l'utilisateur et entre objets, nous allons passer au chapitre suivant où nous réaliserons notre première application avec KDevelop - là, vous pourrez aussi tester tout ce qui a été mentionné précédemment et en voir les effets.

Nous vous conseillons aussi de compléter ce chapitre en approfondissant le manuel de référence de Qt
, et plus spécialement les classes `
QApplication`, `
QWidget` et `QObject`, ainsi que la documentation de la classe `
KApplication` de la bibliothèque KDE-Core. Le manuel de Référence des Bibliothèques de KDE donne aussi une description complète sur l'appel des constructeurs de `
QApplication` et `
KApplication`, y compris le traitement des arguments de la ligne de commande.

## Créer une nouvelle Application

KAppWizard, l'Assistant d'Application KDE, vous aide à commencer à travailler sur de nouveaux projets avec KDevelop. Ainsi, tous vos projets seront d'abord créés par l'assistant ; ensuite, vous pourrez commencer à les construire et à étendre le squelette de code source déjà fourni. KAppWizard vous permet aussi de choisir entre plusieurs types de projets selon les objectifs de votre projet :

- Application KDE Normale : inclut le code source de la structure complète d'une application KDE standard avec le support du modèle Controleur-Document-Vue, une barre de menus, une barre d'outils
  et une barre d'état ainsi qu'un ensemble de documentations standards basées sur SGML
  , des liens KDE et des icônes d'applications. C'est le type d'application généralement utilisé pour un nouveau projet KDE& ;;

- Mini Application KDE : contient la même structure générale que le type d'Application KDE Normale mais avec la différence que le code de l'application ne fournit qu'un widget comme fenêtre& ;;

- Application Qt
  Normale : globalement similaire à une application KDE normale avec la différence que le projet est uniquement basé sur la bibliothèque Qt
  et ne contient aucun support de KDE. C'est utile pour des projets qui doivent être portables pour les plates-formes Windows ou qui ne nécessitent pas les bibliothèques de KDE
  pour l'utilisateur final& ;;

- Application C : uniquement basée sur le compilateur C, elle s'exécute dans une console& ;;

- Application C++ : uniquement basée sur le compilateur C++, elle s'exécute dans une console comme une application C et ne nécessite donc pas X-Window& ;;

- Projet personnalisé : crée un projet vide sans aucun code source. C'est utile pour porter dans KDevelop des projets existant déjà ou pour des projets que vous commencez à partir de rien. Notez que vous devrez gérer vous-même tous les fichiers de construction (NdT : makefiles) et les scripts de configuration (NdT : configure scripts).

Dans ce chapitre, nous allons voir comment KAppWizard peut être appelé et ce qui doit être fait pour générer un projet d'application KDE. Ce sera aussi la première étape de notre tour d'horizon, où nous créerons la version initiale d'un projet d'exemple. Pour tous les types de projets, les étapes sont globalement les mêmes, certaines options pouvant juste être disponibles ou non.

### Appel de KAppWizard et Génération de Projet

#### Lancement de KAppWizard et Première Page

Pour débuter votre première application KDE, ouvrez KDevelop. Sélectionnez ensuite "Nouveau..." dans le menu "Projet". KAppWizard démarre et vous voyez sur la première page une arborescence contenant les types de projets. Quand un type de projet est sélectionné, vous voyez un aperçu de l'apparence qu'aura l'application après le processus de construction. Choisissez le sous-arbre KDE, type Normal. Appuyez ensuite sur le bouton "Suivant" en bas de la première page de l'assistant. Cela vous mènera à la page suivante où vous devrez définir les options générales du projet.

#### La Page des Paramètres de Génération

Pour notre application exemple, nous choisissons `KScribble` comme nom de projet ; vous devez donc le saisir dans le champ "Nom du projet". Sélectionnez ensuite le dossier où vous voulez construire votre projet ; le dossier par défaut est votre dossier utilisateur. Vous pouvez saisir le chemin manuellement ou vous pouvez appuyer sur le bouton à droite pour sélectionner le dossier dans une boîte de dialogue.

Ensuite, vous devez saisir le numéro de version. Pour la première version, définissez le à `0.1`. Il est habituel de numéroter les nouvelles applications qui sont en cours de développement avec un numéro de sortie inférieur à 1, et comme la version initiale contiendra uniquement l'architecture standard, nous appelerons cette version 0.1.

Enfin, ajoutez votre nom dans le champ "Auteur" et votre adresse de courrier électronique. Vous pouvez laisser tels quels (valeurs par défaut) les autres paramètres.

Pour obtenir des informations sur toutes les autres options, vous pouvez faire un clic droit sur les options et vous obtiendrez une fenêtre d'aide rapide décrivant le but de cette option.

Ces options sont :

- générer les sources et les en-têtes : génère le code source de l'application

- Fichiers standards GNU : ajoute une copie de la Licence Publique Générale GNU GPL au projet ainsi que des fichiers standards pour informer l'utilisateur lors de la distribution du paquetage

- Manuel d'utilisation : le manuel d'utilisation en SGML
  , déjà préparé pour votre projet

- Documentation de l'API
  : crée une documentation initiale au format HTML pour l'Interface de Programmation d'Application (NdT : API signifie littéralement Application Programming Interface)

- Fichier lsm : le "Linux Software Map", utilisé par les sites de distribution, il contient une description rapide sur le but du projet et ses prérequis

- Fichier .kdelnk
  : un lien KDE qui installera votre application dans le menu "Applications" du tableau de bord de KDE

- Icône de Programme : une icône qui représente votre projet et peut être utilisée pour créer un lien sur le bureau.

Maintenant, nous allons passer à la page suivante en appuyant à nouveau sur le bouton "Suivant" pour définir le modèle des fichiers d'en-têtes de votre projet.

#### Les modèles des En-têtes et des fichiers Sources

La page de modèle des fichiers d'en-tête vous permet d'ajouter automatiquement, dans vos fichiers d'en-tête, un préambule contenant le nom du fichier, la date de construction, l'année du copyright ainsi que votre nom et votre adresse électronique. Vous n'avez pas à convertir ces parties en majuscule car KAppWizard le fait automatiquement et enregistre le modèle de ce projet pour l'utiliser lors de la création de nouveaux fichiers.

La seconde partie du modèle d'en-tête par défaut contient des informations sur la licence. Par défaut, votre projet est placé sous la Licence Publique Générale GNU GPL qui est aussi incluse dans le paquetage. Cette licence est utilisée pour protéger votre code source contre toute personne qui copierait seulement les sources pour son usage personnel. La Licence Publique Générale, qui vous offre cette licence gratuitement et protège vos droits en tant qu'auteur, est habituelle pour la distribution le logiciels libres. Pour obtenir plus d'informations sur cette licence, vous devriez consulter ultérieurement le fichier COPYING dans le répertoire de base de votre nouveau projet, qui est une copie de la GPL et est déjà distribué avec votre application.

Cependant, vous pouvez choisir une autre licence ou un autre modèle d'en-tête que vous utilisez déjà pour vos projets. Dans ce cas, vous pouvez éditer directement le modèle donné par défaut. Pour cela, le modèle apparaît dans une fenêtre d'édition. Pour effacer la page par défaut, sélectionnez "Nouveau" ; pour utiliser un autre modèle, choisissez "Chargement..." qui vous permet de choisir le fichier de modèle.

Quand vous avez terminé, allez à la page suivante en appuyant sur "Suivant". C'est la page de modèle pour vos fichiers sources, elles est globalement identique à la page de modèle d'en-tête. La seule différence est que ce modèle est utilisé pour vos fichiers d'implantation.

#### Création du Projet

Maintenant que vous avez défini toutes les options de KScribble, sélectionnez "Suivant" et appuyez sur le bouton "Créer" au bas de la fenêtre de l'assistant. Si ce bouton n'est pas disponible, vous n'avez pas défini toutes les options correctement. Pour corriger une erreur, revenez en arrière dans l'assistant en appuyant sur "Précédent".

Ensuite, vous allez voir ce que fait KAppWizard - il copie tous les modèles dans le dossier de votre projet et crée le nouveau projet. Lorsque KAppWizard a terminé, le bouton "Annuler" se change en un bouton "Quitter" pour sortir de l'assistant. Après cette dernière étape, vous avez terminé la création d'un nouveau projet. Ensuite, KDevelop le charge et l'affichage de l'arborescence vous permet de naviguer à travers les fichiers et les classes du projet.

Dans la section suivante, nous discuterons de la construction et de l'exécution de votre première version de KScribble, ainsi que de l'organisation du code source.

### La Première Construction

Après la génération du projet, nous allons d'abord faire un petit tour dans le code source pour avoir une vision globale de la façon dont fonctionne l'architecture de l'application. Cela ne nous fera pas vraiment avancer mais il peut être utile de savoir où effectuer les modifications dans les prochaines étapes. Lorsque vous ouvrez la page LFV (Logical File Viewer) de la vue arborescente, vous voyez des dossiers qui contiennent déjà des fichiers du projet utiles au développeur. Les deux premiers dossiers sont "En-têtes" et "Sources". Évidemment, le dossier En-têtes contient tous les fichiers d'en-tête et le dossier Sources tous les codes sources. Les autres dossiers ne nous intéressent pas pour l'instant, nous y reviendrons plus tard pour voir ce qu'ils contiennent. Les deux dossiers contiennent donc les fichiers suivants :

En-têtes :

- kscribble.h : contient la déclaration de la classe KScribbleApp

- kscribbledoc.h : contient la déclaration de la classe KScribbleDoc

- kscribbleview.h : contient la déclaration de la classe KScribbleView

- resource.h : contient un ensemble de macros pour les identificateurs de menus

Sources :

- kscribble.cpp : contient l'implantation de la classe KScribbleApp

- kscribbledoc.cpp : contient l'implantation de la classe KScribbleDoc

- kscribbleview.cpp : contient l'implantation de la classe KScribbleView

- main.cpp : contient l'implantation de la fonction main().

Avant de rentrer dans les sources, nous allons laisser KDevelop construire et exécuter notre nouvelle application. Pour cela, sélectionnez "Construire" dans le menu "Construire" ou cliquez sur le bouton correspondant de la barre d'outils
. La fenêtre des messages s'ouvre au bas de KDevelop et vous permet de voir ce que `make` fait grâce aux messages qu'il donne :

    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'

Comme vous le constatez, nous avons mis des numéros au début de chaque ligne qui n'apparaissent pas dans les messages ; c'est juste pour simplifier la description de ce qui s'est passé pendant la construction. D'abord, `make` travaille récursivement. Cela signifie qu'il débute dans le dossier où il a été appelé, entre d'abord dans les sous-dossiers, retourne et traite le dossier suivant. À la fin, le dossier où il a été lancé est traité et `make` termine. C'est pourquoi `make` est lancé dans le dossier principal du projet qui contient les sources. Aux lignes 1 et 2, vous voyez que le processus `make` entre dans le dossier `docs`, puis dans le sous-dossier `en`. Comme il n'y a rien à faire, il quitte ces dossiers jusqu'à revenir au répertoire source `kscribble` à la ligne 11. Ensuite, le vrai travail commence : `make` appele le compilateur, ici `g++`, pour compiler le fichier source `kscribbleview.cpp`. La macro `-DHAVE&&lowbar;;CONFIG&&lowbar;;H` indique que le fichier `config.h` doit être utilisé. Ce fichier, qui contient des macros spécifiques à chaque plate-forme et à l'application, est situé dans le dossier principal du projet. Les commandes `-I` qui suivent ajoutent un chemin vers des fichiers d'inclusion (NdT : appelés aussi "includes") où `g++` pourra trouver les "includes" dont il a besoin. Ces chemins sont le dossier courant, le dossier principal du projet (avec `-I..`) et le chemin des includes pour les fichiers d'en-tête de KDE, Qt
et X11. Les dossiers de ces fichiers d'includes sont déterminés par le script `configure` et définis dans les Makefiles, c'est pourquoi le compilateur sait où ils sont situés. Enfin, `-O0` définit l'optimisation à zéro (aucune optimisation), `-g` active le déboguage, `-Wall` définit les avertissements du compilateur à `all` et `-c` dit au compilateur de produire un fichier objet intermédiaire, c'est-à-dire seulement compiler le fichier.

Cela est aussi fait pour les autres fichiers sources de notre projet aux lignes 13-15. Évidemment, nos sources sont compilées mais au lieu de lier (NdT : opération réalisée par l'éditeur de liens) les fichiers objets intermédiaires des sources pour en faire un exécutable, nous voyons d'autres commandes. À la ligne 16, vous voyez que le programe "moc" est appelé pour traiter le fichier d'en-tête `kscribble.h` qui génère le fichier `kscribble.moc.cpp`. Ensuite, à la ligne 17, le fichier source est aussi compilé. La même chose se passe pour les autres fichiers d'en-tête du projet jusqu'à la ligne 21. En fait, comme la boîte à outils Qt
contient le mécanisme signal/slot mais reste une implantation C++, vous utilisez des mots-clés comme les déclarations `signals:` et `slots:` dans vos classes qui ne sont pas, à l'origine, dans le langage C++. Cela vous permet de faire facilement communiquer les objets qui héritent de la classe `QObject`, évitant ainsi l'utilisation des traditionnels pointeurs sur les fonctions de callback. Aussi, l'application nécessite les sources qui implantent cette fonctionnalité et c'est pour cela que `moc` est appelé. Moc est le Compilateur de Méta Objet (NdT : Moc signifie littéralement Meta Object Compiler) de la boîte à outils Qt
et construit l'implantation des mécanismes de signal et de slot en analysant le fichier d'en-tête et en générant un fichier source qui doit être compilé dans le binaire. Comme KDevelop utilise `automoc` pour déterminer quels fichiers doivent être traités, vous n'avez pas besoin de vous préoccuper des appels à `moc` et au compilateur C++ pour les fichiers générés par moc. Souvenez-vous seulement des règles qui permettent à une classe d'utiliser le mécanisme de signal et de slot de `QObject` ou toute classe qui hérite de `QObject` elle-même, vous devez aussi inclure la macro `Q&&lowbar;;OBJECT` (sans point-vigule& ;!) au début de la déclaration de la classe et la déclaration des signaux et des slots.

Enfin, votre binaire est construit par le compilateur. Le binaire généré est appelé `kscribble`, l'éditeur de liens inclut le chemin vers KDE et vers les bibliothèques de X11 et lie les sources avec les bibliothèques `kfile, kfm, kdeui, kdecore, qt, Xext` et `X11`. Ensuite, c'est terminé et make se termine.

### Le Squelette des Sources

Pour décrire le concept de fonctionnement d'une application KDE, nous allons d'abord regarder précisément le squelette de sources déjà fourni par l'Assistant d'Application. Comme nous l'avons déjà vu, nous avons un ensemble de sources et de fichiers d'en-tête qui constituent le code initial de l'application et la rendent prête à être exécutée. De ce fait, la plus simple façon d'expliquer le code est de suivre l'implantation ligne par ligne, comme il est traité durant l'exécution du programme jusqu'à ce qu'il entre dans la boucle d'événements principale et soit prêt à accepter les entrées de l'utilisateur. Ensuite, nous regarderons les fonctionnalités qui permettent les interactions avec l'utilisateur et comment certaines choses fonctionnent. C'est probablement la meilleure façon d'expliquer l'architecture et comme elle est similaire pour presque toutes les applications KDE
, cela vous permettra de lire plus facilement le code source d'autres projets. En plus, vous apprendrez quoi et où changer dans le code pour faire en sorte que vos applications se comportent comme prévu.

#### La fonction `main()`

Comme l'application commence son exécution en entrant dans la fonction `main()`, ce sera aussi notre point de départ pour examiner le code. La fonction `main()` de KScribble est implantée dans le fichier `main.cpp` et peut également être trouvée grâce au Navigateur de Classe en sélectionnant le sous-dossier "Fonctions" du dossier "Globaux" :

    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->show();
    14   if(argc > 1){
    15        kscribble->openFile(argv[1]);
    16      }
    17    }
    18    return app.exec();
    19  }

La première chose qui se passe généralement est la création d'un objet `
KApplication` qui reçoit le nom de notre application KScribble comme troisième paramètre. Lors de la création d'une nouvelle `
KApplication`, une nouvelle instance de `
KConfig` est également créée, permettant d'accéder au fichier de configuration $HOME/.kde/share/config/appname + rc qui contient toutes les informations que nous voulons utiliser lors du lancement des fenêtres de l'application. Le nom passé au constructeur de `app` sera utilisé plus tard comme titre de la fenêtre. Ici, le code est un petit peu différent du code d'exemple donné précédemment pour convertir une application Qt
en une application KDE. Une fois que l'objet `
KApplication` est présent, nous testons si l'application est démarrée par le gestionnaire de sessions de `kwm` ou manuellement par l'utilisateur. Cela est déterminé en appelant `isRestored()` sur l'objet `app` qui retourne `true` pour la gestion de sessions et `false` pour un lancement manuel. Comme la gestion des sessions est une fonctionnalité importante des applications KDE
et largement utilisée par l'architecture mais plus longue à expliquer, nous allons d'abord continuer par la section `else&&lcub;;&&rcub;;` ; ensuite, nous y reviendrons et expliquerons la fonctionnalité de gestion des sessions dans une étape ultérieure.

#### Lancement de l'Application par l'Utilisateur

La section `else&&lcub;;&&rcub;;` crée maintenant une instance de la classe `KScribbleApp` à la ligne 12. Cet objet est appelé pour s'afficher à la ligne 13, comme d'habitude ; la ligne 14 détermine si un argument a été passé à la ligne de commande et, comme c'est souvent le nom d'un fichier, appelle l'objet `kscribble` pour l'ouvrir avec `openFile()`. Remarquez que nous n'avons pas appelé la méthode `setTopWidget(kscribble)` pour notre application - c'est déjà fait par la classe dont hérite `KScribbleApp`. Maintenant, nous allons regarder notre objet `KScribbleApp` - qu'est-ce que c'est et que fournit-il déjà ? La seule chose que nous savons jusqu'à maintenant, c'est que ça doit être un Widget pour représenter l'interface utilisateur dans la fenêtre pricipale. Allons dans l'implantation de la classe `KScribbleApp` qui se trouve dans le fichier `kscribble.cpp` ou par un clic sur l'icône de classe dans le Navigateur de Classe. L'instance est créée par le constructeur. D'abord, nous voyons qu'elle hérite de la classe `
KTMainWindow` qui fait partie de la bibliothèque `kdeui`. Cette classe hérite elle-même de `
QWidget` donc, comme d'habitude, nous avons un widget normal comme fenêtre de plus haut niveau (NdT : top-level window). `
KTMainWindow` contient beaucoup de fonctionnalités qui sont utilisées par la classe `KScribbleApp`. Elle fournit une barre de menus, une barre d'outils
, une barre d'état et le support de la gestion de sessions. La seule chose que nous ayons à faire en dérivant de `
KTMainWindow` est de créer tous les objets dont nous avons besoin et de créer un autre widget qui sera géré par notre instance de `
KTMainWindow` comme vue principale au centre de la fenêtre ; habituellement, c'est ici que l'utilisateur travaille comme une vue d'édition de texte.

##### Le Constructeur

Regardons le code du constructeur et voyons comment l'instance est créée :

    1   KScribbleApp::KScribbleApp()
    2   {
    3     config=kapp->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    }

Nous voyons que notre instance de `
KConfig` pointe maintenant vers la configuration de l'application donc nous pourrons travailler avec les entrées du fichier de configuration ultérieurement. Ensuite, tous les composants requis par l'application sont créés par les fonctions membres correspondantes, spécifiquement à notre fenêtre principale :

- initMenuBar() : construit la barre de menus

- initToolBar() : construit la barre d'outils

- initStatusBar() : crée la barre d'état

- initKeyAccel() : définit tous les accélérateurs clavier
  pour notre application avec les configurations du clavier globale et spécifique à l'application

- initDocument() : crée l'objet document pour la fenêtre de l'application

- initView() : crée le widget principal pour notre vue dans la fenêtre principale

- readOptions() : lit tous les paramètres spécifiques à l'application dans le fichier de configuration et initialise le reste de l'application, comme la liste des fichiers récemment ouverts, la position des barres et la taille de la fenêtre.

Enfin, nous désactivons certaines commandes que l'utilisateur peut activer car elles ne doivent pas être disponibles dans l'état courant de l'application. Comme nous avons maintenant un aperçu global de la façon dont est créée la fenêtre de l'application, nous allons regarder en détail comment les éléments de l'interface utilisateur sont construits par les méthodes ci-dessus.

##### La Barre de Menus

Comme nous l'avons vu au-dessus, la barre de menus de KScribble est créée par la méthode `initMenuBar()`. En fait, nous créons un ensemble de `
QPopupMenu`s qui apparaissent si l'utilisateur sélectionne une entrée de menu. Ensuite, nous les insérons dans la barre de menus et nous les connectons aux entrées.

D'abord, nous créons notre `recent&&lowbar;;file&&lowbar;;menu` qui contiendra les noms des 5 derniers fichiers ouverts. Nous devons le faire en premier car ce menu est inséré dans le `file&&lowbar;;menu`. Ensuite, nous ajoutons directement la connexion - nous récupérons juste le signal qui est émis par l'entrée de menu avec son numéro d'entrée et appelons `slotFileOpenRecent( int )`, qui ouvre ensuite le bon fichier de la liste des fichiers récemment ouverts.

Ensuite, nous créons notre menu "Fichier". C'est le menu qui sera visible dans la barre de menus. Les actions standards sont ensuite insérées une par une dans le menu popup - d'abord, les commandes pour créer un nouveau fichier, ouvrir un fichier, fermer un fichier... et enfin "E&&;xit" pour fermer l'application. Toutes les entrées de menu doivent être créées dans l'ordre dans lequel elles apparaîtront ensuite donc nous devons rester vigilants sur ce que nous voulons mettre et à quelle place. À titre d'exemple, regardons les entrées suivantes& ;:

    file_menu->insertItem(Icon("fileopen.xpm"), i18n("&&;Open..."), ID_FILE_OPEN );
    file_menu->insertItem(i18n("Open &&;recent"), recent_files_menu, ID_FILE_OPEN_RECENT );

La première ligne insère une entrée "Open...". Comme nous voulons qu'elle ait une icône, nous utilisons la méthode `insertItem()` avec le nom de l'icône. Pour comprendre le processus de chargement d'icône, nous devons savoir comment et où est déclaré `Icon()` - en fait, c'est une macro fournie par la classe `
KApplication` :

    #define Icon(x) kapp->getIconLoader()->loadIcon(x)

Elle utilise, d'ailleurs, la macro interne suivante pour accéder à l'objet application :

    #define kapp KApplication::getKApplication()

Cela signifie que l'objet `
KApplication` contient déjà une instance du chargeur d'icône - nous devons seulement y accéder ; ensuite, il chargera l'icône correpondante. Comme nos icônes viennent toutes des bibliothèques de KDE
, nous n'avons pas à nous préoccuper de quoi que ce soit d'autre - elles sont installées automatiquement sur le système et nous n'avons donc pas besoin de les inclure dans le paquetage de notre application pour pouvoir les utiliser.

Après le paramètre d'icône (qui est optionnel), nous insérons le nom de l'entrée de menu par `i18n("&&;Open...")`. Là, nous devons signaler deux choses : premièrement, l'entrée est insérée avec la méthode `i18n()`. Comme pour `Icon()`, c'est aussi une macro définie dans `
kapp.h` et appelle l'objet `KLocale` de `
KApplication` pour traduire l'entrée dans la langue utilisée actuellement :

    #define i18n(X) KApplication::getKApplication()->getLocale()->translate(X)

Il faut signaler que quelqu'un pourrait penser "Je ne veux pas utiliser de macros" - vous pouvez le faire dans la plupart des cas. Mais ici, il est nécessaire d'utiliser `i18n()` car pour l'internationalisation, les fichiers de traduction correspondants doivent être générés. Comme ce processus de génération repose sur l'utilisation de la chaîne de caractères `i18n`, vous devez utiliser cette macro.

Comme vous l'avez peut-être déjà deviné, le symbole &&; (et commercial) dans les entrées de menu est interprété ultérieurement comme une petite ligne sous la lettre correspondante dans l'entrée de menu. Cela permet un accès rapide à la commande du menu via le clavier quand l'utilisateur appuie simultanément sur la touche `Alt` et la lettre soulignée.

Enfin, nous donnons à l'entrée de menu un identificateur (NdT : ID) qui est une valeur entière par laquelle nous pourrons trouver l'entrée ultérieurement. Pour garder un oeil sur les valeurs utilisées, celles-ci sont définies par des macros et sont regroupées dans le fichier `resource.h` de votre projet. Par souci de cohérence, ces macros sont écrites en majuscules, commencent par ID&&lowbar;; et sont suivies du nom du menu et de celui de l'entrée. Cela aide énormément à se remémorer le sens de chaque entrée n'importe où dans le code ; il n'est donc plus nécessaire d'aller systématiquement dans l'implantation de la barre de menus pour chercher les entrées.

Le deuxième exemple d'entrée montre une autre variante de la méthode `insertItem()`. Ici, nous ajoutons le menu popup recent&&lowbar;;files&&lowbar;;menu comme un élément de menu. Cela signifie que l'entrée s'affiche elle-même avec la chaîne donnée "Open recent", suivie par une flèche vers la droite. Lors d'une sélection, le menu popup des fichiers récemment ouverts apparaît et l'utilisateur peut choisir un des derniers fichiers.

Enfin, il y a beaucoup d'autres manières d'insérer des éléments de menu - l'architecture rend cela aussi simple que possible. Plus d'informations sur la classe `
QMenuData` peuvent être trouvées dans la documentation de Qt
.

Maintenant, après avoir créé les menus popup `file&&lowbar;;menu, edit&&lowbar;;menu` et `view&&lowbar;;menu`, nous devons insérer aussi un menu "Aide". Nous pourrions le faire comme pour les autres menus mais la classe `
KApplication` fournit une méthode simple et rapide pour le faire :

    help_menu = kapp->getHelpMenu(true, i18n("KScribble\n" VERSION ));

C'est tout ce que nous avons à faire pour obtenir un menu d'aide qui contient une entrée pour le contenu de l'aide accessible avec le raccourci clavier
F1, une boîte de dialogue "À propos" pour l'application et une boîte de dialogue "À propos" pour KDE (qui peut être désactivée en appelant `getHelpMenu(false,...);`). Le contenu de la boîte de dialogue "À propos" de notre application est à nouveau défini avec la chaîne `i18n()` - VERSION prend la macro qui est définie dans le fichier `config.h` pour le numéro de version du projet donc nous n'avons pas besoin de le changer manuellement à chaque fois que nous voulons diffuser une nouvelle version. N'hésitez pas à ajouter ici des informations sur votre application, par exemple votre nom, votre adresse électronique, le copyright, etc.

Maintenant, nous n'avons plus qu'à insérer les popups dans la barre de menus. Comme `
KTMainWindow` construit déjà une barre de menus pour nous, il suffit de les insérer en appelant `menuBar()->insertItem();`.

Ce qu'il reste à faire est de connecter les entrées de menu avec les méthodes qu'elles exécuteront. C'est pourquoi, nous connectons chaque menu popup par son signal `activated(& ;int& ;)` à une méthode `commandCallback(& ;int& ;)` qui contient un `switch` qui appelle les méthodes correspondantes pour les entrées de menu. En plus, nous connectons le signal `highlighted(& ;int& ;)` des popups pour fournir de l'aide sur chaque entrée dans la barre d'état. Lorsque l'utilisateur déplace sa souris ou le focus du clavier
sur une entrée, la barre d'état affiche alors le message d'aide correspondant.

Après avoir terminé avec la barre de menus, nous pouvons passer à la barre d'outils
dans la section suivante. Remarquez qu'une instance de `
KTMainWindow` peut avoir seulement une seule barre de menus visible à la fois ; c'est pourquoi, si vous voulez construire plusieurs barres de menus, vous devez les créer séparément avec des instances de `
KMenuBar` et définir l'une d'elles comme la barre de menus courante avec la méthode appropriée de `
KTMainWindow`. Consultez la documentation de la classe
`
KMenuBar` pour plus de détails sur ses fonctionnalités étendues, voir aussi Configuration des Barres de Menus et des Barres d'Outils.

##### La Barre d'Outils

La création de barres d'outils
est bien plus simple que pour les barres de menus. Comme `
KTMainWindow` fournit déjà des barres d'outils
qui sont créées dès leur première insertion, vous êtes libre d'en créer plusieurs. Ajoutez juste les boutons pour les fonctions que vous voulez fournir :

    toolBar()->insertButton(Icon("filenew.xpm"), ID_FILE_NEW, true, i18n("New File") );

Ceci ajoute un bouton aligné à gauche avec l'icône "filenew.xpm" et l'identificateur (NdT : ID) correspondant dans la barre d'outils
. Le troisième paramètre décide si le bouton doit être activé ou non ; par défaut, nous le définissons à `true` car nos méthodes `disableCommand()` à la fin du constructeur le font automatiquement pour nous, à la fois pour les entrées du menu et de la barre d'outils
. Enfin, le dernier paramètre est utilisé pour la "bulle d'aide" - quand l'utilisateur place le pointeur de la souris sur le bouton pour le mettre en surbrillance, une petite fenêtre, qui contient un court message d'aide dont le contenu est défini ici, apparaît. Enfin, les boutons de la barre d'outils
sont connectés à notre méthode `commandCallback()` par leur signal `clicked()`. Lors du signal `pressed()`, nous permettons à l'utilisateur de recevoir le message d'aide correspondant dans la barre d'état.

Informations supplémentaires :

Comme les barres d'outils
sont créées en utilisant la classe `
KToolBar`, vous devriez consulter la documentation correspondante. Avec `
KToolBar`, beaucoup de choses nécessaires pour une barre d'outils
peuvent être réalisées, comme un popup retardé si votre bouton veut afficher un menu quand le bouton reste enfoncé ou même l'utilisation d'autres widgets comme par exemple une liste déroulante. Par défaut, la barre d'outils
remplit complètement la largeur de la fenêtre ce qui est sympathique pour l'utilisation d'une seule barre. Lorsque vous en avez plus d'une, vous devriez penser à définir la taille de la barre à l'extrémité du bouton le plus à droite, ainsi les autres barres peuvent s'afficher dans la même ligne, sous la barre de menus. Nous évoquerons certaines techniques de conception et d'extension des barres d'outils
dans la section Configuration des Barres de Menus et des Barres d'Outils.

##### La Barre d'État

La barre d'état est, comme les autres barres, déjà fournie par l'instance de `
KTMainWindow` donc nous avons juste à insérer nos éléments dedans comme nous le souhaitons. Par défaut, l'architecture contient seulement une entrée qui affiche l'aide de la barre d'état. Pour beaucoup d'applications, ce n'est pas suffisant, vous pourrez donc ajouter les entrées dont vous avez besoin pour afficher, par exemple, des coordonnées ou autre chose.

De plus, une application ne peut avoir qu'une seule barre d'état, comme pour la barre de menus. Si vous voulez en construire plusieurs, vous devrez les créer séparément et définir la barre courante avec la méthode appropriée de `
KTMainWindow`. La barre d'état permet aussi d'insérer des widgets qui peuvent être utilisés pour créer des zones pour afficher des barres de progression, comme KDevelop le fait. Référez-vous à la documentation de la classe
`KStatusBar`.

##### Raccourcis Clavier

Une fois rendu à la méthode `initKeyAccel()`, nous avons déjà construit les éléments standards de la fenêtre principale d'une application - la barre de menus, la barre d'outils
et la barre d'état.

Cependant, nous n'avons pas encore défini les raccourcis clavier
par lesquels l'utilisateur expérimenté qui veut uniquement travailler avec son clavier peut accéder rapidement aux commandes qui sont le plus souvent utilisées pendant une session de travail de notre programme. Pour cela, nous aurions pu insérer les touches de raccourci
, par exemple, lors de l'insertion des éléments du menu mais KDE offre une bonne solution pour construire et maintenir les raccourcis clavier
. Beaucoup d'utilisateurs veulent d'un côté qu'ils soient configurables et d'un autre côté les raccourcis
standards doivent être les mêmes pour toutes les applications. C'est pourquoi, le Centre de Contrôle de KDE permet de configurer les raccourcis
clavier standards en utilisant la classe `
KAccel`. En plus, les bibliothèques de KDE
contiennent un widget qui permet aux utilisateurs de configurer facilement les raccourcis
clavier spécifiques à l'application. Comme l'architecture d'application utilise seulement des éléments de menus qui sont des actions standards comme "Nouveau" ou "Quitter", celles-ci sont définies par la méthode `initKeyAccel()`. Les actions standards doivent juste être connectées, pour la configuration du clavier spécifique à votre application, vous devez les insérer d'abord en spécifiant le nom du raccourci
clavier et ensuite les connecter. Comme nos raccourcis
sont tous présents dans la barre de menus, nous devons changer le raccourci
pour les entrées du popup. Enfin, nous appelons `readSettings()` qui lit la configuration courante depuis la fenêtre du bureau de KDE (NdT : KDE rootwindow) où est stockée la configuration des raccourcis
standards, puis les paramètres des raccourcis
spécifié dans le fichier de configuration de l'application. Quand nous aurons progressé dans notre projet d'exemple, nous vous dirons aussi comment modifier avec une boîte de dialogue de configuration les raccourcis
spécifiques à notre application, voir Configuration des Barres de Menus et des Barres d'Outils pour cette partie du processus de développement.

##### Le Modèle Document-Vue

Les deux appels de fonctions membres suivants, `initDocument()` et `initView()`, permettent enfin de construire la partie que les fenêtres de l'application sont supposées fournir à l'utilisateur : une interface pour travailler avec les données que l'application est sensée manipuler ; et c'est aussi la raison pour laquelle l'architecture d'application contient trois classes `*App`, `*View` et `*Doc`. Pour comprendre pourquoi cette structure est utile, nous allons regarder un peu au-delà du code actuel et introduire un peu de théorie, ensuite nous reviendrons au programme pour voir comment l'architecture de KDevelop supporte ce modèle.

Typiquement, tout ce qui a été expliqué sur cette architecture est que nous avons besoin d'une instance de l'application qui contient une fenêtre principale. Cette fenêtre est chargée de fournir l'interface basique pour l'utilisateur - elle contient la barre de menus, les barres d'outils
, la barre d'état et le contrôleur d'événements pour les interactions avec l'utilisateur. En plus, elle contient la zone qui est appelée la "Vue". Le but d'une vue est généralement d'afficher les données que l'utilisateur peut manipuler, par exemple un morceau de fichier texte. Cependant, le fichier texte, bien que probablement plus grand que la vue, est capable de s'afficher à l'écran, il permet à l'utilisateur d'aller dans la partie qu'il veut voir (c'est pourquoi c'est une vue) et l'utilisateur peut alors changer les données du contenu du fichier. Pour donner au programmeur une meilleure façon de séparer les parties du code de l'application, le Modèle Document-Vue a été inventé. Bien que n'étant pas un standard, il fournit la structure de fonctionnement d'une application :

- un objet Contrôleur contenu par l'application

- un objet Vue qui affiche les données avec lesquelles l'utilisateur veut travailler

- un objet Document qui contient réellement les données qui sont manipulées.

Revenons à notre exemple de travail avec un fichier texte - là, le modèle s'applique de la façon suivante : le Document lit le contenu du fichier et fournit des méthodes aussi bien pour modifier les données que pour enregistrer à nouveau le fichier. La Vue, elle, traite les événements que l'utilisateur produit avec le clavier et la souris et utilise les méthodes de l'objet document pour manipuler les données du document.

Enfin, l'objet contrôleur est responsable de l'interaction avec l'utilisateur en fournissant les objets document et vue, ainsi que les interfaces pour envoyer des commandes comme l'ouverture et l'enregistrement. En plus, certaines méthodes de l'objet vue peuvent être fournies par des commandes accessibles par des accélérateurs
clavier ou la souris sur les barres de menus et les barres d'outils
.

Le modèle Document-Vue a des avantages - il sépare le code du programme à la mode "orientée objet" et par là offre plus de flexibilité ; par exemple, le même objet document peut être affiché simultanément par deux vues, soit avec une nouvelle vue dans une nouvelle fenêtre, soit en séparant la fenêtre courante qui contient alors deux objets vue qui forment la zone de vue de la fenêtre.

Si vous êtes issu des systèmes MS-Windows, vous devez être familier avec tout cela - les MFC fournissent déjà un modèle de document prêt à être utilisé. Pour les applications KDE et Qt
, les choses sont un peu différentes. Qt
est une boîte à outils puissante car elle fournit la majorité des classes, widgets, etc nécessaires. Mais, il n'y a eu aucune intention de gérer le modèle document-vue et comme KDE hérite de Qt
, ce modèle n'a pas été non plus introduit. En fait, cela s'explique aussi par le fait que les applications X ne travaillent généralement pas en MDI (Multiple Document Interface). Chaque fenêtre principale est responsable de ses propres données et cela réduit le besoin d'un modèle de document au fait que les méthodes pour travailler sur le document sont toujours écrites dans les widgets. Actuellement, la seule exception est le projet KOffice qui fournit une suite de bureautique complète comprenant un traitement de texte, un tableur, etc. Techniquement, cela est réalisé par deux changements dans l'utilisation normale de Qt
et KDE :

- KOffice utilise KOM et différents mécanismes pour la communication entre objets

- les applications KOffice utilisent un modèle document-vue qui permet à toutes les applications de travailler avec n'importe quelles données de KOffice.

Mais, comme l'objectif de KDevelop est d'utiliser les bibliothèques actuelles de KDE 1.1.x et Qt
1.4x, nous ne pouvons pas utiliser ce modèle par défaut - cela apparaîtra dans les prochaines versions de KDE 2 qui contiendra (probablement) deux changements majeurs par rapport à la situation actuelle :

1. une interface MDI pour
   KTMainWindow

2. les bibliothèques KOM qui fournissent un modèle de document.

C'est pourquoi, pour l'instant, la façon de travailler des développeurs d'applications est soit d'implanter toutes les méthodes de documents dans leur vue, soit d'essayer de reproduire eux-mêmes un modèle de document. KDevelop souscrit à cette tentative en fournissant les classes requises et les méthodes de base qui sont généralement utilisées pour un modèle Document-Vue avec les architectures d'application de Qt
et KDE.

Revenons au code, vous pouvez maintenant imaginer le but des deux méthodes que nous avons mentionnées au début de cette section : les fonctions `initDocument()` et `initView()`. `initDocument()` construit l'objet document qui représente les données de la fenêtre de l'application et initialise les attributs de base comme le bit de modification qui indique si les données utilisées ont été modifiées par l'utilisateur. Ensuite, la méthode `initView()` construit le widget `*View`, le connecte au document et appelle la méthode `setView()` de `
KTMainWindow` pour dire à la fenêtre `*App` d'utiliser le widget `*View` comme vue centrale.

Pour le développeur, il est important de savoir que durant le processus de développement, il doit :

- ré-implanter dans l'objet `*View` les méthodes virtuelles de `
  QWidget` pour les événements du clavier et de la souris afin de pouvoir manipuler les données

- ré-implanter le `paintEvent()` de `
  QWidget` dans l'objet `*View` pour redessiner (Ndt : repaint()) la vue après des modifications

- compléter l'implantation pour l'impression du document via la méthode d'impression de l'objet `*View`

- ajouter la sérialisation pour permettre à l'objet `*Doc` de charger et enregistrer le fichier

- ajouter l'implantation de la structure des données du document à l'objet `*Doc` qui représente logiquement en mémoire les données du document

- ajouter les méthodes auxquelles l'utilisateur peut accéder via des raccourcis
  clavier, des menus ou des barres d'outils
  .

##### Configuration de l'Application

Maintenant, après avoir créé toutes les instances de l'instance de `
KTMainWindow` de notre application pour créer la fenêtre principale, nous devons initialiser certaines valeurs qui influencent l'apparence du programme. Pour cela, nous appelons `readOptions()` qui récupère toutes les valeurs et appelle les méthodes nécessaires pour définir les attributs correspondants. La bibliothèque KDE-Core contient la classe `
KConfig` qui fournit une bonne façon de stocker les valeurs dans des fichiers de configuration et permet aussi de les relire. De plus, comme chaque instance de `
KApplication` crée déjà son fichier de ressources, nous devons seulement accéder à ce fichier et créer nos valeurs. Comme `
KConfig` nous donne l'objet fichier, nous devons utiliser la classe `
KConfigBase` pour lire et écrire toutes les entrées. L'écriture est très facile avec les méthodes `writeEntry()` mais la lecture dépend du type d'attribut que nous voulons initialiser. Généralement, une entrée dans le fichier de configuration contient un nom de valeur et une valeur. Les valeurs qui appartiennent au même contexte peuvent être regroupées dans des groupes, c'est pourquoi nous devons définir le nom du groupe afin d'accéder ensuite à ses valeurs : le groupe doit être défini seulement une seule fois pour lire les attributs qui sont dans le même groupe. Regardons ce que nous voulons lire :

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

Comme nous l'avons vu dans un des morceaux de code précédents, la première action réalisée par notre constructeur était :

    config=kapp->getConfig();

qui positionne le pointeur `config` de type `
KConfig` sur la configuration de l'application. Nous n'avons donc pas besoin de nous préoccuper de l'emplacement de ce fichier de configuration. En fait, ce fichier est, conformément au Système de Fichiers Standard de KDE (KDE FSS) (NdT : KDE FSS signifie KDE File System Standard), situé dans `&&dollar;;HOME/.kde/share/config/` ; nous regarderons plus précisément le KDE FSS dans une autre section quand nous définirons l'emplacement pour l'installation des fichiers du projet. Comme le fichier de configuration est placé dans le répertoire utilisateur (NdT : user's home directory), chaque utilisateur possède sa propre apparence de l'application, excepté les valeurs qui sont situées dans le fichier de configuration global du système qui peut optionnellement être créé et installé par le programmeur dans le dossier de KDE. Mais, bien que cela puisse être utile dans certains cas, nous devrions éviter toute dépendance de l'application envers l'existence d'entrées de fichier. C'est pourquoi toutes les méthodes de lecture fournies par `
KConfigBase` permettent d'ajouter une valeur par défaut à utiliser lorsque l'entrée n'existe pas. Une autre chose importante pour le programmeur est que le fichier de configuration est stocké sous la forme d'un fichier texte, et, pour cette raison, vous devez vous souvenir que :

- l'utilisateur peut changer le fichier de configuration avec un simple éditeur de texte

- si l'utilisateur veut changer les valeurs à la main, les entrées doivent être très explicites pour déterminer leur utilisation

- pour les entrées qui doivent être enregistrées mais qui sont aussi critiques en terme de sécurité comme les mots de passe, vous devez chercher une solution propre pour garantir la sécurité.

Maintenant que nous connaissons les bases, nous allons analyser le code. Comme cela a été dit, nous avons juste à utiliser notre pointeur de configuration pour accéder aux valeurs. D'abord, à la ligne 4, nous définissons le groupe courant à "General Options". Cela indique que les valeurs utilisées sont des attributs relativement globaux pour l'application. Ensuite, nous lisons les valeurs pour la barre d'outils
et la barre d'état - elles doivent être enregistrées lorsque l'application est fermée afin de pouvoir restaurer leur état quand l'utilisateur redémarre le programme. Comme les barres peuvent seulement être actives ou inactives, nous utilisons une valeur booléenne, c'est pourquoi notre méthode est `readBoolEntry()`. Le processus est identique pour les deux barres donc nous considérerons seulement les lignes 7-10 pour regarder ce qui se passe avec la barre d'outils
. D'abord, nous lisons la valeur dans une variable temporaire `bViewToolbar` à la ligne 7. Dans le fichier, le nom de la valeur est "Show Toolbar" et, si la valeur n'est pas présente (ce qui peut être le cas lors du premier démarrage de l'application), la valeur par défaut est définie à `true`. Ensuite, nous positionnons la coche de l'entrée de menu pour (dés)activer la barre d'outils
suivant sa valeur : nous appelons `setItemChecked()` pour le menu de la vue, avec l'entrée `ID&&lowbar;;VIEW&&lowbar;;TOOLBAR` et notre attribut. Enfin, nous faisons en sorte que la barre d'outils
utilise cette valeur. Par défaut, la barre d'outils
est visible donc nous devons faire quelque chose seulement si `bViewToolbar` vaut `false`. Avec `enableToolBar()` (ligne 10), nous forçons la barre à se cacher si elle est désactivée.

Ensuite, nous devons lire la position de la barre. Comme l'utilisateur peut avoir changé la position de la barre en glissant la barre avec la souris vers une autre zone de la vue, ceci doit aussi être enregistré afin de pouvoir restaurer son état. En regardant les classes `
KToolBar` et `
KMenuBar`, nous voyons que la position des barres peut valoir :

    enum BarPosition {Top, Left, Bottom, Right, Floating, Flat}

Comme cette valeur doit être écrite sous forme numérique, nous devons la lire avec `readNumEntry()` et la convertir en une valeur de position. Avec `setMenuBarPos()` et `setBarPos()`, nous disons aux barres de s'afficher.

Vous avez aussi probablement noté que le menu "Fichier" contient un menu pour les fichiers récemment utilisés. Les noms de ces fichiers sont stockés dans une liste de chaînes de caractères qui doit être enregistrée lors de la fermeture de l'application et maintenant, nous devons les lire pour restaurer le menu. D'abord, nous initialisons la liste avec les entrées enregistrées en utilisant `readListEntry()`. Ensuite, dans une boucle `for`, nous créons une entrée de menu pour chaque élément de la liste.

Enfin, nous devons juste prendre en compte la géométrie de notre fenêtre. Nous lisons son apparence avec une variable `QSize` contenant une valeur x et y pour la largeur et la hauteur de la fenêtre. Comme la fenêtre est initialisée par `
KTMainWindow`, nous n'avons pas besoin de nous soucier de la valeur par défaut et nous utiliserons `resize()` seulement si l'entrée n'est pas vide.

Ce qui reste à expliquer dans la construction de l'application est que nous devons initialement désactiver les commandes utilisateur qui ne seraient pas disponibles si certaines instances ne correspondent pas aux critères requis. Ce sont l'enregistrement de fichier et les opérations qui utilisent le presse-papiers. Pendant la vie de l'application, nous devons y faire attention à plusieurs reprises mais cela reste vraiment simple. L'architecture nous donne seulement deux méthodes pour activer/désactiver la barre de menus et les éléments de la barre d'outils
avec un seul appel à la méthode à la fois.

##### Exécution

Au long de la section précédente, nous avons seulement surveillé ce qui se passe pendant l'appel au constructeur de notre instance de `KScribbleApp` qui nous donne la fenêtre principale. Après le retour à la fonction `main()`, nous devons appeler `show()` pour afficher la fenêtre. Ici, ce qui est différent d'une `
KApplication` ou d'une `
QApplication`, c'est que nous utilisons `
KTMainWindow` comme instance de notre widget principal ; nous n'avons pas besoin de le définir avec `setMainWidget()`. Cela est fait par `
KTMainWindow` lui-même et nous n'avons pas besoin de nous en soucier. La seule chose restante est d'interpréter la ligne de commande. Nous lisons la ligne de commande et testons si `int argc` est > 1, ce qui indique que l'utilisateur a lancé notre application avec `kscribble nom&&lowbar;;de&&lowbar;;fichier&&lowbar;;a&&lowbar;;ouvrir`. Notre fenêtre est alors sensée ouvrir le fichier ayant ce nom et appeler `openDocumentFile()` avec le nom du fichier.

La dernière ligne de la fonction `main()` fait le travail attendu : elle exécute l'instance de l'application et le programme entre dans la boucle d'événements.

Dans la section La Fonction main(), nous avons commencé à séparer le processus d'exécution par `if( app.isRestored() )` et décrit le processus de lancement habituel. La suite vous donne maintenant une introduction à la gestion de sessions et comment notre application l'utilise.

#### Lancement par Gestion de Sessions

Comme nous l'avons dit, la fonction `main()` teste si l'application a été lancée par le gestionnaire de sessions. Le gestionnaire de sessions est responsable de l'enregistrement de l'état actuel de toutes les fenêtres ouvertes de l'application sur le bureau de l'utilisateur et doit les restaurer quand l'utilisateur se connecte à nouveau, ce qui signifie que l'application n'est pas lancée par l'utilisateur mais automatiquement exécutée. La partie du code qui est exécutée était :

    6    if (app.isRestored())
    7    {
    8       RESTORE(KScribbleApp);
    9    }

Dans La Fonction main(), nous avons indiqué que nous testons le type de lancement en interrogeant `app.isRestored()`. Ensuite, la ligne 8 est exécutée. Cela ressemble à quelque chose de simple mais, en fait, il en résulte un processus d'exécution complexe que nous allons suivre dans cette section.

RESTORE(), quant à elle, est une macro fournie par `
KTMainWindow`. Elle est remplacée par le code suivant :

    if (app.isRestored()){
      int n = 1;
      while (KTMainWindow::canBeRestored(n)){
    	(new KScribbleApp)->restore(n);
    	n++;
      }
    }

Cela restaurera toutes les fenêtres de l'application de la classe `KScribbleApp` en créant les instances et en appelant `restore()` pour la nouvelle fenêtre. Il est important de comprendre que si votre application utilise plusieurs widgets différents qui héritent de `
KTMainWindow`, vous devez remplacer la macro et déterminer le type des widgets principaux (NdT : top widgets) en utilisant `
KTMainWindow::classNameOfToplevel(n)` au lieu de la classe `KScribbleApp`.

La méthode `restore()` lit ensuite la partie du fichier de session qui contient les informations concernant la fenêtre. Comme `
KTMainWindow` enregistre tout cela pour nous, nous n'avons rien de spécial à faire. Ensuite, seules les informations spécifiques à notre instance de `KScribbleApp` doivent être retrouvées. Souvent, c'est un fichier temporaire que nous avons créé pour enregistrer le document ou une autre initialisation qui est requise. Pour obtenir ces informations de restauration, nous devons seulement réécrire deux méthodes virtuelles de `
KTMainWindow`, `saveProperties()` et `readProperties()`. Les informations que nous devons enregistrer pour la session sont si le fichier actuellement ouvert est modifié ou non et le nom du fichier. Si le fichier est modifié, nous obtiendrons un fichier temporaire pour l'enregistrer. Au début de la session, ces informations sont utilisées pour restaurer le contenu du document :

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

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

Ici, la ligne `kapp->checkRecoverFile()` paraît un peu étrange car `b&&lowbar;;canRecover` n'est pas initialisé. Cela est fait par la méthode qui le met à `true`, s'il y a un fichier de restauration.

Comme nous avons seulement enregistré un document dans un fichier de restauration (NdT : recover file) s'il était modifié, nous positionnons le bit de modification pour indiquer que les informations n'ont pas été enregistrées dans le fichier original. Nous devons aussi faire attention au fait que le fichier de restauration possède un nom de fichier différent du fichier original qui était ouvert. C'est pourquoi, nous devons réinitialiser le nom de fichier et le chemin à l'ancien nom de fichier. Enfin, nous avons les informations que nous voulions restaurer et nous pouvons supprimer le fichier temporaire du gestionnaire de sessions.

Résumé :

Tout au long de ce chapitre, vous avez appris comment l'application est lancée, soit par un appel normal de l'utilisateur, soit par le gestionnaire de sessions. Nous avons parcouru le code pour apprendre comment les parties de l'interface visuelle de l'application sont construites et comment initialiser les attributs grâce aux entrées du fichier de configuration. Maintenant, vous pouvez exécuter l'application pour tester ces fonctions et voir comment la fenêtre du programme réagit.

### Contenu Supplémentaire sur les Projets KDevelop

Au-delà du code source fourni, les projets KDevelop contiennent beaucoup de choses supplémentaires qui intéresseront le développeur. Parmi elles, on trouve :

- une icône de programme

- une mini-icône de programme

- un fichier .kdelnk

- un échantillon de fichier de documentation SGML

- un ensemble de documentations de l'API
  générées par les sources de l'architecture.

Mise à part la documentation de l'API
, ces éléments du projet seront installés ensemble avec le binaire de l'application. Comme l'architecture de projet doit être aussi ouverte que possible, vous devrez adapter ces éléments aux objectifs de votre projet. Premièrement, vous devez éditer les icônes fournies. Cela donnera à votre application un indentifiant unique par lequel l'utilisateur peut déterminer visuellement votre application dans les menus du gestionnaire de fenêtres. Le fichier .kdelnk
est un fichier qui installe votre application dans le menu `Applications` de `kpanel` (NdT : le tableau de bord de KDE). Il devra être édité pour définir le chemin d'installation que nous détaillerons ultérieurement dans ce manuel. Enfin, la documentation que vous voudrez fournir à l'utilisateur est écrite en SGML
. Cela permet de créer très facilement des formats de sortie différents à partir de la même source. Par défaut, KDevelop propose de créer un ensemble de fichiers HTML à partir de cette source ; pour les projets KDE, il utilisera automatiquement le programme `ksgml2html
` pour donner une apparence homogène, dans le style de KDE, à la documentation. Dans une section ultérieure, nous verrons comment éditer les sources SGML
et ce qu'il faut faire pour l'installation vers l'utilisateur final.

Enfin, la documentation de l'API
(Application Programming Interface) vous permet, ainsi qu'aux autres développeurs, d'aller rapidement dans le code et d'utiliser les classes sans avoir à deviner la finalité de chacune d'elles. Nous apprendrons comment étendre la documentation de l'API
dans une étape ultérieure ; pour l'instant, il suffit de savoir que la documentation est générée par le programme `KDoc
` qui traite les fichiers d'en-tête et crée les fichiers HTML, c'est pourquoi toute la documentation est placée dans les en-têtes.

## Conception de Vue d'Application

Lorsque vous développez une application ayant une interface utilisateur graphique, la tâche principale est de fournir des "vues" à l'application. Une vue est généralement un widget qui affiche les données d'un document et fournit des méthodes pour manipuler le contenu du document. Cela peut être fait par l'utilisateur via des événements qu'il émet avec le clavier ou la souris ; les opérations plus complexes sont généralement traitées par les barres d'outils
et les barres de menus qui interagissent avec la vue et le document. La barre d'état donne des informations sur le document, la vue ou l'état de l'application. À titre d'exemple, nous regarderons comment un éditeur est construit et où nous pouvons trouver tel et tel élément.

Un éditeur est généralement supposé fournir une interface à l'utilisateur lui permettant de visualiser et/ou modifier le contenu d'un document texte. Si vous lancez KEdit, vous voyez l'interface visuelle suivante :

- la barre de menus : fournit des opérations complexes comme l'ouverture, l'enregistrement et la fermeture de fichiers ainsi que l'arrêt de l'application

- la barre d'outils
  : fournit des icônes qui permettent d'accéder plus rapidement aux fonctions les plus utilisées

- la barre d'état : affiche l'état de la position du curseur avec la ligne et la colonne courante

- la vue au centre de la fenêtre : affiche un document et permet au curseur connecté au clavier et à la souris de travailler sur les données.

Il paraît donc évident que la vue est la partie la plus unique de l'application et que sa conception décide de l'utilisabilité et de l'acceptabilité de l'application. Cela signifie qu'une des premières étapes dans le développement est de déterminer le but de l'application et quel type de concept de vue correspondra le mieux pour permettre à n'importe quel utilisateur de travailler avec l'application en fournissant un minimum d'effort pour apprendre à dominer l'interface utilisateur.

Pour certains cas comme l'édition de texte ou l'affichage de fichiers HTML, des vues sont fournies par Qt
et par les bibliothèques de KDE
; nous discuterons certains aspects de ces widgets de haut niveau dans la section suivante. Mais pour la plupart des applications, de nouveaux widgets doivent être conçus et implantés. C'est là que le programmeur devient un "designer" et qu'on lui demande d'être créatif. Mais, n'oubliez pas d'être intuitif. Souvenez-vous que beaucoup d'utilisateurs n'accepteront pas une application qui n'est pas :

- visuellement agréable

- pourvue de nombreuses fonctionnalités

- facile à manipuler

- d'utilisation rapidement assimilable.

Nul besoin d'ajouter que la stabilité est un objectif majeur. Personne ne peut éviter tous les bogues mais un minimum peut être atteint au moins grâce à une conception soignée et l'utilisation vaste de la conception orientée objet. Le C++ rend la programmation agréable si vous savez exploiter ses capacités - héritage, encapsulation et réutilisabilité du code existant.

Lorsque vous créez un projet KDE ou Qt
, vous devez toujours avoir une vue qui hérite de `
QWidget`, soit par héritage direct soit parce que le widget de la bibliothèque que vous voulez utiliser hérite de `
QWidget`. C'est pourquoi, l'Assistant d'Application construit une vue qui est une instance de la classe `&<;yourapp&>;View` qui hérite déjà de `
QWidget`. L'application crée votre vue dans la méthode `initView()` où une instance est créée et connectée au widget principal comme étant sa vue avec `KTMainWidget::setView()`.

Ce chapitre décrit donc comment utiliser les widgets des bibliothèques pour créer des vues pour les applications KDE ou Qt
qui sont générées avec KDevelop ; ensuite, nous regarderons les bibliothèques et quels types de vues sont déjà fournis.

### Utiliser les Vues des Bibliothèques

Quand la conception de votre application est achevée, vous devriez d'abord regarder le code existant qui vous rendra la vie plus facile. Une partie de ce travail est de chercher un widget qui peut être utilisé comme vue ou au moins comme un élément de celle-ci, soit directement soit par héritage. Les bibliothèques de KDE et Qt
contiennent déjà un ensemble de widgets qui peuvent être utilisés pour cela. Pour les utiliser, vous avez deux options :

1. supprimer la nouvelle classe de vue et créer une instance du widget de la bibliothèque ; ensuite, définissez-le comme étant la vue

2. changer l'héritage de la classe de vue fournie en la classe du widget de la bibliothèque à utiliser.

De toute façon, il faut savoir que si l'application n'est actuellement pas liée avec la bibliothèque qui contient le widget, l'édition de lien échouera. Après avoir décidé d'utiliser un certain widget, regardez la bibliothèque à lier ; ensuite, ouvrez "Projet"->"Options" dans la barre de menus. Allez à la page "Édition de liens" et regardez les cases à cocher indiquant les bibliothèques actuellement utilisées. Si la bibliothèque de votre widget de vue est déjà cochée, vous pouvez laisser telles quelles les options du projet et commencer à effectuer les modifications nécessaires au gré de votre choix. Sinon, les options d'édition de lien vous permettent d'ajouter une bibliothèque grâce à une case à cocher, cochez-la et cliquez sur "OK" pour quitter la boîte de dialogue des options du projet. Dans les autres cas, ajoutez la bibliothèque dans la ligne d'édition en bas avec l'option `-l`. Pour les bibliothèques que votre application doit rechercher avant de préparer les Makefiles, sur la machine de l'utilisateur, avec le script `configure` , ajoutez la macro de recherche correspondante dans le fichier `configure.in` situé dans le dossier de base de votre projet et ajoutez la macro à la ligne d'édition. Notez que vous devez exécuter "Construire"->"Autoconf et automake" et "Construire->Configurer" avant que les Makefiles ne contiennent le contenu correct de la macro de la bibliothèque.

Également, si les fichiers d'include de la bibliothèque ne sont pas dans les chemins d'include actuels (que l'on peut voir avec l'option `-I` dans la fenêtres des messages de "Make"), vous devez ajouter le chemin dans la boîte de dialogue des Options du Projet, à la page "Options de compilation", avec l'option `-I` ou la macro automake correspondante dans la ligne d'édition des "Options supplémentaires".

#### Vues Qt

En regardant la première page de la documentation en ligne de Qt
, vous trouverez un lien vers des captures d'écran de widgets (NdT : "Widget Screenshots") où vous pourrez voir à quoi ressemblent les widgets de Qt
. Ils sont prêts à l'emploi et peuvent être combinés ensemble pour former des widgets complexes afin de créer des vues ou des boîtes de dialogue d'applications. Dans la suite, nous en présenterons certains qui sont très utiles pour créer des vues d'applications mais gardez à l'esprit que les bibliothèques de KDE
contiennent parfois d'autres widgets ayant le même but ; nous les verrons dans la prochaine section.

Voici un ensemble de conseils sur l'utilisation des composants de Qt
:

1. si votre zone de vue n'est pas assez grande pour afficher toutes les données, l'utilisateur doit pouvoir faire défiler le document grâce à des barres à droite et en bas de la vue. Pour cela, Qt
   fournit la classe `QScrollView` qui donne une zone fille que l'on peut faire défiler. Comme expliqué, vous pouvez faire hériter votre widget de `QScrollView` ou en utiliser une instance pour gérer le widget de vue de votre document& ;;

2. pour créer une ScrollView vous-même, dérivez le widget de View de `
   QWidget` et ajoutez des `QScrollBar`s verticale et horizontale (c'est ce que fait le widget KHTMLView de KDE)& ;;

3. pour du traitement de texte, utilisez `QMultiLineEdit`. Cette classe fournit un widget d'édition de texte complet qui est déjà capable de couper, copier et coller du texte et est géré par une barre de défilement& ;;

4. utilisez `QTableView` pour afficher des données qui sont organisées en table. Comme `QTableView` est gérée par des barres de défilement, c'est une bonne solution pour des applications de calcul sur des tables& ;;

5. pour afficher deux widgets différents ou deux instances du widget en même temps, utilisez `QSplitter`. Cela vous permet de séparer les vues en divisons horizontales ou verticales. La fenêtre de Mail de Netscape est un bon exemple de ce à quoi cela peut ressembler - la vue principale est divisée par un séparateur vertical, la fenêtre de droite est ensuite à nouveau divisée horizontalement& ;;

6. `QListView` affiche des informations dans une liste et un arbre. C'est utile pour créer des arborescences de fichiers ou toute information organisée hiérarchiquement avec laquelle vous voulez interagir.

Vous voyez que Qt
, seul, offre un large éventail de widgets qui sont prêts à l'emploi donc vous n'avez pas besoin d'inventer de nouvelles solutions si ceux-ci vous conviennent. L'avantage d'utiliser des widgets standards est que les utilisateurs savent déjà comment les manipuler et n'ont plus qu'à se concentrer sur les données affichées.

#### Vues KDE

Les bibliothèques de KDE
ont été inventées pour rendre plus simple la conception d'applications pour l'Environnement de Bureau KDE et apporter plus de fonctionnalités que celles offertes par Qt
seul. Pour voir ce qui est disponible, nous allons regarder l'arbre de documentation dans KDevelop. Vous voyez que les bibliothèques de KDE commencent avec `kdecore` qui est la base de toutes les applications KDE
. Ensuite, `kdeui` apporte des éléments d'interface utilisateur. C'est là que vous trouverez des choses utiles. Pour créer de nouvelles applications, la bibliothèque `kdeui` contient :

1. `
   KTabListBox` : une zone de liste multi-colonnes où l'utilisateur peut changer les lignes par glisser-déposer
   (NdT : drag'n drop)& ;;

2. `
   KTreeList` : hérite de `
   QTableView` et fournit un arbre développable/réductible (NdT : collapsible tree). Cela peut être utilisé à la place de `QListView`. Dans KDE 2.0, cette classe disparaîtra& ;;

3. `
   KEdit` : les classes de base de l'application KEdit qui fait partie de KDE. Cela peut être utilisé à la place de `
   QMultiLineEdit`& ;;

4. `
   KNewPanner` : gère deux widgets fils comme `
   QSplitter`. Dans KDE 2.0, cette classe disparaîtra& ;;

Par ailleurs, la bibliothèque `khtmlw` fournit un widget complet d'interprétation HTML prêt à l'emploi. On peut déjà le faire défiler donc vous n'avez pas besoin de vous en soucier. Une utilisation possible est de l'intégrer comme widget de prévisualisation pour un éditeur HTML ; il est également utilisé par des applications comme KFM, KDEHelp
et KDevelop pour afficher des fichiers HTML.

### Créer vos propres Vues

Maintenant que vous avez une vision globale de ce qui est déjà fourni, vous pourrez remarquer que pour beaucoup de types d'utilisation, des widgets existent déjà et sont prêts à l'emploi ou peuvent être combinés ensemble. KMail, ainsi que KDevelop lui-même utilisent des composants de bibliothèques de vues pour afficher leurs données.

Pour les applications qui utilisent un format de fichier spécial ou qui doivent utiliser des fonctions graphiques, vous serez probablement forcé de créer votre propre widget de vue pour manipuler les données. Cela est réalisé dans notre exemple par la classe `KScribbleView` qui fournit déjà une zone de vue de base.

Hériter de `
QWidget` est nécessaire pour surcharger les méthodes virtuelles afin de traiter les événements utilisateur, c'est probablement le travail le plus long, au-delà de fournir les menus popups pour accéder facilement à certaines fonctions. Il paraît également judicieux d'implanter un ensemble de slots auxquels on peut accéder grâce aux boutons de la barre d'outils
ou aux commandes de la barre de menus pour s'y connecter, ainsi que des méthodes pour manipuler des variables comme, par exemple, une couleur de dessin.

Afin d'être complets, nous allons répéter les méthodes nécessaires :

a) Événements Clavier -- les touches TAB et Shift-TAB :

changent le focus d'entrée du clavier du widget courant vers le widget suivant dans l'ordre du focus. Le focus peut être donné aux widgets en appelant `setFocusPolicy
()` et en traitant les événements suivants :

- `virtual void focusInEvent
  (
  QFocusEvent * )`

- `virtual void focusOutEvent
  (
  QFocusEvent * )`

b) toute autre saisie au clavier :

- `virtual void keyPressEvent
  (
  QKeyEvent * )`

- `virtual void keyReleaseEvent
  (
  QKeyEvent * )`

c) mouvements de la souris :

- `virtual void mouseMoveEvent
  (
  QMouseEvent * )`

- `virtual void enterEvent
  (
  QEvent * )`

- `virtual void leaveEvent
  (
  QEvent * )`

d) actions des boutons de la souris :

- `virtual void mousePressEvent
  (
  QMouseEvent * )`

- `virtual void mouseReleaseEvent
  (
  QMouseEvent * )`

- `virtual void mouseDoubleClickEvent
  (
  QMouseEvent * )`

e) événements de la fenêtre contenant le widget :

- `virtual void moveEvent
  (
  QMoveEvent * )`

- `virtual void resizeEvent
  (
  QResizeEvent * )`

- `virtual void closeEvent
  (
  QCloseEvent * )`

En ré-implantant ces fonctions, vous devrez prendre garde à certains points pour éviter des erreurs d'implantation qui rendront impossible une modification ultérieure du comportement du widget :

1. déclarez vos méthodes virtuelles comme virtual et conservez l'accès "protégé" (NdT : protected). Cela permet de réutiliser le widget par héritage et conserve une certaine homogénéité& ;;

2. ne codez pas en dur un traitement d'événement qui devrait être configurable. Cela est d'autant plus vrai pour les événements du clavier qui pourraient être réalisés avec des raccourcis
   clavier si une fonction est appelée. Cela est même valable pour les traitements de texte ! (pensez que beaucoup d'utilisateurs sont habitués au comportement de leur éditeur favori. Si cela est configurable, ils pourront utiliser le comportement auquel ils sont habitués)& ;;

3. transmettez le "signal" de surbrillance (NdT : highlighting) des menus popups au widget principal pour activer l'aide dans la barre d'état.

## Configuration des Barres de Menus et des Barres d'Outils

Les barres de menus et les barres d'outils
font partie des éléments les plus importants d'une application pour permettre de travailler avec une structure de document. En règle générale, vous devriez rendre toutes les fonctions disponibles via la barre de menus. Les méthodes qui peuvent ne pas être disponibles à un certain moment de la vie de l'application devraient aussi être désactivées.

De plus, une application ne peut contenir qu'une seule barre de menus mais plusieurs barres d'outils
. D'un autre côté, les barres d'outils devraient contenir uniquement les commandes les plus fréquemment utilisées, représentées par des icônes ou fournir des méthodes à accès rapide comme les listes déroulantes pour sélectionner des valeurs.

### Comment ça fonctionne ?

Chaque entrée, que ce soit une entrée de menu ou un élément d'une barre d'outils, possède un identificateur de ressource (NdT : ID) qui est une valeur entière. Comme ces valeurs ne peuvent pas être utilisées deux fois, elles sont définies par des macros où les valeurs numériques sont remplacées par un nom d'identificateur descriptif qui peut alors être utilisé dans le code source.

Tous les identificateurs de ressource sont regroupés dans le fichier `resource.h` où vous pouvez contrôler les valeurs utilisées. De toute façon, le compilateur vous avertira si vous avez utilisé deux fois la même valeur pour construire des entrées. Le fichier de ressource devrait aussi contenir tous les accélérateurs
de menu définis par les macros de remplacement IDK. Voici un exemple :

    (resource.h)

    #define ID_VIEW_TOOLBAR             12010

    (kscribble.cpp)

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

Ceci insère l'entrée "Toolbar" au menu popup "View" de la barre de menus dans l'application kscribble. Le nom de l'identificateur de ressource est géré pour contenir le nom du menu et le nom de l'action. Le symbole & (NdT : ampersand) est placé devant la lettre qui fait office d'accélérateur
clavier et l'entrée elle-même est entourée par la macro i18n() pour l'internationalisation.

Lors de l'activation de l'élément de menu, le "switch" de commandCallback() est appelé avec le numéro d'identifiant. Ici, vous devez ajouter une valeur de comparaison correspondante avec la méthode que vous voulez exécuter lors de l'activation de l'entrée du menu :

    	case ID_VIEW_TOOLBAR:
    		slotViewToolBar();
    		break;

Note : vous n'avez pas besoin d'utiliser le système d'identifiants (NdT : ID system). Si aucun identifiant n'est donné, le menu est numéroté automatiquement. L'architecture de KDevelop l'utilise car il permet d'accéder aux identifiants de menu ou de barre d'outils
pour créer des cas de `switch` qui sélectionnent le slot à appeler lors du signal `activated()` pour les menus et `clicked()` pour les boutons de la barre d'outils
. La connexion peut aussi être faite directement en utilisant les méthodes fournies par les classes fournissant les menus et les barres d'outils
.

### Ajouter un nouveau Menu

Une nouvelle barre de menus est ajoutée à une application de la façon suivante :

1. ajouter un pointeur vers le nouveau menu dans l'en-tête de la classe App

2. appeler le constructeur de `
   QPopupMenu` pour le pointeur dans `initMenuBar()` à l'emplacement où votre barre de menus doit apparaître

3. insérer les éléments de menu corespondants dans le menu popup et définir leurs identifiants de ressource dans le fichier de ressource

4. ajouter les connexions pour `commandCallback()` et `statusCallback()` au menu à la fin de `initMenuBar()`

5. ajouter les méthodes que vous voulez appeler par les entrées de menu dans les fichiers d'en-tête et d'implantation

6. ajouter les cas de switch pour les entrées aux méthodes `commandCallback()` et `statusCallback()`.

### Intégrer des boutons à la Barre d'Outils

Des boutons peuvent être ajoutés à une barre d'outils comme des entrées à un menu, à la différence que la méthode utilisée est `insertButton()` et qu'elle prend en paramètres une icône de bouton et un texte de bulle d'aide au lieu d'un texte de menu.

Les icônes que vous voulez utiliser peuvent être chargées par `KIconLoader` ; `
KApplication` offre aussi les macros `ICON()` et `Icon()` pour accéder au chargeur d'icônes et charger l'icône. Ces macros prennent le nom du fichier de l'icône en paramètre pour charger l'icône à partir du système de fichiers de KDE, dans un certain ordre (voir `KIconLoader` pour l'ordre de recherche).

Les bibliothèques de KDE
offrent aussi un ensemble de boutons de barre d'outils
qui peuvent être utilisés pour des actions standards. Au cas où elles ne vous conviendraient pas, vous devrez dessiner vos propres icônes. KDevelop permet cela en sélectionnant "Nouveau" dans le menu "Fichier", puis en sélectionnant Pixmap comme type de fichier. Souvent, vous placerez les icônes de votre barre d'outils
dans un sous-dossier "toolbar
" de votre projet et les installerez dans le dossier toolbar
spécifique à votre application.

### Configuration des Barres d'État

Les projets KDevelop utilisent déjà la barre d'état en affichant des messages sur les entrées du menu et sur les boutons de la barre d'outils
. Quand vous ajoutez une entrée de menu, ajoutez aussi un message d'état dans la méthode `statusCallback()`.

`statusCallback()` utilise la méthode `slotStatusHelpMsg()` pour afficher un message dans la barre d'état pendant 2 secondes. Lorsque vous exécutez une commande, vous devriez utiliser la méthode `slotStatusMsg()` dès le début avec la chaîne de caractères décrivant ce que votre application fait ; avant un "return" ou la fin de la méthode, vous devrez réinitialiser le message dans la barre d'état en appelant la même méthode avec la chaîne de caractères "Ready".

### Configuration des Raccourcis Clavier

Les raccourcis
clavier sont une chose très professionnelle que vous devriez toujours ajouter à votre application. Ils sont principalement utilisés par les utilisateurs expérimentés qui veulent travailler plus vite avec leurs applications et veulent apprendre des raccourcis
. Pour cela, les bibliothèques de KDE
contiennent la classe `
KAccel` qui fournit les combinaisons de touches des raccourcis
clavier et l'accès aux raccourcis
clavier standards configurés globalement.

Par défaut, les applications fenêtrées générées par KDevelop utilisent seulement les raccourcis
clavier standards comme F1 pour accéder à l'aide en ligne, Ctrl+N pour un Nouveau fichier, etc. Vous devriez d'abord regarder la liste des raccourcis
clavier déjà définis dans `
KAccel` avant d'en ajouter un nouveau.

Si votre application contient beaucoup de raccourcis
clavier, vous devriez les rendre configurables dans le menu "Options", soit en les associant avec le reste de la configuration de l'application dans un `
QWidget`, soit tout seul. Les bibliothèques de KDE fournissent déjà un `KKeyChooser` utilisable dans des boîtes de dialogue à onglet, tandis que `KKeyDialog` est une boîte de dialogue de configuration des raccourcis clavier prête à l'emploi.

Consultez les classes suivantes pour plus d'informations :

`
KAccel`(
kdecore), `
KKeyChooser`, `
KKeyDialog` (
kdeui)

## L'Éditeur de Boîtes de Dialogue : Où vos Boîtes de Dialogue sont Construites

### Ce que fournit l'Éditeur de boîtes de dialogue

L'éditeur de boîtes de dialogue interne à KDevelop est conçu pour vous aider à construire les widgets et les boîtes de dialogue qui correspondent aux besoins de votre application et réduit significativement le temps nécessaire pour étendre l'interface graphique utilisateur (NdT : GUI) de votre application. La seule limitation actuelle est que l'éditeur de boîtes de dialogue ne supporte pas la gestion de la mise en page qui est proposée par Qt
; c'est pourquoi les boîtes de dialogue ont des tailles statiques et cela peut conduire à des situations où, par exemple, la largeur d'une étiquette (NdT : label) n'est pas assez grande pour contenir toute la longueur de sa traduction.

D'un autre côté, l'état courant de l'éditeur, associé à la gestion de projets de KDevelop, reste la façon la plus rapide de créer des applications aux fonctionnalités nombreuses pour l'Environnement de Bureau KDE.

### Widgets de Qt
et KDE

Actuellement, les widgets supportés sont :

Widgets de Qt :

- QWidget - un widget qui peut être spécifié par vous-même et peut contenir aussi d'autres widgets. Cela permet de créer une hiérarchie de widgets dans une boîte de dialogue& ;;

- QLabel
  - une étiquette qui représente une information de type texte sur le widget. Utilisez QLabel
  , par exemple, devant des zones de saisie pour indiquer l'objectif de la zone de saisie ou quelle variable, par exemple, une liste déroulante permet de définir& ;;

- QPushButton - un bouton qui permet, par exemple, d'appeler une autre boîte de dialogue (comme QFileDialog pour sélectionner un nom de fichier)& ;;

- QCheckBox - une case à cocher pour, par exempe, activer/désactiver des options. QCheckBox est largement utilisé dans les boîtes de dialogue de configuration& ;;

- QLCDNumber - affiche des nombres dans le style LCD. Souvent utilisé pour des horloges& ;;

- QRadioButton - Comme QCheckBox, souvent utilisé pour laisser l'utilisateur choisir des options. QRadioButton spécialise le choix des options lorsqu'elles dépendent les unes des autres, par exemple, vous avez trois boutons radio mais vous voulez que l'utilisateur sélectionne une des trois options données. Consultez `
  QButtonGroup` pour plus d'informations& ;;

- QComboBox - une liste déroulante permet à l'utilisateur de choisir une valeur en la sélectionnant dans un menu qui se déroule vers le bas ou en insérant la valeur, s'il est possible d'y écrire& ;;

- QListBox - fournit une liste à une seule colonne d'éléments qui peut défiler& ;;

- QListView - crée une liste multi-colonnes qui peut être utilisée pour afficher, par exemple, des arborescences de fichiers ou des tables& ;;

- QMultiLineEdit - fournit un éditeur multi-lignes& ;;

- QProgressBar - affiche la progression d'une action qui demande beaucoup de temps pour se terminer& ;;

- QSpinBox - permet de choisir des valeurs numériques avec des boutons haut/bas ou en insérant la valeur, si l'écriture est activée& ;;

- QSlider - définit, avec une glissière, une valeur dans une plage définie par le programme& ;;

- QScrollBar - indique l'étendue d'une valeur et définit la valeur courante grâce à un "ascenseur" ainsi que des boutons haut/bas ; souvent utilisé pour des widgets dont le contenu est plus grand que la zone de vue réellement visible. En utilisant la barre de défilement, la zone visible peut être déplacée vers une autre partie du contenu du widget& ;;

- QGroupBox - fournit une zone de cadre avec un titre pour indiquer que les widgets fils appartiennent à la même zone.

Widgets KDE :

- KColorButton - un bouton (NdT : pushbutton) affichant une couleur sélectionnée. Lors d'un appui sur le bouton, la boîte de dialogue de Sélection de couleur de KDE est affichée, dans laquelle l'utilisateur peut choisir une autre couleur. Souvent utilisé pour les applications de dessin ou, dans tous les cas, quand une couleur doit être définie& ;;

- KCombo - similaire à `
  QComboBox`. Permet à l'utilisateur de choisir une valeur dans un menu déroulant& ;;

- KDatePicker - un widget complet pour laisser l'utilisateur choisir une valeur de date& ;;

- KDateTable - une table de calendrier pour sélectionner une date dans un mois. Utilisé par `KDatePicker` pour créer la boîte de dialogue de choix de date& ;;

- KKeyButton - un bouton pour sélectionner une valeur de touche. Si le bouton est sélectionné, il devient actif. Appuyer sur une touche du clavier changera la valeur de touche du bouton. Souvent utilisé pour configurer des raccourcis clavier& ;;

- KLed - un widget de LED (Light Emitting Diode) pour afficher un certain état& ;;

- KLedLamp - une lampe LED qui supporte aussi les actions de clic& ;;

- KProgress - similaire à `QProgressBar`, `KProgress` supporte d'autres valeurs& ;;

- KRestrictedLine - un `QLineEdit` qui accepte seulement certaines entrées de l'utilisateur. Peut être utilisé pour restreindre l'accès à certaines données par des boîtes de dialogue de mot de passe& ;;

- KSeparator - un widget de séparation à utiliser, dans tous les cas, lorsque les applications KDE
  nécessitent un séparateur pour fournir un affichage unique. Souvent utilisé dans des boîtes de dialogue pour séparer logiquement certaines parties si `QGroupBox` ne convient pas& ;;

- KTreeList - une liste développable/réductible (NdT : collapsible list) pour afficher des arborescences comme `QListView`.

### Propriétés des Widgets Qt
supportés

Le chapitre suivant donne une vision complète des widgets de la boîte à outils Qt
actuellement supportés. Pour avoir une meilleure compréhension des propriétés, elles sont séparées de leur héritage. Comme tous les widgets héritent de `
QWidget`, cette classe est décrite en premier. Toutes les propriétés de `
QWidget` sont disponibles pour tous les autres widgets donc elles ne seront pas listées à chaque fois. Pour les groupes de widgets qui héritent d'une sous-classe abstraite de `
QWidget` comme classe de base, les propriétés de la classe de base sont listées en premier (bien que cette classe ne représente pas elle-même un widget dans l'éditeur de boîtes de dialogue). Ensuite, les propriétés du widget pour le widget disponible du groupe contiennent les propriétés qui lui sont spécifiques. Pour une meilleure compréhension, l'arbre d'héritage des widgets disponibles est donné ci-dessous :

- QWidget

  - QButton (abstrait)

    - QCheckBox

    - QPushButton

    - QRadioButton

  - QComboBox

  - QFrame (actuellement abstrait)

    - QGroupBox

    - QLCDNumber

    - QLabel

    - QProgressBar

    - QScrollView (actuellement abstrait)

      - QListView

    - QSpinBox

    - QTableView (abstrait)

      - QListBox

      - QMultiLineEdit

  - QLineEdit

  - QScrollBar

  - QSlider

#### Propriétés de
QWidget

`
QWidget` est la classe de base pour presque tous les widgets dans Qt
et KDE. Les widgets qui héritent de `
QWidget` permettront donc d'utiliser les mêmes paramètres dans la plupart des cas.

- Apparence :

  - BgColor: Couleur du fond du widget

  - BgMode : Mode du fond du widget

  - BgPalColor : Palette de couleur du fond

  - BgPixmap : Nom du fichier pour une image de fond

  - Cursor : Curseur au-dessus du widget

  - Font : Police du widget

  - MaskBitmap : Nom du fichier pour le bitmap de masque

- Code C++ :

  - AcceptsDrops : si défini à true, l'élément du widget acceptera les "dépots" par les mécanismes de glisser-déposer
    (NdT : drag'n drop
    mechanisms ) (le protocole de "glisser-déposer"
    de Qt
    , pas celui de KDE 1.x !)

  - Connections : connecte les signaux de l'élément aux slots

  - FocusProxy : l'élément qui donne son focus au widget.

  - HasFocus : définit si, par défaut, le widget a le focus. Notez que seulement un élément par boîte de dialogue peut avoir cette valeur à true

  - ResizeToParent : redimensionne le widget à la taille de son parent (non visible en mode édition)

  - VarName : Nom de variable de l'élément. Changez-le avec le nom qui décrit le but de l'élément.

- Général :

  - IsEnabled : définit si le widget acceptera les événements utilisateur

  - IsHidden : définit si l'élément est visible (false) ou caché (true)

  - Name : définit le nom du widget. Notez que le nom est différent de VarName dans le code C++.

- Géométrie :

  - Height : hauteur de l'élément

  - IsFixedSize :

  - MaxHeight : valeur maximale de Height

  - MaxWidth : valeur maximale de Width

  - MinHeight : valeur minimale de Height

  - MinWidth : valeur minimale de Width

  - SizeIncX : nombre de pixels pour le redimensionnement dans la direction X

  - SizeIncY : nombre de pixels pour le redimensionnement dans la direction Y

  - Width : largeur de l'élément

  - X : position horizontale (abscisse), comptée depuis le coin gauche

  - Y : position verticale (ordonnée), comptée du haut vers le bas

#### Widgets qui héritent de
QButton

`
QButton` est une classe de widget abstraite qui fournit des propriétés communes aux boutons.

Hérite de QWidget

Hérité par QCheckBox, QPushButton et QRadioButton.

- Apparence :

  - setPixmap : définit le nom du fichier de pixmap à utiliser

- Général :

  - setText : le texte sur les étiquettes, boutons et cases ; pré-définit aussi le texte pour les zones de saisie.

  - setAutoRepeat : si activé, le signal clicked() est émis à des intervalles réguliers lorsque le bouton est enfoncé. Aucun effet sur les boutons à bascule (NdT : toggle buttons).

  - setAutoResize : active l'auto-redimensionnement si true. Quand l'auto-redimensionnement est actif, le bouton se redimensionne lui-même lorsque son contenu a changé.

##### Propriétés de QCheckBox

Hérite de QWidget et QButton

- Général :

  - isChecked : (setChecked) définit si la case à cocher est cochée lors de sa construction

##### Propriétés de QPushButton

Hérite de QWidget et QButton

- Général :

  - isAutoDefault : (setAutoDefault) le bouton automatiquement par défaut (NdT : auto-default button) devient le bouton par défaut s'il reçoit le focus du clavier.

  - isDefault : (setDefault) il ne peut y a voir qu'un seul bouton par défaut et il est seulement autorisé dans les boîtes de dialogue (voir `QDialog`). Le bouton par défaut émet `clicked()` si l'utilisateur a appuyé sur la touche "Entrée".

  - isMenuButton : (setIsMenuButton) indique au bouton de dessiner un triangle d'indication de menu s'il est activé. Le menu doit être inséré séparément.

  - isToggleButton : (setToggleButton) fait d'un bouton un bouton à bascule, si bien que le bouton se comporte comme une case à cocher.

  - isToggledOn : (setOn) (public slot) bascule un bouton dans l'état "on".

##### Propriétés de QRadioButton

Hérite de QWidget et QButton

- Général :

  - isChecked : (setChecked) définit si le bouton radio est coché lors de la construction

#### Propriétés de
QComboBox

Hérite de QWidget

(aucune propriété supplémentaire)

#### Widgets qui héritent de QFrame

Hérite de QWidget

Pour l'instant, seulement utilisée comme une classe abstraite.

- Apparence :

  - Margin (setMargin) : définit la marge, qui est la distance entre le pixel le plus à l'intérieur du cadre et celui qui est le plus à l'extérieur du contenu.

##### Propriétés de QGroupBox

Hérite de QWidget et QFrame

- Général :

  - Title : (setTitle) définit le titre du groupe d'éléments qui est affiché dans le cadre.

##### Propriétés de QLCDNumber

Hérite de QWidget et QFrame

- Général :

  - NumDigits : (setNumDigits) définit le nombre de chiffres affichés dans QLCDNumber

  - Value : (display) (public slot) définit la valeur initiale de QLCDNumber

##### Propriétés de QLabel

Hérite de QWidget et QFrame

- Apparence :

  - Margin (setMargin) : définit la marge qui est, pour QLabel
    , la distance du cadre à la première lettre du texte de l'étiquette, suivant l'alignement de l'étiquette.

- Code C++ :

  - Buddy : (setBuddy) définit le widget compagnon de l'étiquette.

- Général :

  - Text : (setText) définit le texte de l'étiquette.

  - isAutoResize : (setAutoResize) si true, l'étiquette se redimensionnera elle-même si son contenu a changé. Le coin en haut à gauche n'est pas déplacé.

##### Propriétés de QProgressBar

Hérite de QWidget et QFrame

- Général :

  - TotalSteps : (setTotalSteps) (public slot) définit le nombre total d'étapes de la barre de progression. Durant l'itération de l'action dont vous voulez afficher la progression, vous devez appeler setProgress(int) pour faire avancer l'étape de progression affichée à (int).

##### QScrollView

Hérite de QWidget et QFrame

Hérité par QListBox (abstrait pour l'instant)

Fournit un widget que l'on peut faire défiler et qui gère l'affichage d'un widget fils avec des barres de défilement verticale et horizontale.

###### QListView

Hérite de QWidget, QFrame et QListView

Fournit une liste pour afficher hiérarchiquement des données, soit dans une table soit dans un arbre. Gère elle-même les barres de défilement à travers QScrollView.

- Apparence :

  - ListViewFont : (setFont()) définit la police des éléments de la ListView

  - ListViewPalette : (setPalette()) définit la palette des éléments de la ListView

  - TreeStepSize : (setTreeStepSize(int)) décalage en pixels entre un élément fils et son élément père

  - hScrollBarMode : mode de barre de défilement fourni par QScrollView pour la barre de défilement horizontale

  - isAllColumnsShowFocus : (setAllColumnsShowFocus(bool)) affiche le focus sur toutes les colonnes d'un élément

  - isMultiSelection : active les multi-sélections des éléments de la liste

  - isRootDecorated : active les symboles + et - pour ouvrir et fermer les arbres

  - vScrollBarMode : mode de barre de défilement fourni par QScrollView pour la barre de défilement verticale

- Général :

  - Entries : vous permet d'insérer une liste d'entrées qui sont pré-définies comme QListViewItems.

  - isAutoUpdate :

##### Propriétés de QSpinBox

Hérite de QWidget et QFrame

- Général :

  - MaxValue : définit la valeur maximale que l'utilisateur peut choisir

  - MinValue : définit la valeur minimale que l'utilisateur peut choisir

  - Prefix :

  - Suffix :

  - Value : valeur pré-définie quand le widget est affiché

  - isWrapping :

##### Widgets qui héritent de QTableView

Hérite de QWidget, QFrame et QTableView

Hérité par QListBox et QMultiLineEdit

###### Propriétés de QListBox

Hérite de QWidget, QFrame et QTableView

- Général :

  - isAutoBottomScrollBar: (setAutoBottomScrollBar)

  - isAutoScroll : (setAutoScroll)

  - isAutoScrollBar : (setAutoScrollBar)

  - isAutoUpdate : (setAutoUpdate)

  - isBottomScrollBar : (setBottomScrollBar)

  - isDragSelect : (setDragSelect)

  - isSmoothScrolling : (setSmoothScrolling)

- Géométrie :

  - setFixedVisibleLines : définit une hauteur fixe pour le widget de façon à ce que le nombre de lignes de texte donné soit affiché en utilisant la police courante.

###### Propriétés de QMultiLineEdit

Hérite de QWidget, QFrame et QTableView

- Général :

  - Text : (setText) (public slot) définit le texte du widget

  - isAutoUpdate : (setAutoUpdate) utilisé pour éviter le scintillement pendant de grandes modifications ; la vue n'est pas rafraîchie si désactivé.

  - isOverWriteMode : (setOverwriteMode) (public slot) définit si le mode écrasement est activé ou non.

  - isReadOnly : (setReadOnly) (public slot) rend le texte du widget en lecture seule ; désactive les entrées de texte.

  - isTextSelected : (selectAll)(public slot) marque tout le texte comme sélectionné

- Géométrie :

  - setFixedVisibleLines: définit une hauteur fixe pour le widget de façon à ce que le nombre de lignes de texte donné soient affichées en utilisant la police courante.

#### Propriétés de QLineEdit

Hérite de QWidget

- Général :

  - CursorPosition : (setCursorPosition) définit la position du curseur par défaut

  - MaxLength : (setMaxLength) définit la longueur maximale de la chaîne de caractères

  - Text : (setText) (public slot) définit le contenu affiché lors de la construction

  - hasFrame : (setFrame) dessine la zone de saisie dans un cadre de deux pixels, si activé

  - isTextSelected : (selectAll) (public slot) définit le texte à sélectionner.

#### Propriétés de QScrollBar

Hérite de QWidget et `QRangeControl`.

- Général :

  - MaxValue : définit la valeur maximale de la barre de défilement ; utilisé dans le constructeur (optionnel)

  - MinValue : définit la valeur minimale de la barre de défilement ; utilisé dans le constructeur (optionnel)

  - Orientation : (setOrientation) définit l'orientation de la barre de défilement à horizontale ou verticale

  - Value : définit la valeur initiale de la barre de défilement ; utilisé dans le constructeur (optionnel)

  - isTracking : (setTracking) si activé, la barre de défilement émet le signal `valueChanged()` lorsque la barre est déplacée ; sinon, seulement lorsque le bouton de la souris est relâché.

#### Propriétés de QSlider

Hérite de QWidget et `QRangeControl`.

- Général :

  - MaxValue : définit la valeur maximale de la glissière ; utilisé dans le constructeur (optionnel)

  - MinValue : définit la valeur minimale de la glissière ; utilisé dans le constructeur (optionnel)

  - Orientation : (setOrientation) définit l'orientation de la glissière à horizontale ou verticale

  - Value : (setValue) (public slot) utilise `QRangeControl::setValue()` pour définir la valeur

  - isTracking :(setTracking) si activé, la glissière émet le signal `valueChanged()` lorsque la barre est déplacée ; sinon, seulement lorsque le bouton de la souris est relâché.

### Propriétés des Widgets KDE supportés

- QWidget

  - QButton (abstrait)

    - QPushButton

      - KColorButton

      - KKeyButton

  - QComboBox

    - KCombo

  - QFrame (abstrait actuellement)

    - KDatePicker

    - KLedLamp

    - KProgress

    - KSeparator

    - QTableView (abstrait)

      - KDateTable

      - KTreeList

  - QLineEdit

    - KRestrictedLine

- KLed

#### KColorButton

Hérite de QPushButton

- Général :

  - DisplayedColor (setColor()) : la couleur affichée sur le bouton

#### KKeyButton

#### KCombo

Hérite de QComboBox

- Général :

  - Entries : liste des chaînes de caractères qui sont les entrées affichées dans la liste déroulante

  - Text : le texte affiché actuellement dans la liste déroulante

  - isAutoResize : redimensionne la liste déroulante à l'élément courant

#### KDatePicker

- Apparence :

  - FontSize : la taille de la police pour le sélecteur de date

#### KLedLamp

#### KProgress

#### KSeparator

- Général :

  - Orientation : définit l'orientation du séparateur à horizontale ou verticale ; par défaut, horizontale.

#### KDateTable

#### KTreeList

- Apparence :

  - TreeListBgColor

  - TreeListPalette

  - isBottomScrollbar

  - isScrollBar

  - isShowItemText

  - isSmoothScrolling

  - isTreeDrawing

- Général :

  - Entries

  - isAutoUpdate

#### KRestrictedLine

#### KLed

Hérite de QWidget

- Apparence :

  - LedColor : (setColor()) définit la couleur de la LED affichée

### Construire une nouvelle boîte de dialogue

Élaborer une nouvelle boîte de dialogue est très facile si vous êtes déjà familier avec les applications de construction graphique. KDevelop permet de créer visuellement un widget et d'afficher son apparence telle qu'elle se présentera à l'utilisateur. En plus, vous pouvez avoir une prévisualisation de votre widget en sélectionnant "Aperçu" dans le menu "Affichage".

Pour commencer la construction d'une boîte de dialogue ou de n'importe quel widget, passez dans l'Éditeur de boîtes de dialogue et sélectionnez "Nouveau" dans le menu "Fichier". Sélectionnez "Boîte de dialogue Qt/KDE (*.kdevdlg)" dans la boîte de dialogue "Nouveau fichier" et saisissez le nom de fichier de la boîte de dialogue. Construisez votre boîte de dialogue et quand vous avez terminé, sélectionnez "Générer les fichiers sources complets" dans le menu "Construire".

Saisissez ensuite toutes les informations nécessaires dans la boîte de dialogue "Nouvelle boîte de dialogue". Ce sont :

1. l'héritage de la boîte de dialogue. Ceci est nécessaire parce que tout widget dérive au moins de `
   QWidget`. Au-delà des types de widgets fournis par Qt, vous pouvez hériter, par exemple, d'une classe abstraite que vous avez développée vous-même au sein de votre projet. Dans ce cas, sélectionnez "Personnalisé" et saisissez le chemin menant au fichier d'en-tête dans la zone de saisie en-dessous& ;;

2. le nom de la boîte de dialogue. Ceci définit le nom de la classe pour la boîte de dialogue générée. Sélectionnez un nom de classe décrivant explicitement ce que fait la boîte de dialogue ; au cas où vous héritez de `QDialog`, vous pourriez saisir un nom qui se termine par `Dlg` afin de vous aider à vous souvenir que c'est une boîte de dialogue. Les conventions de nommage devraient néanmoins correspondre à celles de KDE et Qt
   : utilisez des lettres majuscules pour votre nom de classe. Pour, par exemple, une boîte de sélection de taille de quadrillage (NdT : grid-size selection dialog), vous pourriez saisir `GridSizeDlg`.

3. les noms des fichiers générés. Ceux-ci sont pré-définis lorsque vous donnez le nom de la boîte de dialogue mais peuvent être modifiés utlérieurement. Si vous voulez utiliser d'autres noms de fichiers, la convention de nommage devrait respecter celle de KDE et Qt
   : les noms des fichiers sont écrits en minuscules et contiennent le nom de la classe afin de se rappeler rapidement quelle classe est à l'intérieur. Les fichiers de données qui doivent être définis contiendront ensuite le code généré qui construira votre boîte de dialogue. Après, vous ne devrez pas éditer ce fichier manuellement ; utilisez le fichier d'implantation pour les ajouts au code de construction de la boîte de dialogue et à l'implantation des méthodes.

La boîte de dialogue s'affiche ensuite sous la forme d'un widget avec un quadrillage. Comme l'éditeur de boîte de dialogue utilise cette grille pour positionner les widgets fils, vous pouvez modifier la taille du quadrillage avec l'entrée "Taille de la grille" dans le menu "Affichage", si la valeur prédéfinie ne vous convient pas.

Sélectionnez ensuite l'onglet "Widgets" dans la partie gauche et cliquez sur le bouton du widget que vous voulez ajouter à votre widget principal. Il apparaît immédiatement dans le coin en haut à gauche du widget principal et il est sélectionné dans un cadre redimensionnable. Ensuite, déplacez ou redimensionnez le widget avec la souris. Le curseur changera pour indiquer quelle action peut être effectuée à sa position courante.

Après avoir terminé la construction, sélectionnez "Générer les fichiers" dans le menu "Construire" ou cliquez sur le bouton correspondant de la barre d'outils
. Les fichiers seront ensuite générés à l'endroit prédéfini et inclus dans vos fichiers sources. Une reconstruction ou un "make" compilera tous les fichiers générés dans votre projet et vous pourrez ajouter un appel au constructeur idoine pour créer une instance de la boîte de dialogue ou du widget. Pour les projets KDE, toutes les propriétés du widget qui seront visibles, par exemple le texte d'une étiquette, sont définies avec la macro `i18n()` de `
kapp.h` pour permettre l'internationalisation. C'est pourquoi, vous devriez faire un "Exécuter make messages et fusionner" lorsque vous avez terminé la construction et l'implantation.

Pendant la création d'une boîte de dialogue ou d'un widget, vous devriez respecter les règles suivantes :

- Essayez de rester homogène ! C'est probablement la règle la plus importante dans la constructions d'éléments graphiques. Souvenez-vous qu'un utilisateur n'acceptera une application que si elle est simple à comprendre, quelle que soit la complexité des services qu'elle rend& ;;

- Ajoutez de l'aide partout où c'est possible avec des bulles d'aide, de l'aide "Qu'est-ce que c'est...?" ou de l'Aide rapide. Cela permet d'obtenir directement des informations sur l'utilité des composants graphiques& ;;

- Surveillez le focus du clavier
  ! Le générateur ne gère pas cela - cela doit être pris en considération lors de la construction d'un widget : sinon vous devrez réordonner manuellement votre code d'initialisation ce qui n'est pas une tâche très amusante. Le focus du clavier
  sur n'importe quel widget signifie l'ordre dans lequel les éléments obtiennent le focus d'entrée du clavier lorsque l'utilisateur appuie sue les touches "tab" ou "shift+tab". Ce serait très désagréable si le focus sautait d'un widget à un autre au lieu de passer au widget visible suivant, au-dessous ou à droite du widget courant. C'est pourquoi, vous devriez construire vos widgets de haut en bas et de gauche à droite afin de préserver une certaine homogénéité du focus.

### Définir les Propriétés des Widgets

Les propriétés d'un widget peuvent facilement être définies avec les entrées de la fenêtre des propriétés. Quand un widget devient sélectionné, la fenêtre des propriétés est automatiquement mise à jour avec les propriétés du widget courant. Comme tous les widgets dérivent de `
QWidget`, vous pouvez définir les propriétés `
QWidget` ainsi que les propriétés qui sont spécifiques au widget sélectionné.

Les propriétés peuvent être des :

- valeurs entières, comme la géométrie du widget ou la taille de la police

- valeurs booléennes pour activer/désactiver certains paramètres du widget. Définies avec des listes déroulantes contenant true et false& ;;

- valeurs énumérées d'un widget, par exemple la palette. Définies avec des listes déroulantes contenant la liste des valeurs possibles& ;;

- valeurs de couleur pour, par exemple, la couleur d'affichage. Définies avec la boîte de dialogue de sélection de couleur de KDE& ;;

- valeurs de police pour, par exemple, des étiquettes. Veillez à utiliser des valeurs qui ne sont pas des valeurs par défaut si vous ne voulez pas que KDE rafraîchisse la police. Définies avec la boîte de dialogue de sélection de police de KDE& ;;

- noms de fichiers pour, par exemple, des images de fond. N'utilisez pas des images au format gif ici car elles pourraient ne plus être supportées dans des versions de Qt
  supérieures à 1.42.

### Intégrer la Boîte de Dialogue

Lorsque votre widget est créé, vous voulez probablement l'ajouter au projet afin d'exécuter l'action pour laquelle il a été conçu. Comme un widget peut avoir plusieurs finalités, nous allons considérer les deux cas : un widget héritant de `
QWidget` et un autre de `QDialog`.

#### Héritage de `
QWidget`

Supposons que vous avez créé un widget qui est un morceau de votre vue principale. S'il remplit toute la zone de vue, vous devez ajouter un pointeur d'instance à la déclaration d'en-tête de votre instance de `
KTMainWindow` qui remplace le widget de vue actuellement défini. Modifiez ensuite le code dans la méthode `initView` pour définir ce widget comme la vue principale. En plus, vous pouvez supprimer la classe de vue (NdT : View class) du projet généré mais souvenez-vous que l'instance de document et l'instance de App dépendent de la classe de vue. Dans ce cas, d'un point de vue technique, il est mieux de créer une mini application KDE et de construire votre instance de `
KTMainWindow` vous-même.

Plus souvent, le widget est juste une partie de la zone de vue, ce qui signifie qu'il est combiné avec d'autres widgets. Ceci peut être réalisé en utilisant une des classes suivantes qui fournit une division pour séparer deux widgets.

1. `QSplitter`

2. `KPanner`

3. `KNewPanner`

Si la vue principale doit contenir plus de deux widgets, vous devez utilisez une autre instance du séparateur qui sera l'un des deux widgets gérés par le premier. Ajoutez ensuite les widgets correspondants de chaque côté et définissez le premier séparateur comme la zone de vue.

#### Héritage de `QDialog`

Si votre widget hérite de `QDialog`, il est probablement sensé changer une ou plusieurs valeurs ; ceci est souvent utilisé pour définir les préférences d'une application. Pour appeler la boîte de dialogue, vous devez ajouter un slot dans la classe `App` en ajoutant la déclaration de la méthode et le corps de son implantation. Ajoutez ensuite l'appel au constructeur ainsi que les appels à `show()` ou `exec()` de la boîte de dialogue. Enfin, vous devez veiller à traiter les résultats de la boîte de dialogue ; soit la boîte de dialogue modifie elle-même directement les valeurs du widget parent, soit elle retrouve les valeurs de la boîte de dialogue (ce qui devrait rendre votre boîte de dialogue beaucoup plus réutilisable dans d'autres projets). Pensez à appeler `delete` si vous aviez créé l'instance de la boîte de dialogue avec `new` pour éviter les fuites de mémoire.

Enfin, vous devez connecter une entrée de menu (avec l'aide correspondante dans la barre d'état) au nouveau slot qui appelle la boîte de dialogue ; facultativement, un raccourci clavier
et une icône de barre d'outils
. Pour cela, ajoutez un identificateur de ressource au fichier `resource.h` avec un define. Ajoutez ensuite une entrée de menu correspondante à l'un des menus popups déjà présents dans la barre de menus ou créez un nouveau popup pour ajouter l'entrée de menu. Une entrée de menu est constituée de :

- un pixmap d'icône optionnel. Utilisez la macro `Icon("iconname.xpm")` de `
  KApplication` pour obtenir une instance de l'icône fournie par `KIconLoader`& ;;

- le nom de l'entrée de menu. Ajoutez la avec la macro `i18n("&&;entryname")` de `
  KApplication` pour permettre l'internationalisation. Le symbole "&" doit être devant la lettre qui apparaîtra soulignée pour y accéder directement avec le clavier& ;;

- l'instance du membre à appeler. Normalement, ce devrait être le pointeur `this`.

- le slot du membre à appeler. Utilisez `SLOT(yourmethod()` pour appeler le slot lors de l'émission du signal `activated()`.

- la touche de raccourci clavier
  . Elle devrait être définie à zéro car ceci est fait avec une entrée dans `initKeyAccel()` où vous devez introduire une touche de raccourci clavier
  en même temps que le slot à appeler. Appelez ensuite `changeMenuAccel()` pour changer le raccourci clavier
  de l'élément de menu. Cela sera alors configurable via la boîte de dialogue de configuration des raccourcis clavier. Pour des actions standards, utilisez les valeurs énumérées données par `
  KAccel`.

- l'identificateur de menu défini dans `resource.h`

## Support de l'Impression

L'impression est généralement fournie par votre application pour permettre à l'utilisateur de générer une version papier du document qu'il a créé avec l'application ; c'est pourquoi, elle est seulement nécessaire pour les programmes qui sont utilisés pour produire quelque chose que l'utilisateur peut vouloir imprimer comme, par exemple, du texte ou des images. Dans tous les cas, cela nécessite une interface qui est fournie par la bibliothèque Qt
à travers deux classes : la classe `QPrintDialog`, une boîte de dialogue permettant de configurer l'impression, et la classe `QPainter` qui est aussi généralement utilisée pour dessiner le contenu des widgets. Comme la classe de vue d'une application est chargée d'afficher le document, elle est aussi responsable de son impression.

### La Boîte de Dialogue d'Impression de Qt

La boîte de dialogue d'impression de Qt
peut directement être utilisée en incluant `qprintdialog.h`. Quand vous utilisez l'architecture d'application de KDE, elle est déjà utilisée par la classe de vue donc vous devez seulement compléter l'implantation de la méthode `print()` en utilisant `QPainter`.

### La Classe QPainter

Indépendamment des capacités de l'imprimante, vous pouvez utiliser `QPainter` pour dessiner votre document dans l'imprimante fournie par `QPrinter` comme vous le feriez dans un widget. La seule difficulté apparaît lorsque vous avez besoin d'implanter la façon dont les choses sont imprimées.

## Fonctions d'Aide

Une partie très importante du processus de développement est de fournir des fonctionnalités d'aide à l'utilisateur, là où c'est possible. La plupart des développeurs ont tendance à reporter cela mais vous devez vous souvenir qu'un utilisateur normal n'est pas forcément un expert d'Unix. Il peut très bien venir du côté sombre des logiciels, là où l'utilisation est parsemée de douceurs qui permettent à l'utilisateur d'utiliser une application sans même toucher à une seule page du manuel. C'est pourquoi les bibliothèques de KDE et Qt
fournissent tous les moyens permettant d'ajouter des fonctions d'aide prêtes à l'emploi qui rendront votre application professionnelle. Dans l'application, ces fonctions sont :

- les bulles d'aide

- l'aide rapide

- l'aide de la barre d'état

- les boutons "Qu'est-ce que c'est...?"

En plus, l'application devrait fournir un accès direct à la documentation en ligne au format HTML en appuyant sur la touche standard d'aide F1. Comme KDevelop propose aussi toutes sortes d'aides, et que les applications KDE générées par l'assistant d'application contiennent déjà le support pour cela, ce chapitre vous aidera à trouver où et comment ajouter des fonctions d'aide.

Pendant le développement de votre application, vous devriez essayer d'être homogène dans tout ce que vous faites ; c'est pourquoi, vous devez prendre les mesures nécessaires directement pendant l'extension du code. Cela vous empêchera de plonger à nouveau dans le code et de chercher à comprendre ce que fait votre application ou ce que vous sous-entendiez par certains morceaux de code.

### Bulles d'aide

Les bulles d'aide sont une façon très simple de donner de l'aide. Ce sont de petits messages d'aide qui s'affichent lorsque l'utilisateur déplace sa souris sur un widget qui fournit une bulle d'aide et disparaît lorsque la souris s'en va. L'utilisation la plus habituelle des bulles d'aide est dans les barres d'outils
, où vos bulles d'aide devraient être aussi petites que possible, car les barres d'outils
peuvent être configurées pour afficher leur contenu de différentes façons : en affichant le bouton seul, en affichant le bouton avec le texte sur la droite, le bouton avec le texte en-dessous ou seulement le texte. Cette possibilité devrait être configurable par l'utilisateur mais ce n'est pas une obligation. Dans tous les cas, le texte est affiché comme une bulle d'aide et une barre d'outils
est généralement constituée de boutons et d'autres widgets comme les zones de saisie et les listes déroulantes. Pour une référence complète, consultez la référence de la classe `
KToolBar` située dans la bibliothèque KDE-UI.

À titre d'exemple, nous allons considérer le bouton "Nouveau fichier" d'une application générique& ;:

    toolBar()->insertButton(Icon("filenew.xpm"), ID_FILE_NEW, true, i18n("New File") );

Ici, la partie `i18n("New File")` définit le message de la bulle d'aide. Il est entouré par la macro i18n() fournie par `
kapp.h` pour traduire la bulle d'aide dans la langue actuellement sélectionnée.

Les bulles d'aide peuvent aussi être ajoutées à n'importe quel widget personnalisé en utilisant les classes `QToolTip` et `
QToolTipGroup` fournies par Qt
. Voici un exemple d'utilisation :

    QToolTip::add( yourwidget, i18n("your Tip") );

Pour plus d'informations, consultez le Manuel de Référence de Qt
, classe `
QToolTip`.

### Ajouter une Aide Rapide

Les fenêtres d'Aide Rapide sont un autre bon exemple de manière de donner de l'aide. L'utilisateur peut accéder à l'aide rapide sur un widget qui y est connecté en cliquant avec le bouton droit de la souris et en sélectionnant Aide Rapide (NdT : "Quick-Help") dans le menu contextuel. L'Aide Rapide est donc à mi-chemin entre une aide détaillée et des bulles d'aide - la documentation serait trop exhaustive et une bulle d'aide ne donnerait pas assez de détails. Pour voir comment fonctionne l'Aide Rapide, ouvrez n'importe quelle boîte de dialogue de KDevelop et cliquez avec le bouton droit sur un élément de la boîte de dialogue. Sélectionnez ensuite l'entrée "Aide Rapide" et vous obtiendrez le message d'aide. En plus, ces messages peuvent être formatés avec de la couleur, une police et peuvent même contenir des URL pour référer à une certaine page Web (et peuvent donc aussi pointer sur le manuel d'utilisation).

Pour utiliser l'Aide Rapide, ajoutez le fichier d'inclusion `
kquickhelp.h` à votre fichier source contenant de l'aide rapide. Comme la classe `
KQuickHelp` fait partie de la bibliothèque KDE-UI, il devrait déjà être utilisé par votre application ; sinon, ajoutez kdeui à l'option d'édition de lien de votre projet.

Voici un exemple :

    KQuickHelp::add( yourwidget, i18n("your Tip") );

qui est strictement identique à l'utilisation de QToolTip. Lors de la construction d'une boîte de dialogue avec l'éditeur de boîtes de dialogue de KDevelop, ajoutez vos bulles d'aide et votre aide rapide dans le fichier d'implantation - PAS dans le fichier source car il est reconstruit par l'éditeur de boîtes de dialogues à chaque fois que vous éditez le widget.

La classe `
KQuickHelp` permet aussi de formater du texte en utilisant des balises (NdT : tags). Elle autorise aussi les hyperliens, tels que les protocoles Internet, les couleurs et les types et tailles de police. Consultez KDE Library Reference Guide et la documentation de la classe
pour plus d'informations sur `
KQuickTip`.

### Extension de l'Aide dans la Barre d'État

Comme les applications graphiques générées par KDevelop contiennent déjà une barre d'état, elles offrent aussi un ensemble de messages de barre d'état pour tous les éléments de menu ou de barre d'outils
. Un message d'aide de barre d'état est un message court qui étend le sens d'une bulle d'aide, ou peut être vu comme un remplacement d'une bulle d'aide pour les éléments des barres de menus, et qui est affiché dans la barre d'état lorsque l'utilisateur entre dans un menu et met la surbrillance sur un élément du menu ; ainsi, tous les éléments du menu connectent leur signal `highlighted(int)` à la méthode `statusCallback(int)` qui sélectionne le message approprié dans une instruction switch. Lorsque vous ajoutez un élément à un menu existant ou à une barre d'outils
, ajoutez une entrée correspondante dans cette méthode avec une courte description de l'action que l'utilisateur déclenchera en activant ce bouton ou cette entrée de menu.

Exemple :

    	case ID_FILE_NEW:
    		slotStatusHelpMsg(i18n("Creates a new document"));
    		break;

Ceci affichera un message dans la barre d'état en appelant la méthode `slotStatusHelpMsg()`, avec la chaîne d'aide traduite correspondante, lorsque l'utilisateur met la surbrillance sur un élément de menu ou de barre d'outils
ayant l'identificateur ID&&lowbar;;FILE&&lowbar;;NEW qui est connecté à la méthode `statusCallback()`. Les barres d'outils se connectent à cette méthode avec leur signal `pressed(int)` qui permet à l'utilisateur d'appuyer sur un bouton de la barre d'outils
et déplacer plus loin la souris s'il ne veut pas déclencher la commande. `
KToolBar` possède aussi le signal `highlighted(int, bool)` qui peut être utilisé à la place du signal prédéfini pour afficher le message quand l'utilisateur met le bouton en surbrillance.

### Le Bouton "What's This...?"

Le bouton "What's This...?"
fournit des fenêtres d'aide comme Quickhelp
mais avec l'hypothèse que l'utilisateur veut obtenir de l'aide sur un widget précis dans la vue ou sur un élément de barre d'outils
. Il est placé dans la barre d'outils
et est activé lorsque l'utilisateur clique sur le bouton. Le curseur se change en un curseur avec une flèche et un point d'interrogation semblable à l'apparence du bouton lui-même. Ensuite, l'utilisateur peut cliquer sur un widget visible et une fenêtre d'aide s'affiche. À titre d'exercice, vous pourriez tester ce comportement avec le bouton What's this...? (NdT : Qu'est-ce que c'est...?) de KDevelop. Pour ajouter le bouton What's This...?, procédez ainsi :

1. incluez `qwhatsthis.h` dans votre code source

2. ajoutez une donnée membre privée `
   QWhatsThis whats&&lowbar;;this` ou avec un autre nom à la déclaration de votre classe dérivant de `
   KTMainWindow`

3. définisez un identificateur de ressource pour votre bouton what's this dans le fichier `resource.h`, par exemple `&&num;;define ID&&lowbar;;HELP&&lowbar;;WHATS&&lowbar;;THIS 10100`

4. dans votre méthode de création de la barre d'outils
   (généralement `initToolBar()`), ajoutez l'emplacement où vous voulez que le bouton soit affiché :

         whats_this = new QWhatsThis;
         QToolButton *btnwhat = whats_this->whatsThisButton(toolBar());
         QToolTip::add(btnwhat, i18n("What's this...?"));
         toolBar()->insertWidget(ID_HELP_WHATS_THIS, btnwhat->sizeHint().width(), btnwhat);
         btnwhat->setFocusPolicy(QWidget::NoFocus);

5. enfin, ajoutez les messages que vous voulez voir lors d'un clic sur un certain widget comme ceci :

       whats_this->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."));

## Extension de la Documentation avec SGML

Du fait que les projets manquent souvent d'un manuel d'utilisation complet, tous les projets KDevelop contiennent un manuel pré-construit qui peut facilement être adapté ; un autre des objectifs de KDE est ainsi rempli : fournir suffisamment d'aide en ligne pour guider les utilisateurs qui ne sont pas habitués à une application. Ce chapitre vous explique donc comment étendre le modèle de documentation fourni et ce que vous devez faire pour le rendre disponible à l'utilisateur.

### Pourquoi SGML ?

SGML
(Standard Generalized Markup Language) est un langage avec lequel on peut écrire les spécifications d'un langage de marquage mais n'est pas un langage de marquage en lui-même. La spécification de ce langage de marquage est appelée une DTD (Document Type Definition) qui contient la structure d'un document et les balises valides utilisables. Ensuite, un système SGML fournit un ensemble de fichiers de remplacement qui traduisent les balises de la DTD dans le format de sortie désiré - et c'est de cette façon que cela fonctionne. Le format de sortie le plus utilisé est probablement HTML pour fournir de l'aide en ligne à travers des serveurs web, à une époque où les standards de l'Internet sont accessibles même depuis des systèmes à un seul bureau. KDE utilise intensivement la documentation HTML aussi bien par le biais de son application KDEHelp
où toutes les applications KDE sont listées et qui donne accès à leurs manuels d'utilisation que par le menu d'aide qui permet, depuis une application, d'accéder directement à l'aide en ligne.

Actuellement, KDE (et par conséquent KDevelop) utilise le paquetage des SGML-Tools 1.x (voir \|\|) qui était connu sous le nom de paquetage LinuxDoc. Il contient une DTD appelée `LinuxDoc` et un ensemble de fichiers de correspondance pour différents formats de sortie, ainsi que les outils nécessaires pour réaliser effectivement le remplacement des balises `LinuxDoc`. La DTD LinuxDoc est basée sur la DTD Qwertz qui, elle-même, avait été écrite afin de fournir une bonne correpondance (remplacement de balises), spécialement pour le système de traitement de texte &latex;, et qui permet donc de produire des impressions de bonne qualité. Le paquetage a ensuite tiré son nom de l'utilisation qui en a été faite pour écrire les documentations du LDP (Linux Documentation Project) et a ensuite changé de nom parce que c'est un système sgml qui n'a pas nécessairement de rapport avec le projet Linux mais peut être utilisé sur n'importe quel système Unix. Vous pourriez aussi écrire votre propre DTD et vos correspondances si le coeur vous en dit.

Pendant ce temps, une autre DTD a vu le jour pour remplir les mêmes objectifs : la "DTD DocBook". DocBook a évidemment de nombreux avantages sur la DTD LinuxDoc, notamment en offrant de meilleures balises et correspondances pour les tables et l'insertion de graphiques mais cela reste aussi possible avec LinuxDoc. C'est pourquoi, les SGML-Tools ont basculé afin de fournir le support de la DTD DocBook dans la série des versions 2.x, qui inclut aussi un convertisseur produisant un sgml DocBook à partir d'un original LinuxDoc.

Dans l'état actuel du développement de KDE, nous utilisons encore la DTD LinuxDoc pour certaines raisons :

- écrire de la documentation LinuxDoc est facile

- installer les SGML-Tools 1.x permettant d'utiliser LinuxDoc est encore plus simple

- KDE fournit un outil supplémentaire appelé `ksgml2html` qui ajoute le style de documentation KDE à la sortie générée par le convertisseur `sgml2html` des SGML-Tools 1.x afin de produire une sortie HTML.

J'ai personnellement remarqué, pendant l'écriture des manuels de Kdevelop, qu'utiliser la DTD LinuxDoc est très facile et s'accorde bien avec les besoins que j'avais pour écrire la documentation. Le rythme d'apprentissage est très rapide et en quelques jours, vous serez devenu un expert de sgml-tools/DTD LinuxDoc, ce qui vous épargnera le temps que vous auriez passé à apprendre un système de formatage comme &tex; pour les sorties papier de votre documentation ou un langage à balise pour les sorties HTML.

Une raison majeure de continuer à utiliser les sgml-tools 1.x est que la plupart des distributions contiennent ce paquetage et tous les outils nécessaires pour d'autres formats de sortie. Cela rend l'installation aussi simple que possible et l'écriture en elle-même n'est pas très compliquée, vous allez le voir. Les formats de sortie que vous pouvez obtenir avec les sgml-tools sont :

- HTML avec l'apparence KDE si vous utilisez `ksgml2html`

- texte brut

- GNU info

- format Lyx

- formats &tex;, DVI, PostScript et PDF

- Rich Text Format (RTF).

### Ce que la Documentation contient déjà

Lors de la création d'un projet KDevelop, le répertoire `docs/en` contient déjà le fichier de documentation en anglais `index.sgml` et les fichiers résultant de la génération au format HTML. Ceux-ci sont déjà inclus dans le projet et l'emplacement d'installation est prédéfini au répertoire HTML de KDE. La documentation est déjà adaptée au nom de votre projet, son numéro de version et les informations sur le programmeur. En plus, la sortie génère le fichier index.html qui contient la table des matières (qui est ouverte par l'Aide de KDE quand l'utilisateur demande de l'aide) ; une introduction à l'installation et des informations sur le copyright en relation avec la Licence GPL sont incluses.

Par conséquent, lorsque vous étendez la documentation, vous devez seulement ajouter les informations qui sont spécifiques à votre projet. Notez que pour les projets KDE, vous devez exécuter "Construire le manuel d'utilisation" dans le menu "Projet" après la création du projet. Le fichier index.sgml est à nouveau traité par `ksgml2html
` et le style KDE est ajouté à la sortie HTML. Ouvrez le dossier `docs/en` dans l'onglet RFV et ajoutez le fichier `logotp3.gif` au projet via le menu contextuel ; définissez ensuite correctement les propriétés du fichier afin qu'il s'installe au même endroit que les fichier HTML - dans `$(kde&&lowbar;;htmldir)/en/&<;votre&&lowbar;;projet&>;/logotp3.gif`.

### Écrire de la Documentation SGML

Cette section a été ajoutée car SGML (ou pour être plus précis : la DTD LinuxDoc) semble rester difficile pour les débutants qui souhaitent écrire de la documentation. En parcourant des applications KDE, j'ai remarqué que certaines contenaient le fichier sgml de modèle mais l'auteur a ensuite édité la sortie html au lieu du fichier sgml. Il en résulte des problèmes pour les traducteurs - s'ils veulent fournir dans leur langue natale de la documentation sur votre application, ils devront éditer chaque fichier HTML et cela rend impossible la réutilisation de la documentation pour d'autres formats, pas seulement dans la version anglaise mais aussi pour toutes les versions internationalisées. Vous voyez donc que c'est un comportement limitant et une mauvaise situation ; personnellement, je pense que cela vient du fait que les auteurs connaissent HTML et non SGML. Comme beaucoup veulent éviter d'apprendre un nouveau langage de formatage, ils utilisent la sortie HTML qu'ils éditent comme modèle. Si vous saviez à quel point SGML est simple (et utile) avec LinuxDoc, vous comprendriez qu'apprendre les quelques balises supplémentaires nécessaires pour le formatage SGML vaut le coup.

Voilà pourquoi les sections suivantes introduiront les parties les plus importantes d'un fichier sgml LinuxDoc et comment étendre votre documentation.

#### La Déclaration de la DTD

Un fichier SGML, quelque soit la DTD utilisée, doit toujours commencer avec la déclaration de la DTD. Cela indique à l'analyseur syntaxique (NdT : parser) SGML comment doit être utilisée une DTD. C'est pourquoi, la première balise (une expression entre crochets, comme &<;votrebalise&>; votrecontenu &<;/votrebalise&>;) est toujours le DOCTYPE :

`&<;!doctype linuxdoc system&>;`

Cela indique au formateur sgml qu'il doit utiliser la DTD LinuxDoc.

##### La Structure du Document

Avec LinuxDoc, la balise suivante est la balise de début du type de style de document. La DTD LinuxDoc permet un ensemble complet de types que vous pouvez sélectionner, selon le but du document ou sa longueur. Les formats disponibles sont :

- `&<;notes&>;` pour de brèves explications& ;;

- `&<;article&>;` pour écrire des articles d'environ 10-20 pages (recommandé). Ceci est utilisé par les modèles de KDevelop et la plupart des applications KDE& ;;

- `&<;report&>;` pour des articles qui sont plus longs que le type &<;article&>;& ;;

- `&<;book&>;` pour écrire des livres plus longs - les manuels de KDevelop ont été rédigés en utilisant ce type de document& ;;

- `&<;slides&>;` pour des transparents. C'est utile pour des présentations. Bien sur, vous utiliserez le format de sortie &latex; dans la plupart des cas& ;;

- `&<;letter&>;` pour des lettres classiques& ;;

- `&<;telefax&>;` pour un fax& ;;

- `&<;manpage&>;` pour une page de manuel (NdT : manpage).

Remarquez que ces formats décrivent seulement la structure globale du document - pas le format de sortie. Comme mentionné, le modèle de documentation de Kdevelop généré par défaut utilise la structure &<;article&>;. Elle est utilisée par la majorité des applications hormis KDevelop qui utilise le format &<;book&>;. Cela importe peu dans la sortie HTML mais pour le format &latex;, la différence est plus nette. Les manuels sont vraiment des "livres" avec des pages séparées pour chaque chapitre (c'est la principale différence).

Enfin, la fin du fichier sgml doit avoir une balise fermante pour le type de structure de document - pour &<;article&>;, ce sera &&etago;;article&>;.

#### Pages de Titre

La section qui suit la structure du document décrit toutes les entrées que l'on trouve généralement sur une page de titre. Le modèle prédéfini ne l'utilise pas explicitement mais définit seulement les informations pour `&<;title&>;`, `&<;author&>;` et `&<;date&>;` car cela convient dans la plupart des cas. Dans le cas spécial de la structure `&<;book&>;`, vous voudrez probablement définir une page de titre complète. Voici la liste des balises correspondantes tirée du source sgml de ce manuel :

    &<;!doctype linuxdoc system&>;
    &<;book&>;
    &<;titlepag&>;
    &<;title&>;The KDevelop Programming Handbook
    &<;subtitle&>;The User Guide to C++ Application Design for the K Desktop Environment (KDE) with the KDevelop IDE, Version 1.2
    &<;author&>;
    &<;name&>;Ralf Nolden &<;htmlurl url="mailto:Ralf.Nolden@post.rwth-aachen.de"
    								   name = "&<;Ralf.Nolden@post.rwth-aachen.de&>;"&>;
    &<;inst&>;The KDevelop Team
    &<;date&>;Version 1.2 , July 7, 1999
    &<;abstract&>;
    This handbook itself is part of the KDevelop Integrated Development Environment
    and is therefore also licensed under the GNU General Public License;
    see &<;ref id="Copyright" name="Copyright"&>; for more information.
    &&etago;;abstract&>;

Ceci recouvre tout ce qu'une page de titre contient normalement. La balise `&<;author&>;` peut aussi inclure une balise `&<;thanks&>;` pour insérer des remerciements aux co-auteurs, relecteurs, etc. `&<;inst&>;` représente l'institut ou la société pour laquelle l'auteur a écrit la documentation ; vous pourriez aussi ajouter ici le nom de votre équipe, comme je l'ai fait. `&<;abstract&>;` contient une courte description qui est également placée sur la page de titre. Cela est un peu gênant pour les sorties imprimées où cette section serait imprimée au verso de la page de titre où sont regoupés le copyright, etc. ; cela peut être modifié dans la sortie au format &latex; en éditant le fichier &tex;.

#### Index

La DTD LinuxDoc définit un ensemble de balises pour les différents index qui apparaissent régulièrement dans les documents. Celles-ci sont :

- &<;toc&>; pour la table des matières

- &<;lof&>; pour la liste des figures

- &<;lot&>; pour la liste des tableaux

Les balises ouvrantes correspondantes ne nécessitent pas forcément une balise fermante ; elles sont insérées juste après la page de titre, avant le début du document avec les sections et chapitres correspondants.

Lorsque vous voulez indexer des mots-clés pour un glossaire qui est placé à la fin du document, vous disposez de 4 balises différentes ; deux qui laissent la phrase indexée dans la page et deux pour les entrées d'index qui ne sont pas affichées.

- &<;idx&>; pour une entrée d'index normale

- &<;cdx&>; pour une entrée d'index true-type

- &<;nidx&>; pour une entrée d'index n'apparaissant pas dans le document

- &<;ncdx&>; comme précédemment pour une entrée d'index tt

Ces balises sont ignorées par tous les moteurs (l'outil qui fait la correspondance des balises sgml avec leur format de document) excepté `sgml2latex` qui génère un fichier d'index `index.idx` qui peut être converti en fichier &tex;-index avec `makeindex index.idx`. L'index en lui-même peut être inséré ultérieurement dans le fichier de sortie &tex; avec `\printindex`. J'ai modifié (NdT : patché) ma correspondance pour la sortie &latex; afin de la faire automatiquement (mais je ne sais toujours pas comment inclure l'index dans la table des matières...).

#### Le Contenu du Document

Après avoir expliqué la plupart des détails sur la structure générale, nous abordons le contenu réel du document. Suivant le type de structure du document, on trouve une balise `&<;sect&>;` si on utilise `&<;book&>;`, vous devez commencer vos chapitres par `&<;chapt&>;`.

Après la balise de début, vous pouvez structurer chaque chapitre avec `&<;sect1&>;`, `&<;sect2&>;` etc. jusqu'au nombre maximal de niveaux de sous-sections (4).

La balise ouvrante du chapitre est suivie par le titre de ce chapitre. Vous avez le choix d'utiliser `&<;title&>;` et `&&etago;;title&>;` pour le titre du chapitre (optionnel). Ensuite, après le titre du chapitre, vous devez ajouter une balise &<;p&>; pour réellement commencer le contenu de la sous-section. Dans celle-ci, vous avez toutes les possibilités pour formater votre document avec des listes, des énumérations, des puces et des descriptions de listes. De plus, les citations, les extraits de code, etc peuvent être insérés avec des balises ; consultez le guide de documentation des `sgmltools` pour une liste complète. Vous pourrez en profiter pour regarder la section sur les "caractères spéciaux". Elle contient tous les remplacements valides pour les caractères hors des alphabets usuels comme les crochets, les barres obliques et les symboles comme la marque déposée etc. Avec ces balises, vous pouvez structurer le contenu du texte selon les besoins de la documentation de votre application.

### Comment appeler l'Aide dans les Boîtes de Dialogue

Dans les boîtes de dialogue, on appelle souvent l'aide en ajoutant un bouton "Aide" ; ensuite, vous ajoutez un slot qui est appelé lorsque le bouton est enfoncé. Dans l'implantation du slot, appelez

    kapp->invokeHTMLHelp( QString aFilename, QString aTopic );

où `aFilename` est le nom du fichier à appeler dans le dossier de la documentation HTML de votre application ; par exemple, index-3.html. Ensuite, `aTopic` est la section à appeler. Le préfixe de hachage est ajouté automatiquement ; saisissez juste le chapitre que vous voulez avoir sur cette page, en fait, cela peut être le nom d'une sous-section.

## Documentation de Classe avec KDoc

Une autre partie importante de la documentation est la description informative des interfaces de votre classe. Cela vous permettra, ainsi qu'à d'autres programmeurs, d'utiliser vos classes en lisant la documentation HTML de la classe qui peut être générée avec `KDoc
`. KDevelop supporte pleinement l'utilisation de `KDoc
` pour créer la documentation des bibliothèques de KDE, ainsi vos architectures d'applications sont déjà documentées. Un bon point de départ, avant que vous ne rentriez vous-même dans le code fourni, est de lire la documentation en-ligne qui est incluse. Dans la suite, nous décrirons comment obtenir la documentation de l'API
(NdT : Interface de Programmation d'Application, littéralement Application Programming Interface), où KDevelop vous permet de l'ajouter et quels sont les types de balises spéciales fournies en plus par `KDoc
`.

### Comment utiliser les Fonctionnalités de Documentation de KDevelop

Pour créer la documentation de l'API
après avoir généré votre projet, sélectionnez "Construire la documentation de l'API
" dans le menu "Projet". Cela traitera tous les fichiers d'en-tête et créera la sortie HTML. Ensuite, vous pourrez accéder à la documentation en choisisant "Documentation de l'API
" dans le menu "Aide" ou bien le symbole de livre correspondant dans l'arborescence "Documentation", dossier "Projet courant".

La documentation contient déjà des références croisées entre les documentations en-ligne des classes
de Qt
et de KDE. Ainsi, vous pouvez suivre facilement l'héritage avec l'aperçu de l'héritage. Cela peut aussi vous aider à débuter avec les documentations de Qt
et de KDE.

### Ajouter la Documentation d'une Classe ou d'un Membre

De même que KDevelop fournit tous les moyens d'ajouter automatiquement du code, il offre aussi directement de la documentation. Lorsque vous utilisez le Générateur de classe en choisissant "Projet"->"Nouvelle classe", ajoutez un message d'aide descriptif dans la zone de documentation. Cela ajoutera la documentation dans l'en-tête de la classe.

Lorsque vous ajoutez des fonctions membres et des attributs avec les outils de classe, ajoutez aussi la documentation du membre de la classe dans les zones de documentation correspondantes. Vous pourriez penser que la documentation est une partie du processus de développement qui n'est pas vraiment nécessaire. Mais souvenez-vous que plus votre projet grandit et plus il y aura de personnes à prendre part au processus de développement, la documentation des classes
est alors la meilleure façon de ne pas perdre du temps. Si les développeurs doivent deviner, par le nom des méthodes, ce que fait réellement la méthode, c'est probablement que la sémantique n'est pas comprise et la méthode ne réalise pas la tâche à laquelle le développeur s'attendait. C'est pourquoi vous devez garder une trace de votre documentation et la regénérer aussi souvent que possible.

Par ailleurs, les fichiers de documentation ne sont PAS inclus dans le projet, et ne supportent pas non plus l'internationalisation. C'est pourquoi la documentation de l'API
doit être réalisée en anglais, ce qui permet à des groupes de développeurs internationaux de travailler sur vos sources.

Si vous voulez ajouter manuellement de la documentation dans le fichier d'en-tête, ajoutez la documentation au-dessus de la méthode ou de la classe dans un commentaire de style C, avec la particularité que la première ligne doit commencer par une barre oblique (NdT : slash) suivie de deux astérisques.

Exemple :

      /** enables menuentries/toolbar items
    	*/
      void enableCommand(int id_);

### Balises Spéciales

NOTE : La documentation suivante est tirée de la documentation fournie avec KDoc
, écrite par Sirtaj S. Kang taj@.kde.org), l'auteur de KDoc
; Copyright (c) 1997

La documentation est composée de :

- Texte normal. Les paragraphes doivent être séparés par au moins une ligne vide.

- Texte de la forme

      &<;pre&>;
      .....morceaux de code....
      &<;/pre&>;

- Différentes balises de la forme :

      @nombalise [balise paramètres]

Les balises valides pour chaque type d'entité de code source sont :

- Classes

        @short [une phrase de texte]
      	Une description brève de la classe
        @author [une phrase de texte]
      	Auteur de la classe
        @version [une phrase de texte]
      	Version de la classe (Généralement, j'utilise la valeur "Id" de RCS/CVS)
        @see [une ou plusieurs références à des classes ou méthodes]
      	Références à d'autres documentations

- Méthodes

        @see
      	comme ci-dessus
        @return [une phrase]
      	Une phrase décrivant la valeur de retour
        @param [paramètre nom identificateur] [paramètre description]
      	Décrit un paramètre. La description du paramètre peut utiliser
      	plusieurs lignes et se termine par une ligne vide, la fin du
      	commentaire, ou une autre entrée de paramètre. Pour cette raison,
      	les entrées de paramètre devraient être la fin du commentaire.

- Constantes, Énumérations, Propriétés

        @see
      	comme ci-dessus

- Voir aussi `@ref` Contrairement au format javadoc, la méta-balise "@ref" a le même format que @see mais peut être utilisée n'importe où dans la documentation (toutes les autres balises doivent apparaître sur des lignes différentes).

## Internationalisation

### Qu'est-ce que i18n ?

i18n est un système d'internationalisation qui est utilisé pour fournir des versions internationalisées d'une application ou d'un projet. La difficulté dans l'écriture des applications est que celles-ci supportent seulement la langue qui a été utilisée pour leur réalisation ; visuellement, cela se remarque sur les étiquettes, les entrées de menus, etc. Le but de l'internationalisation est de fournir des applications et des fonctions de bibliothèque dans la langue de l'utilisateur et donc de permettre aux utilisateurs qui ne sont pas capables de comprendre la langue originale d'utiliser plus aisément les fonctionnalités.

### Comment KDE supporte l'Internationalisation

KDE, en tant qu'un des environnements de bureau les plus modernes, a décidé qu'un de ses nombreux objectifs est de fournir aux utilisateurs des applications dans leur langue natale et de simplifier le travail des développeurs voulant fournir leurs applications dans n'importe laquelle des langues supportées.

Techniquement, cela est réalisé par le Système de Fichiers Standard de KDE
qui contient le support de la localisation pour les langues en terme de documentation et en permettant l'internationalisation de l'application grâce à la classe `KLocale` de la bibliothèque KDE-core. Cette classe fait toute la traduction, suivant la langue de préférence définie dans le Centre de Contrôle de KDE.

Par ailleurs, le développeur doit savoir deux choses pour permettre à son application d'utiliser cette fonctionnalité :

1. inclure `
   kapp.h` dans votre code source lorsqu'un texte visible apparaît dans votre application, par exemple dans les fichiers sources qui contiennent des QLabel
   s

2. partout où vous définissez des chaînes de caractères "visibles", encadrez-les par la macro `i18n()` fournie par `
   kapp.h` afin de réaliser la traduction

3. lorsque vous devez accéder à un objet localisé, utilisez la macro `klocale` fournie par `
   kapp.h`

C'est globalement tout ce que vous avez à penser pendant le codage. Notez que vous ne devez pas internationaliser les chaînes de caractères de configuration qui sont utilisées par `
KConfig` car d'une part, ce n'est pas nécessaire et d'une autre part, la lecture ne fonctionnera plus.

### Ajouter une Langue à votre Projet

KDevelop simplifie aussi le travail des développeurs pour inclure le support de langues natives dans leurs applications. Lorsque vous créez un nouveau projet KDE, un sous-dossier `po` est ajouté dans le dossier principal de votre projet. C'est ici que sera placé le fichier &<;application&>;.pot lorsque sa génération sera terminée. Le fichier .pot contient déjà toutes les chaînes qui utilisent la macro i18n(), vous devez donc seulement écrire votre code en utilisant à nouveau cette macro. De temps en temps, vous devrez faire un "Projet"-"Exécuter make messages et fusionner" qui extrait automatiquement à nouveau toutes les macros et reconstruit le fichier .pot.

Pour ajouter une langue à votre application, choisissez "Projet"-"Ajouter un fichier de traduction" qui ouvre la boîte de dialogue de sélection de langue. Choisissez la langue désirée et cliquez sur OK. Ensuite, le fichier &<;lang&>;.po correspondant sera généré dans le dossier `po`. Vous pouvez alors commencer à traduire le fichier po en le sélectionnant dans le dossier po dans l'onglet RFV ou depuis LFV, dossier "Traductions". Si vous avez installé KTranslator
, le fichier .po sera ouvert dans la fenêtre "Outils", sinon comme un fichier texte dans la fenêtre en-tête/ressource. KTranslator
simplifie énormément la traduction des chaînes de caractères en analysant les traductions existantes de votre installation locale de KDE si bien qu'elles peuvent être directement utilisées.

Pour l'édition à la main, nous allons prendre un exemple :

    #: kscribble.cpp:619
    msgid "Opens an existing document"
    msgstr ""

Vous voyez ci-dessus une chaîne de caractères qui a été extraite de la ligne 619 du fichier `kscribble.cpp`. `
msgid` et `
msgstr` sont des balises qui donnent des informations pour la traduction ; `
msgstr` contiendra la traduction de la chaîne. Vous devez veiller à respecter les séquences d'échappement comme \n ou \t qui devront apparaître aussi dans la traduction. Une traduction en français ressemblerait donc à ceci :

    #: kscribble.cpp:619
    msgid "Opens an existing document"
    msgstr "Ouvre un document existant"

C'est tout ce que vous devez faire pour traduire ; lorsque vous avez terminé, enregistrez le fichier. Lorsque "make" s'exécute dans le dossier po, les fichiers de messages seront traités et des erreurs pourront apparaître si les chaînes de caractères ne sont pas conformes, par exemple si des séquences d'échappement sont manquantes. Éditez ensuite à nouveau la chaîne du message correspondant et assurez-vous que "make" s'exécute sans erreurs.

De plus, vous devrez être très vigilants lorsque vous traduisez des chaînes contenant un "et commercial" (NdT : le symbole &&;). La lettre après ce symbole est utilisée comme accélérateur clavier
en complément de la touche ALT pour accéder à la barre de menus ou à des éléments de menus en déplaçant plus rapidement le focus du clavier
vers l'élément sélectionné. Si la même lettre d'accélérateur
apparaît dans la même zone de focus de clavier
(qui peut être tantôt le widget principal, tantôt une boîte de dialogue), chaque widget après le premier ne peut pas être accédé par l'accélérateur clavier
présumé. Donc, même les traducteurs ont une responsabilité dans l'utilisabilité de l'application dans leur langue. Il n'y a également aucune garantie que la lettre originale apparaîtra dans la traduction donc les traducteurs doivent travailler avec précaution et tester l'application dans leur langue après avoir installé la traduction pour s'assurer qu'elle s'exécute sans dysfonctionnements.

### Contacts des Équipes de Traduction

L'équipe KDE fournit aussi de nombreux contacts pour les développeurs qui contribuent au projet KDE en tant que traducteurs. Ceux-ci sont organisés en équipes par langue et coordonnent leur travail de traduction. Pour une liste récente et savoir à qui demander de traduire votre application, consultez \|\|.

Les informations ci-dessous sont extraites du site web de KDE et contiennent les adresses des contacts en date du 6 mars 1999. Si vous voulez rejoindre une équipe, veuillez contacter directement l'un des coordinateurs.

La traduction de KDE est organisée par Juraj Bednar mailto:bednar@rak.isternet.sk et Matthias Elter me@kde.org

Vous pouvez vous abonner à la liste de discussion kde-i18n-doc@kde.org de KDE sur l'internationalisation en envoyant un mail à kde-i18n-doc-request@kde.org et en mettant le mot "subscribe" dans la ligne de sujet. Avant de commencer un travail de traduction, veuillez contacter les coordinateurs d'équipe de traduction correspondants pour éviter un travail en double.

br Équipe de traduction en Breton :

  coordinateur : Jañ-Mai DRAPIER jdrapier@club-internet.fr

  site web : http://perso.club-internet.fr/jdrapier

ca Équipe de traduction en Catalan :

  coordinateur : Sebastià Pla sastia@redestb.es

cs Équipe de traduction en Tchèque :

  coordinateur : Miroslav Flídr flidr@kky.zcu.cz

da Équipe de traduction en Danois :

  coordinateur : Erik Kjær Pedersen erik@binghamton.edu

de Équipe de traduction en Allemand :

  coordinateur : Thomas Diehl th.diehl@gmx.net

  site web : \|\|

  liste de discussion : envoyez un mail avec le sujet 'subscribe' à : kde-i18n-de-request@kde.org

  Forum web pour discussions et avis des utilisateurs : \|\|

el Équipe de traduction en Grec :

  coordinateur : Theodore J. Soldatos theodore@eexi.gr

eo Équipe de traduction en Esperanto :

  coordinateur : Wolfram Diestel diestel@rzaix340.rz-uni-leipzig.de

es Équipe de traduction en Espagnol :

  coordinateur : Boris Wesslowski, Alonso Lara Boris@Wesslowski.com

  site web : \|\|

  liste de discussion : envoyez un mail avec le sujet 'subscribe' à : kde-es@kde.org

et Équipe de traduction en Estonien :

  coordinateur : Hasso C. Tepper hasso@ewsound.estnet.ee

fi Équipe de traduction en Finlandais :

  coordinateur : Kim Enkovaara kim.enkovaara@iki.fi

fr Équipe de traduction en Français :

  coordinateur : Francois-Xavier Duranceau duranceau@kde.org

  site web : \|\|

  liste de discussion : envoyer un message vide à : kde-francophone-subscribe@egroups.fr

he Équipe de traduction en Hébreu :

  coordinateur : Erez Nir erez-n@actcom.co.il

hr Équipe de traduction en Croate :

  coordinateur : Vladimir Vuksan vuksan@veus.hr

hu Équipe de traduction en Hongrois :

  coordinateur : Marcell Lengyel miketkf@yahoo.com site web :\|\|

is Équipe de traduction en Islandais :

  coordinateurs : Logi Ragnarsson logir@imf.au.dk, Thorarinn R. Einarsson thori@mindspring.com, Bjarni R. Einarsson bre@netverjar.is, Hrafnkell Eiriksson hkelle@rhi.hi.is, Gudmundur Erlingsson gudmuner@lexis.hi.is, Richard Allen ra@hp.is

it Équipe de traduction en Italien :

  coordinateur : Andrea Rizzi rizzi@kde.org

ko Équipe de traduction en Coréen :

  coordinateur : LinuxKorea Co. kde@linuxkorea.co.kr

mk Équipe de traduction en Macédonien :

  coordinateur : Sasha Konecni sasha@msi-uk.com

nl Équipe de traduction en Hollandais :

  coordinateur : flidr@CyberGate.zcu.cz flidr@CyberGate.zcu.cz

no Équipe de traduction en Norvégien :

  coordinateur : Hans Petter Bieker zerium@webindex.no

pl Équipe de traduction en Polonais :

  coordinateur : Piotr Roszatycki dexter@fnet.pl

pt Équipe de traduction en Portugais :

  coordinateur : Pedro Morais pmmm@camoes.rnl.ist.utl.pt

pt&&lowbar;;BR Équipe de traduction en Portugais Brésilien :

  coordinateur : Elvis Pfützenreuter epx@netville.com.br

ro Équipe de traduction en Roumain :

  coordinateur : Paul Ionescu ipaul@romsys.ro

ru Équipe de traduction en Russe :

  coordinateur : Denis Y. Pershin dyp@inetlab.com

sk Équipe de traduction en Slovaque :

  coordinateur : Juraj Bednar bednar@isternet.sk

  liste de discussion : envoyez un mail avec le sujet 'subscribe' à : sk-i18n@rak.isternet.sk

sl Équipe de traduction en Slovène :

  coordinateur : blazzupancic@hotmail.com blazzupancic@hotmail.com

sv Équipe de traduction en Suédois :

  coordinateur : Anders Widell d95-awi@nada.kth.se

tr Équipe de traduction en Turc :

  coordinateur : Gorkem Cetin gorkem@linux.org.tr

zh&&lowbar;;GB2312 Équipe de traduction en Chinois Simplifié :

  coordinateur : Wang Jian larkw@263.net

zh&&lowbar;;TW&&lowbar;;Big5 Équipe de traduction en Chinois BIG5 :

  coordinateur : Chou Yeh-Jyi ycchou@ccca.nctu.edu.tw

## Trouver les Erreurs

### Macros de déboguage fournies par Qt

Les Macros de Déboguage fournies par la bibliothèque Qt
peuvent être consultées sur la page debug.html de votre Manuel de Référence de Qt
, accessible grâce au lien "Debugging Techniques" de la page d'index de la Documentation de Qt
.

Les macros les plus utilisées sont

- ASSERT(b)

- CHECK&&lowbar;;PTR(p)

Dans ce cas, b est une expression booléenne qui donne un avertissement de déboguage si b est faux& ;; p est un pointeur qui est vérifié et renvoie un avertissement si p est nul.

Des détails peuvent être trouvés dans la Référence en ligne de Qt
.

### Macros de KDE

NOTE : Ce chapitre est une copie du document de Kalle Dalheimer kalle@kde.org expliquant les macros KDEBUG
incluses dans le paquetage KDE-libs, à la page kdebug.html.

Dernière modification : Sat Sep 13 11:56:01 CEST 1997

Qu'est-ce que KDebug

KDebug est un système de macros et de fonctions qui rendent plus performante l'utilisation de messages de diagnostic dans votre code. Vous pouvez donner à un message un niveau de sévérité parmi 4 et une zone. Vous pouvez choisir à l'exécution où doivent aller les messages de diagnostic et lesquels doivent être imprimés. Voici comment utiliser KDebug dans votre code.

La macro KDEBUG

Utiliser KDebug est très simple. Tout ce que vous avez à faire, c'est d'ajouter &&num;;include &<;kdebug.h&>; au début de chaque fichier source dans lequel vous voulez utiliser les messages de diagnostic et les afficher en appelant la macro KDEBUG
. Cette macro attend trois paramètres. Le premier est le niveau de sévérité. Utilisez une des constantes suivantes :

- KDEBUG&&lowbar;;INFO

- KDEBUG&&lowbar;;WARN

- KDEBUG&&lowbar;;ERROR

- KDEBUG&&lowbar;;FATAL

Le deuxième paramètres est la zone. Une zone est une partie de KDE que vous définissez vous-même. Ensuite, à l'exécution, vous pouvez choisir de quelles zones les messages de diagnostic doivent être imprimés. Veuillez consulter kdelibs/kdecore/kdebugareas.txt pour la liste des plages de zones déjà allouées. Choisissez une zone dans la plage allouée pour votre application. Si votre application n'y est pas déjà et que vous avez un accès CVS, vous pouvez y ajouter une plage pour votre application, sinon, envoyez-moi juste un courrier électronique. Il est probablement judicieux de définir des constantes symboliques pour les zones que vous voulez utiliser mais vous êtes entièrement maître à bord. Enfin, le troisième paramètre est le texte que vous voulez afficher. KDebug met automatiquement en préfixe le nom logique de l'application si vous effectuez la sortie dans un fichier, vers stderr (NdT : la sortie d'erreur standard) ou le syslog. Un changement de ligne est toujours ajouté donc vous n'avez pas besoin de (et ne devriez pas) le faire. Si vous avez besoin de paramètres, vous pouvez utiliser l'une des macros KDEBUG1, ..., KDEBUG9. Elles autorisent d'un à neuf paramètres. La syntaxe est exactement la même que printf ie vous devez inclure dans votre message les descripteurs de format qui seront remplacés par les paramètres additionnels. Voici un exemple :

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

KASSERT

Il y a aussi les macros KASSERT, KASSERT1, ..., KASSERT9 qui fonctionnent comme leurs équivalents KDEBUG
, sauf qu'elles ont un booléen supplémentaire comme premier paramètre. Le message sera affiché uniquement si ce paramètre vaut false. Note : vous ne devriez utiliser ni KDEBUG
ni KASSERT
avant que l'objet
KApplication soit construit. Note 2& ;: KDebug ne fournit aucun support de l'internationalisation car il doit servir uniquement pour les développeurs. Si vous voulez informer l'utilisateur qu'une condition est refusée (comme "il est impossible d'écrire dans ce fichier"), utilisez KMsgBox.

Options de compilation

Aucune option de compilation supplémentaire n'est nécessaire pour utiliser KDebug. Mais quand vous sortez votre produit (cela s'applique essentiellement aux personnes qui créent des distributions comme les paquetages .rpm ou .deb), vous devriez compiler avec l'option -DNDEBUG. Cela supprimera simplement tout le code de déboguage de votre application et la rendra plus petite et plus rapide (par exemple, elle utilisera 256 ko de mémoire non partageable en moins).

Comment gérer les messages de diagnostic à l'exécution

Vous pouvez appuyer sur Ctrl-Shift-F12, à n'importe quel moment, dans toute
KApplication et la boîte de dialogue "Debug Settings" apparaîtra. Vous pourrez y définir, séparément pour chaque niveau de sécurité, quoi faire avec les messages de diagnostic de ce niveau. Les configurations possibles sont les suivnates :

- Output : dans cette liste déroulante, vous pouvez choisir où seront dirigés les messages. Les choix possibles sont : "File", "Message Box", "Shell" (c'est-à-dire stderr) et "syslog". Ne dirigez pas directement les messages fatals vers le syslog à moins que vous ne soyez vous-même administrateur système. La valeur par défaut est : "Message Box".

- File : ceci est significatif seulement si vous avez dirigé les messages dans un fichier (NdT : option "File"). Ici, vous donnez le nom du fichier (relativement au répertoire courant) qui est défini à kdebug.dbg par défaut.

- Area : les zones qui doivent être prises en compte. Chaque message qui n'est pas mentionné ici ne sera simplement pas affiché (à moins que ce champ reste vide qui est la valeur par défaut et signifie que tous les messages doivent être affichés). Vous pouvez saisir plusieurs zones séparées par des virgules et vous pouvez aussi utiliser des plages avec la syntaxe début-fin. Aussi, une entrée valide pourrait être : 117,214-289,356-359,221. Veuillez ne pas utiliser d'espace.

Sinon, vous pouvez aussi cocher la case "Abort on fatal errors". Dans ce cas, si un message de diagnostic ayant le niveau de sévérité "KDEBUG&&lowbar;;FATAL
" arrive, l'application s'arrête avec un signal SIGABRT après avoir affiché le message. Lorsque vous fermez la boîte de dialogue avec OK, vos choix s'appliquent immédiatement et sont enregistrés dans un fichier de configuration spécifique à l'application. N'oubliez pas que ces paramètres sont spécifiques à une seule application ! Lorsque vous appuyez sur Annuler, vos valeurs sont perdues et les anciennes sont restaurées.

## Le Système de Fichiers Standard de KDE

Ce chapitre est une copie du Système de Fichiers Standard de KDE (NdT : KDE FSSTD) écrit par Richard Moore rich@kde.org et publié sur le site web de KDE à \|\|.

Système de Fichiers Standard de KDE

Ce fichier documente la structure de répertoires que KDE et toutes les applications compatibles avec KDE doivent utiliser. Ceci est la version 0.0.4 du standard.

### Introduction

Le but du KDE FSSTD
est de s'assurer que toutes les ressources (icônes, types Mime, etc) requises par les applications KDE
sont stockées dans une structure de répertoires cohérente. Suivre cette structure permet aux applications d'utiliser des outils comme la classe KIconLoader et de séparer les données nécessaires à KDE spécifiques à la plate-forme des données indépendantes de la plate-forme (rendant possible l'installation de plusieurs architectures). Dans ce document, les noms des répertoires se terminent par le caractère `/`. Lorsque le mot 'appname' apparaît entre inférieur/supérieur &<;comme ceci&>;, cela signifie qu'il devrait y avoir une entrée correspondante pour chaque application KDE installée. Le mot 'lang' est utilisé de la même façon pour indiquer qu'il doit y avoir une entrée pour chaque langue supportée selon le système de nommage à deux caractères (par exemple : 'fr' pour Français, 'de' pour Allemand).

### Organisation des Répertoires

La structure de répertoires de KDE est indiquée ci-dessous, la racine de l'arborescence d'installation de KDE est souvent '/opt/kde' mais peut être déterminée à l'exécution en utilisant la méthode kdedir() de
KApplication (cela remplace la variable d'environnement KDEDIR dont l'utilisation est maintenant obsolète). Ce document utilise kdedir() pour dénoter ce répertoire.

- kdedir()/

  - bin/

    - Binaires des applications

  - lib/

    - bibliothèques standards de kde (libkdecore, etc.)

    - &<;appname&>;/

      - Données spécifiques de l'application dépendantes de la plate-forme

  - include/

    - fichiers d'en-tête standards de kde

  - parts/

  - cgi-bin/

    - programmes CGI pour kdehelp

  - share/

    - doc/

      - HTML/

        - default --> Lien vers kdedir()/share/doc/HTML/en

        - &<;lang&>;/

          - &<;appname&>;/

            - index.html

            - autres fichiers d'aide de l'application

    - config/

    - applnk/

      - System/

      - Utilities/

      - Applications/

      - Games/

      - kfind.kdelnk

      - khelp.kdelnk

      - khome.kdelnk

      - krefresh.kdelnk

    - mimelnk/

      - magic

      - text/

      - audio/

    - partlnk/

      - &<;partname&>;.kdelnk

    - icons/

      - Icônes utilisées dans les fichiers kdelnk

      - &<;appname&>;.xpm

      - mini/

        - Mini-icônes pour kpanel

    - toolbar
      /

      - Pixmaps standard de barre d'outils
        (par ex : fileopen.xpm)

    - wallpapers/

      - Papiers peints utilisés par kdisplay

    - apps/

      - &<;appname&>;/

        - toolbar
          /

          - Pixmaps de barre d'outils

        - pics/

          - Autres pixmaps de l'application

        - Données spécifiques à l'application (indépendantes de la plate-forme)

      - &<;libname&>;/

        - pics/

    - locale/

      - &<;lang&>;/

        - LC&&lowbar;;MESSAGES/

          - &<;appname&>;.mo

### Ce que cela signifie pour les développeurs d'application

Une application KDE standard installera ses fichiers à différents endroits dans la structure ci-dessus. Les seuls éléments nécessaires sont le binaire de l'application, le fichier kdelnk de l'application, l'icône de l'application et les fichiers d'aide de l'application - tous les autres sont facultatifs. Les choses les plus couramment installées sont :

    Type de fichier                                   Emplacement

    Binaire de l'application (requis)                 kdedir()/bin/
    Fichier kdelnk de l'application (requis)          kdedir()/share/applnk/
    Icône de l'application icon (requis)              kdedir()/share/icons/&<;appname&>;.xpm
    Fichiers d'aide de l'application (requis)         kdedir()/share/doc/default/HTML/&<;appname&>;/&<;index&>;.html
    Pixmaps de la barre d'outils de l'application     kdedir()/share/apps/&<;appname&>;/toolbar/
    Données de l'application (pour la plate-forme)    kdedir()/share/apps/&<;appname&>;/
    Données de l'application (non-spécifiques)        kdedir()/lib/&<;appname&>;/

### Documentation de l'Application

J'ai suggéré de mettre nécessairement au moins une page dans

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

pour toute application KDE. L'application est libre d'utiliser le répertoire pour stocker toutes les données liées à l'aide dont elle a besoin.

Les applications qui supportent plus d'une langue devront placer les autres langues dans kdedir()/doc/&<;lang&>;/HTML/&<;appname&>;/&<;appname&>;.html avec, comme d'habitude, un répertoire 'lang' pour chaque code de langue. En organisant les fichiers de la sorte, des liens pourront être créés entre les fichiers d'aide de deux applications différentes qui supportent toutes les deux une langue donnée.

Je ne suis pas 100 &&percnt;; satisfait de la solution que j'ai suggérée car elle ne permet pas de se rabattre sur une langue par défaut si une traduction requise n'est pas disponible.

### Ce que cela signifie pour les développeurs de bibliothèques

- kdedir()/share/apps/&<;libname&>;/toolbar

Icônes des barres d'outils pour les widgets de la bibliothèque

- kdedir()/share/apps/&<;libname&>;/pics

Toute autre image bitmap pour les widgets de la bibliothèque

## Utilisation du Système de Fichiers dans les Projets KDevelop

Le chapitre précédent couvrait le standard du Système de Fichiers de KDE, et celui-ci traite de ce que vous avez à faire pour utiliser ce système de fichiers. Un projet KDE utilise le système de fichiers au moins pour les procédures d'installation ; nous parlerons donc des paramètres d'installation des fichiers de votre projet. Votre application peut utiliser des fichiers installés par la suite, il est donc important de savoir comment récupérer le chemin relatif par le standard. Cela permet à votre application de travailler où que soit le système de fichier KDE et évite d'avoir à coder en dur les informations sur les fichiers.

### Accéder à des Fichiers pendant l'Exécution

Après l'installation de votre projet par les utilisateurs, votre application peut avoir besoin d'informations sur les fichiers pendant l'exécution. Lors de la période de développement, vous rencontrerez au moins une erreur au moment où vous lancerez votre application dans l'environnement KDevelop : dans "Aide"-"Contenu" ou en appuyant sur la touche F1, le manuel de l'application sera manquant. Cela se manifeste par un message indiquant que le fichier index.html est introuvable - si vous n'avez pas installé votre application dans votre système de fichiers KDE. Votre application demande à KDEHelp
d'ouvrir votre page d'index en cherchant le répertoire d'installation à travers les méthodes de `
KApplication` pour accéder au système de fichiers, nous allons donc regarder ce que `
KApplication` propose et examiner quelques exemples d'utilisation. D'autres classes de `KDE-Core`, telles que `KIconLoader` et `KLocale`, font aussi usage du système de fichier KDE ; nous en reparlerons plus loin.

### Méthodes de
KApplication

La classe
KApplication offre les méthodes suivantes pour accéder au système de fichiers KDE :

    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 )

Les méthodes sont généralement utilisées avec l'instance de `
KApplication` de votre application, où `
KApplication` offre une macro `kapp` destinée à recevoir le pointeur :

&&num;;define kapp
KApplication::getKApplication()

Les méthodes sont donc généralement utilisées de la façon suivante :

    QString sounddir=kapp->kde_sounddir();

Cet exemple enregistre le chemin du répertoire son de KDE sous forme d'une `QString`, où vous ajouterez par exemple le nom d'un fichier son. Vous pouvez ensuite utiliser cette information et jouer un fichier son qui se trouve là. Vous devriez toujours tester l'existence d'un fichier en utilisant la méthode `exists()` de la classe `QFileInfo`.

Au sein de ces méthodes,

    void invokeHTMLHelp( QString aFilename, QString aTopic ) const [public]

occupe une place privilégiée, puisqu'elle sert à appeler l'aide de KDE. Généralement, vous devriez l'employer partout où l'utilisateur peut avoir besoin d'aide, par exemple lorsqu'on lui présente une boîte de dialogue. La touche F1 ne servira pas à afficher le contenu de l'aide, mais la page d'aide correspondante. Pour en faire bon usage, ajoutez un bouton "Aide" à votre boîte de dialogue et créez un slot à connecter au signal `pressed()`. Dans cette méthode, utilisez `
invokeHTMLHelp()` avec la page et le sujet correspondants ; au cas où la documentation de votre application n'est pas terminée, laissez cette section vide afin de la compléter par la suite.

La documentation de `
KApplication` dit :

Appelle le visualiseur d'aide HTML kdehelp.

Paramètres& ;: aTopic& ;: cela permet l'aide contextuelle. Sa valeur sera concaténée au nom de fichier, précédé d'un "&&num;;" (dièse).

aFilename& ;: le nom du fichier à charger. Son emplacement est déterminé automatiquement selon le KFSSTND. Si aFilename est vide, on utilise le nom logique de l'application (appname) suivi de .html.

Les méthodes de `
KApplication` extrairont les chemins suivants :

    kde_htmldir()         kdedir()/share/doc/HTML         Renvoie le répertoire où KDE enregistre
                                                          sa documentation HTML

    kde_appsdir()         kdedir()/share/applnk           Renvoie le répertoire où les applications KDE
                                                          enregistrent leur fichier .kdelnk

    kde_icondir()         kdedir()/share/icons            Renvoie le répertoire où les icônes KDE sont stockées

    kde_datadir()         kdedir()/share/apps             Renvoie le répertoire où les applications KDE
                                                          enregistrent leurs données propres

    kde_localedir()       kdedir()/share/locale           Renvoie le répertoire où les information relatives aux pays
                                                          (comme les messages traduits par exemple) sont enregistrées

    kde_cgidir()          kdedir()/cgi-bin                Renvoie le répertoire où sont stockés les scripts cgi

    kde_sounddir()        kdedir()/share/sounds           Renvoie le répertoire où les données sonores sont stockées.
                                                          Ce répertoire est destiné aux sons spécifiques à KDE.
                                                          Les données sonores des applications devraient aller
                                                          dans le répertoire kde_datadir()

    kde_toolbardir()      kdedir()/share/toolbar          Renvoie le répertoire où les icônes de barres d'outils sont stockées

    kde_wallpaperdir()    kdedir()/share/wallpapers       Renvoie le répertoire où les fonds d'écran KDE sont stockés

    kde_bindir()          kdedir()/bin                    Renvoie le répertoire où les binaires des applications KDE sont stockés

    kde_configdir()       kdedir()/share/config           Renvoie le répertoire où les fichiers de configuration sont stockés

    kde_mimedir()         kdedir()/share/mimelnk          Renvoie le répertoire où les types MIME sont stockés

    localkdedir()         $HOME/.kde                      Renvoie le répertoire de base de KDE

    localconfigdir()      $HOME/.kde/share/config         Renvoie le répertoire de configuration local de KDE

Pour rechercher un fichier particulier, utilisez `findFile(const char *file)` qui recherchera parmi plusieurs chemins du Système de Fichiers de KDE :

1. $KDEDIR

2. $KDEPATH

3. "&&lsqb;;KDE Setup&&rsqb;;:Path=" entrée dans un fichier de configuration

Si le fichier est introuvable, la méthode isEmpty() de la classe QString renverra True (Vrai)

### Les Méthodes de KIconLoader

QPixmap loadIcon ( const QString &&;name, int w = 0, int h = 0 )

QPixmap reloadIcon ( const QString &&;name, int w = 0, int h = 0)

QPixmap loadMiniIcon ( const QString &&;name , int w = 0, int h = 0 )

QPixmap loadApplicationIcon ( const QString &&;name, int w = 0, int h = 0 )

QPixmap loadApplicationMiniIcon ( const QString &&;name, int w = 0, int h = 0 )

bool insertDirectory ( int index, const QString &&;dir&&lowbar;;name )

### Configurer l'Installation des Fichiers

Nous avons vu plus haut où les applications KDE
devraient placer leurs fichiers et comment accéder à ceux-ci pendant l'exécution, nous allons maintenant voir comment régler les propriétés des fichiers correctement afin qu'ils s'installent au bon endroit. Les Makefiles supportent un ensemble de macros permettant d'installer vos fichiers dans le Système de Fichiers de KDE, celles-ci doivent être utilisées pour configurer l'installation des fichiers.

Pour définir les propriétés, ouvrez votre projet et sélectionnez "Projet"-"Propriétés du Fichier" ce qui ouvrira la boîte de dialogue des Propriétés du Fichier. Celle-ci apparaîtra si vous sélectionnez un nom de fichier actuellement inclus dans le projet. Tout d'abord, un fichier a un type, qui peut être l'un des suivants :

- HEADER : spécifie un fichier comme fichier d'en-tête

- SOURCE : spécifie un fichier comme fichier source

- SCRIPT : spécifie un fichier comme fichier script

- DATA : spécifie un fichier comme fichier de données, qui s'installe généralement comme une icône ou une documentation HTML

- PO : spécifie un fichier comme fichier de traduction

- KDEV&&lowbar;;DIALOG : spécifie un fichier comme fichier de boîte de dialogue destiné à être interprété par la bibliothèque des boîtes de dialogue

Par la suite, un fichier est inclus dans le projet, si "Inclure dans la Distribution" est coché. Cela permet de s'assurer que le fichier sera inclus dans l'archive tar ou le paquetage.

Si un fichier doit être installé, vous devez activer "Installer". Cela permettra de fixer le chemin d'installation pour le fichier sélectionné, là où le nom du fichier est déjà inséré.

Maintenant, comme nous l'avons vu plus haut, le Makefile dispose déjà d'un ensemble de macros pour le Système de Fichiers Standard. Celles-ci sont utilisées pour fixer le chemin d'installation et s'assurer que les fichiers vont réellement se retrouver sur le système de fichiers de KDE et pas ailleurs. Les macros qui peuvent être utilisées doivent être encadrées de parenthèses et sont précédées d'un dollar. Lorsque le script configure construit les Makefiles sur le système de l'utilisateur final, il va déterminer les valeurs pour ces macros qui correspondent au vrai nom de répertoire et étendra la macro Makefile.am vers sa vraie destination.

Si vous regardez un projet d'application KDE standard, vous remarquerez dans les propriétés de votre fichier `index.html` qu'il utilise déjà une macro permettant de déterminer où il doit aller :

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

Cela signifie que make doit installer le fichier index.html dans le répertoire kde-html, sous-répertoire en pour English (Anglais), sous-répertoire de l'application et le nom du fichier. Vous pourriez tout aussi bien utiliser un autre nom de fichier si vous souhaitez le renommer à la destination de l'installation.

Pour la destination des binaires vous devez pour le moment éditer le Makefile.am du projet si vous souhaitez que la destination ne soit pas la section "Application" du tableau de bord :

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

Valeurs possibles (selon le Standard du Système de Fichiers de KDE) :

- Applications

- Games

- Graphics

- Internet

- Multimedia

- Settings

- System

- Utilities

Si vous ne précisez pas de répertoire, votre lien ira directement à la racine du tableau de bord.

La liste suivante contient les macros qui peuvent être utilisées lors de la configuration de l'installation des fichiers :

    kde_htmldir       Où vos docs doivent aller. (contient un sous-répertoire par langue)
    kde_appsdir       Où le fichier application (.kdelnk) doit aller.
    kde_icondir       Où votre icône doit aller.
    kde_minidir       Où votre mini-icône doit aller.
    kde_datadir       Où installer les données de votre application. (Utilisez un sous-répertoire)
    kde_locale        Où les traductions doivent aller. (contient un sous-répertoire par langue)
    kde_cgidir        Où les exécutables cgi-bin doivent aller.
    kde_confdir       Où les fichiers de configuration doivent aller.
    kde_mimedir       Où les types MIME doivent aller.
    kde_toolbardir    Où les icônes de barres d'outils doivent aller.
    kde_wallpaperdir  Où les fonds d'écran doivent aller.

Utilisez ces macros avec les sous-répertoires et les noms de fichiers adéquats pour configurer les propriétés d'installation. Par défaut, la destination des fichers de documentation HTML, du fichier kdelnk, de l'Icône, de la Mini-icône et des traductions est déjà configurée ; vous n'avez donc pas à faire de modification, puisque ceci a été réalisé par l'assistant d'application de KDevelop.

### Organiser les Données du Projet

Un autre problème apparaît souvent dans la création d'un projet, si le développeur souhaite inclure des données supplémentaires qui devront être installées avec le projet. Vous savez où vous voudrez les installer, mais comment les organiser dans l'arborescence du source ?

Il est de bon conseil de rassembler toutes les données dans des répertoires qui correspondent plus ou moins aux Standards du Système de Fichiers de KDE. Prenons par exemple les icônes de barre d'outils
dont peut avoir besoin votre application. Créer ces icônes dans le répertoire principal du projet n'est pas une très bonne idée car elles seront difficiles à retrouver avec un visualiseur de fichier externe et les supprimer serait plus ardu. Créez donc votre icône avec "Fichier"-"Nouveau" et choisissez le sous-répertoire `toolbar
` ; si ce répertoire n'existe pas, il peut facilement être créé avec la boîte de dialogue "sélection du répertoire". Les icônes existantes peuvent être copiées et incluses dans le projet avec "Projet"-"Ajouter fichier(s) existant(s)", où vous devez choisir le fichier et sa destination. Lorsque vous sélectionnez le répertoire destination, vous pouvez créer le sous-répertoire `toolbar
` avant tout dans la boîte de dialogue. Quand vous avez terminé, appuyez sur OK et les fichiers seront copiés et inclus dans le projet.

À titre d'exemple, une icône de barre d'outils
peut aller au chemin suivant :

$(kde&&lowbar;;datadir)/&<;appname&>;/toolbar
/&<;youricon&>;.xpm

Les images et les icônes supplémentaires non utilisées comme les icônes de barre d'outils
peuvent être stockées dans un sous-répertoire pics au lieu de toolbar
.

### Le Fichier `kdelnk`

Le fichier &<;appname&>;.kdelnk
actuellement inclu dans votre projet s'installera dans la structure du tableau de bord de KDE. Vous pourriez penser qu'il est déjà créé, et que vous n'auriez pas d'autres informations à apporter. Malgré les qualités avancées de KDevelop pour vous aider à créer, programmer et concevoir des applications, il ne peut pas déterminer le but exact de votre application - et c'est cette information que vous devez ajouter au fichier kdelnk. Comme c'est un fichier texte, sélectionnez le depuis le RFV ou le LFV ; il sera ouvert dans la fenêtre Fichier En-Tête/Ressources.

Le fichier kdelnk par défaut ressemblera à ça :

    # 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

Il contient déjà la configuration de base pour les données propres à l'application comme l'icône, le nom du binaire, le nom de l'application, etc. Vous pouvez voir que la section Comment (Commentaire) est toujours vide. Vous devez ajouter la bulle d'aide qui sera affichée lorsque le curseur de la souris passera au dessus de l'icône sur le bureau ou dans le tableau de bord. Si scribble était un petit programme de dessin, vous écririez par exemple :

    Comment=Un simple programme de dessin

Chaque ligne de commentaire contiendra par la suite la même description traduite dans la langue symbolisée par les crochets. Demandez aux traducteurs d'ajouter une bonne traduction dans leur langue maternelle ou incluez le fichier kdelnk lorsque vous demandez à ce que le fichier po soit traduit ; la même remarque s'applique au nom de l'application fixée dans les lignes Name.

Pour plus d'informations sur le but du fichier kdelnk, en particulier pour l'interprétation de la ligne de commande, voir Référence des Bibliothèques KDE

## Conseils de Programmation

Approchant de la fin de ce manuel, j'aimerais résumer plusieurs points auxquels les programmeurs devraient être vigilants pendant le codage. Ceux-ci sont principalement des astuces de programmation C++ ayant trait à la programmation KDE et Qt en particulier et sont partiellement issus du Centre du Développeur KDE que vous pouvez trouver sur Internet à l'adresse \|\|, d'autres sont le fruit de mon expérience personnelle.

### Règles générales

Noms de fichiers

  Tout d'abord, lorsque vous créez des fichiers sources, vous devriez toujours utiliser des noms de fichiers en minuscules. KDevelop supporte ceci si vous utilisez l'auto-suggestion de noms de fichiers. Cela permet aux autres développeurs de se souvenir plus facilement des fichiers sources à rechercher lorsqu'ils doivent déboguer votre application.

Noms de classes

  Il est conseillé que les noms de classes des projets KDE respectent ces règles :

  - les noms de classe devraient commencer par la lettre K suivie du nom de la classe exprimant son intérêt. Cela peut être par exemple `KMyWidget` pour un widget spécifique à une application& ;;

  - les champs de classe devraient toujours commencer par des minuscules, avec la première lettre en majuscule pour les mots suivants, comme par exemple `myWidgetPointer()`& ;;

  - les méthodes qui renvoient la valeur d'un champ privé ne devraient pas utiliser le préfixe `get`. Vous devriez lui préférer un nom descriptif. Exemple : `b&&lowbar;;myboolean` est un champ privé. La méthode renvoyant la valeur actuelle serait par exemple `myBoolean()`.

Accès aux fichiers au sein du code

  Vous devez éviter de coder tout chemin en dur, et utiliser les Standards du Système de Fichiers de KDE. Vous avez juste à vérifier le chemin d'installation de vos fichiers par les macros de `Makefile.am` comme décrit dans le présent manuel. Au sein du code, vous devriez utiliser les méthodes de `KApplication` pour extraire le chemin réel.

Documentation des classes

  Autre point déjà mentionné, la documentation des classes. Vous devriez utiliser les règles de formatage de `KDoc` telles qu'elles sont utilisées par tous les développeurs KDE pour documenter leurs classes. Vous devriez ajouter au moins une ligne à chacun des membres de vos classes pour que vous puissiez vous souvenir de leur but et pour que les autres puissent réutiliser votre code. La réutilisation du code par la GPL est bien plus sensée si vous savez où trouver une solution existante et si les classes sont documentées. La Référence de la Bibliothèque Qt est un bon exemple d'interfaces bien documentées, bien qu'elle n'utilise pas `KDoc`.

Utilisez `new` pour créer des widgets

  Au sein de votre implantation, vous devriez toujours préférer la création massive de widgets avec `new`. La bibliothèque Qt a la bonne habitude de supprimer automatiquement tous les widgets fils créés avec `new`, vous n'avez donc pas à utiliser `delete` dans ces cas. C'est une des fonctionnalités pratiques des plus importantes de Qt et vous devriez en user et en abuser.

Deboguage

  Quand vient le moment de déboguer, vous devriez utiliser les macros fournies par `KDebug`. Celles-ci sont similaires aux macros Qt, mais peuvent être obtenues par CTRL+SHIFT+F12. Voir Référence des Bibliothèques KDE pour plus d'informations sur le filtrage d'évenements de ces macros. Vous pourriez aussi utiliser `assert()`, mais vous devriez essayer d'être logique dans votre code de déboguage.

Déclarations `const`

  Par la suite, vous devriez utiliser des déclarations `const` pour les méthodes qui ne devraient changer aucun champ privé. Ce serait le cas pour toutes les méthodes qui retournent seulement la valeur actuelle d'un champ privé. Cela permet d'éviter de modifier une valeur accidentellement et de détecter de telles erreurs dès la compilation. Maintenant, pour l'initialisation des membres const vous devriez combiner const avec `static` et initialiser la valeur en dehors du constructeur, comme ceci :

      class foo {
      	static const int value;
      };

      const foo::value = 10;

  Le C++ ANSI autorise l'initialisation du champ dans le constructeur mais vous devriez l'éviter car certains compilateurs n'offrent pas cette fonctionnalité.
Les méthodes virtuelles

  Comme nous l'avons vu dans la section Interaction avec l'Utilisateur, vous devriez conserver les droits d'accès et la déclaration par `virtual` lorsque vous surchargez des méthodes virtuelles. Tout au moins, vous ne devriez pas réduire l'accès d'une méthode virtuelle de protégé à privé.

Déclarations anticipées

  Les en-têtes de classe doivent être inclus lorsque vous déréférencez n'importe quel objet ou instance de classe dans votre code source. Cela signifie que si votre classe utilise un membre d'une autre classe, vous devriez remplacer la directive &&num;;include par une déclaration anticipée de la classe. Par exemple, au lieu de :

      #include <qpushbutton.h>

      class KMyWidget:public QWidget
      {

      private:
        QPushButton* ok_button;
      };

  déclarez seulement la classe `QPushButton` dans le fichier d'en-tête :

      class QPushButton;

      class KMyWidget:public QWidget
      {

      private:
        QPushButton* ok_button;
      };

  et placez la directive d'inclusion dans le fichier source correspondant où, par exemple, l'instance `ok&&lowbar;;button` est déréférencée avec une méthode de la classe `QPushButton`. Cela permet de gagner du temps à la compilation, spécialement si vous utilisez des instances de classes sur lesquelles vous êtes en train de travailler. Le compilateur recompilera tous les sources qui incluent le fichier d'en-tête si vous avez effectué des modifications à l'interface de la classe, c'est pourquoi un simple ajout d'une méthode qui retourne seulement une valeur interne provoquera le recompilation de tous les sources qui incluent le fichier d'en-tête de cette classe.

Avertissements de Paramètres Inutiles et arguments par défaut

  Vous devriez aussi omettre les paramètres formels des méthodes qui ne nécessitent pas forcément ce paramètre pour fonctionner. Cela évite les avertissements de `paramètre inutilisé` de votre compilateur quand il voit une méthode qui attend un paramètre formel mais ne l'utilise pas dans son implantation. Généralement, vous définirez des arguments par défaut pour plusieurs méthodes. Ils devraient toujours être placés dans la déclaration du membre de la classe au lieu de les définir dans l'implantation des méthodes.

Utiliser `config.h`

  Les projets KDevelop comme tout autre projet qui utilise `autoconf` pour créer les script `configure` produisent un fichier `config.h` après l'exécution du script `configure` sur la machine cible. Les valeurs trouvées par `configure` sont listées dedans et peuvent être utilisées dans le code source. La directive pour inclure le fichier `config.h` est :

      #ifdef HAVE_CONFIG_H
      #include <config.h>
      #endif

  Une des entrées de `config.h` les plus couramment utilisées est probablement le définition du type `bool` pour les compilateurs qui ne respectent pas la norme la plus récente du C++ ANSI.

Utiliser `0` au lieu de `NULL`

  Vous devriez toujours utiliser directement `0` au lieu de `NULL` pour les valeurs prédéfinies comme le font les bibliothèques de KDE et Qt. Cela améliore la portabilité de vos applications pour différents compilateurs qui ont des problèmes avec `NULL`.

Variables temporaires

  Vous devriez toujours déclarer les instances temporaires avant de les utiliser. En général, cela est considéré comme étant meilleur. Par exemple :

      // Ne faites pas :
      for( int i=0; i<n; i++){
        // faire quelque chose
        };

      // Mais écrivez :
      int i;

      for(i=0; i<n; i++){
        // faire quelque chose
        };

  Cela est aussi valable pour les variables temporaires dans les appels de fonctions :

      // Ne faites pas :
      setColor( &&;(QColor(black)) );

      // Mais écrivez :
      QColor color(black);
      setColor( &&;color );

### Dépendances des Systèmes d'Exploitation

Comme les projets KDevelop utilisent les outils GNU pour créer les projets, vous êtes sûr que votre application fonctionnera sur presque tous les systèmes Unix. Cependant, vous pouvez rencontrer des problèmes lors de la compilation de votre application sur un autre Unix parce que les fichiers d'en-tête sont situés à des endroits différents ou bien que vous avez besoin d'une autre implantation, spécialement lorsque vous utilisez des fonctions de bas niveau de l'OS qui peuvent être différentes d'un système à l'autre.

En programmant avec C++ et Qt/KDE, vous avez du remarquer que les classes de Qt contiennent un grand ensemble de fonctionnalités qui sont déjà indépendantes du compilateur et de l'OS et rendent les choses plus simples, des chaînes de caractères (QString) à la lecture/écriture de fichiers (QFile) ; en utilisant Qt, vous rendez donc obsolètes la plupart des spécificités des systèmes d'exploitation.

Néanmoins, si vous utilisez Qt et que vous avez besoin d'utiliser des &&num;;defines pour votre application, vous devriez inclure `qglobal.h` et utiliser les &&num;;defines qui y sont déjà prédéfinis pour différents systèmes d'exploitation et compilateurs, comme ci-dessous.

Au lieu de laisser les distributeurs d'OS appliquer des correctifs à votre application (comme beaucoup le font pour construire des paquetages rpm ou autre), vous devriez utiliser des defines pour les sections qui sont spécifiques au système d'exploitation (mais vous n'avez pas besoin d'utiliser l'option -D à la compilation, les définitions de systèmes d'exploitation sont automatiquement prises en compte). La liste ci-dessous définit les systèmes disponibles et leurs définitions (les defines supplémentaires sont entre parenthèses) :

AIX :

  &&num;;ifdef &&lowbar;;AIX

BSDI Unix :

  &&num;;if defined(bsdi) &&verbar;;&&verbar;; defined(&&lowbar;;&&lowbar;;bsdi&&lowbar;;&&lowbar;;)

Dec Ultrix :

  &&num;;if defined (ultrix) &&verbar;;&&verbar;; defined(&&lowbar;;&&lowbar;;ultrix) &&verbar;;&&verbar;; defined(&&lowbar;;&&lowbar;;ultrix&&lowbar;;&&lowbar;;)

DG Unix :

  &&num;;if defined(DGUX)

FreeBSD :

  &&num;;ifdef &&lowbar;;&&lowbar;;FreeBSD&&lowbar;;&&lowbar;;

GNU Hurd :

  &&num;;if defined(&&lowbar;;&&lowbar;;GNU&&lowbar;;&&lowbar;;)

HP-UX :

  &&num;;if defined (hpux) &&verbar;;&&verbar;; defined (&&lowbar;;&&lowbar;;hpux) &&verbar;;&&verbar;; defined (&&lowbar;;&&lowbar;;hpux&&lowbar;;&&lowbar;;)

Linux :

  &&num;;if defined(linux) &&verbar;;&&verbar;; defined(&&lowbar;;&&lowbar;;linux) &&verbar;;&&verbar;; defined(&&lowbar;;&&lowbar;;linux&&lowbar;;&&lowbar;;)

NetBSD :

  &&num;;ifdef &&lowbar;;&&lowbar;;NetBSD&&lowbar;;&&lowbar;;

OpenBSD :

  &&num;;ifdef &&lowbar;;&&lowbar;;OpenBSD&&lowbar;;&&lowbar;;

OSF Unix :

  &&num;;if defined(&&lowbar;;&&lowbar;;osf&&lowbar;;&&lowbar;;)

QNX :

  &&num;;if defined(&&lowbar;;&&lowbar;;QNX&&lowbar;;&&lowbar;;)

SCO UnixWare :

  &&num;;if defined(&&lowbar;;UNIXWARE)

SCO UnixWare 7 :

  &&num;;if defined(sco) &&verbar;;&&verbar;; defined(&&lowbar;;UNIXWARE7)

SCO :

  &&num;;if defined(&&lowbar;;SCO&&lowbar;;DS) &&verbar;;&&verbar;; defined(M&&lowbar;;UNIX) &&verbar;;&&verbar;; defined(M&&lowbar;;XENIX)

SGI Irix :

  &&num;;if defined(sgi) &&verbar;;&&verbar;; defined(&&lowbar;;&&lowbar;;sgi)

SunOS :

  &&num;;if defined (sun) &&verbar;;&&verbar;; defined (&&lowbar;;&&lowbar;;sun) &&verbar;;&&verbar;; defined (&&lowbar;;&&lowbar;;sun&&lowbar;;&&lowbar;;)

Sun Solaris :

  &&num;;if defined (&&lowbar;;OS&&lowbar;;SUN&&lowbar;;) &&verbar;;&&verbar;; defined (&&lowbar;;&&lowbar;;SVR4)

## Licences

Cette section traite des questions de la licence des applications qui sont créées avec l'EDI KDevelop. D'abord, nous allons présenter le comportement par défaut, nous discuterons des avantages des applications sous licence GPL et enfin, nous traiterons des questions liées au développement commercial d'applications.

### La Licence GPL

KDevelop, lui-même, est sous Licence Publique Générale GNU GPL. Cette licence assure que tout utilisateur peut copier, modifier et redistribuer le paquetage de code source de KDevelop sous les termes de cette licence. La licence garantit cela ainsi que les droits des membres de l'Équipe KDevelop comme auteurs de ce produit.

Au-delà de cette raison et de l'envie d'aider les auteurs de logiciels libres à développer leurs produits, toutes les applications générées par KDevelop contiennent une référence à la licence GPL ainsi qu'une copie de cette licence. Les développeurs peuvent utiliser cette licence comme une base pour distribuer leur produit mais n'y sont pas obligés.

L'auteur, en utilisant la GPL comme licence de son produit, a aussi les avantages suivants :

- vous pouvez utiliser tout code existant sous licence GPL et l'inclure dans votre paquetage (du moment qu'il n'y a pas de restriction qui interfèrent avec la réutilisation du code à cause de limitations de la licence du logiciel utilisé)& ;;

- votre code possède une licence de copyright qui protège vos droits comme auteur original& ;;

- la réutilisation de votre code par d'autres auteurs améliore le développement global d'applications libres.

### Questions sur les Licences de KDE et Qt

La licence de Qt a provoqué des troubles dans la communauté de développement de KDE jusqu'à l'arrivée de Qt 2.0 avec sa licence QPL. La société Troll Tech, en tant que possesseur et créateur de Qt, fournit gratuitement la version Unix de la bibliothèque mais avec la restriction que vous ne pouvez pas changer le code distibué et le redistribuer sans leur accord explicite. C'est la raison pour laquelle de nombreux développeurs de logiciels libres ont eu tendance à condamner cette licence car elle n'était pas absolument libre, particulièrement pour effectuer des modifications. D'un autre côté, la bibliothèque Qt offre de nombreux avantages qui la rendent très attractive pour développer des applications commerciales :

- en achetant une licence commerciale, vous pouvez écrire des applications portables pour les plates-formes Unix et Windows

- l'architecture de classes et d'applications fournit une bonne solution pour simplifier la conception d'application

- vous pouvez développer pour les Unices sans dépendre de la licence GPL lorsque vous utilisez une licence commerciale.

Le projet KDE a choisi la bibliothèque Qt comme base du développement de l'environnement de bureau pour les systèmes Unix et de l'architecture d'application étendue qui complète les possibilités de Qt. Les développeurs peuvent tirer profit de KDE en utilisant les bibliothèques fournies.

Les bibliothèques de KDE sont distribuées sous licence LGPL, la licence GNU GPL pour les bibliothèques (NdT : GNU Library General Public License). Qu'est-ce que cela signifie pour les développeurs ?

#### Développement non-commercial

Pour un développement non-commercial, la bibliothèque Qt est fournie gratuitement. Votre application peut utiliser la bibliothèque du moment qu'elle ne la modifie pas et que le développeur fournit aussi gratuitement le code source de son application.

La LGPL des bibliothèques de KDE garantit aussi l'utilisation des bibliothèques de KDE pour un développement non-commercial. Vous pouvez utiliser les bibliothèques de KDE autant que votre application en a besoin.

#### Développement commercial

Pour un développement commercial, la société Troll Tech permet d'acheter une licence commerciale. Cela permet d'utiliser la bibliothèque Qt pour des développements, selon les besoins de votre application ou de votre projet. Vous pouvez distribuer votre application comme vous voulez, sous la forme de binaires ou de code source, indépendamment de toute licence GPL.

Lorsque vous utilisez les bibliothèques de KDE, vous devez consulter la licence LGPL qui permet explicitement le développement commercial en utilisant des bibliothèques distribuées sous licence LGPL. Vous devez juste regarder les clauses de la licence pour connaître les restrictions qui apparaissent lorsque vous utilisez les bibliothèques de KDE comme base de développement d'une application commerciale basée sur KDE.

### La Licence de votre Produit

Par cela, l'Équipe KDevelop, en tant qu'auteur de l'Environnement de Développement Intégré KDevelop, vous permet de distribuer toute application qui a été créée par et avec l'EDI KDevelop sous les termes de la licence de votre choix, dépendant seulement des termes de la licence qui viendrait des restrictions qui sont créées par l'utilisation de code qui est placé dans les bibliothèques utilisées par le produit final. Celles-ci sont :

- pour les applications Qt : les restrictions de la licence de Qt qui s'appliquent à la nature de votre distribution, selon que c'est du logiciel non-commercial (libre) ou commercial& ;;

- pour les applications KDE : les restrictions de la licence de Qt selon la nature de votre distribution plus les restrictions de la LGPL (GNU Library General Public License) telle qu'elle est incluse dans votre copie des bibliothèques de KDE& ;;

- pour tous les autres codes sources pré-générés, vous êtes libre du choix de la licence.

C'est pourquoi, vous pouvez changer la licence par défaut telle qu'elle est incluse dans toute architecture d'application ou application de base générée par KDevelop selon votre choix ; vous devez seulement veiller aux restrictions dues aux bibliothèques avec lesquelles votre application est liée.

Si vous avez des questions supplémentaires sur les licences, n'hésitez pas à interroger l'Équipe KDevelop.

## Références

Le Manuel de Programmation de KDevelop contient des informations tirées des diverses sources sur Internet ou de courriers électroniques provenant de différentes listes de discussion comme :

Documentation de KDoc
: Sirtaj S. Kang taj@.kde.org

Centre du Développeur KDE maintenu par Sirtaj S. Kang taj@.kde.org

Internationalisation de KDE : Matthias Elter me@kde.org

Documentation de KDebug : Kalle Dalheimer kalle@kde.org

Le Système de Fichiers Standard de KDE : Richard Moore rich@kde.org

mini-HOWTO du Développeur KDE : David Sweet <dsweet@chaos.umd.edu>

Le contenu des chapitres correspondants sont la propriété des auteurs originaux.

## Copyright

    KDevelop Copyright 1998, 1999, 2000 L'Équipe KDevelop.

    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.

## Informations supplémentaires

### Exemple de Makefile.am pour une bibliothèque partagée

    # Exemple de Makefile.am pour une bibliothèque partagée. Ceci construit
    # une bibliothèque nommée "example" comme libexample.so.2.1.2
    # Ce Makefile.am est tiré des kdelibs et a été modifié pour servir
    # d'exemple.
    #
    # David Sweet
    #

    INCLUDES=  $(all_includes)

    lib_LTLIBRARIES  = libexample.la

    # Note : Si vous spécifiez a:b:c comme version à la ligne suivante,
    #  la bibliothèque générée aura la version (a-c).c.b. Dans cet exemple,
    #  la version est 2.1.2.
    libexample_la_LDFLAGS = -version-info 3:2:1 $(all_libraries)

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

    # Quels en-têtes ne doivent pas être installés lors du make install ?
    noinst_HEADERS = version.h

    libexample_la_SOURCES = code1.cpp code2.cpp
    						code3.cpp

    #  USE_AUTOMOC est pratique. Il se charge de toutes les dépendances
    #  venant de moc.
    #  (Vous devez quand même inclure, par exemple, header1.moc dans code1.cpp)
    libexample_la_METASOURCES = USE_AUTOMOC