<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook V3.1-Based Variant V1.0//EN" [
 <!ENTITY kdevelop "<application>kdevelop</application>">
 <!ENTITY tex "<application>TeX</application>">
 <!ENTITY latex "<application>LaTeX</application>">
 <!ENTITY etago "&lt;/">
 <!ENTITY % addindex "IGNORE">
 <![ %addindex; [ <!ENTITY docindex SYSTEM "docindex.docbook"> ]]>
]>
<book lang="fr">

<bookinfo>
<title>Le Manuel de Programmation de KDevelop</title>
<subtitle>Le Manuel de l'Utilisateur pour la Conception d'Applications C++
pour l'Environnement de Bureau KDE avec l'EDI KDevelop, Version 1.2</subtitle>
<authorgroup>

<author>
<firstname>Ralf</firstname>
<surname>Nolden</surname>
<affiliation>
<orgname>L'Équipe KDevelop</orgname>
<address><email>Ralf.Nolden@post.rwth-aachen.de</email></address>
</affiliation>
</author>

<othercredit role="translator">
<firstname>François-Xavier</firstname>
<surname>Duranceau</surname>
<affiliation>
<address><email>duranceau@kde.org</email></address>
</affiliation>
</othercredit>

<othercredit role="translator">
<firstname>Anne-Marie</firstname>
<surname>Mahfouf</surname>
<affiliation>
<address><email>a-m.mahfouf@lineone.net</email></address>
</affiliation>
</othercredit>

<othercredit role="translator">
<firstname>Ludovic</firstname>
<surname>Grossard</surname>
<affiliation>
<address><email>ludovic.grossard@libertysurf.fr</email></address>
</affiliation>
</othercredit>

<othercredit role="translator">
<firstname>Erwan</firstname>
<surname>Loisant</surname>
<affiliation>
<address><email>erwan@fr.st</email></address>
</affiliation>
</othercredit>

</authorgroup>
<date>07/07/1999</date>
<releaseinfo>1.02.00</releaseinfo>
<keywordset>
<keyword>KDE</keyword>
</keywordset>
<abstract>
<para>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 <link linkend="Copyright">Copyright</link> pour plus de
détails.</para>
</abstract>
</bookinfo>

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

<para> 
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.  </para>

<sect1 id="ce-que-vous-devriez-dj-savoir">
<title>Ce que vous devriez déjà savoir </title>

<para>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 <indexterm remap="idx"><primary>Qt</primary></indexterm> ainsi que les bibliothèques
de KDE <indexterm remap="idx"><primary>bibliothèques
de KDE</primary></indexterm> et la conception d'Interfaces Utilisateur. Vous devriez aussi vous
familiariser avec KDevelop en lisant <ulink url="../index.html">Le Manuel d'Utilisation de KDevelop</ulink> qui contient une description complète des
fonctionnalités fournies par l'EDI.    </para>
</sect1>

<sect1 id="propos-de-ce-manuel">
<title>À propos de ce Manuel </title>

<para>  
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 <indexterm remap="idx"><primary>barres
d'outils</primary></indexterm>, les barres de menus et les zones de vues.    </para>

<para>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.    </para>

<para>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 <indexterm remap="idx"><primary>API</primary></indexterm>  et à étoffer les manuels en ligne.    
<emphasis remap="bf">Dans le chapitre suivant</emphasis>, nous nous attarderons sur les bibliothèques de
KDE et de Qt <indexterm remap="idx"><primary>bibliothèques de
KDE et de Qt</primary></indexterm> , 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 <indexterm remap="idx"><primary>Qt</primary></indexterm> 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.      </para>

<para><emphasis remap="bf">Dans les chapitres suivants</emphasis>, vous apprendrez :  
<itemizedlist>
<listitem>
<para>comment créer une application avec le KAppWizard</para>
</listitem>
<listitem>
<para>ce que les squelettes de projet fournissent eux-mêmes</para>
</listitem>
<listitem>
<para>ce que signifie le code déjà créé</para>
</listitem>
<listitem>
<para>comment créer vos propres vues</para>
</listitem>
<listitem>
<para>comment étendre les fonctionnalités de votre application avec 
des boîtes de dialogue, des barres de menus et des barres d'outils <indexterm remap="idx"><primary>barres d'outils</primary></indexterm></para>
</listitem>
<listitem>
<para>comment rendre votre application conviviale en fournissant des fonctions d'aide et  </para>
</listitem>
<listitem>
<para>comment écrire une documentation en ligne en SGML <indexterm remap="idx"><primary>SGML</primary></indexterm>.  </para>
</listitem>
</itemizedlist>
   </para>
</sect1>

<sect1 id="informations-supplmentaires">
<title>Informations supplémentaires </title>

<para>  
Des informations supplémentaires sur la programmation
avec Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>/KDE sont accessibles de différentes manières :    
<itemizedlist>
<listitem>
<para><emphasis>Programmer avec Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></emphasis> par Matthias Kalle Dalheimer, publié par
O'Reilly (voir <ulink url="http://www.oreilly.com">\|\|</ulink>), qui traite de presque tous
les aspects de la boîte à outils graphique   Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> et contient aussi des
exemples</para>
</listitem>
<listitem>
<para><ulink url="../index.html">Le Manuel d'Utilisation de KDevelop</ulink>, fourni avec l'EDI KDevelop,  </para>
</listitem>
<listitem>
<para><emphasis>Référence en ligne</emphasis> de la bibliothèque Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, fournie au format HTML 
avec votre copie de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> et disponible en PostScript sur <ulink url="http://www.troll.no">\|\|</ulink>  </para>
</listitem>
<listitem>
<para>Sur Internet, consultez    
<itemizedlist>
<listitem>
<para>le site web de Troll Tech à <ulink url="http://www.troll.no">\|\|</ulink></para>
</listitem>
<listitem>
<para>le site web de KDE à <ulink url="http://www.kde.org">\|\|</ulink></para>
</listitem>
<listitem>
<para>le site web du développeur KDE à <ulink url="http://developer.kde.org">\|\|</ulink></para>
</listitem>
<listitem>
<para>la page d'accueil de KDevelop à <ulink url="http://www.kdevelop.org">\|\|</ulink></para>
</listitem>
</itemizedlist>
  </para>
</listitem>
</itemizedlist>
   
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++. </para>

<para>Pour obtenir de l'aide sur l'EDI KDevelop, vous pouvez envoyez vos requêtes à notre 
liste de discussion à <ulink url="mailto:kdevelop@fara3.cs.uni-potsdam.de">kdevelop@fara3.cs.uni-potsdam.de</ulink>. 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. </para>
</sect1>
</chapter>

<chapter id="les-bibliothques-de-kde-et-qt-qt">
<title>Les Bibliothèques de KDE et Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> </title>

<para> 
La société norvégienne Troll Tech (<ulink url="http://www.troll.no">\|\|</ulink>) fournit une boîte 
à outils graphique (NdT&&nbsp;;: GUI toolkit)  nommée Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>. Ici, graphique doit 
être pris au sens  d'"<emphasis remap="bf">I</emphasis>nterface <emphasis remap="bf">U</emphasis>tilisateur <emphasis remap="bf">G</emphasis>raphique" (NdT&&nbsp;;: GUI 
signifie littéralement Graphical User Interface). Les applications basées sur Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> 
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 <indexterm remap="idx"><primary>Qt</primary></indexterm> offre des avantages techniques qui rendent 
la conception d'applications vraiment simple. En plus, Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> est aussi disponible
pour les systèmes Microsoft Windows, ce qui permet aux développeurs de fournir leurs 
applications pour les deux plates-formes. </para>

<para>L'équipe KDE (<ulink url="http://www.kde.org">\|\|</ulink>) dont le but est de rendre l'utilisation 
des Systèmes Unix plus conviviale a décidé d'utiliser la boîte à outils Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> 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 <emphasis>kwm</emphasis>, le 
gestionnaire de fichiers <emphasis>kfm</emphasis>  et le tableau de bord <emphasis>kpanel</emphasis> 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 <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm> 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 <indexterm remap="idx"><primary>glisser-déposer</primary></indexterm>, autorisent la gestion de session et bien plus si toutes les 
fonctionnalités offertes par les bibliothèques de KDE <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm> sont utilisées. </para>

<para>La boîte à outils Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> et les bibliothèques de KDE <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm> 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 <indexterm remap="idx"><primary>les applications KDE</primary></indexterm> et Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> sont créées, en général. </para>

<sect1 id="la-bote-outils-graphique-qt-qt">
<title>La boîte à outils graphique Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> </title>

<para> 
Comme mentionné précédemment, la bibliothèque Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> 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 : </para>

<para><itemizedlist>
<listitem>
<para>un ensemble complet de classes et de méthodes prêtes à être utilisées 
même pour des fonctions non graphiques</para>
</listitem>
<listitem>
<para>une bonne solution pour les interactions avec l'utilisateur par 
l'intermédiaire des méthodes virtuelles et du mécanisme signal/slot</para>
</listitem>
<listitem>
<para>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</para>
</listitem>
<listitem>
<para>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...).  </para>
</listitem>
</itemizedlist>
    </para>

<para>Il apparaît donc essentiel de connaître les classes de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, 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 <indexterm remap="idx"><primary>Qt</primary></indexterm> ; ensuite, nous en ferons
un programme KDE.   </para>

<sect2 id="la-premire-application-qt-qt">
<title>La première Application Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> </title>

<para>  Comme d'habitude, les programmes écrits en C++ doivent contenir une fonction
<literal remap="tt">main()</literal> 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 <indexterm remap="idx"><primary>Qt</primary></indexterm>, 
expliquer les étapes de base de l'exécution et voir pourquoi et comment la
fenêtre de l'application apparaît :    
<screen> 
#include &lt;qapplication.h&gt; 
#include &lt;qpushbutton.h&gt; 
 
int main( int argc, char **argv ) 
{ 
QApplication a( argc, argv ); 
 
QPushButton hello( "Hello world!" ); 
hello.resize( 100, 30 ); 
 
a.setMainWidget( &&amp;;hello ); 
hello.show(); 
return a.exec(); 
} 
</screen>
 </para>

<para>Globalement, l'application dessine une fenêtre contenant un bouton dont le 
texte est "Hello world". Comme pour toute application basée sur Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, 
vous devez d'abord créer une instance de la classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>, 
ici représentée par <literal remap="tt">a</literal>. </para>

<para>Ensuite, le programme crée une instance de la classe <literal remap="tt">QPushButton</literal> appelée 
<literal remap="tt">hello</literal>, ce sera le bouton. Le constructeur de <literal remap="tt">hello</literal> 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. </para>

<para>Ensuite, la méthode <literal remap="tt">resize()</literal> est appelée pour le bouton <literal remap="tt">hello</literal>. 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 <literal remap="tt">setMainWidget()</literal> est appelée pour <literal remap="tt">a</literal> et la méthode <literal remap="tt">show()</literal> 
pour <literal remap="tt">hello</literal>. La <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> est enfin exécutée par le <literal remap="tt">a.exec()</literal>, 
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. </para>
</sect2>

<sect2 id="le-manuel-de-rfrence-de-qt-qt">
<title>Le Manuel de Référence de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> </title>

<para> 
Maintenant, regardons rapidement le manuel de référence de la 
bibliothèque Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>. Pour cela, lançons KDevelop et choisissons 
"Bibliothèque Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>" 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 <indexterm remap="idx"><primary>Qt</primary></indexterm>. 
Ce sera votre source d'information privilégiée sur Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, 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 (<literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> et <literal remap="tt">QPushButton</literal>), sélectionnez 
"Alphabetical Class List" et cherchez les noms correspondants. Cliquez sur le 
lien pour consulter la documentation de la classe <indexterm remap="idx"><primary>documentation de la classe</primary></indexterm>. </para>

<para>Pour <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>, 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. </para>
</sect2>

<sect2 id="dissection-de-lexemple">
<title>Dissection de l'exemple </title>

<para> 
En commençant par <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>, vous trouverez toutes les méthodes 
utilisées dans notre premier exemple : </para>

<para><itemizedlist>
<listitem>
<para>le constructeur <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication()</literal></para>
</listitem>
<listitem>
<para>la méthode <literal remap="tt">setMainWidget()</literal> et</para>
</listitem>
<listitem>
<para>la méthode <literal remap="tt">exec()</literal>. </para>
</listitem>
</itemizedlist>
 </para>

<para>Disséquons l'utilisation de ces méthodes : </para>

<para><orderedlist><listitem>
<para>créer d'abord une instance de la classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> avec le 
constructeur afin de pouvoir utiliser les éléments graphiques fournis par Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> </para>
</listitem>
<listitem>
<para>créer un widget qui sera le contenu de la fenêtre du programme</para>
</listitem>
<listitem>
<para>définir le widget comme widget principal pour <literal remap="tt">a</literal></para>
</listitem>
<listitem>
<para>exécuter l'instance <literal remap="tt">a</literal> de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>. </para>
</listitem>
</orderedlist>
 </para>

<para>Le second objet de notre programme est le PushButton, une instance de la classe 
<literal remap="tt">QPushButton</literal>.  
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 
<literal remap="tt">resize()</literal> pour changer la taille du bouton en fonction de son contenu - le bouton 
doit être agrandi pour que la chaîne apparaisse complètement. </para>

<para>Et la méthode <literal remap="tt">show()</literal> ? Eh bien, vous constatez que, comme la plupart des autres 
widgets, <literal remap="tt">QPushButton</literal> est basé sur un héritage simple - ici, la documentation 
indique <emphasis>Inherits</emphasis> <literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal>. Suivez le lien vers la classe 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal>. 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 <literal remap="tt">show()</literal> n'est pas listée, c'est sûrement une méthode 
fournie par l'héritage. La classe dont hérite <literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal> est <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>.</para>

<para>Suivez à nouveau le lien et vous verrez un grand nombre de méthodes que la classe 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> définit (dont la méthode <literal remap="tt">show()</literal>). Maintenant, nous comprenons 
mieux ce qui s'est passé avec le bouton dans l'exemple : </para>

<para><orderedlist><listitem>
<para>créer une instance de <literal remap="tt">QPushButton</literal>, utiliser le deuxième constructeur 
pour définir le texte du bouton  </para>
</listitem>
<listitem>
<para>redimensionner le widget pour que tout le texte qu'il contient apparaisse</para>
</listitem>
<listitem>
<para>définir le widget comme étant le widget principal de l'instance <literal remap="tt">a</literal> de 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal></para>
</listitem>
<listitem>
<para>dire au widget de s'afficher sur l'écran en appelant <literal remap="tt">show()</literal>, une méthode 
héritée de  <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>. </para>
</listitem>
</orderedlist>
 </para>

<para>Après l'appel à la méthode <literal remap="tt">exec()</literal>, 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 <indexterm remap="idx"><primary>Qt</primary></indexterm>, 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 <indexterm remap="idx"><primary>Qt</primary></indexterm> fournit pour 
traiter les événements utilisateur. </para>

<para>(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 <indexterm remap="idx"><primary>documentation de la classe</primary></indexterm> <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> et <ulink url="../kde_libref/index.html">le Guide de Référence des Bibliothèques de KDE</ulink>).</para>

<para><emphasis remap="bf">Résumé :</emphasis> </para>

<para>Une application Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> doit toujours avoir une instance de la classe 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>. 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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> 
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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> pour être visibles. </para>
</sect2>

<sect2 id="user-interaction">
<title>Interaction avec l'Utilisateur </title>

<para> 
Après avoir lu les dernières sections, vous devriez déjà savoir : 
<itemizedlist>
<listitem>
<para>ce que fournit la bibliothèque Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> en termes d'applications graphiques </para>
</listitem>
<listitem>
<para>comment un programme utilisant Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> est créé</para>
</listitem>
<listitem>
<para>où et comment chercher des informations, avec le navigateur de documentation, 
sur les classes que vous voulez utiliser.</para>
</listitem>
</itemizedlist>
 </para>

<para>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. </para>

<para>Pour cela, le système de fenêtrage (NdT : Window system) envoie tous les événements 
d'interaction à l'application correspondante. La <indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication les envoie ensuite 
à la fenêtre active sous la forme d'un <literal remap="tt"><indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent</literal> et les widgets eux-mêmes 
doivent décider ce qu'ils veulent en faire. Un widget reçoit l'événement et traite 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>::<literal remap="tt">event(<indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent*)</literal>, 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 <literal remap="tt">event()</literal> 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 : </para>

<para><emphasis remap="bf">a) Événements clavier -- touches TAB et Shift-TAB :</emphasis> </para>

<para>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 
<literal remap="tt">setFocusPolicy<indexterm remap="ncdx"><primary><literal>setFocusPolicy()</literal></primary></indexterm>()</literal> et traitant les gestionnaires d'événements : </para>

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

<para><emphasis remap="bf">b) toutes les autres entrées du clavier :</emphasis> 
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void keyPressEvent<indexterm remap="ncdx"><primary><literal>keyPressEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QKeyEvent</literal></primary></indexterm>QKeyEvent * )</literal> </para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void keyReleaseEvent<indexterm remap="ncdx"><primary><literal>keyReleaseEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QKeyEvent</literal></primary></indexterm>QKeyEvent * )</literal> </para>
</listitem>
</itemizedlist>
 </para>

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

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

<para><emphasis remap="bf">e) événements de la fenêtre contenant le widget :</emphasis> 
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void moveEvent ( <indexterm remap="cdx"><primary><literal>QMoveEvent</literal></primary></indexterm>QMoveEvent * )</literal> </para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void resizeEvent ( <indexterm remap="cdx"><primary><literal>QResizeEvent</literal></primary></indexterm>QResizeEvent * )</literal> </para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void closeEvent ( <indexterm remap="cdx"><primary><literal>QCloseEvent</literal></primary></indexterm>QCloseEvent * )</literal> </para>
</listitem>
</itemizedlist>
 </para>

<para>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. <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> 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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>. </para>
</sect2>

<sect2 id="interaction-entre-objets-par-signal-et-slot">
<title>Interaction entre Objets par Signal et Slot </title>

<para> 
Nous arrivons maintenant à l'avantage le plus évident de la boîte à outils Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> : 
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 <literal remap="tt">callback</literal> 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 <indexterm remap="idx"><primary>Qt</primary></indexterm> et expliqué dans <emphasis>Programmer avec Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></emphasis> par K.&&nbsp;;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 : </para>

<para><orderedlist><listitem>
<para>la déclaration d'une classe utilisant des "signaux/slots" doit contenir
la macro <literal remap="tt">Q&&lowbar;;OBJECT</literal> au début (sans le point-virgule) et doit dériver de la 
classe <literal remap="tt">QObject</literal></para>
</listitem>
<listitem>
<para>un signal peut être émis par le mot-clé <literal remap="tt">emit</literal>, exemple <literal remap="tt">emit signal(parameters);</literal> 
de l'intérieur de n'importe quelle fonction membre d'une classe qui autorise les 
signaux/slots</para>
</listitem>
<listitem>
<para>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 <literal remap="tt">signals:</literal></para>
</listitem>
<listitem>
<para>toutes les méthodes qui peuvent être connectées à un signal sont déclarées dans des 
sections avec le mot-clé supplémentaire <literal remap="tt">slot</literal>, exemple : <literal remap="tt-bf">public slots:</literal> dans 
la déclaration de la classe</para>
</listitem>
<listitem>
<para>le compilateur de méta-objet <literal remap="tt">moc</literal> 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 <literal remap="tt">moc</literal> sont ensuite compilés par le compilateur C++. </para>
</listitem>
</orderedlist>
 </para>

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

<para>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. </para>

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

<sect3 id="exemple-dutilisation">
<title>Exemple d'utilisation </title>

<para> 
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 : </para>

<para><screen> 
#include &lt;qapplication.h&gt; 
#include &lt;qpushbutton.h&gt; 
 
int main( int argc, char **argv ) 
{ 
QApplication a( argc, argv ); 
 
QPushButton hello( "Hello world!" ); 
hello.resize( 100, 30 ); 
 
a.setMainWidget( &&amp;;hello ); 
 
connect(&&amp;;hello, SIGNAL( clicked() ), &&amp;;a, SLOT( quit() )); 
 
hello.show(); 
return a.exec(); 
} 
</screen>
 </para>

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

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

<para>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, <emphasis>est</emphasis> le slot qui sera exécuté lors de l'émission du signal. </para>

<para>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 
<ulink url="../kde_libref/index.html">Le Guide de Référence des Bibliothèques de KDE</ulink> 
et dans le Manuel de Référence de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>. </para>
</sect3>
</sect2>
</sect1>

<sect1 id="ce-que-fournit-kde">
<title>Ce que fournit KDE </title>

<sect2 id="les-bibliothques-de-kde-1.1.x">
<title>Les bibliothèques de KDE 1.1.x </title>

<para> 
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 <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm> dans cette version. Les principales 
bibliothèques de KDE <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm> que vous allez utiliser pour créer vos propres applications KDE <indexterm remap="idx"><primary>applications KDE</primary></indexterm> 
sont&&nbsp;;: </para>

<para><itemizedlist>
<listitem>
<para>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 </para>
</listitem>
<listitem>
<para>la bibliothèque KDE-UI, contenant des éléments d'interface utilisateur
comme les barres de menus, les barres d'outils <indexterm remap="idx"><primary>barres d'outils</primary></indexterm>, etc</para>
</listitem>
<listitem>
<para>la bibliothèque KFile, contenant les boîtes de dialogue de sélection de fichier.</para>
</listitem>
</itemizedlist>
   
En plus, pour des applications spécifiques, KDE fournit les bibliothèques suivantes : </para>

<para><itemizedlist>
<listitem>
<para>la bibliothèque KHTMLW, contenant un widget complet interprétant du HTML, qui est 
utilisé dans différents programmes comme KDEHelp <indexterm remap="idx"><primary>KDEHelp</primary></indexterm>, KFM ou KDevelop</para>
</listitem>
<listitem>
<para>la bibliothèque KFM, permettant d'utiliser le gestionnaire de fichiers de KDE à 
l'intérieur de n'importe quelle application</para>
</listitem>
<listitem>
<para>la bibliothèque KAB, le KAddressBook. Elle fournit un accès au carnet d'adresses 
pour des applications telles que les clients de messagerie</para>
</listitem>
<listitem>
<para>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). </para>
</listitem>
</itemizedlist>
 </para>

<para>Maintenant, nous allons regarder ce qui doit être fait pour convertir notre 
application Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>  en une application KDE. </para>
</sect2>

<sect2 id="exemple-dapplication-kde">
<title>Exemple d'Application KDE </title>

<para> 
Dans la suite, vous allez voir qu'écrire une application KDE n'est vraiment pas plus 
difficile que d'écrire une application Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>. 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 <indexterm remap="idx"><primary>Qt</primary></indexterm> utilisé 
précédemment : </para>

<para><screen> 
#include &lt;kapp.h&gt; 
#include &lt;qpushbutton.h&gt; 
 
int main( int argc, char **argv ) 
{ 
KApplication a( argc, argv ); 
 
QPushButton hello( "Hello world!" ); 
hello.resize( 100, 30 ); 
 
a.setTopWidget( &&amp;;hello ); 
 
connect(&&amp;;hello, SIGNAL( clicked() ), &&amp;;a, SLOT( quit() )); 
 
hello.show(); 
return a.exec(); 
} 
</screen>
 </para>

<para>D'abord, vous voyez que nous avons changé <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> en <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>. 
Ensuite, nous avons du changer la méthode <literal remap="tt">setMainWidget()</literal> précédemment utilisée en
<literal remap="tt">setTopWidget</literal> que <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> 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. </para>

<para>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. </para>

<para>Nous vous conseillons aussi de compléter ce chapitre en approfondissant le manuel de 
référence de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, et plus spécialement les classes <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>, 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> et <literal remap="tt">QObject</literal>, ainsi que la documentation de la classe 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> de la bibliothèque KDE-Core. Le manuel de 
<ulink url="../kde_libref/index-3.html">Référence des Bibliothèques de KDE</ulink> 
donne aussi une description complète sur l'appel des constructeurs de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> 
et <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>, y compris le traitement des arguments de la ligne de commande. </para>
</sect2>
</sect1>
</chapter>

<chapter id="creating-new-applications">
<title>Créer une nouvelle Application </title>

<para> 
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 : </para>

<para><itemizedlist>
<listitem>
<para>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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> et une barre d'état ainsi qu'un ensemble de 
documentations standards basées sur SGML <indexterm remap="idx"><primary>SGML</primary></indexterm>, des liens KDE et des icônes d'applications. 
C'est le type d'application généralement utilisé pour un nouveau projet KDE&&nbsp;;; </para>
</listitem>
<listitem>
<para>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&&nbsp;;;</para>
</listitem>
<listitem>
<para>Application Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Normale : globalement similaire à une application KDE normale 
avec la différence que le projet est uniquement basé sur la bibliothèque Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> 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 <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm> pour 
l'utilisateur final&&nbsp;;;</para>
</listitem>
<listitem>
<para>Application C : uniquement basée sur le compilateur C, elle s'exécute dans une 
console&&nbsp;;;</para>
</listitem>
<listitem>
<para>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&&nbsp;;;</para>
</listitem>
<listitem>
<para>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).</para>
</listitem>
</itemizedlist>
 </para>

<para>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. </para>

<sect1 id="appel-de-kappwizard-et-gnration-de-projet">
<title>Appel de KAppWizard et Génération de Projet </title>

<sect2 id="lancement-de-kappwizard-et-premire-page">
<title>Lancement de KAppWizard et Première Page </title>

<para> 
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. </para>
</sect2>

<sect2 id="la-page-des-paramtres-de-gnration">
<title>La Page des Paramètres de Génération </title>

<para> 
Pour notre application exemple, nous choisissons <literal remap="tt">KScribble</literal> 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. </para>

<para>Ensuite, vous devez saisir le numéro de version. Pour la première version, définissez 
le à <literal remap="tt">0.1</literal>. 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. </para>

<para>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. </para>

<para>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. </para>

<para>Ces options sont : 
<itemizedlist>
<listitem>
<para><emphasis remap="bf">générer les sources et les en-têtes :</emphasis>  génère le code source de 
l'application </para>
</listitem>
<listitem>
<para><emphasis remap="bf">Fichiers standards GNU :</emphasis>  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</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Manuel d'utilisation :</emphasis> le manuel d'utilisation en SGML <indexterm remap="idx"><primary>SGML</primary></indexterm>, déjà préparé 
pour votre projet</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Documentation de l'API <indexterm remap="idx"><primary>API</primary></indexterm> :</emphasis> crée une documentation initiale au format HTML 
pour l'Interface de Programmation d'Application (NdT : API signifie littéralement 
<emphasis remap="bf">A</emphasis>pplication <emphasis remap="bf">P</emphasis>rogramming <emphasis remap="bf">I</emphasis>nterface)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Fichier lsm :</emphasis> le "Linux Software Map", utilisé par les sites de distribution, 
il contient une description rapide sur le but du projet et ses prérequis</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Fichier .kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm> :</emphasis> un lien KDE qui installera votre application dans 
le menu "Applications" du tableau de bord de KDE</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Icône de Programme :</emphasis> une icône qui représente votre projet et peut être 
utilisée pour créer un lien sur le bureau.</para>
</listitem>
</itemizedlist>
 </para>

<para>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. </para>
</sect2>

<sect2 id="les-modles-des-en-ttes-et-des-fichiers-sourc">
<title>Les modèles des En-têtes et des fichiers Sources</title>

<para> 
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. </para>

<para>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. </para>

<para>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. </para>

<para>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. </para>
</sect2>

<sect2 id="cration-du-projet">
<title>Création du Projet </title>

<para> 
Maintenant que vous avez défini toutes les options de <emphasis>KScribble</emphasis>,
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".    </para>

<para>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.    </para>

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

<sect1 id="la-premire-construction">
<title>La Première Construction </title>

<para>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 :</para>

<para><emphasis remap="bf">En-têtes :</emphasis>  
<itemizedlist>
<listitem>
<para><emphasis remap="bf">kscribble.h :</emphasis> contient la déclaration de la classe <emphasis remap="bf">KScribbleApp</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">kscribbledoc.h :</emphasis> contient la déclaration de la classe <emphasis remap="bf">KScribbleDoc</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">kscribbleview.h :</emphasis> contient la déclaration de la classe <emphasis remap="bf">KScribbleView</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">resource.h :</emphasis> contient un ensemble de macros pour les identificateurs de menus  </para>
</listitem>
</itemizedlist>
    
<emphasis remap="bf">Sources :</emphasis> 
<itemizedlist>
<listitem>
<para><emphasis remap="bf">kscribble.cpp :</emphasis> contient l'implantation de la classe <emphasis remap="bf">KScribbleApp</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">kscribbledoc.cpp :</emphasis> contient l'implantation de la classe <emphasis remap="bf">KScribbleDoc</emphasis> </para>
</listitem>
<listitem>
<para><emphasis remap="bf">kscribbleview.cpp :</emphasis> contient l'implantation de la classe <emphasis remap="bf">KScribbleView</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">main.cpp :</emphasis> contient l'implantation de la fonction <emphasis remap="bf">main()</emphasis>.
</para>
</listitem>
</itemizedlist>
    
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 <indexterm remap="idx"><primary>barre
d'outils</primary></indexterm>. La fenêtre des messages s'ouvre au bas de KDevelop et vous permet
de voir ce que <literal remap="tt">make</literal> fait grâce aux messages qu'il donne :   
<screen>  
1   Making all in docs  
2   make[1]: Entering directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs'  
3   Making all in en  
4   make[2]: Entering directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs/en'  
5   make[2]: Nothing to be done for `all'.  
6   make[2]: Leaving directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs/en'    
7   make[2]:
Entering directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs'    
8  make[2]: Nothing to be done for `all-am'.   
9   make[2]: Leaving directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs'   
10  make[1]: Leaving directory
`/home/rnolden/Tutorial/kscribble1/kscribble/docs'   
11  make[1]: Entering
directory `/home/rnolden/Tutorial/kscribble1/kscribble'   
12  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include 
-I/usr/X11R6/include    -O0 -g -Wall  -c  	kscribbleview.cpp  
13  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include 
-I/usr/X11R6/include    -O0 -g -Wall  -c  	kscribbledoc.cpp  
14  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include 
-I/usr/X11R6/include    -O0 -g -Wall  -c           	kscribble.cpp  
15  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include 
-I/usr/X11R6/include    -O0 -g -Wall  -c  	main.cpp  
16  /usr/bin/moc ./kscribble.h -o kscribble.moc.cpp  
17  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include
 -I/usr/X11R6/include    -O0 -g -Wall  -c  	kscribble.moc.cpp         
18  /usr/bin/moc ./kscribbledoc.h -o kscribbledoc.moc.cpp  
19  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include
-I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c  
kscribbledoc.moc.cpp  
20  /usr/bin/moc ./kscribbleview.h -o kscribbleview.moc.cpp  
21  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include
-I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c  
kscribbleview.moc.cpp    
22  /bin/sh ../libtool --silent --mode=link g++  -O0
-g -Wall   -o kscribble -L/opt/kde/lib  -L/usr/X11R6/lib -rpath /opt/kde/lib 
	-rpath /usr/X11R6/lib kscribbleview.o kscribbledoc.o kscribble.o
main.o kscribble.moc.o kscribbledoc.moc.o kscribbleview.moc.o  	-lkfile -lkfm
-lkdeui -lkdecore -lqt -lXext -lX11     
23  make[1]: Leaving directory `/home/rnolden/Tutorial/kscribble1/kscribble'  
</screen>
  </para>

<para>  
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, <literal remap="tt">make</literal> 
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
<literal remap="tt">make</literal> termine. C'est pourquoi <literal remap="tt">make</literal> est lancé dans le dossier
principal du projet qui contient les sources. Aux lignes 1 et 2, vous voyez
que le processus <literal remap="tt">make</literal> entre dans le dossier <literal remap="tt">docs</literal>, puis dans le
sous-dossier <literal remap="tt">en</literal>. Comme il n'y a rien à faire, il quitte ces dossiers
jusqu'à revenir au répertoire source <literal remap="tt">kscribble</literal> à la ligne 11. Ensuite, le
vrai travail commence : <literal remap="tt">make</literal> appele le compilateur, ici <literal remap="tt">g++</literal>, pour
compiler le fichier source <literal remap="tt">kscribbleview.cpp</literal>. La macro
<literal remap="tt">-DHAVE&&lowbar;;CONFIG&&lowbar;;H</literal> indique que le fichier <literal remap="tt">config.h</literal> 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
<literal remap="tt">-I</literal> qui suivent ajoutent un chemin vers des fichiers d'inclusion (NdT :
appelés aussi "includes") où <literal remap="tt">g++</literal> pourra trouver les "includes" dont il a
besoin. Ces chemins sont le dossier courant, le dossier principal du projet
(avec <literal remap="tt">-I..</literal>) et le chemin des includes pour les fichiers d'en-tête de KDE,
Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> et X11. Les dossiers de ces fichiers d'includes sont déterminés par
le script <literal remap="tt">configure</literal> et définis dans les Makefiles, c'est pourquoi le
compilateur sait où ils sont situés. Enfin, <literal remap="tt">-O0</literal> définit l'optimisation à
zéro (aucune optimisation), <literal remap="tt">-g</literal> active le déboguage, <literal remap="tt">-Wall</literal> définit
les avertissements du compilateur à <literal remap="tt">all</literal> et <literal remap="tt">-c</literal> dit au compilateur de
produire un fichier objet intermédiaire, c'est-à-dire seulement compiler le
fichier.    </para>

<para>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 <literal remap="tt">kscribble.h</literal> qui génère le fichier
<literal remap="tt">kscribble.moc.cpp</literal>. 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 <indexterm remap="idx"><primary>Qt</primary></indexterm> contient le
mécanisme signal/slot mais reste une implantation C++, vous utilisez des
mots-clés comme les déclarations <literal remap="tt">signals:</literal> et <literal remap="tt">slots:</literal> 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 <literal remap="tt">QObject</literal>,
é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 <literal remap="tt">moc</literal> est appelé. Moc est le
Compilateur de Méta Objet (NdT : Moc signifie littéralement Meta Object
Compiler) de la boîte à outils Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> 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 <literal remap="tt">automoc</literal> pour déterminer quels fichiers doivent être
traités, vous n'avez pas besoin de vous préoccuper des appels à <literal remap="tt">moc</literal> 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 <literal remap="tt">QObject</literal> ou toute classe qui hérite de <literal remap="tt">QObject</literal> elle-même,
vous devez aussi inclure la macro <literal remap="tt">Q&&lowbar;;OBJECT</literal> (sans point-vigule&&nbsp;;!) au début
de la déclaration de la classe et la déclaration des signaux et des slots.</para>

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

<sect1 id="le-squelette-des-sources">
<title>Le Squelette des Sources </title>

<para>  
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 <indexterm remap="idx"><primary>applications KDE</primary></indexterm>, 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.   </para>

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

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

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

<para>La première chose qui se passe généralement est la création d'un objet 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> qui
reçoit le nom de notre application <emphasis>KScribble</emphasis> comme troisième paramètre.
Lors de la création d'une nouvelle <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>, une nouvelle
instance de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> 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 <literal remap="tt">app</literal> 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 <indexterm remap="idx"><primary>Qt</primary></indexterm> en une application KDE. Une fois que l'objet <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>
est présent, nous testons si l'application est démarrée par le gestionnaire de
sessions de <literal remap="tt">kwm</literal> ou manuellement par l'utilisateur. Cela est déterminé en
appelant <literal remap="tt">isRestored()</literal> sur l'objet <literal remap="tt">app</literal>  qui retourne <literal remap="tt">true</literal> pour
la gestion  de sessions et <literal remap="tt">false</literal> pour un lancement manuel.    Comme la
gestion des sessions est une fonctionnalité importante des applications
KDE <indexterm remap="idx"><primary>applications
KDE</primary></indexterm> et largement utilisée par l'architecture mais plus longue à expliquer,
nous allons d'abord continuer par la section <literal remap="tt">else&&lcub;;&&rcub;;</literal> ; ensuite, nous y
reviendrons et expliquerons la fonctionnalité de gestion des sessions dans une
étape ultérieure.      </para>
</sect2>

<sect2 id="lancement-de-lapplication-par-lutilisateur">
<title>Lancement de l'Application par l'Utilisateur </title>

<para>  La section <literal remap="tt">else&&lcub;;&&rcub;;</literal> crée maintenant une instance de la classe
<literal remap="tt">KScribbleApp</literal> à 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 <literal remap="tt">kscribble</literal> pour l'ouvrir avec <literal remap="tt">openFile()</literal>.    Remarquez que
nous n'avons pas appelé la méthode <literal remap="tt">setTopWidget(kscribble)</literal> pour notre
application - c'est déjà fait par la classe dont hérite <literal remap="tt">KScribbleApp</literal>.
Maintenant, nous allons regarder notre objet <literal remap="tt">KScribbleApp</literal> - 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
<literal remap="tt">KScribbleApp</literal> qui se trouve dans le fichier <literal remap="tt">kscribble.cpp</literal> 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
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> qui fait partie de la bibliothèque <literal remap="tt">kdeui</literal>. Cette
classe hérite elle-même de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> donc, comme d'habitude, nous
avons un widget normal comme fenêtre de plus haut niveau (NdT : top-level
window). <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> contient beaucoup de fonctionnalités qui sont
utilisées par la classe <literal remap="tt">KScribbleApp</literal>. Elle fournit une barre de menus,
une barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>, une barre d'état et le support de la gestion de
sessions. La seule chose que nous ayons à faire en dérivant de
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> 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
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> comme vue principale au centre de la fenêtre ;
habituellement, c'est ici que l'utilisateur travaille comme une vue d'édition
de texte.    </para>

<sect3 id="le-constructeur">
<title>Le Constructeur </title>

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

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

<para>Nous voyons que notre instance de
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> 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 :      </para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">initMenuBar() :</emphasis> construit la barre de menus</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initToolBar() :</emphasis> construit la barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm></para>
</listitem>
<listitem>
<para><emphasis remap="bf">initStatusBar() :</emphasis> crée la barre d'état</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initKeyAccel() :</emphasis> définit tous les accélérateurs clavier
<indexterm><primary>accelerator</primary></indexterm> pour notre application avec les configurations du clavier
globale et spécifique à l'application</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initDocument() :</emphasis> crée l'objet document pour la fenêtre de l'application</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initView() :</emphasis> crée le widget principal pour notre vue dans la fenêtre
principale</para>
</listitem>
<listitem>
<para><emphasis remap="bf">readOptions() :</emphasis> 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.  </para>
</listitem>
</itemizedlist>
</para>

<para>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.    </para>
</sect3>

<sect3 id="la-barre-de-menus">
<title>La Barre de Menus </title>

<para>  Comme nous l'avons vu au-dessus, la barre de menus de <emphasis>KScribble</emphasis> est 
créée par la méthode
<literal remap="tt">initMenuBar()</literal>. En fait, nous créons un ensemble de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QPopupMenu</literal></primary></indexterm>QPopupMenu</literal>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.   </para>

<para>D'abord, nous créons notre <literal remap="tt">recent&&lowbar;;file&&lowbar;;menu</literal> qui contiendra les noms des 5
derniers fichiers ouverts. Nous devons le faire en premier car ce menu est
inséré dans le <literal remap="tt">file&&lowbar;;menu</literal>. 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 <literal remap="tt">slotFileOpenRecent( int )</literal>, qui ouvre ensuite
le bon fichier de la liste des fichiers récemment ouverts.    </para>

<para>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&&amp;;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&&nbsp;;:     </para>

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

<para>La première ligne insère une entrée "Open...". Comme nous voulons qu'elle ait une icône,
nous utilisons la méthode <literal remap="tt">insertItem()</literal> 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é <literal remap="tt">Icon()</literal> - 
en fait, c'est une macro fournie par la classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> : </para>

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

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

<para><screen> 
#define kapp KApplication::getKApplication() 
</screen>
 </para>

<para>Cela signifie que l'objet <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> 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 <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm>, 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. </para>

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

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

<para>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 <literal remap="tt">i18n()</literal> 
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 <literal remap="tt">i18n</literal>, vous devez utiliser cette macro. </para>

<para>Comme vous l'avez peut-être déjà deviné, le symbole &&amp;; (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 <literal remap="tt">Alt</literal> et la lettre soulignée.</para>

<para>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 <literal remap="tt">resource.h</literal> 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. </para>

<para>Le deuxième exemple d'entrée montre une autre variante de la méthode <literal remap="tt">insertItem()</literal>. 
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. </para>

<para>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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>QMenuData</literal></primary></indexterm>QMenuData</literal> 
peuvent être trouvées dans la documentation de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>. </para>

<para>Maintenant, après avoir créé les menus popup <literal remap="tt">file&&lowbar;;menu, edit&&lowbar;;menu</literal> et <literal remap="tt">view&&lowbar;;menu</literal>, 
nous devons insérer aussi un menu "Aide". Nous pourrions le faire comme pour les autres 
menus mais la classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> fournit une méthode simple et rapide pour le 
faire : </para>

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

<para>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 <indexterm><primary>shortcuts</primary></indexterm> 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 <literal remap="tt">getHelpMenu(false,...);</literal>). Le contenu de la boîte de dialogue
"À propos" de notre application est à nouveau défini avec la chaîne <literal remap="tt">i18n()</literal> - VERSION 
prend la macro qui est définie dans le fichier <literal remap="tt">config.h</literal> 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. </para>

<para>Maintenant, nous n'avons plus qu'à insérer les popups dans la barre de menus. 
Comme <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> construit déjà une barre de menus pour nous, il suffit 
de les insérer en appelant <literal remap="tt">menuBar()-&gt;insertItem();</literal>. </para>

<para>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 
<literal remap="tt">activated(&&nbsp;;int&&nbsp;;)</literal> à une méthode <literal remap="tt">commandCallback(&&nbsp;;int&&nbsp;;)</literal> 
qui contient un <literal remap="tt">switch</literal> qui appelle les méthodes correspondantes pour les entrées 
de menu. En plus, nous connectons le signal <literal remap="tt">highlighted(&&nbsp;;int&&nbsp;;)</literal> 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 <indexterm remap="idx"><primary>focus du clavier</primary></indexterm> sur une entrée, la barre d'état affiche 
alors le message d'aide correspondant. </para>

<para>Après avoir terminé avec la barre de menus, nous pouvons passer à la barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> 
dans la section suivante. Remarquez qu'une instance de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> 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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>KMenuBar</literal></primary></indexterm>KMenuBar</literal> et définir l'une d'elles comme la barre de menus 
courante avec la méthode appropriée de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>. Consultez la 
documentation de la classe <indexterm remap="idx"><primary>documentation de la classe</primary></indexterm> <literal remap="tt"><indexterm remap="cdx"><primary><literal>KMenuBar</literal></primary></indexterm>KMenuBar</literal> pour plus de détails sur ses 
fonctionnalités étendues, voir aussi <link linkend="Configuring-Menubars-and-Toolbars">Configuration des Barres de Menus et des Barres d'Outils</link>. </para>
</sect3>

<sect3 id="la-barre-doutils">
<title>La Barre d'Outils </title>

<para> 
La création de barres d'outils <indexterm remap="idx"><primary>barres d'outils</primary></indexterm> est bien plus simple que pour les barres de menus. 
Comme <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> fournit déjà des barres d'outils <indexterm remap="idx"><primary>barres d'outils</primary></indexterm> 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 : </para>

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

<para>Ceci ajoute un bouton aligné à gauche avec l'icône "filenew.xpm" et l'identificateur 
(NdT : ID) correspondant dans la barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>. Le troisième paramètre décide si 
le bouton doit être activé ou non ; par défaut, nous le définissons à <literal remap="tt">true</literal> car nos 
méthodes <literal remap="tt">disableCommand()</literal> à la fin du constructeur le font automatiquement pour 
nous, à la fois pour les entrées du menu et de la barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>. 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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> sont connectés à notre méthode 
<literal remap="tt">commandCallback()</literal> par leur signal <literal remap="tt">clicked()</literal>. Lors du signal <literal remap="tt">pressed()</literal>, 
nous permettons à l'utilisateur de recevoir le message d'aide correspondant dans la 
barre d'état. </para>

<para><emphasis remap="bf">Informations supplémentaires :</emphasis> </para>

<para>Comme les barres d'outils <indexterm remap="idx"><primary>barres d'outils</primary></indexterm> sont créées en utilisant la classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal>, 
vous devriez consulter la documentation correspondante. Avec <literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal>, 
beaucoup de choses nécessaires pour une barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> 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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> 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 <indexterm remap="idx"><primary>barres d'outils</primary></indexterm>  dans la section <link linkend="Configuring-Menubars-and-Toolbars">Configuration des Barres de Menus et des Barres d'Outils</link>. </para>
</sect3>

<sect3 id="la-barre-dtat">
<title>La Barre d'État </title>

<para> 
La barre d'état est, comme les autres barres, déjà fournie par l'instance de 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> 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. </para>

<para>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 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>. 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 <indexterm remap="idx"><primary>documentation de 
la classe</primary></indexterm> <literal remap="tt">KStatusBar</literal>. </para>
</sect3>

<sect3 id="raccourcis-clavier">
<title>Raccourcis Clavier </title>

<para> 
Une fois rendu à la méthode <literal remap="tt">initKeyAccel()</literal>, 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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> et la barre d'état. </para>

<para>Cependant, nous n'avons pas encore défini les raccourcis clavier <indexterm><primary>accelerator</primary></indexterm> 
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<indexterm><primary>accelerator</primary></indexterm>, par exemple, lors de l'insertion des
éléments du menu mais KDE offre une bonne solution pour construire et maintenir 
les raccourcis clavier<indexterm><primary>accelerator</primary></indexterm>. Beaucoup d'utilisateurs veulent d'un côté 
qu'ils soient configurables et d'un autre côté les raccourcis<indexterm><primary>accelerator</primary></indexterm> 
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<indexterm><primary>accelerator</primary></indexterm> 
clavier standards en utilisant la classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal>. En plus, les 
bibliothèques de KDE <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm> contiennent un widget qui permet aux utilisateurs de 
configurer facilement les raccourcis<indexterm><primary>shortcuts</primary></indexterm> 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 <literal remap="tt">initKeyAccel()</literal>. 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<indexterm><primary>accelerator</primary></indexterm>
clavier et ensuite les connecter. Comme nos raccourcis <indexterm><primary>accelerator</primary></indexterm> sont tous 
présents dans la barre de menus, nous devons changer le raccourci <indexterm><primary>accelerator</primary></indexterm> 
pour les entrées du popup. Enfin, nous appelons <literal remap="tt">readSettings()</literal> qui lit la 
configuration courante depuis la fenêtre du bureau de KDE (NdT : KDE rootwindow) où est
stockée la configuration
des raccourcis<indexterm><primary>accelerator</primary></indexterm> standards, puis les paramètres des 
raccourcis<indexterm><primary>accelerator</primary></indexterm> 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<indexterm><primary>accelerator</primary></indexterm> 
spécifiques à notre application, voir <link linkend="Configuring-Menubars-and-Toolbars">Configuration des Barres de Menus et des Barres d'Outils</link> pour cette partie du 
processus de développement. </para>
</sect3>

<sect3 id="le-modle-document-vue">
<title>Le Modèle Document-Vue </title>

<para> 
Les deux appels de fonctions membres suivants, <literal remap="tt">initDocument()</literal> et <literal remap="tt">initView()</literal>, 
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 <literal remap="tt">*App</literal>, <literal remap="tt">*View</literal>
et <literal remap="tt">*Doc</literal>. 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. </para>

<para>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 <indexterm remap="idx"><primary>barres d'outils</primary></indexterm>, 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 : </para>

<para><itemizedlist>
<listitem>
<para> un objet Contrôleur contenu par l'application</para>
</listitem>
<listitem>
<para> un objet Vue qui affiche les données avec lesquelles l'utilisateur veut 
travailler </para>
</listitem>
<listitem>
<para> un objet Document qui contient réellement les données qui sont manipulées.</para>
</listitem>
</itemizedlist>
 </para>

<para>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.</para>

<para>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<indexterm><primary>accelerator</primary></indexterm> clavier ou la souris sur les barres de menus et 
les barres d'outils <indexterm remap="idx"><primary>barres d'outils</primary></indexterm>.</para>

<para>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.</para>

<para>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 <indexterm remap="idx"><primary>Qt</primary></indexterm>, les choses sont un peu différentes. Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> 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 <indexterm remap="idx"><primary>Qt</primary></indexterm>, 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 <emphasis>KOffice</emphasis> 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 <indexterm remap="idx"><primary>Qt</primary></indexterm> et KDE :</para>

<para><itemizedlist>
<listitem>
<para>KOffice utilise KOM et différents mécanismes pour la communication entre objets </para>
</listitem>
<listitem>
<para>les applications KOffice utilisent un modèle document-vue qui permet à toutes les 
applications de travailler avec n'importe quelles données de KOffice.</para>
</listitem>
</itemizedlist>
</para>

<para>Mais, comme l'objectif de KDevelop est d'utiliser les bibliothèques actuelles de 
KDE 1.1.x et Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> 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 :
<orderedlist><listitem>
<para>une interface MDI pour <indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow  </para>
</listitem>
<listitem>
<para>les bibliothèques KOM qui fournissent un modèle de document.</para>
</listitem>
</orderedlist>
</para>

<para>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 <indexterm remap="idx"><primary>Qt</primary></indexterm> et KDE.</para>

<para>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 <literal remap="tt">initDocument()</literal> et
<literal remap="tt">initView()</literal>. <literal remap="tt">initDocument()</literal> 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 <literal remap="tt">initView()</literal> construit le widget <literal remap="tt">*View</literal>, 
le connecte au document et appelle la méthode <literal remap="tt">setView()</literal> de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> 
pour dire à la fenêtre <literal remap="tt">*App</literal> d'utiliser le widget <literal remap="tt">*View</literal> comme vue centrale.</para>

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

<para><itemizedlist>
<listitem>
<para>ré-implanter dans l'objet <literal remap="tt">*View</literal> les méthodes virtuelles de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> 
pour les événements du clavier et de la souris afin de pouvoir manipuler les données</para>
</listitem>
<listitem>
<para>ré-implanter le <literal remap="tt">paintEvent()</literal> de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> dans l'objet <literal remap="tt">*View</literal> 
pour redessiner (Ndt : repaint()) la vue après des modifications</para>
</listitem>
<listitem>
<para>compléter l'implantation pour l'impression du document via la méthode d'impression 
de l'objet <literal remap="tt">*View</literal> </para>
</listitem>
<listitem>
<para>ajouter la sérialisation pour permettre à l'objet <literal remap="tt">*Doc</literal> de charger et 
enregistrer le fichier </para>
</listitem>
<listitem>
<para>ajouter l'implantation de la structure des données du document à l'objet <literal remap="tt">*Doc</literal> 
qui représente logiquement en mémoire les données du document</para>
</listitem>
<listitem>
<para>ajouter les méthodes auxquelles l'utilisateur peut accéder via des 
raccourcis<indexterm><primary>accelerator</primary></indexterm> clavier, des menus ou des barres d'outils <indexterm remap="idx"><primary>barres d'outils</primary></indexterm>.</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="configuration-de-lapplication">
<title>Configuration de l'Application</title>

<para>Maintenant, après avoir créé toutes les instances de l'instance de 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> 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 <literal remap="tt">readOptions()</literal> 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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> 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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> crée déjà son
fichier de ressources, nous devons seulement accéder à ce fichier et créer nos 
valeurs. Comme <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> nous donne l'objet fichier, nous devons utiliser 
la classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfigBase</literal></primary></indexterm>KConfigBase</literal> pour lire et écrire toutes les entrées. L'écriture 
est très facile avec les méthodes <literal remap="tt">writeEntry()</literal> 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 :</para>

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

<para>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 :</para>

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

<para>qui positionne le pointeur <literal remap="tt">config</literal> de type <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> 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 <literal remap="tt">&&dollar;;HOME/.kde/share/config/</literal> ; 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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfigBase</literal></primary></indexterm>KConfigBase</literal> 
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 :</para>

<para><itemizedlist>
<listitem>
<para>l'utilisateur peut changer le fichier de configuration avec un simple éditeur 
de texte </para>
</listitem>
<listitem>
<para>si l'utilisateur veut changer les valeurs à la main, les entrées doivent être 
très explicites pour déterminer leur utilisation</para>
</listitem>
<listitem>
<para>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é.</para>
</listitem>
</itemizedlist>
</para>

<para>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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> 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 <literal remap="tt">readBoolEntry()</literal>. 
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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>. D'abord, 
nous lisons la valeur dans une variable temporaire <literal remap="tt">bViewToolbar</literal> à 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 à <literal remap="tt">true</literal>. Ensuite, nous positionnons la coche de 
l'entrée de menu pour (dés)activer la barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> suivant sa valeur : nous 
appelons <literal remap="tt">setItemChecked()</literal> pour le menu de la vue, avec l'entrée <literal remap="tt">ID&&lowbar;;VIEW&&lowbar;;TOOLBAR</literal> 
et notre attribut. Enfin, nous faisons en sorte que la barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> utilise cette 
valeur. Par défaut, la barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> est visible donc nous devons faire quelque 
chose seulement si <literal remap="tt">bViewToolbar</literal> vaut <literal remap="tt">false</literal>. Avec <literal remap="tt">enableToolBar()</literal> (ligne 10), 
nous forçons la barre à se cacher si elle est désactivée.</para>

<para>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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal> et <literal remap="tt"><indexterm remap="cdx"><primary><literal>KMenuBar</literal></primary></indexterm>KMenuBar</literal>, nous voyons 
que la position des barres peut valoir :</para>

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

<para>Comme cette valeur doit être écrite sous forme numérique, nous devons la lire avec 
<literal remap="tt">readNumEntry()</literal> et la convertir en une valeur de position. Avec <literal remap="tt">setMenuBarPos()</literal> 
et <literal remap="tt">setBarPos()</literal>, nous disons aux barres de s'afficher.</para>

<para>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 <literal remap="tt">readListEntry()</literal>. Ensuite, dans 
une boucle <literal remap="tt">for</literal>, nous créons une entrée de menu pour chaque élément de la liste.</para>

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

<para>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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> avec un seul appel à la 
méthode à la fois.</para>
</sect3>

<sect3 id="excution">
<title>Exécution</title>

<para>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 <literal remap="tt">KScribbleApp</literal> qui nous donne la fenêtre 
principale. Après le retour à la fonction <literal remap="tt">main()</literal>, nous devons appeler <literal remap="tt">show()</literal> 
pour afficher la fenêtre. Ici, ce qui est différent d'une <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> ou 
d'une <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>, c'est que nous utilisons <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> comme 
instance de notre widget principal ; nous n'avons pas besoin de le définir avec 
<literal remap="tt">setMainWidget()</literal>. Cela est fait par <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> 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 <literal remap="tt">int argc</literal> est &gt; 1, ce qui indique que l'utilisateur a 
lancé notre application avec <literal remap="tt">kscribble nom&&lowbar;;de&&lowbar;;fichier&&lowbar;;a&&lowbar;;ouvrir</literal>. Notre fenêtre 
est alors sensée ouvrir le fichier ayant ce nom et appeler <literal remap="tt">openDocumentFile()</literal>
avec le nom du fichier.</para>

<para>La dernière ligne de la fonction <literal remap="tt">main()</literal> fait le travail attendu : elle exécute
l'instance de l'application et le programme entre dans la boucle d'événements.</para>

<para>Dans la section <link linkend="The-main-Function">La Fonction main()</link>, nous avons 
commencé à séparer le processus d'exécution par <literal remap="tt">if( app.isRestored() )</literal> 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.</para>
</sect3>
</sect2>

<sect2 id="lancement-par-gestion-de-sessions">
<title>Lancement par Gestion de Sessions</title>

<para>Comme nous l'avons dit, la fonction <literal remap="tt">main()</literal> 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 :</para>

<para><screen>6    if (app.isRestored())
7    {
8       RESTORE(KScribbleApp);
9    }
</screen>
</para>

<para>Dans <link linkend="The-main-Function">La Fonction main()</link>, nous avons indiqué que 
nous testons le type de lancement en interrogeant <literal remap="tt">app.isRestored()</literal>. 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.</para>

<para>RESTORE(), quant à elle, est une macro fournie par <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>. Elle est 
remplacée par le code suivant :</para>

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

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

<para>La méthode <literal remap="tt">restore()</literal> lit ensuite la partie du fichier de session qui 
contient les informations concernant la fenêtre. Comme <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> 
enregistre tout cela pour nous, nous n'avons rien de spécial à faire. Ensuite, seules 
les informations spécifiques à notre instance de <literal remap="tt">KScribbleApp</literal> 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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>,
<literal remap="tt">saveProperties()</literal> et <literal remap="tt">readProperties()</literal>. 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 :</para>

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

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

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

<para>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.</para>

<para><emphasis remap="bf">Résumé :</emphasis></para>

<para>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.</para>
</sect2>
</sect1>

<sect1 id="contenu-supplmentaire-sur-les-projets-kdevel">
<title>Contenu Supplémentaire sur les Projets KDevelop</title>

<para>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 :</para>

<para><itemizedlist>
<listitem>
<para>une icône de programme</para>
</listitem>
<listitem>
<para>une mini-icône de programme</para>
</listitem>
<listitem>
<para>un fichier .kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
<listitem>
<para>un échantillon de fichier de documentation SGML <indexterm remap="idx"><primary>SGML</primary></indexterm></para>
</listitem>
<listitem>
<para>un ensemble de documentations de l'API <indexterm remap="idx"><primary>API</primary></indexterm> générées par les sources de 
l'architecture.</para>
</listitem>
</itemizedlist>
</para>

<para>Mise à part la documentation de l'API <indexterm remap="idx"><primary>API</primary></indexterm>, 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 <indexterm remap="idx"><primary>.kdelnk</primary></indexterm> est un fichier qui installe votre application dans le menu 
<literal remap="tt">Applications</literal> de <literal remap="tt">kpanel</literal> (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 <indexterm remap="idx"><primary>SGML</primary></indexterm>. 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 <literal remap="tt">ksgml2html <indexterm remap="idx"><primary>ksgml2html</primary></indexterm></literal> 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 <indexterm remap="idx"><primary>SGML</primary></indexterm> et ce qu'il faut 
faire pour l'installation vers l'utilisateur final.</para>

<para>Enfin, la documentation de l'API <indexterm remap="idx"><primary>API</primary></indexterm> (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 <indexterm remap="idx"><primary>API</primary></indexterm> dans une étape 
ultérieure ; pour l'instant, il suffit de savoir que la documentation est générée 
par le programme <literal remap="tt">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></literal> 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.</para>
</sect1>
</chapter>

<chapter id="conception-de-vue-dapplication">
<title>Conception de Vue d'Application</title>

<para>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 <indexterm remap="idx"><primary>barres d'outils</primary></indexterm>
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.</para>

<para>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 <emphasis>KEdit</emphasis>, vous voyez l'interface visuelle suivante :</para>

<para><itemizedlist>
<listitem>
<para>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 </para>
</listitem>
<listitem>
<para>la barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> : fournit des icônes qui permettent d'accéder plus 
rapidement aux fonctions les plus utilisées </para>
</listitem>
<listitem>
<para>la barre d'état : affiche l'état de la position du curseur avec la ligne et 
la colonne courante </para>
</listitem>
<listitem>
<para>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. </para>
</listitem>
</itemizedlist>
</para>

<para>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.</para>

<para>Pour certains cas comme l'édition de texte ou l'affichage de fichiers HTML, des 
vues sont fournies par Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> et par les bibliothèques de KDE <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm> ; 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 :</para>

<para><itemizedlist>
<listitem>
<para>visuellement agréable </para>
</listitem>
<listitem>
<para>pourvue de nombreuses fonctionnalités</para>
</listitem>
<listitem>
<para>facile à manipuler</para>
</listitem>
<listitem>
<para>d'utilisation rapidement assimilable.</para>
</listitem>
</itemizedlist>
</para>

<para>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.</para>

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

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

<sect1 id="utiliser-les-vues-des-bibliothques">
<title>Utiliser les Vues des Bibliothèques</title>

<para>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 <indexterm remap="idx"><primary>Qt</primary></indexterm> 
contiennent déjà un ensemble de widgets qui peuvent être utilisés pour cela. Pour les 
utiliser, vous avez deux options :</para>

<para><orderedlist><listitem>
<para> 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 </para>
</listitem>
<listitem>
<para> changer l'héritage de la classe de vue fournie en la classe du widget de 
la bibliothèque à utiliser.</para>
</listitem>
</orderedlist>
</para>

<para>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"-&gt;"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 <literal remap="tt">-l</literal>. Pour les bibliothèques que votre
application doit rechercher avant de préparer les Makefiles, sur la machine de
l'utilisateur, avec le script <literal remap="tt">configure</literal> , ajoutez la macro de recherche
correspondante dans le fichier <literal remap="tt">configure.in</literal> situé dans le dossier de base
de votre projet et ajoutez la macro à la ligne d'édition. Notez que vous devez
exécuter "Construire"-&gt;"Autoconf et automake" et "Construire-&gt;Configurer" avant
que les Makefiles ne contiennent le contenu correct de la macro de la bibliothèque.</para>

<para>É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 <literal remap="tt">-I</literal> 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 <literal remap="tt">-I</literal> ou 
la macro automake correspondante dans la ligne d'édition des "Options supplémentaires".</para>

<sect2 id="vues-qt-qt">
<title>Vues Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></title>

<para>En regardant la première page de la documentation en ligne de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, vous 
trouverez un lien vers des captures d'écran de widgets (NdT : "Widget Screenshots") 
où vous pourrez voir à quoi ressemblent les widgets de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>. 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 <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm> contiennent parfois d'autres 
widgets ayant le même but ; nous les verrons dans la prochaine section.</para>

<para>Voici un ensemble de conseils sur l'utilisation des composants de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> :</para>

<para><orderedlist><listitem>
<para>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 <indexterm remap="idx"><primary>Qt</primary></indexterm> fournit la classe <literal remap="tt">QScrollView</literal> qui donne 
une zone fille que l'on peut faire défiler. Comme expliqué, vous pouvez faire hériter 
votre widget de <literal remap="tt">QScrollView</literal> ou en utiliser une instance pour gérer le widget 
de vue de votre document&&nbsp;;;</para>
</listitem>
<listitem>
<para>pour créer une ScrollView vous-même, dérivez le widget de View de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> 
et ajoutez des <literal remap="tt">QScrollBar</literal>s verticale et horizontale (c'est ce que fait le widget 
KHTMLView de KDE)&&nbsp;;;</para>
</listitem>
<listitem>
<para>pour du traitement de texte, utilisez <literal remap="tt">QMultiLineEdit</literal>. 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&&nbsp;;;</para>
</listitem>
<listitem>
<para>utilisez <literal remap="tt">QTableView</literal> pour afficher des données qui sont organisées en table. 
Comme <literal remap="tt">QTableView</literal> est gérée par des barres de défilement, c'est une bonne solution 
pour des applications de calcul sur des tables&&nbsp;;;</para>
</listitem>
<listitem>
<para>pour afficher deux widgets différents ou deux instances du widget en même temps, 
utilisez <literal remap="tt">QSplitter</literal>. 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&&nbsp;;;</para>
</listitem>
<listitem>
<para><literal remap="tt">QListView</literal> 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.</para>
</listitem>
</orderedlist>
</para>

<para>Vous voyez que Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, 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.</para>
</sect2>

<sect2 id="vues-kde">
<title>Vues KDE</title>

<para>Les bibliothèques de KDE <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm> 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 <indexterm remap="idx"><primary>Qt</primary></indexterm> 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 <literal remap="tt">kdecore</literal> qui est la base de toutes les applications KDE <indexterm remap="idx"><primary>applications KDE</primary></indexterm>.
Ensuite, <literal remap="tt">kdeui</literal> 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
<literal remap="tt">kdeui</literal> contient :</para>

<para><orderedlist><listitem>
<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KTabListBox</literal></primary></indexterm>KTabListBox</literal> : une zone de liste multi-colonnes où l'utilisateur peut
changer les lignes par glisser-déposer <indexterm remap="idx"><primary>glisser-déposer</primary></indexterm> (NdT : drag'n drop)&&nbsp;;;</para>
</listitem>
<listitem>
<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KTreeList</literal></primary></indexterm>KTreeList</literal> : hérite de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QTableView</literal></primary></indexterm>QTableView</literal> et fournit un arbre
développable/réductible (NdT : collapsible tree). Cela peut être utilisé à la place
de <literal remap="tt">QListView</literal>. Dans KDE 2.0, cette classe disparaîtra&&nbsp;;;</para>
</listitem>
<listitem>
<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KEdit</literal></primary></indexterm>KEdit</literal> : les classes de base de l'application <emphasis>KEdit</emphasis> qui fait
partie de KDE. Cela peut être utilisé à la place de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QMultiLineEdit</literal></primary></indexterm>QMultiLineEdit</literal>&&nbsp;;;</para>
</listitem>
<listitem>
<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KNewPanner</literal></primary></indexterm>KNewPanner</literal> : gère deux widgets fils comme <literal remap="tt"><indexterm remap="cdx"><primary><literal>QSplitter</literal></primary></indexterm>QSplitter</literal>. Dans
KDE 2.0, cette classe disparaîtra&&nbsp;;;</para>
</listitem>
</orderedlist>
</para>

<para>Par ailleurs, la bibliothèque <literal remap="tt">khtmlw</literal> 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 <indexterm remap="idx"><primary>KDEHelp</primary></indexterm> et KDevelop pour afficher des fichiers HTML.</para>
</sect2>
</sect1>

<sect1 id="creating-your-own-views">
<title>Créer vos propres Vues</title>

<para>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.</para>

<para>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 <literal remap="tt">KScribbleView</literal> qui fournit déjà une zone de vue de base.</para>

<para>Hériter de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> 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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> 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.</para>

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

<para><emphasis remap="bf">a) Événements Clavier -- les touches TAB et Shift-TAB :</emphasis></para>

<para>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
<literal remap="tt">setFocusPolicy<indexterm remap="ncdx"><primary><literal>setFocusPolicy()</literal></primary></indexterm>()</literal> et en traitant les événements suivants :</para>

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

<para><emphasis remap="bf">b) toute autre saisie au clavier :</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void keyPressEvent<indexterm remap="ncdx"><primary><literal>keyPressEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QKeyEvent</literal></primary></indexterm>QKeyEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void keyReleaseEvent<indexterm remap="ncdx"><primary><literal>keyReleaseEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QKeyEvent</literal></primary></indexterm>QKeyEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

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

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

<para><emphasis remap="bf">e) événements de la fenêtre contenant le widget :</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void moveEvent<indexterm remap="ncdx"><primary><literal>moveEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QMoveEvent</literal></primary></indexterm>QMoveEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void resizeEvent<indexterm remap="ncdx"><primary><literal>resizeEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QResizeEvent</literal></primary></indexterm>QResizeEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void closeEvent<indexterm remap="ncdx"><primary><literal>closeEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QCloseEvent</literal></primary></indexterm>QCloseEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para>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 :</para>

<para><orderedlist><listitem>
<para>déclarez vos méthodes virtuelles comme <emphasis remap="bf">virtual</emphasis> 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é&&nbsp;;; </para>
</listitem>
<listitem>
<para>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<indexterm><primary>accelerator</primary></indexterm> 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)&&nbsp;;;</para>
</listitem>
<listitem>
<para>transmettez le "signal" de surbrillance (NdT : highlighting) des menus popups au widget
principal pour activer l'aide dans la barre d'état.</para>
</listitem>
</orderedlist>
</para>
</sect1>
</chapter>

<chapter id="configuring-menubars-and-toolbars">
<title>Configuration des Barres de Menus et des Barres d'Outils</title>

<para>Les barres de menus et les barres d'outils <indexterm remap="idx"><primary>barres d'outils</primary></indexterm> 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.</para>

<para>De plus, une application ne peut contenir qu'une seule barre de menus mais plusieurs
barres d'outils <indexterm remap="idx"><primary>barres d'outils</primary></indexterm>. 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.</para>

<sect1 id="comment-a-fonctionne">
<title>Comment ça fonctionne ?</title>

<para>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.</para>

<para>Tous les identificateurs de ressource sont regroupés dans le fichier <literal remap="tt">resource.h</literal> 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<indexterm><primary>accelerator</primary></indexterm> de menu définis
par les macros de remplacement IDK. Voici un exemple :</para>

<para><programlisting>(resource.h)

#define ID_VIEW_TOOLBAR             12010


(kscribble.cpp)

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

<para>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<indexterm><primary>accelerator</primary></indexterm> clavier et
l'entrée elle-même est entourée par la macro i18n() pour l'internationalisation.</para>

<para>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 :</para>

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

<para>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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> pour créer des cas de <literal remap="tt">switch</literal> qui sélectionnent le slot
à appeler lors du signal <literal remap="tt">activated()</literal> pour les menus et <literal remap="tt">clicked()</literal> pour les
boutons de la barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>. La connexion peut aussi être faite directement
en utilisant les méthodes fournies par les classes fournissant les menus et les
barres d'outils <indexterm remap="idx"><primary>barres d'outils</primary></indexterm>.</para>
</sect1>

<sect1 id="ajouter-un-nouveau-menu">
<title>Ajouter un nouveau Menu</title>

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

<para><orderedlist><listitem>
<para>ajouter un pointeur vers le nouveau menu dans l'en-tête de la classe App</para>
</listitem>
<listitem>
<para>appeler le constructeur de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QPopupMenu</literal></primary></indexterm>QPopupMenu</literal> pour le pointeur dans <literal remap="tt">initMenuBar()</literal>
à l'emplacement où votre barre de menus doit apparaître</para>
</listitem>
<listitem>
<para>insérer les éléments de menu corespondants dans le menu popup et définir leurs
identifiants de ressource dans le fichier de ressource</para>
</listitem>
<listitem>
<para>ajouter les connexions pour <literal remap="tt">commandCallback()</literal> et <literal remap="tt">statusCallback()</literal> au menu
à la fin de <literal remap="tt">initMenuBar()</literal></para>
</listitem>
<listitem>
<para>ajouter les méthodes que vous voulez appeler par les entrées de menu dans les
fichiers d'en-tête et d'implantation</para>
</listitem>
<listitem>
<para>ajouter les cas de switch pour les entrées aux méthodes <literal remap="tt">commandCallback()</literal>
et <literal remap="tt">statusCallback()</literal>.</para>
</listitem>
</orderedlist>
</para>
</sect1>

<sect1 id="intgrer-des-boutons-la-barre-doutils">
<title>Intégrer des boutons à la Barre d'Outils</title>

<para>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 <literal remap="tt">insertButton()</literal> 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.</para>

<para>Les icônes que vous voulez utiliser peuvent être chargées par <literal remap="tt">KIconLoader</literal> ;
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> offre aussi les macros <literal remap="tt">ICON()</literal> et <literal remap="tt">Icon()</literal> 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 <literal remap="tt">KIconLoader</literal> pour l'ordre de recherche).</para>

<para>Les bibliothèques de KDE <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm> offrent aussi un ensemble de boutons de barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>
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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> dans un sous-dossier
"toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>" de votre projet et les installerez dans le dossier toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>
spécifique à votre application.</para>
</sect1>

<sect1 id="configuration-des-barres-dtat">
<title>Configuration des Barres d'État</title>

<para>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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>. Quand vous ajoutez une
entrée de menu, ajoutez aussi un message d'état dans la méthode <literal remap="tt">statusCallback()</literal>.</para>

<para><literal remap="tt">statusCallback()</literal> utilise la méthode <literal remap="tt">slotStatusHelpMsg()</literal> pour afficher un
message dans la barre d'état pendant 2 secondes. Lorsque vous exécutez une commande,
vous devriez utiliser la méthode <literal remap="tt">slotStatusMsg()</literal> 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".</para>
</sect1>

<sect1 id="configuration-des-raccourcis-clavier">
<title>Configuration des Raccourcis Clavier</title>

<para>Les raccourcis<indexterm><primary>accelerator</primary></indexterm> 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<indexterm><primary>shortcuts</primary></indexterm>. Pour cela, les
bibliothèques de KDE <indexterm remap="idx"><primary>bibliothèques de KDE</primary></indexterm> contiennent la classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal> qui fournit les
combinaisons de touches des raccourcis<indexterm><primary>accelerator</primary></indexterm> clavier et l'accès aux
raccourcis<indexterm><primary>accelerator</primary></indexterm> clavier standards configurés globalement.</para>

<para>Par défaut, les applications fenêtrées générées par KDevelop utilisent seulement
les raccourcis<indexterm><primary>accelerator</primary></indexterm> 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<indexterm><primary>accelerator</primary></indexterm> clavier déjà définis dans <literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal>
avant d'en ajouter un nouveau.</para>

<para>Si votre application contient beaucoup de raccourcis<indexterm><primary>accelerator</primary></indexterm> 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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>, soit tout
seul. Les bibliothèques de KDE fournissent déjà un <literal remap="tt">KKeyChooser</literal> utilisable dans
des boîtes de dialogue à onglet, tandis que <literal remap="tt">KKeyDialog</literal> est une boîte de dialogue
de configuration des raccourcis clavier prête à l'emploi.</para>

<para>Consultez les classes suivantes pour plus d'informations :</para>

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

<chapter id="lditeur-de-botes-de-dialogue-o-vos-botes-de-">
<title>L'Éditeur de Boîtes de Dialogue : Où vos Boîtes de Dialogue sont Construites</title>

<sect1 id="ce-que-fournit-lditeur-de-botes-de-dialogue">
<title>Ce que fournit l'Éditeur de boîtes de dialogue</title>

<para>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 <indexterm remap="idx"><primary>Qt</primary></indexterm> ; 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.</para>

<para>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.</para>
</sect1>

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

<para>Actuellement, les widgets supportés sont :</para>

<para><emphasis remap="bf">Widgets de Qt :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</emphasis> - 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&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm></emphasis> - une étiquette qui représente une information de type texte sur
le widget. Utilisez QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm>, 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&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QPushButton</emphasis> - un bouton qui permet, par exemple, d'appeler une autre boîte de
dialogue (comme QFileDialog pour sélectionner un nom de fichier)&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QCheckBox</emphasis> - une case à cocher pour, par exempe, activer/désactiver des
options. QCheckBox est largement utilisé dans les boîtes de dialogue de configuration&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QLCDNumber</emphasis> - affiche des nombres dans le style LCD. Souvent utilisé pour
des horloges&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QRadioButton</emphasis> - 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
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QButtonGroup</literal></primary></indexterm>QButtonGroup</literal> pour plus d'informations&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf"><indexterm remap="cdx"><primary><literal>QComboBox</literal></primary></indexterm>QComboBox</emphasis> - 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&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QListBox</emphasis> - fournit une liste à une seule colonne d'éléments qui peut défiler&&nbsp;;; </para>
</listitem>
<listitem>
<para><emphasis remap="bf">QListView</emphasis> - crée une liste multi-colonnes qui peut être utilisée pour
afficher, par exemple, des arborescences de fichiers ou des tables&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QMultiLineEdit</emphasis> - fournit un éditeur multi-lignes&&nbsp;;; </para>
</listitem>
<listitem>
<para><emphasis remap="bf">QProgressBar</emphasis> - affiche la progression d'une action qui demande beaucoup
de temps pour se terminer&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QSpinBox</emphasis> - permet de choisir des valeurs numériques avec des boutons
haut/bas ou en insérant la valeur, si l'écriture est activée&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QSlider</emphasis> - définit, avec une glissière, une valeur dans une plage définie
par le programme&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QScrollBar</emphasis> - 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&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QGroupBox</emphasis> - fournit une zone de cadre avec un titre pour indiquer que les
widgets fils appartiennent à la même zone.</para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">Widgets KDE :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">KColorButton</emphasis> - 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&&nbsp;;;</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KCombo</emphasis> - similaire à <literal remap="tt"><indexterm remap="cdx"><primary><literal>QComboBox</literal></primary></indexterm>QComboBox</literal>. Permet à l'utilisateur de choisir une valeur dans un menu déroulant&&nbsp;;; </para>
</listitem>
<listitem>
<para><emphasis remap="bf">KDatePicker</emphasis> - un widget complet pour laisser l'utilisateur choisir une valeur de date&&nbsp;;; </para>
</listitem>
<listitem>
<para><emphasis remap="bf">KDateTable</emphasis> - une table de calendrier pour sélectionner une date dans un mois. Utilisé par <literal remap="tt">KDatePicker</literal> pour créer la boîte de dialogue de choix de date&&nbsp;;; </para>
</listitem>
<listitem>
<para><emphasis remap="bf">KKeyButton</emphasis> - 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&&nbsp;;; </para>
</listitem>
<listitem>
<para><emphasis remap="bf">KLed</emphasis> - un widget de LED (Light Emitting Diode) pour afficher un certain état&&nbsp;;; </para>
</listitem>
<listitem>
<para><emphasis remap="bf">KLedLamp</emphasis> - une lampe LED qui supporte aussi les actions de clic&&nbsp;;; </para>
</listitem>
<listitem>
<para><emphasis remap="bf">KProgress</emphasis> - similaire à <literal remap="tt">QProgressBar</literal>, <literal remap="tt">KProgress</literal> supporte d'autres valeurs&&nbsp;;; </para>
</listitem>
<listitem>
<para><emphasis remap="bf">KRestrictedLine</emphasis> - un <literal remap="tt">QLineEdit</literal> 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&&nbsp;;; </para>
</listitem>
<listitem>
<para><emphasis remap="bf">KSeparator</emphasis> - un widget de séparation à utiliser, dans tous les cas, lorsque les applications KDE <indexterm remap="idx"><primary>applications KDE</primary></indexterm> 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 <literal remap="tt">QGroupBox</literal> ne convient pas&&nbsp;;; </para>
</listitem>
<listitem>
<para><emphasis remap="bf">KTreeList</emphasis> - une liste développable/réductible (NdT : collapsible list) pour afficher des arborescences comme <literal remap="tt">QListView</literal>.</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="proprits-des-widgets-qt-qt-supports">
<title>Propriétés des Widgets Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> supportés</title>

<para>Le chapitre suivant donne une vision complète des widgets de la boîte à outils Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>
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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>,
cette classe est décrite en premier. Toutes les propriétés de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> 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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>
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 :</para>

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

<sect2 id="qwidget">
<title>Propriétés de <indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</title>

<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> est la classe de base pour presque tous les widgets dans Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>
et KDE. Les widgets qui héritent de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> permettront donc d'utiliser
les mêmes paramètres dans la plupart des cas.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Apparence :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">BgColor: </emphasis> Couleur du fond du widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">BgMode :</emphasis> Mode du fond du widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">BgPalColor :</emphasis> Palette de couleur du fond</para>
</listitem>
<listitem>
<para><emphasis remap="bf">BgPixmap :</emphasis> Nom du fichier pour une image de fond</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Cursor :</emphasis> Curseur au-dessus du widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Font :</emphasis> Police du widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MaskBitmap :</emphasis> Nom du fichier pour le bitmap de masque</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Code C++ :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">AcceptsDrops :</emphasis> si défini à true, l'élément du widget acceptera les
"dépots" par les mécanismes de glisser-déposer <indexterm remap="idx"><primary>glisser-déposer</primary></indexterm> (NdT : drag'n drop <indexterm remap="idx"><primary>drag'n drop</primary></indexterm> mechanisms )
(le protocole de "glisser-déposer" <indexterm remap="idx"><primary>"glisser-déposer"</primary></indexterm> de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> , pas celui de KDE 1.x !)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Connections :</emphasis> connecte les signaux de l'élément aux slots</para>
</listitem>
<listitem>
<para><emphasis remap="bf">FocusProxy :</emphasis> l'élément qui donne son focus au widget.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">HasFocus :</emphasis> 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</para>
</listitem>
<listitem>
<para><emphasis remap="bf">ResizeToParent :</emphasis> redimensionne le widget à la taille de son parent
(non visible en mode édition)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">VarName :</emphasis> Nom de variable de l'élément. Changez-le avec le nom qui
décrit le but de l'élément.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">IsEnabled :</emphasis> définit si le widget acceptera les événements utilisateur</para>
</listitem>
<listitem>
<para><emphasis remap="bf">IsHidden :</emphasis> définit si l'élément est visible (false) ou caché (true)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Name :</emphasis> définit le nom du widget. Notez que le nom est différent de
VarName dans le code C++.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Géométrie :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Height :</emphasis> hauteur de l'élément</para>
</listitem>
<listitem>
<para><emphasis remap="bf">IsFixedSize :</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">MaxHeight :</emphasis> valeur maximale de Height</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MaxWidth :</emphasis> valeur maximale de Width</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinHeight :</emphasis> valeur minimale de Height</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinWidth :</emphasis> valeur minimale de Width</para>
</listitem>
<listitem>
<para><emphasis remap="bf">SizeIncX :</emphasis> nombre de pixels pour le redimensionnement dans la direction X</para>
</listitem>
<listitem>
<para><emphasis remap="bf">SizeIncY :</emphasis> nombre de pixels pour le redimensionnement dans la direction Y</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Width :</emphasis> largeur de l'élément</para>
</listitem>
<listitem>
<para><emphasis remap="bf">X :</emphasis> position horizontale (abscisse), comptée depuis le coin gauche</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Y :</emphasis> position verticale (ordonnée), comptée du haut vers le bas</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="qbutton">
<title>Widgets qui héritent de <indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</title>

<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal> est une classe de widget abstraite qui fournit des propriétés
communes aux boutons.</para>

<para>Hérite de <link linkend="QWidget">QWidget</link></para>

<para>Hérité par <link linkend="QCheckBox">QCheckBox</link>, <link linkend="QPushButton">QPushButton</link>
et <link linkend="QRadioButton">QRadioButton</link>.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Apparence :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">setPixmap :</emphasis> définit le nom du fichier de pixmap à utiliser</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">setText :</emphasis> le texte sur les étiquettes, boutons et cases ; pré-définit aussi
le texte pour les zones de saisie.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">setAutoRepeat :</emphasis> 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).</para>
</listitem>
<listitem>
<para><emphasis remap="bf">setAutoResize :</emphasis> active l'auto-redimensionnement si true. Quand
l'auto-redimensionnement est actif, le bouton se redimensionne lui-même lorsque
son contenu a changé.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>

<sect3 id="qcheckbox">
<title>Propriétés de QCheckBox</title>

<para>Hérite de <link linkend="QWidget">QWidget</link> et <link linkend="QButton">QButton</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">isChecked : (setChecked)</emphasis> définit si la case à cocher est cochée lors de sa construction</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qpushbutton">
<title>Propriétés de QPushButton</title>

<para>Hérite de <link linkend="QWidget">QWidget</link> et <link linkend="QButton">QButton</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">isAutoDefault : (setAutoDefault)</emphasis> le bouton automatiquement par défaut
(NdT : auto-default button) devient le bouton par défaut s'il reçoit le focus du clavier.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isDefault : (setDefault)</emphasis> 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 <literal remap="tt">QDialog</literal>). Le bouton
par défaut émet <literal remap="tt">clicked()</literal> si l'utilisateur a appuyé sur la touche "Entrée".</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isMenuButton : (setIsMenuButton)</emphasis> indique au bouton de dessiner un triangle
d'indication de menu s'il est activé. Le menu doit être inséré séparément.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isToggleButton : (setToggleButton)</emphasis> fait d'un bouton un bouton à bascule,
si bien que le bouton se comporte comme une case à cocher.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isToggledOn : (setOn)</emphasis> (public slot) bascule un bouton dans l'état "on".</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qradiobutton">
<title>Propriétés de QRadioButton</title>

<para>Hérite de <link linkend="QWidget">QWidget</link> et <link linkend="QButton">QButton</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">isChecked : (setChecked)</emphasis> définit si le bouton radio est coché lors de la construction</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>
</sect2>

<sect2 id="qcombobox">
<title>Propriétés de <indexterm remap="cdx"><primary><literal>QComboBox</literal></primary></indexterm>QComboBox</title>

<para>Hérite de <link linkend="QWidget">QWidget</link></para>

<para>(aucune propriété supplémentaire)</para>
</sect2>

<sect2 id="qframe">
<title>Widgets qui héritent de QFrame</title>

<para>Hérite de <link linkend="QWidget">QWidget</link></para>

<para>Pour l'instant, seulement utilisée comme une classe abstraite.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Apparence :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Margin (setMargin) :</emphasis> 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.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>

<sect3 id="qgroupbox">
<title>Propriétés de QGroupBox</title>

<para>Hérite de <link linkend="QWidget">QWidget</link> et <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Title : (setTitle)</emphasis> définit le titre du groupe d'éléments qui est affiché dans le cadre.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qlcdnumber">
<title>Propriétés de QLCDNumber</title>

<para>Hérite de <link linkend="QWidget">QWidget</link> et <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">NumDigits : (setNumDigits)</emphasis> définit le nombre de chiffres affichés dans QLCDNumber</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Value : (display)</emphasis> (public slot) définit la valeur initiale de QLCDNumber</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qlabel">
<title>Propriétés de QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm></title>

<para>Hérite de <link linkend="QWidget">QWidget</link> et <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Apparence :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Margin (setMargin) :</emphasis> définit la marge qui est, pour QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm>, la distance
du cadre à la première lettre du texte de l'étiquette, suivant l'alignement de l'étiquette.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Code C++ : </emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Buddy : (setBuddy)</emphasis> définit le widget compagnon de l'étiquette.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Text : (setText)</emphasis> définit le texte de l'étiquette.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoResize : (setAutoResize)</emphasis> si true, l'étiquette se redimensionnera
elle-même si son contenu a changé. Le coin en haut à gauche n'est pas déplacé.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qprogressbar">
<title>Propriétés de QProgressBar</title>

<para>Hérite de <link linkend="QWidget">QWidget</link> et <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">TotalSteps : (setTotalSteps)</emphasis> (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).</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

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

<para>Hérite de <link linkend="QWidget">QWidget</link> et <link linkend="QFrame">QFrame</link></para>

<para>Hérité par <link linkend="QListBox">QListBox</link>
(abstrait pour l'instant)</para>

<para>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.</para>

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

<para>Hérite de <link linkend="QWidget">QWidget</link>, <link linkend="QFrame">QFrame</link> et
<link linkend="QListView">QListView</link></para>

<para>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 <link linkend="QScrollView">QScrollView</link>.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Apparence :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">ListViewFont :</emphasis> (setFont()) définit la police des éléments de la ListView</para>
</listitem>
<listitem>
<para><emphasis remap="bf">ListViewPalette :</emphasis> (setPalette()) définit la palette des éléments de la ListView</para>
</listitem>
<listitem>
<para><emphasis remap="bf">TreeStepSize :</emphasis> (setTreeStepSize(int)) décalage en pixels entre un
élément fils et son élément père</para>
</listitem>
<listitem>
<para><emphasis remap="bf">hScrollBarMode :</emphasis> mode de barre de défilement fourni par <link linkend="QScrollView">QScrollView</link> pour la barre de défilement horizontale</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAllColumnsShowFocus :</emphasis> (setAllColumnsShowFocus(bool)) affiche le focus sur
toutes les colonnes d'un élément</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isMultiSelection :</emphasis> active les multi-sélections des éléments de la liste</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isRootDecorated :</emphasis> active les symboles + et - pour ouvrir et fermer les arbres</para>
</listitem>
<listitem>
<para><emphasis remap="bf">vScrollBarMode :</emphasis> mode de barre de défilement fourni par <link linkend="QScrollView">QScrollView</link> pour la barre de défilement verticale</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Entries :</emphasis> vous permet d'insérer une liste d'entrées qui sont pré-définies
comme QListViewItems.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoUpdate :</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect4>
</sect3>

<sect3 id="qspinbox">
<title>Propriétés de QSpinBox</title>

<para>Hérite de <link linkend="QWidget">QWidget</link> et <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">MaxValue :</emphasis>  définit la valeur maximale que l'utilisateur peut choisir</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinValue :</emphasis>  définit la valeur minimale que l'utilisateur peut choisir</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Prefix :</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">Suffix :</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">Value :</emphasis>     valeur pré-définie quand le widget est affiché</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isWrapping :</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qtableview">
<title>Widgets qui héritent de QTableView</title>

<para>Hérite de <link linkend="QWidget">QWidget</link>, <link linkend="QFrame">QFrame</link> et
<link linkend="QTableView">QTableView</link></para>

<para>Hérité par <link linkend="QListBox">QListBox</link> et <link linkend="QMultiLineEdit">QMultiLineEdit</link></para>

<sect4 id="qlistbox">
<title>Propriétés de QListBox</title>

<para>Hérite de <link linkend="QWidget">QWidget</link>, <link linkend="QFrame">QFrame</link> et
<link linkend="QTableView">QTableView</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">isAutoBottomScrollBar: (setAutoBottomScrollBar)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoScroll : (setAutoScroll)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoScrollBar : (setAutoScrollBar)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoUpdate : (setAutoUpdate)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isBottomScrollBar : (setBottomScrollBar)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isDragSelect : (setDragSelect)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isSmoothScrolling : (setSmoothScrolling)</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Géométrie :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">setFixedVisibleLines :</emphasis> 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.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect4>

<sect4 id="qmultilineedit">
<title>Propriétés de QMultiLineEdit</title>

<para>Hérite de <link linkend="QWidget">QWidget</link>, <link linkend="QFrame">QFrame</link>
et <link linkend="QTableView">QTableView</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Text : (setText) </emphasis> (public slot) définit le texte du widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoUpdate : (setAutoUpdate)</emphasis> utilisé pour éviter le scintillement
pendant de grandes modifications ; la vue n'est pas rafraîchie si désactivé.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isOverWriteMode : (setOverwriteMode) </emphasis>(public slot) définit si le mode
écrasement est activé ou non.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isReadOnly : (setReadOnly)</emphasis> (public slot) rend le texte du widget en
lecture seule ; désactive les entrées de texte.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTextSelected : (selectAll)</emphasis>(public slot) marque tout le texte comme sélectionné</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Géométrie :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">setFixedVisibleLines:</emphasis> 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.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect4>
</sect3>
</sect2>

<sect2 id="qlineedit">
<title>Propriétés de QLineEdit</title>

<para>Hérite de <link linkend="QWidget">QWidget</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">CursorPosition : (setCursorPosition)</emphasis> définit la position du curseur par défaut</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MaxLength : (setMaxLength) </emphasis> définit la longueur maximale de la chaîne de caractères</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Text : (setText) </emphasis> (public slot) définit le contenu affiché lors de la construction</para>
</listitem>
<listitem>
<para><emphasis remap="bf">hasFrame : (setFrame) </emphasis> dessine la zone de saisie dans un cadre de deux pixels, si activé</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTextSelected : (selectAll) </emphasis> (public slot) définit le texte à sélectionner.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="qscrollbar">
<title>Propriétés de QScrollBar</title>

<para>Hérite de <link linkend="QWidget">QWidget</link> et <literal remap="tt">QRangeControl</literal>.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">MaxValue :</emphasis> définit la valeur maximale de la barre de défilement ; utilisé 
dans le constructeur (optionnel)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinValue :</emphasis> définit la valeur minimale de la barre de défilement ; utilisé 
dans le constructeur (optionnel)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Orientation : (setOrientation)</emphasis> définit l'orientation de la barre de 
défilement à horizontale ou verticale</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Value : </emphasis> définit la valeur initiale de la barre de défilement ; utilisé 
dans le constructeur (optionnel)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTracking : (setTracking)</emphasis> si activé, la barre de défilement émet le 
signal <literal remap="tt">valueChanged()</literal> lorsque la barre est déplacée ; sinon, seulement lorsque 
le bouton de la souris est relâché.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="qslider">
<title>Propriétés de QSlider</title>

<para>Hérite de <link linkend="QWidget">QWidget</link> et <literal remap="tt">QRangeControl</literal>.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">MaxValue :</emphasis> définit la valeur maximale de la glissière ; utilisé dans le
constructeur (optionnel)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinValue :</emphasis> définit la valeur minimale de la glissière ; utilisé dans le
constructeur (optionnel)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Orientation : (setOrientation)</emphasis> définit l'orientation de la glissière à
horizontale ou verticale</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Value : (setValue)</emphasis> (public slot) utilise <literal remap="tt">QRangeControl::setValue()</literal>
pour définir la valeur</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTracking :(setTracking)</emphasis> si activé, la glissière émet le signal
<literal remap="tt">valueChanged()</literal> lorsque la barre est déplacée ; sinon, seulement lorsque le bouton
de la souris est relâché.</para>
</listitem>
</itemizedlist>

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

<sect1 id="proprits-des-widgets-kde-supports">
<title>Propriétés des Widgets KDE supportés</title>

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

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

<para>Hérite de <link linkend="QPushButton">QPushButton</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">DisplayedColor (setColor())</emphasis> : la couleur affichée sur le bouton</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

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

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

<para>Hérite de <link linkend="QComboBox">QComboBox</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Entries</emphasis> : liste des chaînes de caractères qui sont les entrées affichées dans la liste déroulante</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Text</emphasis> : le texte affiché actuellement dans la liste déroulante</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoResize</emphasis> : redimensionne la liste déroulante à l'élément courant</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

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

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Apparence :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">FontSize</emphasis> : la taille de la police pour le sélecteur de date</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

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

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

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

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Orientation</emphasis> : définit l'orientation du séparateur à horizontale ou verticale ; par défaut, horizontale.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

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

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

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Apparence :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">TreeListBgColor</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">TreeListPalette</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isBottomScrollbar</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isScrollBar</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isShowItemText</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isSmoothScrolling</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTreeDrawing</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Général :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Entries</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoUpdate</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

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

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

<para>Hérite de <link linkend="QWidget">QWidget</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Apparence :</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">LedColor : (setColor())</emphasis> définit la couleur de la LED affichée</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>

<sect1 id="construire-une-nouvelle-bote-de-dialogue">
<title>Construire une nouvelle boîte de dialogue</title>

<para>É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".</para>

<para>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".</para>

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

<para><orderedlist><listitem>
<para>l'héritage de la boîte de dialogue. Ceci est nécessaire parce que
tout widget dérive au moins de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>. 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&&nbsp;;;</para>
</listitem>
<listitem>
<para>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 <literal remap="tt">QDialog</literal>, vous
pourriez saisir un nom qui se termine par <literal remap="tt">Dlg</literal> 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 <indexterm remap="idx"><primary>Qt</primary></indexterm> : 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 <literal remap="tt">GridSizeDlg</literal>.</para>
</listitem>
<listitem>
<para>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 <indexterm remap="idx"><primary>Qt</primary></indexterm> : 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.</para>
</listitem>
</orderedlist>
</para>

<para>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.</para>

<para>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.</para>

<para>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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>. 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 <literal remap="tt">i18n()</literal> de <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal> 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.</para>

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

<para><itemizedlist>
<listitem>
<para>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&&nbsp;;;</para>
</listitem>
<listitem>
<para>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&&nbsp;;;</para>
</listitem>
<listitem>
<para>Surveillez le <emphasis remap="bf">focus du clavier <indexterm remap="idx"><primary>focus du clavier</primary></indexterm></emphasis> ! 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 <emphasis remap="bf">focus du clavier <indexterm remap="idx"><primary>focus du clavier</primary></indexterm></emphasis> 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.</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="dfinir-les-proprits-des-widgets">
<title>Définir les Propriétés des Widgets</title>

<para><indexterm><primary>propriététs de widget</primary></indexterm><indexterm><primary>éditeur de boîtes de dialogue</primary></indexterm><indexterm><primary>fenêtre de propriétés</primary></indexterm>
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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>, vous pouvez définir les
propriétés <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> ainsi que les propriétés qui sont spécifiques
au widget sélectionné.</para>

<para>Les propriétés peuvent être des :</para>

<para><itemizedlist>
<listitem>
<para>valeurs entières, comme la géométrie du widget ou la taille de la police</para>
</listitem>
<listitem>
<para>valeurs booléennes pour activer/désactiver certains paramètres du widget.
Définies avec des listes déroulantes contenant true et false&&nbsp;;;</para>
</listitem>
<listitem>
<para>valeurs énumérées d'un widget, par exemple la palette. Définies avec
des listes déroulantes contenant la liste des valeurs possibles&&nbsp;;;</para>
</listitem>
<listitem>
<para>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&&nbsp;;;</para>
</listitem>
<listitem>
<para>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&&nbsp;;;</para>
</listitem>
<listitem>
<para>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 <indexterm remap="idx"><primary>Qt</primary></indexterm> supérieures à 1.42.</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="intgrer-la-bote-de-dialogue">
<title>Intégrer la Boîte de Dialogue</title>

<para>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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> et un autre
de <literal remap="tt">QDialog</literal>.</para>

<sect2 id="hritage-de-qwidgetqwidget">
<title>Héritage de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal></title>

<para>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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> qui
remplace le widget de vue actuellement défini. Modifiez ensuite le code dans
la méthode <literal remap="tt">initView</literal> 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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>
vous-même.</para>

<para>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.</para>

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

<para>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.</para>
</sect2>

<sect2 id="hritage-de-qdialog">
<title>Héritage de <literal remap="tt">QDialog</literal></title>

<para>Si votre widget hérite de <literal remap="tt">QDialog</literal>, 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 <literal remap="tt">App</literal>
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 à <literal remap="tt">show()</literal> ou <literal remap="tt">exec()</literal> 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 <literal remap="tt">delete</literal>
si vous aviez créé l'instance de la boîte de dialogue avec <literal remap="tt">new</literal>
pour éviter les fuites de mémoire.</para>

<para>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<indexterm><primary>accelerator</primary></indexterm> et une icône
de barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>. Pour cela, ajoutez un identificateur de ressource
au fichier <literal remap="tt">resource.h</literal> 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 :</para>

<para><itemizedlist>
<listitem>
<para>un pixmap d'icône optionnel. Utilisez la macro <literal remap="tt">Icon("iconname.xpm")</literal>
de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> pour obtenir une instance de l'icône fournie par
<literal remap="tt">KIconLoader</literal>&&nbsp;;;</para>
</listitem>
<listitem>
<para>le nom de l'entrée de menu. Ajoutez la avec la macro <literal remap="tt">i18n("&&amp;;entryname")</literal>
de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> pour permettre l'internationalisation. Le symbole "&"
doit être devant la lettre qui apparaîtra soulignée pour y accéder directement
avec le clavier&&nbsp;;;</para>
</listitem>
<listitem>
<para>l'instance du membre à appeler. Normalement, ce devrait être le pointeur <literal remap="tt">this</literal>.</para>
</listitem>
<listitem>
<para>le slot du membre à appeler. Utilisez <literal remap="tt">SLOT(yourmethod()</literal> pour appeler le slot
lors de l'émission du signal <literal remap="tt">activated()</literal>.</para>
</listitem>
<listitem>
<para>la touche de raccourci clavier<indexterm><primary>accelerator</primary></indexterm>. Elle devrait être définie à zéro
car ceci est fait avec une entrée dans <literal remap="tt">initKeyAccel()</literal> où vous devez introduire une
touche de raccourci clavier<indexterm><primary>accelerator</primary></indexterm> en même temps que le slot à appeler. Appelez
ensuite <literal remap="tt">changeMenuAccel()</literal> pour changer le raccourci clavier<indexterm><primary>accelerator</primary></indexterm>
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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal>.</para>
</listitem>
<listitem>
<para>l'identificateur de menu défini dans <literal remap="tt">resource.h</literal></para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
</chapter>

<chapter id="support-de-limpression">
<title>Support de l'Impression</title>

<para><indexterm remap="ncdx"><primary><literal>QPrinter</literal></primary></indexterm><indexterm remap="ncdx"><primary><literal>QPainter</literal></primary></indexterm><indexterm remap="ncdx"><primary><literal>QPrintdialog</literal></primary></indexterm><indexterm><primary>printing</primary></indexterm>
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 <indexterm remap="idx"><primary>Qt</primary></indexterm> 
à travers deux classes : la classe <literal remap="tt">QPrintDialog</literal>, une boîte de dialogue permettant de 
configurer l'impression, et la classe <literal remap="tt">QPainter</literal> 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.</para>

<sect1 id="la-bote-de-dialogue-dimpression-de-qt-qt">
<title>La Boîte de Dialogue d'Impression de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></title>

<para>La boîte de dialogue d'impression de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> peut directement être utilisée en incluant 
<literal remap="tt">qprintdialog.h</literal>. 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 <literal remap="tt">print()</literal> en utilisant <literal remap="tt">QPainter</literal>.</para>
</sect1>

<sect1 id="la-classe-qpainter">
<title>La Classe QPainter</title>

<para>Indépendamment des capacités de l'imprimante, vous pouvez utiliser <literal remap="tt">QPainter</literal> pour 
dessiner votre document dans l'imprimante fournie par <literal remap="tt">QPrinter</literal> 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.</para>
</sect1>
</chapter>

<chapter id="fonctions-daide">
<title>Fonctions d'Aide</title>

<para>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 <indexterm remap="idx"><primary>Qt</primary></indexterm> 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 :</para>

<para><itemizedlist>
<listitem>
<para>les bulles d'aide</para>
</listitem>
<listitem>
<para>l'aide rapide</para>
</listitem>
<listitem>
<para>l'aide de la barre d'état</para>
</listitem>
<listitem>
<para>les boutons "Qu'est-ce que c'est...?"</para>
</listitem>
</itemizedlist>
</para>

<para>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.</para>

<para>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.</para>

<sect1 id="bulles-daide">
<title>Bulles d'aide</title>

<para>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 <indexterm remap="idx"><primary>barres d'outils</primary></indexterm>,
où vos bulles d'aide devraient être aussi petites que possible, car les barres d'outils <indexterm remap="idx"><primary>barres d'outils</primary></indexterm>
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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>
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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal> située dans la bibliothèque KDE-UI.</para>

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

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

<indexterm remap="ncdx"><primary><literal>toolBar()</literal></primary></indexterm><indexterm><primary>KToolBar</primary></indexterm></para>

<para>Ici, la partie <literal remap="tt">i18n("New File")</literal> définit le message de la bulle d'aide. Il est
entouré par la macro i18n() fournie par <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal> pour traduire la
bulle d'aide dans la langue actuellement sélectionnée.</para>

<para>Les bulles d'aide peuvent aussi être ajoutées à n'importe quel widget personnalisé
en utilisant les classes <literal remap="tt">QToolTip</literal> et <literal remap="tt"><indexterm remap="cdx"><primary><literal>QToolTipGroup</literal></primary></indexterm>QToolTipGroup</literal> fournies par Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>.
Voici un exemple d'utilisation :</para>

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

Pour plus d'informations, consultez le Manuel de Référence de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, classe 
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QToolTip</literal></primary></indexterm>QToolTip</literal>.</para>
</sect1>

<sect1 id="ajouter-une-aide-rapide">
<title>Ajouter une Aide Rapide</title>

<para>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).</para>

<para>Pour utiliser l'Aide Rapide, ajoutez le fichier d'inclusion <literal remap="tt"><indexterm remap="cdx"><primary><literal>kquickhelp.h</literal></primary></indexterm>kquickhelp.h</literal> à votre fichier
source contenant de l'aide rapide. Comme la classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KQuickHelp</literal></primary></indexterm>KQuickHelp</literal> 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.</para>

<para>Voici un exemple :</para>

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

<para>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.</para>

<para>La classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KQuickHelp</literal></primary></indexterm>KQuickHelp</literal> 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 <ulink url="../kde_libref/index.html">KDE Library Reference Guide</ulink>
et la documentation de la classe <indexterm remap="idx"><primary>documentation de la classe</primary></indexterm> pour plus d'informations sur <literal remap="tt"><indexterm remap="cdx"><primary><literal>KQuickTip</literal></primary></indexterm>KQuickTip</literal>.</para>
</sect1>

<sect1 id="extension-de-laide-dans-la-barre-dtat">
<title>Extension de l'Aide dans la Barre d'État</title>

<para>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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>.
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
<literal remap="tt">highlighted(int)</literal> à la méthode <literal remap="tt">statusCallback(int)</literal> qui sélectionne le message approprié
dans une instruction switch. Lorsque vous ajoutez un élément à un menu existant ou à une
barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>, 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.</para>

<para>Exemple :</para>

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

Ceci affichera un message dans la barre d'état en appelant la méthode <literal remap="tt">slotStatusHelpMsg()</literal>,
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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> ayant l'identificateur ID&&lowbar;;FILE&&lowbar;;NEW
qui est connecté à la méthode <literal remap="tt">statusCallback()</literal>. Les barres d'outils se connectent à cette
méthode avec leur signal <literal remap="tt">pressed(int)</literal> qui permet à l'utilisateur d'appuyer sur un bouton
de la barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> et déplacer plus loin la souris s'il ne veut pas déclencher
la commande. <literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal> possède aussi le signal <literal remap="tt">highlighted(int, bool)</literal>
qui peut être utilisé à la place du signal prédéfini pour afficher le message quand l'utilisateur
met le bouton en surbrillance.</para>
</sect1>

<sect1 id="le-bouton-whats-this...">
<title>Le Bouton "What's This...?"</title>

<para>Le bouton "What's This...?" <indexterm remap="idx"><primary>"What's This...?"</primary></indexterm> fournit des fenêtres d'aide comme Quickhelp<indexterm><primary>KQuickHelp</primary></indexterm> 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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm>. Il est placé dans la barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> 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 :</para>

<para><orderedlist><listitem>
<para>incluez <literal remap="tt">qwhatsthis.h</literal> dans votre code source</para>
</listitem>
<listitem>
<para>ajoutez une donnée membre privée <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWhatsThis</literal></primary></indexterm>QWhatsThis whats&&lowbar;;this</literal> ou avec un autre nom
à la déclaration de votre classe dérivant de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal></para>
</listitem>
<listitem>
<para>définisez un identificateur de ressource pour votre bouton what's this dans le
fichier <literal remap="tt">resource.h</literal>, par exemple <literal remap="tt">&&num;;define ID&&lowbar;;HELP&&lowbar;;WHATS&&lowbar;;THIS 10100</literal></para>
</listitem>
<listitem>
<para>dans votre méthode de création de la barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> (généralement <literal remap="tt">initToolBar()</literal>),
ajoutez l'emplacement où vous voulez que le bouton soit affiché :
<screen>  whats_this = new QWhatsThis;
  QToolButton *btnwhat = whats_this-&gt;whatsThisButton(toolBar());
  QToolTip::add(btnwhat, i18n("What's this...?"));
  toolBar()-&gt;insertWidget(ID_HELP_WHATS_THIS, btnwhat-&gt;sizeHint().width(), btnwhat);
  btnwhat-&gt;setFocusPolicy(QWidget::NoFocus);
</screen>

<indexterm remap="ncdx"><primary><literal>setFocusPolicy()</literal></primary></indexterm></para>
</listitem>
<listitem>
<para>enfin, ajoutez les messages que vous voulez voir lors d'un clic sur un certain widget comme ceci :
<screen>whats_this-&gt;add(class_tree, i18n("Class Viewer\n\n"
		  "The class viewer shows all classes, methods and variables "
		  "of the current project files and allows switching to declarations "
		  "and implementations. The right button popup-menu allows more specialized "
		  "functionality."));
</screen>
</para>
</listitem>
</orderedlist>
</para>
</sect1>
</chapter>

<chapter id="extension-de-la-documentation-avec-sgml-sgml">
<title>Extension de la Documentation avec SGML <indexterm remap="idx"><primary>SGML</primary></indexterm></title>

<para>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.</para>

<sect1 id="pourquoi-sgml">
<title>Pourquoi SGML ?</title>

<para>SGML <indexterm remap="idx"><primary>SGML</primary></indexterm> (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 <indexterm remap="idx"><primary>KDEHelp</primary></indexterm> 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.</para>

<para>Actuellement, KDE (et par conséquent KDevelop) utilise le paquetage des 
SGML-Tools 1.x (voir <ulink url="http://www.sgmltools.org">\|\|</ulink>) qui était connu
sous le nom de paquetage LinuxDoc. Il contient une DTD appelée <literal remap="tt">LinuxDoc</literal>
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 <literal remap="tt">LinuxDoc</literal>. 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.</para>

<para>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.</para>

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

<para><itemizedlist>
<listitem>
<para>écrire de la documentation LinuxDoc est facile</para>
</listitem>
<listitem>
<para>installer les SGML-Tools 1.x permettant d'utiliser LinuxDoc est encore
plus simple</para>
</listitem>
<listitem>
<para>KDE fournit un outil supplémentaire appelé <literal remap="tt">ksgml2html</literal> qui
ajoute le style de documentation KDE à la sortie générée par le
convertisseur <literal remap="tt">sgml2html</literal> des SGML-Tools 1.x afin de produire
une sortie HTML. </para>
</listitem>
</itemizedlist>
</para>

<para>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.</para>

<para>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 :</para>

<para><itemizedlist>
<listitem>
<para>HTML avec l'apparence KDE si vous utilisez <literal remap="tt">ksgml2html</literal></para>
</listitem>
<listitem>
<para>texte brut</para>
</listitem>
<listitem>
<para>GNU info</para>
</listitem>
<listitem>
<para>format Lyx</para>
</listitem>
<listitem>
<para>formats &tex;, DVI, PostScript et PDF</para>
</listitem>
<listitem>
<para>Rich Text Format (RTF).</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="ce-que-la-documentation-contient-dj">
<title>Ce que la Documentation contient déjà</title>

<para>Lors de la création d'un projet KDevelop, le répertoire <literal remap="tt">docs/en</literal>
contient déjà le fichier de documentation en anglais <literal remap="tt">index.sgml</literal> 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.</para>

<para>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 <literal remap="tt">ksgml2html <indexterm remap="idx"><primary>ksgml2html</primary></indexterm></literal> et le style KDE est ajouté à la sortie HTML.
Ouvrez le dossier <literal remap="tt">docs/en</literal> dans l'onglet RFV et ajoutez le fichier 
<literal remap="tt">logotp3.gif</literal> 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 
<literal remap="tt">$(kde&&lowbar;;htmldir)/en/&&lt;;votre&&lowbar;;projet&&gt;;/logotp3.gif</literal>.</para>
</sect1>

<sect1 id="crire-de-la-documentation-sgml">
<title>Écrire de la Documentation SGML</title>

<para>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.</para>

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

<sect2 id="la-dclaration-de-la-dtd">
<title>La Déclaration de la DTD</title>

<para>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 &&lt;;votrebalise&&gt;; votrecontenu 
&&lt;;/votrebalise&&gt;;) est toujours le DOCTYPE :</para>

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

<para>Cela indique au formateur sgml qu'il doit utiliser la DTD LinuxDoc.</para>

<sect3 id="la-structure-du-document">
<title>La Structure du Document</title>

<para>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 :</para>

<para><itemizedlist>
<listitem>
<para><literal remap="tt">&&lt;;notes&&gt;;</literal> pour de brèves explications&&nbsp;;;</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;article&&gt;;</literal> 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&&nbsp;;;</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;report&&gt;;</literal> pour des articles qui sont plus longs que
le type &&lt;;article&&gt;;&&nbsp;;;</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;book&&gt;;</literal> pour écrire des livres plus longs - les manuels de
KDevelop ont été rédigés en utilisant ce type de document&&nbsp;;;</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;slides&&gt;;</literal> pour des transparents. C'est utile pour des
présentations. Bien sur, vous utiliserez le format de sortie &latex; dans la
plupart des cas&&nbsp;;;</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;letter&&gt;;</literal> pour des lettres classiques&&nbsp;;;</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;telefax&&gt;;</literal> pour un fax&&nbsp;;;</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;manpage&&gt;;</literal> pour une page de manuel (NdT : manpage).</para>
</listitem>
</itemizedlist>
</para>

<para>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 &&lt;;article&&gt;;. Elle est
utilisée par la majorité des applications hormis KDevelop qui utilise le
format &&lt;;book&&gt;;. 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).</para>

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

<sect2 id="pages-de-titre">
<title>Pages de Titre</title>

<para>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  
<literal remap="tt">&&lt;;title&&gt;;</literal>, <literal remap="tt">&&lt;;author&&gt;;</literal> et <literal remap="tt">&&lt;;date&&gt;;</literal> car cela convient
dans la plupart des cas. Dans le cas spécial de la structure
<literal remap="tt">&&lt;;book&&gt;;</literal>, 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 :</para>

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

<para>Ceci recouvre tout ce qu'une page de titre contient normalement. La balise <literal remap="tt">&&lt;;author&&gt;;</literal>
peut aussi inclure une balise <literal remap="tt">&&lt;;thanks&&gt;;</literal> pour insérer des
remerciements aux co-auteurs, relecteurs, etc. <literal remap="tt">&&lt;;inst&&gt;;</literal> 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.
<literal remap="tt">&&lt;;abstract&&gt;;</literal> 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;.</para>
</sect2>

<sect2 id="index">
<title>Index</title>

<para>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 :</para>

<para><itemizedlist>
<listitem>
<para>&&lt;;toc&&gt;; pour la table des matières</para>
</listitem>
<listitem>
<para>&&lt;;lof&&gt;; pour la liste des figures</para>
</listitem>
<listitem>
<para>&&lt;;lot&&gt;; pour la liste des tableaux</para>
</listitem>
</itemizedlist>
</para>

<para>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.</para>

<para>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.</para>

<para><itemizedlist><listitem>
<para>&&lt;;idx&&gt;; pour une entrée d'index normale</para>
</listitem>
<listitem>
<para>&&lt;;cdx&&gt;; pour une entrée d'index true-type</para>
</listitem>
<listitem>
<para>&&lt;;nidx&&gt;; pour une entrée d'index n'apparaissant pas dans le document</para>
</listitem>
<listitem>
<para>&&lt;;ncdx&&gt;; comme précédemment pour une entrée d'index tt</para>
</listitem>
</itemizedlist></para>

<para>Ces balises sont ignorées par tous les moteurs (l'outil qui fait la
correspondance des balises sgml avec leur format de document) excepté <literal remap="tt">sgml2latex</literal>
qui génère un fichier d'index <literal remap="tt">index.idx</literal> qui peut être converti en fichier
&tex;-index avec <literal remap="tt">makeindex index.idx</literal>. L'index en lui-même peut être
inséré ultérieurement dans le fichier de sortie &tex; avec <literal remap="tt">\printindex</literal>.
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...).</para>
</sect2>

<sect2 id="le-contenu-du-document">
<title>Le Contenu du Document</title>

<para>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 <literal remap="tt">&&lt;;sect&&gt;;</literal> si on utilise <literal remap="tt">&&lt;;book&&gt;;</literal>, vous
devez commencer vos chapitres par <literal remap="tt">&&lt;;chapt&&gt;;</literal>.</para>

<para>Après la balise de début, vous pouvez structurer chaque chapitre avec
<literal remap="tt">&&lt;;sect1&&gt;;</literal>, <literal remap="tt">&&lt;;sect2&&gt;;</literal> etc. jusqu'au nombre maximal de niveaux
de sous-sections (4).</para>

<para>La balise ouvrante du chapitre est suivie par le titre de ce chapitre. Vous
avez le choix d'utiliser <literal remap="tt">&&lt;;title&&gt;;</literal> et <literal remap="tt">&&etago;;title&&gt;;</literal> pour le titre
du chapitre (optionnel). Ensuite, après le titre du chapitre, vous devez
ajouter une balise &&lt;;p&&gt;; 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 <literal remap="tt">sgmltools</literal> 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.</para>
</sect2>
</sect1>

<sect1 id="comment-appeler-laide-dans-les-botes-de-dial">
<title>Comment appeler l'Aide dans les Boîtes de Dialogue</title>

<para><indexterm><primary>fonctions d'aide</primary></indexterm>
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</para>

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

<para>où <literal remap="tt">aFilename</literal> est le nom du fichier à appeler dans le dossier de la
documentation HTML de votre application ; par exemple, index-3.html. Ensuite,
<literal remap="tt">aTopic</literal> 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.</para>
</sect1>
</chapter>

<chapter id="documentation-de-classe-avec-kdoc-kdoc">
<title>Documentation de Classe avec KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></title>

<para>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 <literal remap="tt">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></literal>. KDevelop supporte pleinement
l'utilisation de <literal remap="tt">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></literal> 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 <indexterm remap="idx"><primary>API</primary></indexterm> (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 <literal remap="tt">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></literal>.</para>

<sect1 id="comment-utiliser-les-fonctionnalits-de-docum">
<title>Comment utiliser les Fonctionnalités de Documentation de KDevelop</title>

<para>Pour créer la documentation de l'API <indexterm remap="idx"><primary>API</primary></indexterm> après avoir généré votre projet,
sélectionnez "Construire la documentation de l'API <indexterm remap="idx"><primary>API</primary></indexterm>" 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 <indexterm remap="idx"><primary>API</primary></indexterm>"
dans le menu "Aide" ou bien le symbole de livre correspondant dans l'arborescence
"Documentation", dossier "Projet courant".</para>

<para>La documentation contient déjà des références croisées entre les
documentations en-ligne des classes <indexterm remap="idx"><primary>documentations en-ligne des classes</primary></indexterm> de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> 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 <indexterm remap="idx"><primary>Qt</primary></indexterm> et de KDE.</para>
</sect1>

<sect1 id="ajouter-la-documentation-dune-classe-ou-dun-">
<title>Ajouter la Documentation d'une Classe ou d'un Membre</title>

<para>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"-&gt;"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. </para>

<para>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 <indexterm remap="idx"><primary>documentation
des classes</primary></indexterm> 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. </para>

<para>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 <indexterm remap="idx"><primary>API</primary></indexterm> doit être réalisée en anglais, ce qui permet à des
groupes de développeurs internationaux de travailler sur vos sources. </para>

<para>Si vous voulez ajouter manuellement de la documentation dans le fichier
d'en-tête, ajoutez la documentation <emphasis remap="bf">au-dessus</emphasis> 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.</para>

<para>Exemple :</para>

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

<sect1 id="balises-spciales">
<title>Balises Spéciales</title>

<para><emphasis remap="bf">NOTE :</emphasis> La documentation suivante est tirée de la
documentation fournie avec KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm>, écrite par Sirtaj S. Kang 
<ulink url="mailto:taj@.kde.org">taj@.kde.org</ulink>), l'auteur de
KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm> ; Copyright (c) 1997</para>

<para>La documentation est composée de :</para>

<para><itemizedlist>
<listitem>
<para>Texte normal. Les paragraphes doivent être séparés par au moins une ligne vide.
</para>
</listitem>
<listitem>
<para>Texte de la forme
<programlisting>&&lt;;pre&&gt;;
.....morceaux de code....
&&lt;;/pre&&gt;;</programlisting>
</para>
</listitem>
<listitem>
<para>Différentes balises de la forme :
<screen>@nombalise [balise paramètres]
</screen>
</para>
</listitem>
</itemizedlist>
</para>

<para>Les balises valides pour chaque type d'entité de code source sont :</para>

<para><itemizedlist>
<listitem>
<para>Classes
<screen>  @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
</screen>

</para>
</listitem>
<listitem>
<para>Méthodes

<screen>  @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.
</screen>

</para>
</listitem>
<listitem>
<para>Constantes, Énumérations, Propriétés
<screen>  @see
	comme ci-dessus
</screen>
</para>
</listitem>
<listitem>
<para>Voir aussi <literal remap="tt">@ref</literal>
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).</para>
</listitem>
</itemizedlist>
</para>
</sect1>
</chapter>

<chapter id="internationalisation">
<title>Internationalisation</title>

<sect1 id="quest-ce-que-i18n">
<title>Qu'est-ce que i18n ?</title>

<para>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.</para>
</sect1>

<sect1 id="comment-kde-supporte-linternationalisation">
<title>Comment KDE supporte l'Internationalisation</title>

<para>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.</para>

<para>Techniquement, cela est réalisé par le Système de Fichiers Standard de
KDE <indexterm remap="idx"><primary>Système de Fichiers Standard de
KDE</primary></indexterm> 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 <literal remap="tt">KLocale</literal> 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.</para>

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

<para><orderedlist><listitem>
<para>inclure <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal> dans votre code source lorsqu'un texte visible
apparaît dans votre application, par exemple dans les fichiers sources qui
contiennent des QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm>s</para>
</listitem>
<listitem>
<para>partout où vous définissez des chaînes de caractères "visibles",
encadrez-les par la macro <literal remap="tt">i18n()</literal> fournie par <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal> afin de
réaliser la traduction</para>
</listitem>
<listitem>
<para>lorsque vous devez accéder à un objet localisé, utilisez la macro
<literal remap="tt">klocale</literal> fournie par <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal></para>
</listitem>
</orderedlist>
</para>

<para>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 <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> car d'une part, ce n'est pas
nécessaire et d'une autre part, la lecture ne fonctionnera plus.</para>
</sect1>

<sect1 id="ajouter-une-langue-votre-projet">
<title>Ajouter une Langue à votre Projet</title>

<para>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 <literal remap="tt">po</literal> est ajouté dans le dossier principal de
votre projet. C'est ici que sera placé le fichier <emphasis>&&lt;;application&&gt;;</emphasis>.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.
<indexterm><primary>menu "Project"</primary></indexterm><indexterm><primary>fichiers PO</primary></indexterm><indexterm><primary>traductions</primary></indexterm><indexterm remap="ncdx"><primary><literal>KLocale</literal></primary></indexterm></para>

<para>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 <emphasis>&&lt;;lang&&gt;;</emphasis>.po correspondant sera généré dans le dossier
<literal remap="tt">po</literal>. 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 <indexterm remap="idx"><primary>KTranslator</primary></indexterm>, le fichier .po sera ouvert dans la
fenêtre "Outils", sinon comme un fichier texte dans la fenêtre
en-tête/ressource. KTranslator <indexterm remap="idx"><primary>KTranslator</primary></indexterm> 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.</para>

<para>Pour l'édition à la main, nous allons prendre un exemple :
<screen>#: kscribble.cpp:619
msgid "Opens an existing document"
msgstr ""
</screen>
</para>

<para>Vous voyez ci-dessus une chaîne de caractères qui a été extraite de la ligne
619 du fichier <literal remap="tt">kscribble.cpp</literal>. <literal remap="tt"><indexterm remap="cdx"><primary><literal>msgid</literal></primary></indexterm>msgid</literal> et <literal remap="tt"><indexterm remap="cdx"><primary><literal>msgstr</literal></primary></indexterm>msgstr</literal> sont
des balises qui donnent des informations pour la traduction ;
<literal remap="tt"><indexterm remap="cdx"><primary><literal>msgstr</literal></primary></indexterm>msgstr</literal> 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 :</para>

<para><screen>#: kscribble.cpp:619
msgid "Opens an existing document"
msgstr "Ouvre un document existant"
</screen>
</para>

<para>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.</para>

<para>De plus, vous devrez être très vigilants lorsque vous traduisez des chaînes
contenant un "et commercial" (NdT : le symbole &&amp;;). La lettre après ce symbole
est utilisée comme accélérateur clavier<indexterm><primary>accélérateur</primary></indexterm> 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 <indexterm remap="idx"><primary>focus du clavier</primary></indexterm> vers l'élément
sélectionné. Si la même lettre d'accélérateur<indexterm><primary>accélérateur</primary></indexterm> apparaît dans
la même zone de focus de clavier <indexterm remap="idx"><primary>focus de clavier</primary></indexterm> (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 <indexterm><primary>accélérateur</primary></indexterm> 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.</para>
</sect1>

<sect1 id="contacts-des-quipes-de-traduction">
<title>Contacts des Équipes de Traduction</title>

<para>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
<ulink url="http://www.kde.org">\|\|</ulink>.</para>

<para>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.</para>

<para>La traduction de KDE est organisée par Juraj Bednar <ulink url="mailto:bednar@rak.isternet.sk">mailto:bednar@rak.isternet.sk</ulink> et
Matthias Elter <ulink url="mailto:me@kde.org">me@kde.org</ulink></para>

<para>Vous pouvez vous abonner à la liste de discussion kde-i18n-doc@kde.org de KDE
sur l'internationalisation en envoyant un mail à <ulink url="mailto:kde-i18n-doc-request@kde.org?subject=subscribe">kde-i18n-doc-request@kde.org</ulink> 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.</para>

<para><variablelist>
<varlistentry>
<term>br Équipe de traduction en Breton :</term>
<listitem>
<para>coordinateur : Jañ-Mai DRAPIER <ulink url="mailto:jdrapier@club-internet.fr">jdrapier@club-internet.fr</ulink></para>
<para>site web : <ulink url="http://perso.club-internet.fr/jdrapier">http://perso.club-internet.fr/jdrapier</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>ca Équipe de traduction en Catalan :</term>
<listitem>
<para>coordinateur : Sebastià Pla <ulink url="mailto:sastia@redestb.es">sastia@redestb.es</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>cs Équipe de traduction en Tchèque :</term>
<listitem>
<para>coordinateur :  Miroslav Flídr <ulink url="mailto:flidr@kky.zcu.cz">flidr@kky.zcu.cz</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>da Équipe de traduction en Danois :</term>
<listitem>
<para>coordinateur :  Erik Kjær Pedersen <ulink url="mailto:erik@binghamton.edu">erik@binghamton.edu</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>de Équipe de traduction en Allemand :</term>
<listitem>
<para>coordinateur : Thomas Diehl <ulink url="mailto:th.diehl@gmx.net">th.diehl@gmx.net</ulink></para>
<para>site web : <ulink url="http://www.dtp-service.com/kde/de/">\|\|</ulink></para>
<para>liste de discussion :  envoyez un mail avec le sujet 'subscribe' à :
<ulink url="mailto:kde-i18n-de-request@kde.org?subject=subscribe">kde-i18n-de-request@kde.org</ulink></para>
<para>Forum web pour discussions et avis des utilisateurs :
<ulink url="http://www.dtp-service.com/discus_d">\|\|</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>el Équipe de traduction en Grec :</term>
<listitem>
<para>coordinateur :  Theodore J. Soldatos <ulink url="mailto:theodore@eexi.gr">theodore@eexi.gr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>eo Équipe de traduction en Esperanto :</term>
<listitem>
<para>coordinateur :  Wolfram Diestel <ulink url="mailto:diestel@rzaix340.rz-uni-leipzig.de">diestel@rzaix340.rz-uni-leipzig.de</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>es Équipe de traduction en Espagnol :</term>
<listitem>
<para>coordinateur :  Boris Wesslowski, Alonso Lara <ulink url="mailto:Boris@Wesslowski.com">Boris@Wesslowski.com</ulink></para>
<para>site web : <ulink url="http://members.xoom.com/keko5/">\|\|</ulink></para>
<para>liste de discussion :  envoyez un mail avec le sujet 'subscribe' à :
<ulink url="mailto:kde-es@kde.org?subject=subscribe">kde-es@kde.org</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>et Équipe de traduction en Estonien :</term>
<listitem>
<para>coordinateur :  Hasso C. Tepper <ulink url="mailto:hasso@ewsound.estnet.ee">hasso@ewsound.estnet.ee</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>fi Équipe de traduction en Finlandais :</term>
<listitem>
<para>coordinateur : Kim Enkovaara <ulink url="mailto:kim.enkovaara@iki.fi">kim.enkovaara@iki.fi</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>fr Équipe de traduction en Français :</term>
<listitem>
<para>coordinateur : Francois-Xavier Duranceau <ulink url="mailto:duranceau@kde.org">duranceau@kde.org</ulink></para>
<para>site web : <ulink url="http://i18n.kde.org/teams/fr/apps/wip-apps.html">\|\|</ulink></para>
<para>liste de discussion : envoyer un message vide à :  <ulink url="mailto:kde-francophone-subscribe@egroups.fr">kde-francophone-subscribe@egroups.fr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>he Équipe de traduction en Hébreu :</term>
<listitem>
<para>coordinateur :  Erez Nir <ulink url="mailto:erez-n@actcom.co.il">erez-n@actcom.co.il</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>hr Équipe de traduction en Croate :</term>
<listitem>
<para>coordinateur :  Vladimir Vuksan
<ulink url="mailto:vuksan@veus.hr">vuksan@veus.hr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>hu Équipe de traduction en Hongrois :</term>
<listitem>
<para>coordinateur :  Marcell Lengyel
<ulink url="mailto:miketkf@yahoo.com">miketkf@yahoo.com</ulink>
site web :<ulink url="http://sophia.jpte.hu/~kde">\|\|</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>is Équipe de traduction en Islandais :</term>
<listitem>
<para>coordinateurs :
Logi Ragnarsson <ulink url="mailto:logir@imf.au.dk">logir@imf.au.dk</ulink>,
Thorarinn R. Einarsson <ulink url="mailto:thori@mindspring.com">thori@mindspring.com</ulink>,
Bjarni R. Einarsson <ulink url="mailto:bre@netverjar.is">bre@netverjar.is</ulink>,
Hrafnkell Eiriksson <ulink url="mailto:hkelle@rhi.hi.is">hkelle@rhi.hi.is</ulink>,
Gudmundur Erlingsson <ulink url="mailto:gudmuner@lexis.hi.is">gudmuner@lexis.hi.is</ulink>,
Richard Allen <ulink url="mailto:ra@hp.is">ra@hp.is</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>it Équipe de traduction en Italien :</term>
<listitem>
<para>coordinateur :  Andrea Rizzi <ulink url="mailto:rizzi@kde.org">rizzi@kde.org</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>ko Équipe de traduction en Coréen :</term>
<listitem>
<para>coordinateur :  LinuxKorea Co. <ulink url="mailto:kde@linuxkorea.co.kr">kde@linuxkorea.co.kr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>mk Équipe de traduction en Macédonien :</term>
<listitem>
<para>coordinateur :  Sasha Konecni <ulink url="mailto:sasha@msi-uk.com">sasha@msi-uk.com</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>nl Équipe de traduction en Hollandais :</term>
<listitem>
<para>coordinateur :  flidr@CyberGate.zcu.cz <ulink url="mailto:flidr@CyberGate.zcu.cz">flidr@CyberGate.zcu.cz</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>no Équipe de traduction en Norvégien :</term>
<listitem>
<para>coordinateur :  Hans Petter Bieker <ulink url="mailto:zerium@webindex.no">zerium@webindex.no</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>pl Équipe de traduction en Polonais :</term>
<listitem>
<para>coordinateur :  Piotr Roszatycki <ulink url="mailto:dexter@fnet.pl">dexter@fnet.pl</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>pt Équipe de traduction en Portugais :</term>
<listitem>
<para>coordinateur :  Pedro Morais <ulink url="mailto:pmmm@camoes.rnl.ist.utl.pt">pmmm@camoes.rnl.ist.utl.pt</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>pt&&lowbar;;BR Équipe de traduction en Portugais Brésilien :</term>
<listitem>
<para>coordinateur :  Elvis Pfützenreuter <ulink url="mailto:epx@netville.com.br">epx@netville.com.br</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>ro Équipe de traduction en Roumain :</term>
<listitem>
<para>coordinateur :  Paul Ionescu <ulink url="mailto:ipaul@romsys.ro">ipaul@romsys.ro</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>ru Équipe de traduction en Russe :</term>
<listitem>
<para>coordinateur :  Denis Y. Pershin <ulink url="mailto:dyp@inetlab.com">dyp@inetlab.com</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>sk Équipe de traduction en Slovaque :</term>
<listitem>
<para>coordinateur :  Juraj Bednar <ulink url="mailto:bednar@isternet.sk">bednar@isternet.sk</ulink></para>
<para>liste de discussion :  envoyez un mail avec le sujet 'subscribe' à :
<ulink url="mailto:sk-i18n@rak.isternet.sk?subject=subscribe">sk-i18n@rak.isternet.sk</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>sl Équipe de traduction en Slovène :</term>
<listitem>
<para>coordinateur :  blazzupancic@hotmail.com
<ulink url="mailto:blazzupancic@hotmail.com">blazzupancic@hotmail.com</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>sv Équipe de traduction en Suédois :</term>
<listitem>
<para>coordinateur :  Anders Widell
<ulink url="mailto:d95-awi@nada.kth.se">d95-awi@nada.kth.se</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>tr Équipe de traduction en Turc :</term>
<listitem>
<para>coordinateur :  Gorkem Cetin
<ulink url="mailto:gorkem@linux.org.tr">gorkem@linux.org.tr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>zh&&lowbar;;GB2312 Équipe de traduction en Chinois Simplifié :</term>
<listitem>
<para>coordinateur :  Wang Jian
<ulink url="mailto:larkw@263.net">larkw@263.net</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>zh&&lowbar;;TW&&lowbar;;Big5 Équipe de traduction en Chinois BIG5 :</term>
<listitem>
<para>coordinateur :  Chou Yeh-Jyi
<ulink url="mailto:ycchou@ccca.nctu.edu.tw">ycchou@ccca.nctu.edu.tw</ulink></para>
</listitem>
</varlistentry>
</variablelist>
</para>
</sect1>
</chapter>

<chapter id="trouver-les-erreurs">
<title>Trouver les Erreurs</title>

<para><indexterm><primary>Macros de déboguage</primary></indexterm></para>

<sect1 id="macros-de-dboguage-fournies-par-qt-qt">
<title>Macros de déboguage fournies par Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></title>

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

<para>Les macros les plus utilisées sont</para>

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

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

<para>Des détails peuvent être trouvés dans la Référence en ligne de Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>.</para>
</sect1>

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

<para><emphasis remap="bf">NOTE :</emphasis> Ce chapitre est une copie du document de Kalle Dalheimer  
<ulink url="mailto:kalle@kde.org">kalle@kde.org</ulink>
expliquant les macros KDEBUG <indexterm remap="idx"><primary>KDEBUG</primary></indexterm> incluses dans le paquetage KDE-libs, à la
page kdebug.html.</para>

<para>Dernière modification : Sat Sep 13 11:56:01 CEST 1997</para>

<para><emphasis remap="bf">Qu'est-ce que KDebug</emphasis></para>

<para>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.</para>

<para><emphasis remap="bf">La macro KDEBUG <indexterm remap="idx"><primary>KDEBUG</primary></indexterm></emphasis></para>

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

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

<para>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 :</para>

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

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

<para>Il y a aussi les macros KASSERT, KASSERT1, ..., KASSERT9 qui fonctionnent comme
leurs équivalents KDEBUG <indexterm remap="idx"><primary>KDEBUG</primary></indexterm>, 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 <indexterm remap="idx"><primary>KDEBUG</primary></indexterm> ni KASSERT <indexterm remap="idx"><primary>KASSERT</primary></indexterm>
avant que l'objet <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication soit construit. Note 2&&nbsp;;: 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.</para>

<para><emphasis remap="bf">Options de compilation</emphasis></para>

<para>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).</para>

<para><emphasis remap="bf">Comment gérer les messages de diagnostic à l'exécution</emphasis></para>

<para>Vous pouvez appuyer sur Ctrl-Shift-F12, à n'importe quel moment, dans
toute <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>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 :</para>

<para><itemizedlist>
<listitem>
<para>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".</para>
</listitem>
<listitem>
<para>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.
</para>
</listitem>
<listitem>
<para>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.</para>
</listitem>
</itemizedlist>
</para>

<para>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 <indexterm remap="idx"><primary>KDEBUG&&lowbar;;FATAL</primary></indexterm>"
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.</para>
</sect1>
</chapter>

<chapter id="le-systme-de-fichiers-standard-de-kde">
<title>Le Système de Fichiers Standard de KDE</title>

<para>Ce chapitre est une copie du Système de Fichiers Standard de KDE (NdT :
KDE FSSTD) écrit par Richard Moore <ulink url="rich@kde.org">rich@kde.org</ulink> et publié sur le site web de KDE à <ulink url="http://www.kde.org">\|\|</ulink>.</para>

<para><emphasis remap="bf">Système de Fichiers Standard de KDE</emphasis></para>

<para>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.</para>

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

<para>Le but du KDE FSSTD <indexterm remap="idx"><primary>KDE FSSTD</primary></indexterm> est de s'assurer que toutes les ressources (icônes,
types Mime, etc) requises par les applications KDE <indexterm remap="idx"><primary>applications KDE</primary></indexterm> 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 
&&lt;;comme ceci&&gt;;, 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).</para>
</sect1>

<sect1 id="organisation-des-rpertoires">
<title>Organisation des Répertoires</title>

<para>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 <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>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.
<indexterm><primary>Système de Fichiers de KDE</primary></indexterm><indexterm><primary>fichiers .kdelnk</primary></indexterm></para>

<para><itemizedlist>
<listitem>
<para>kdedir()/
<itemizedlist>
<listitem>
<para>bin/
<itemizedlist>
<listitem>
<para>Binaires des applications</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>lib/
<itemizedlist>
<listitem>
<para>bibliothèques standards de kde (libkdecore, etc.)</para>
</listitem>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>Données spécifiques de l'application dépendantes de la
plate-forme</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>include/
<itemizedlist>
<listitem>
<para>fichiers d'en-tête standards de kde</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>parts/</para>
</listitem>
<listitem>
<para>cgi-bin/
<itemizedlist>
<listitem>
<para>programmes CGI pour kdehelp</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>share/
<itemizedlist>
<listitem>
<para>doc/
<itemizedlist>
<listitem>
<para>HTML/
<itemizedlist>
<listitem>
<para>default --&gt; Lien vers kdedir()/share/doc/HTML/en</para>
</listitem>
<listitem>
<para><emphasis>&&lt;;lang&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>/ 
<itemizedlist>
<listitem>
<para>index.html </para>
</listitem>
<listitem>
<para>autres fichiers d'aide de
l'application</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>config/</para>
</listitem>
<listitem>
<para>applnk/
<itemizedlist>
<listitem>
<para>System/</para>
</listitem>
<listitem>
<para>Utilities/</para>
</listitem>
<listitem>
<para>Applications/</para>
</listitem>
<listitem>
<para>Games/</para>
</listitem>
<listitem>
<para>kfind.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
<listitem>
<para>khelp.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
<listitem>
<para>khome.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
<listitem>
<para>krefresh.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>mimelnk/
<itemizedlist>
<listitem>
<para>magic</para>
</listitem>
<listitem>
<para>text/</para>
</listitem>
<listitem>
<para>audio/</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>partlnk/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;partname&&gt;;</emphasis>.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>icons/
<itemizedlist>
<listitem>
<para>Icônes utilisées dans les fichiers kdelnk</para>
</listitem>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>.xpm</para>
</listitem>
<listitem>
<para>mini/
<itemizedlist>
<listitem>
<para>Mini-icônes pour kpanel</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>/
<itemizedlist>
<listitem>
<para>Pixmaps standard de barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> (par ex : fileopen.xpm)</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>wallpapers/
<itemizedlist>
<listitem>
<para>Papiers peints utilisés par kdisplay</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>apps/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>/
<itemizedlist>
<listitem>
<para>Pixmaps de barre d'outils</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>pics/
<itemizedlist>
<listitem>
<para>Autres pixmaps de l'application</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>Données spécifiques à l'application
(indépendantes de la plate-forme) 		</para>
</listitem>
</itemizedlist>
     	</para>
</listitem>
<listitem>
<para><emphasis>&&lt;;libname&&gt;;</emphasis>/ 		
<itemizedlist>
<listitem>
<para>pics/</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>locale/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;lang&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>LC&&lowbar;;MESSAGES/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>.mo</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="ce-que-cela-signifie-pour-les-dveloppeurs-da">
<title>Ce que cela signifie pour les développeurs d'application</title>

<para>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 :</para>

<para><screen>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/&&lt;;appname&&gt;;.xpm 
Fichiers d'aide de l'application (requis)         kdedir()/share/doc/default/HTML/&&lt;;appname&&gt;;/&&lt;;index&&gt;;.html
Pixmaps de la barre d'outils de l'application     kdedir()/share/apps/&&lt;;appname&&gt;;/toolbar/ 
Données de l'application (pour la plate-forme)    kdedir()/share/apps/&&lt;;appname&&gt;;/ 
Données de l'application (non-spécifiques)        kdedir()/lib/&&lt;;appname&&gt;;/ 
</screen>

<indexterm><primary>Système de Fichiers de KDE</primary></indexterm></para>
</sect1>

<sect1 id="documentation-de-lapplication">
<title>Documentation de l'Application </title>

<para>J'ai suggéré de mettre nécessairement au moins une page dans </para>

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

<para>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.</para>

<para>Les applications qui supportent plus d'une langue devront placer les
autres langues dans kdedir()/doc/&&lt;;lang&&gt;;/HTML/&&lt;;appname&&gt;;/&&lt;;appname&&gt;;.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.</para>

<para>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.</para>
</sect1>

<sect1 id="ce-que-cela-signifie-pour-les-dveloppeurs-de">
<title>Ce que cela signifie pour les développeurs de bibliothèques</title>

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

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

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

Toute autre image bitmap pour les widgets de la bibliothèque</para>
</sect1>
</chapter>

<chapter id="utilisation-du-systme-de-fichiers-dans-les-p">
<title>Utilisation du Système de Fichiers dans les Projets KDevelop</title>

<para>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.</para>

<sect1 id="accder-des-fichiers-pendant-lexcution">
<title>Accéder à des Fichiers pendant l'Exécution</title>

<para>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 <indexterm remap="idx"><primary>KDEHelp</primary></indexterm> d'ouvrir votre page d'index en cherchant le répertoire d'installation
à travers les méthodes de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> pour accéder au système de
fichiers, nous allons donc regarder ce que <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> propose
et examiner quelques exemples d'utilisation. D'autres classes de <literal remap="tt">KDE-Core</literal>, telles que
<literal remap="tt">KIconLoader</literal> et <literal remap="tt">KLocale</literal>, font aussi usage du système de
fichier KDE ; nous en reparlerons plus loin.</para>
</sect1>

<sect1 id="mthodes-de-kapplicationkapplication">
<title>Méthodes de <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</title>

<para>La classe <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication offre les méthodes suivantes pour accéder au système de fichiers KDE :
<screen>void invokeHTMLHelp ( QString aFilename, QString aTopic ) const
static const QString& kde_htmldir ()
static const QString& kde_appsdir ()
static const QString& kde_icondir ()
static const QString& kde_datadir ()
static const QString& kde_localedir ()
static const QString& kde_cgidir ()
static const QString& kde_sounddir ()
static const QString& kde_toolbardir ()
static const QString& kde_wallpaperdir ()
static const QString& kde_bindir ()
static const QString& kde_configdir ()
static const QString& kde_mimedir ()
static QString localkdedir ()
static QString localconfigdir ()
static QString findFile ( const char *file )
</screen>
</para>

<para><indexterm><primary>KDE File System</primary></indexterm>
Les méthodes sont généralement utilisées avec l'instance de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>
de votre application, où <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> offre une macro <literal remap="tt">kapp</literal>
destinée à recevoir le pointeur :</para>

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

<para>Les méthodes sont donc généralement utilisées de la façon suivante :
<screen>QString sounddir=kapp-&gt;kde_sounddir();
</screen>

Cet exemple enregistre le chemin du répertoire son de KDE sous forme d'une
<literal remap="tt">QString</literal>, 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 <literal remap="tt">exists()</literal> de la classe <literal remap="tt">QFileInfo</literal>.</para>

<para>Au sein de ces méthodes,</para>

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

<para>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 <literal remap="tt">pressed()</literal>.
Dans cette méthode, utilisez <literal remap="tt"><indexterm remap="cdx"><primary><literal>invokeHTMLHelp()</literal></primary></indexterm>invokeHTMLHelp()</literal> 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.</para>

<para>La documentation de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> dit :</para>

<para>Appelle le visualiseur d'aide HTML kdehelp.</para>

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

<para>aFilename&&nbsp;;: 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.</para>

<para>Les méthodes de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> extrairont les chemins suivants :</para>

<para><screen>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
</screen>
</para>

<para>Pour rechercher un fichier particulier, utilisez <literal remap="tt">findFile(const char *file)</literal> qui
recherchera parmi plusieurs chemins du Système de Fichiers de KDE :</para>

<para><orderedlist><listitem>
<para>$KDEDIR</para>
</listitem>
<listitem>
<para>$KDEPATH</para>
</listitem>
<listitem>
<para>"&&lsqb;;KDE Setup&&rsqb;;:Path=" entrée dans un fichier de configuration</para>
</listitem>
</orderedlist>
</para>

<para>Si le fichier est introuvable, la méthode isEmpty() de la classe QString renverra True (Vrai)</para>
</sect1>

<sect1 id="les-mthodes-de-kiconloader">
<title>Les Méthodes de KIconLoader</title>

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

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

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

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

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

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

<sect1 id="configurer-linstallation-des-fichiers">
<title>Configurer l'Installation des Fichiers</title>

<para>Nous avons vu plus haut où les applications KDE <indexterm remap="idx"><primary>applications KDE</primary></indexterm> 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.</para>

<para>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 :</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">HEADER :</emphasis>  spécifie un fichier comme fichier d'en-tête</para>
</listitem>
<listitem>
<para><emphasis remap="bf">SOURCE :</emphasis> spécifie un fichier comme fichier source</para>
</listitem>
<listitem>
<para><emphasis remap="bf">SCRIPT :</emphasis> spécifie un fichier comme fichier script</para>
</listitem>
<listitem>
<para><emphasis remap="bf">DATA :</emphasis> spécifie un fichier comme fichier de données, qui s'installe
généralement comme une icône ou une documentation HTML</para>
</listitem>
<listitem>
<para><emphasis remap="bf">PO :</emphasis> spécifie un fichier comme fichier de traduction</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KDEV&&lowbar;;DIALOG :</emphasis> spécifie un fichier comme fichier de boîte de dialogue
destiné à être interprété par la bibliothèque des boîtes de dialogue</para>
</listitem>
</itemizedlist>
</para>

<para>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.</para>

<para>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é.</para>

<para>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.</para>

<para>Si vous regardez un projet d'application KDE standard, vous remarquerez dans les
propriétés de votre fichier <literal remap="tt">index.html</literal> qu'il utilise déjà une macro
permettant de déterminer où il doit aller :</para>

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

<para>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.</para>

<para>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 :</para>

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

<para>Valeurs possibles (selon le Standard du Système de Fichiers de KDE) :</para>

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

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

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

<para><screen>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.
</screen>
</para>

<para>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.</para>
</sect1>

<sect1 id="organiser-les-donnes-du-projet">
<title>Organiser les Données du Projet</title>

<para>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 ?</para>

<para>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 <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> 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 <literal remap="tt">toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm></literal> ; 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 <literal remap="tt">toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm></literal> 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.</para>

<para>À titre d'exemple, une icône de barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> peut aller au chemin suivant :</para>

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

<para>Les images et les icônes supplémentaires non utilisées comme les icônes de
barre d'outils <indexterm remap="idx"><primary>barre d'outils</primary></indexterm> peuvent être stockées dans un sous-répertoire
<emphasis>pics</emphasis> au lieu de <emphasis>toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm></emphasis>.</para>
</sect1>

<sect1 id="le-fichier-kdelnk">
<title>Le Fichier <literal remap="tt">kdelnk</literal></title>

<para>Le fichier <emphasis>&&lt;;appname&&gt;;</emphasis>.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm> 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.</para>

<para>Le fichier kdelnk par défaut ressemblera à ça :
<screen># KDE Config File
&&lsqb;;KDE Desktop Entry&&rsqb;;
Type=Application
Exec=kscribble
Icon=kscribble.xpm
DocPath=kscribble/index.html
Comment=
Comment&&lsqb;;de&&rsqb;;=
Terminal=0
Name=kscribble
Name&&lsqb;;de&&rsqb;;=kscribble
</screen>
</para>

<para>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 :</para>

<para><screen>Comment=Un simple programme de dessin
</screen>
</para>

<para>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.</para>

<para>
<footnote>
<para>Pour plus d'informations sur le but du fichier kdelnk, en particulier
pour l'interprétation de la ligne de commande, voir
<ulink url="kde_libref.html">Référence des Bibliothèques KDE</ulink></para>
</footnote>
</para>
</sect1>
</chapter>

<chapter id="conseils-de-programmation">
<title>Conseils de Programmation</title>

<para>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 <ulink url="http://www.kde.org">\|\|</ulink>, d'autres sont le fruit
de mon expérience personnelle.</para>

<sect1 id="rgles-gnrales">
<title>Règles générales</title>

<para><variablelist>
<varlistentry>
<term>Noms de fichiers</term>
<listitem>
<para>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.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Noms de classes</term>
<listitem>
<para>Il est conseillé que les noms de classes des projets
KDE respectent ces règles :
<itemizedlist>
<listitem>
<para>les noms de classe devraient commencer par la lettre <emphasis remap="bf">K</emphasis> suivie du nom
de la classe exprimant son intérêt. Cela peut être par exemple <literal remap="tt">KMyWidget</literal>
pour un widget spécifique à une application&&nbsp;;;</para>
</listitem>
<listitem>
<para>les champs de classe devraient toujours commencer par des minuscules,
avec la première lettre en majuscule pour les mots suivants, comme par
exemple <literal remap="tt">myWidgetPointer()</literal>&&nbsp;;;</para>
</listitem>
<listitem>
<para>les méthodes qui renvoient la valeur d'un champ privé ne devraient pas
utiliser le préfixe <literal remap="tt">get</literal>. Vous devriez lui préférer un nom descriptif.
Exemple : <literal remap="tt">b&&lowbar;;myboolean</literal> est un champ privé. La méthode renvoyant la valeur
actuelle serait par exemple <literal remap="tt">myBoolean()</literal>.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Accès aux fichiers au sein du code</term>
<listitem>
<para>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 <literal remap="tt">Makefile.am</literal> comme décrit dans le présent
manuel. Au sein du code, vous devriez utiliser les méthodes de
<literal remap="tt">KApplication</literal> pour extraire le chemin réel.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Documentation des classes</term>
<listitem>
<para>Autre point déjà mentionné, la documentation des classes. Vous devriez utiliser
les règles de formatage de <literal remap="tt">KDoc</literal> 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 <literal remap="tt">KDoc</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Utilisez <literal remap="tt">new</literal> pour créer des widgets</term>
<listitem>
<para>Au sein de votre implantation, vous devriez toujours préférer la création
massive de widgets avec <literal remap="tt">new</literal>. La bibliothèque Qt a la bonne habitude
de supprimer automatiquement tous les widgets fils créés avec <literal remap="tt">new</literal>, vous
n'avez donc pas à utiliser <literal remap="tt">delete</literal> dans ces cas. C'est une des
fonctionnalités pratiques des plus importantes de Qt et vous devriez en user
et en abuser.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Deboguage</term>
<listitem>
<para>Quand vient le moment de déboguer, vous devriez utiliser les macros fournies
par <literal remap="tt">KDebug</literal>. Celles-ci sont similaires aux macros Qt, mais peuvent être
obtenues par CTRL+SHIFT+F12. Voir <ulink url="../kde_libref/index-4.html#ss4.4">Référence des Bibliothèques KDE</ulink> pour plus d'informations sur le
filtrage d'évenements de ces macros. Vous pourriez aussi utiliser
<literal remap="tt">assert()</literal>, mais vous devriez essayer d'être logique dans votre code de déboguage.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Déclarations <literal remap="tt">const</literal></term>
<listitem>
<para>Par la suite, vous devriez utiliser des déclarations <literal remap="tt">const</literal> 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 <literal remap="tt">static</literal> et initialiser la valeur en dehors
du constructeur, comme ceci :</para>
<para><screen>class foo {
	static const int value;
};

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

Le C++ ANSI autorise l'initialisation du champ dans le constructeur mais vous
devriez l'éviter car certains compilateurs n'offrent pas cette fonctionnalité.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Les méthodes virtuelles</term>
<listitem>
<para>Comme nous l'avons vu dans la section <link linkend="User-Interaction">Interaction avec l'Utilisateur</link>, vous devriez conserver les droits d'accès
et la déclaration par <literal remap="tt">virtual</literal> 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é.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Déclarations anticipées</term>
<listitem>
<para>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 :</para>
<para><screen>#include &lt;qpushbutton.h&gt;

class KMyWidget:public QWidget
{

private:
  QPushButton* ok_button;
};
</screen>
</para>
<para>déclarez seulement la classe <literal remap="tt">QPushButton</literal> dans le fichier d'en-tête :</para>
<para><screen>class QPushButton;

class KMyWidget:public QWidget
{

private:
  QPushButton* ok_button;
};
</screen>
</para>
<para>et placez la directive d'inclusion dans le fichier source correspondant
où, par exemple, l'instance <literal remap="tt">ok&&lowbar;;button</literal> est déréférencée avec une
méthode de la classe <literal remap="tt">QPushButton</literal>. 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.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Avertissements de Paramètres Inutiles et arguments par défaut</term>
<listitem>
<para>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 <literal remap="tt">paramètre inutilisé</literal> 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.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Utiliser <literal remap="tt">config.h</literal></term>
<listitem>
<para>Les projets KDevelop comme tout autre projet qui utilise <literal remap="tt">autoconf</literal>
pour créer les script <literal remap="tt">configure</literal> produisent un fichier <literal remap="tt">config.h</literal>
après l'exécution du script <literal remap="tt">configure</literal> sur la machine cible.
Les valeurs trouvées par <literal remap="tt">configure</literal> sont listées dedans et
peuvent être utilisées dans le code source. La directive
pour inclure le fichier <literal remap="tt">config.h</literal> est :</para>
<para><screen>#ifdef HAVE_CONFIG_H
#include &lt;config.h&gt;
#endif
</screen>
</para>
<para>Une des entrées de <literal remap="tt">config.h</literal> les plus couramment utilisées est probablement
le définition du type <literal remap="tt">bool</literal> pour les compilateurs qui ne respectent pas la
norme la plus récente du C++ ANSI.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Utiliser <literal remap="tt">0</literal> au lieu de <literal remap="tt">NULL</literal></term>
<listitem>
<para>Vous devriez toujours utiliser directement <literal remap="tt">0</literal> au lieu de <literal remap="tt">NULL</literal>
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 <literal remap="tt">NULL</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Variables temporaires</term>
<listitem>
<para>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 :</para>
<para><screen>// Ne faites pas :
for( int i=0; i&lt;n; i++){
  // faire quelque chose
  };

// Mais écrivez :
int i;

for(i=0; i&lt;n; i++){
  // faire quelque chose
  };
</screen>
</para>
<para>Cela est aussi valable pour les variables temporaires dans les appels de fonctions :</para>
<para><screen>// Ne faites pas :
setColor( &&amp;;(QColor(black)) );

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

<sect1 id="dpendances-des-systmes-dexploitation">
<title>Dépendances des Systèmes d'Exploitation</title>

<para>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.</para>

<para>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.</para>

<para>Néanmoins, si vous utilisez Qt et que vous avez besoin d'utiliser
des &&num;;defines pour votre application, vous devriez inclure
<literal remap="tt">qglobal.h</literal> 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.</para>

<para>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) :</para>

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

<chapter id="licences">
<title>Licences</title>

<para>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.</para>

<sect1 id="la-licence-gpl">
<title>La Licence GPL</title>

<para>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.</para>

<para>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 <emphasis>peuvent</emphasis> utiliser cette licence
comme une base pour distribuer leur produit mais n'y sont pas obligés.</para>

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

<para><itemizedlist>
<listitem>
<para>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é)&&nbsp;;;</para>
</listitem>
<listitem>
<para>votre code possède une licence de copyright qui protège vos droits
comme auteur original&&nbsp;;;</para>
</listitem>
<listitem>
<para>la réutilisation de votre code par d'autres auteurs améliore
le développement global d'applications libres.</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="questions-sur-les-licences-de-kde-et-qt">
<title>Questions sur les Licences de KDE et Qt</title>

<para>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 :
<itemizedlist>
<listitem>
<para>en achetant une licence commerciale, vous pouvez écrire des applications
portables pour les plates-formes Unix et Windows</para>
</listitem>
<listitem>
<para>l'architecture de classes et d'applications fournit une bonne solution
pour simplifier la conception d'application</para>
</listitem>
<listitem>
<para>vous pouvez développer pour les Unices sans dépendre de la licence GPL
lorsque vous utilisez une licence commerciale.</para>
</listitem>
</itemizedlist>
</para>

<para>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.</para>

<para>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 ?</para>

<sect2 id="dveloppement-non-commercial">
<title>Développement non-commercial</title>

<para>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.</para>

<para>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.</para>
</sect2>

<sect2 id="dveloppement-commercial">
<title>Développement commercial</title>

<para>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.</para>

<para>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.</para>
</sect2>
</sect1>

<sect1 id="la-licence-de-votre-produit">
<title>La Licence de votre Produit</title>

<para>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 :</para>

<para><itemizedlist>
<listitem>
<para>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&&nbsp;;;</para>
</listitem>
<listitem>
<para>pour les applications KDE : les restrictions de la licence de Qt
selon la nature de votre distribution <emphasis>plus</emphasis> les restrictions
de la LGPL (GNU Library General Public License) telle qu'elle est incluse
dans votre copie des bibliothèques de KDE&&nbsp;;;</para>
</listitem>
<listitem>
<para>pour tous les autres codes sources pré-générés, vous êtes libre du choix de
la licence.</para>
</listitem>
</itemizedlist>
</para>

<para>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.</para>

<para>Si vous avez des questions supplémentaires sur les licences, n'hésitez
pas à interroger l'Équipe KDevelop.</para>
</sect1>
</chapter>

<chapter id="rfrences">
<title>Références</title>

<para>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 :</para>

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

<para><emphasis remap="bf">Centre du Développeur KDE</emphasis> maintenu par Sirtaj S. Kang <ulink url="mailto:taj@.kde.org">taj@.kde.org</ulink></para>

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

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

<para><emphasis remap="bf">Le Système de Fichiers Standard de KDE :</emphasis> Richard Moore <ulink url="mailto:rich@kde.org">rich@kde.org</ulink></para>

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

<para>Le contenu des chapitres correspondants sont la propriété des auteurs originaux.</para>
</chapter>

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

<para><screen>
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.
</screen>
</para>
</chapter>
<appendix id="informations-supplmentaires-0">
<title>Informations supplémentaires</title>

<sect1 id="exemple-de-makefile.am-pour-une-bibliothque-">
<title>Exemple de Makefile.am pour une bibliothèque partagée</title>

<para><screen># 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
</screen>
</para>
</sect1>
</appendix>
<![ %addindex; [ &docindex; ]]>
</book>
<!--
Local Variables:
mode: sgml
sgml-omittag: nil
sgml-shorttag: t
sgml-general-insert-case: lower
End:
-->
